Revision: 6503
Author: [email protected]
Date: Wed Jan 26 11:21:46 2011
Log: Strict mode eval/arguments LHS.

Review URL: http://codereview.chromium.org/6335013/
http://code.google.com/p/v8/source/detail?r=6503

Modified:
 /branches/bleeding_edge/src/messages.js
 /branches/bleeding_edge/src/parser.cc
 /branches/bleeding_edge/src/parser.h
 /branches/bleeding_edge/test/mjsunit/strict-mode.js

=======================================
--- /branches/bleeding_edge/src/messages.js     Wed Jan 26 07:16:13 2011
+++ /branches/bleeding_edge/src/messages.js     Wed Jan 26 11:21:46 2011
@@ -241,6 +241,9 @@
strict_duplicate_property: "Duplicate data property in object literal not allowed in strict mode", accessor_data_property: "Object literal may not have data and accessor property with the same name", accessor_get_set: "Object literal may not have multiple get/set accessors with the same name", + strict_lhs_eval_assignment: "Assignment to eval or arguments is not allowed in strict mode", + strict_lhs_postfix: "Postfix increment/decrement may not have eval or arguments operand in strict mode", + strict_lhs_prefix: "Prefix increment/decrement may not have eval or arguments operand in strict mode",
     };
   }
   var format = kMessages[message.type];
=======================================
--- /branches/bleeding_edge/src/parser.cc       Tue Jan 25 10:42:35 2011
+++ /branches/bleeding_edge/src/parser.cc       Wed Jan 26 11:21:46 2011
@@ -2291,6 +2291,11 @@
     Handle<String> type = Factory::invalid_lhs_in_assignment_symbol();
     expression = NewThrowReferenceError(type);
   }
+
+  if (temp_scope_->StrictMode()) {
+    // Assignment to eval or arguments is disallowed in strict mode.
+    CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK);
+  }

   Token::Value op = Next();  // Get assignment operator.
   int pos = scanner().location().beg_pos;
@@ -2518,6 +2523,12 @@
       Handle<String> type = Factory::invalid_lhs_in_prefix_op_symbol();
       expression = NewThrowReferenceError(type);
     }
+
+    if (temp_scope_->StrictMode()) {
+ // Prefix expression operand in strict mode may not be eval or arguments.
+      CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK);
+    }
+
     int position = scanner().location().beg_pos;
     IncrementOperation* increment = new IncrementOperation(op, expression);
     return new CountOperation(true /* prefix */, increment, position);
@@ -2543,6 +2554,12 @@
       Handle<String> type = Factory::invalid_lhs_in_postfix_op_symbol();
       expression = NewThrowReferenceError(type);
     }
+
+    if (temp_scope_->StrictMode()) {
+ // Postfix expression operand in strict mode may not be eval or arguments.
+      CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK);
+    }
+
     Token::Value next = Next();
     int position = scanner().location().beg_pos;
IncrementOperation* increment = new IncrementOperation(next, expression);
@@ -3691,6 +3708,24 @@
   }
   return GetSymbol(ok);
 }
+
+
+// Checks LHS expression for assignment and prefix/postfix increment/decrement
+// in strict mode.
+void Parser::CheckStrictModeLValue(Expression* expression,
+                                   const char* error,
+                                   bool* ok) {
+  ASSERT(temp_scope_->StrictMode());
+  VariableProxy* lhs = expression != NULL
+      ? expression->AsVariableProxy()
+      : NULL;
+
+  if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) {
+    ReportMessage(error, Vector<const char*>::empty());
+    *ok = false;
+  }
+}
+

 // Checks whether octal literal last seen is between beg_pos and end_pos.
 // If so, reports an error.
=======================================
--- /branches/bleeding_edge/src/parser.h        Mon Jan 24 10:13:18 2011
+++ /branches/bleeding_edge/src/parser.h        Wed Jan 26 11:21:46 2011
@@ -613,6 +613,11 @@
                                            bool* is_set,
                                            bool* ok);

+  // Strict mode validation of LValue expressions
+  void CheckStrictModeLValue(Expression* expression,
+                             const char* error,
+                             bool* ok);
+
   // Strict mode octal literal validation.
   void CheckOctalLiteral(int beg_pos, int end_pos, bool* ok);

