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