=======================================
--- /branches/bleeding_edge/test/mjsunit/strict-mode.js Wed Jan 26 10:10:26 2011 +++ /branches/bleeding_edge/test/mjsunit/strict-mode.js Wed Jan 26 11:21:46 2011
@@ -203,3 +203,65 @@
 assertThrows("var x = { get 'foo'() { }, 'foo': 'data' };", SyntaxError)
 assertThrows("var x = { '12': 1, get '12'(){}};", SyntaxError);
 assertThrows("var x = { '12': 1, get 12(){}};", SyntaxError);
+
+// Assignment to eval or arguments
+CheckStrictMode("function strict() { eval = undefined; }", SyntaxError)
+CheckStrictMode("function strict() { arguments = undefined; }", SyntaxError) +CheckStrictMode("function strict() { print(eval = undefined); }", SyntaxError) +CheckStrictMode("function strict() { print(arguments = undefined); }", SyntaxError) +CheckStrictMode("function strict() { var x = eval = undefined; }", SyntaxError) +CheckStrictMode("function strict() { var x = arguments = undefined; }", SyntaxError)
+
+// Compound assignment to eval or arguments
+CheckStrictMode("function strict() { eval *= undefined; }", SyntaxError)
+CheckStrictMode("function strict() { arguments /= undefined; }", SyntaxError) +CheckStrictMode("function strict() { print(eval %= undefined); }", SyntaxError) +CheckStrictMode("function strict() { print(arguments %= undefined); }", SyntaxError) +CheckStrictMode("function strict() { var x = eval += undefined; }", SyntaxError) +CheckStrictMode("function strict() { var x = arguments -= undefined; }", SyntaxError)
+CheckStrictMode("function strict() { eval <<= undefined; }", SyntaxError)
+CheckStrictMode("function strict() { arguments >>= undefined; }", SyntaxError) +CheckStrictMode("function strict() { print(eval >>>= undefined); }", SyntaxError) +CheckStrictMode("function strict() { print(arguments &= undefined); }", SyntaxError) +CheckStrictMode("function strict() { var x = eval ^= undefined; }", SyntaxError) +CheckStrictMode("function strict() { var x = arguments |= undefined; }", SyntaxError)
+
+// Postfix increment with eval or arguments
+CheckStrictMode("function strict() { eval++; }", SyntaxError)
+CheckStrictMode("function strict() { arguments++; }", SyntaxError)
+CheckStrictMode("function strict() { print(eval++); }", SyntaxError)
+CheckStrictMode("function strict() { print(arguments++); }", SyntaxError)
+CheckStrictMode("function strict() { var x = eval++; }", SyntaxError)
+CheckStrictMode("function strict() { var x = arguments++; }", SyntaxError)
+
+// Postfix decrement with eval or arguments
+CheckStrictMode("function strict() { eval--; }", SyntaxError)
+CheckStrictMode("function strict() { arguments--; }", SyntaxError)
+CheckStrictMode("function strict() { print(eval--); }", SyntaxError)
+CheckStrictMode("function strict() { print(arguments--); }", SyntaxError)
+CheckStrictMode("function strict() { var x = eval--; }", SyntaxError)
+CheckStrictMode("function strict() { var x = arguments--; }", SyntaxError)
+
+// Prefix increment with eval or arguments
+CheckStrictMode("function strict() { ++eval; }", SyntaxError)
+CheckStrictMode("function strict() { ++arguments; }", SyntaxError)
+CheckStrictMode("function strict() { print(++eval); }", SyntaxError)
+CheckStrictMode("function strict() { print(++arguments); }", SyntaxError)
+CheckStrictMode("function strict() { var x = ++eval; }", SyntaxError)
+CheckStrictMode("function strict() { var x = ++arguments; }", SyntaxError)
+
+// Prefix decrement with eval or arguments
+CheckStrictMode("function strict() { --eval; }", SyntaxError)
+CheckStrictMode("function strict() { --arguments; }", SyntaxError)
+CheckStrictMode("function strict() { print(--eval); }", SyntaxError)
+CheckStrictMode("function strict() { print(--arguments); }", SyntaxError)
+CheckStrictMode("function strict() { var x = --eval; }", SyntaxError)
+CheckStrictMode("function strict() { var x = --arguments; }", SyntaxError)
+
+// Prefix unary operators other than delete, ++, -- are valid in strict mode
+function StrictModeUnaryOperators() {
+  "use strict";
+  var x = [void eval, typeof eval, +eval, -eval, ~eval, !eval];
+  var y = [void arguments, typeof arguments,
+           +arguments, -arguments, ~arguments, !arguments];
+}

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to