Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(507)

Unified Diff: src/parser.cc

Issue 152813005: Make strict more error messages about "eval" and "arguments" less specific. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Code review (ulan@) Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/parser.cc
diff --git a/src/parser.cc b/src/parser.cc
index 50551ea98d386efaadcf0b8c245ba308214cc71f..211f737d6d89c9fd202f9b1cd0af233c50a04627 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -983,7 +983,7 @@ Statement* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) {
// 'module' Identifier Module
int pos = peek_position();
- Handle<String> name = ParseIdentifier(CHECK_OK);
+ Handle<String> name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
#ifdef DEBUG
if (FLAG_print_interface_details)
@@ -1136,7 +1136,7 @@ Module* Parser::ParseModuleVariable(bool* ok) {
// Identifier
int pos = peek_position();
- Handle<String> name = ParseIdentifier(CHECK_OK);
+ Handle<String> name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
#ifdef DEBUG
if (FLAG_print_interface_details)
PrintF("# Module variable %s ", name->ToAsciiArray());
@@ -1261,13 +1261,14 @@ Statement* Parser::ParseExportDeclaration(bool* ok) {
switch (peek()) {
case Token::IDENTIFIER: {
int pos = position();
- Handle<String> name = ParseIdentifier(CHECK_OK);
+ Handle<String> name =
+ ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
// Handle 'module' as a context-sensitive keyword.
if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("module"))) {
names.Add(name, zone());
while (peek() == Token::COMMA) {
Consume(Token::COMMA);
- name = ParseIdentifier(CHECK_OK);
+ name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
names.Add(name, zone());
}
ExpectSemicolon(CHECK_OK);
@@ -1632,11 +1633,12 @@ void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) {
Statement* Parser::ParseNativeDeclaration(bool* ok) {
int pos = peek_position();
Expect(Token::FUNCTION, CHECK_OK);
- Handle<String> name = ParseIdentifier(CHECK_OK);
+ // Allow "eval" or "arguments" for backward compatibility.
+ Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
Expect(Token::LPAREN, CHECK_OK);
bool done = (peek() == Token::RPAREN);
while (!done) {
- ParseIdentifier(CHECK_OK);
+ ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
done = (peek() == Token::RPAREN);
if (!done) {
Expect(Token::COMMA, CHECK_OK);
@@ -1900,16 +1902,9 @@ Block* Parser::ParseVariableDeclarations(
// Parse variable name.
if (nvars > 0) Consume(Token::COMMA);
- name = ParseIdentifier(CHECK_OK);
+ name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
if (fni_ != NULL) fni_->PushVariableName(name);
- // Strict mode variables may not be named eval or arguments
- if (!declaration_scope->is_classic_mode() && IsEvalOrArguments(name)) {
- ReportMessage("strict_var_name", Vector<const char*>::empty());
- *ok = false;
- return NULL;
- }
-
// Declare variable.
// Note that we *always* must treat the initial value via a separate init
// assignment for variables and constants because the value must be assigned
@@ -2224,7 +2219,8 @@ Statement* Parser::ParseContinueStatement(bool* ok) {
Token::Value tok = peek();
if (!scanner().HasAnyLineTerminatorBeforeNext() &&
tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
- label = ParseIdentifier(CHECK_OK);
+ // ECMA allows "eval" or "arguments" as labels even in strict mode.
+ label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
}
IterationStatement* target = NULL;
target = LookupContinueTarget(label, CHECK_OK);
@@ -2255,7 +2251,8 @@ Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) {
Token::Value tok = peek();
if (!scanner().HasAnyLineTerminatorBeforeNext() &&
tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
- label = ParseIdentifier(CHECK_OK);
+ // ECMA allows "eval" or "arguments" as labels even in strict mode.
+ label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
}
// Parse labeled break statements that target themselves into
// empty statements, e.g. 'l1: l2: l3: break l2;'
@@ -2485,13 +2482,7 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
Expect(Token::LPAREN, CHECK_OK);
catch_scope = NewScope(top_scope_, CATCH_SCOPE);
catch_scope->set_start_position(scanner().location().beg_pos);
- name = ParseIdentifier(CHECK_OK);
-
- if (!top_scope_->is_classic_mode() && IsEvalOrArguments(name)) {
- ReportMessage("strict_catch_variable", Vector<const char*>::empty());
- *ok = false;
- return NULL;
- }
+ name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
Expect(Token::RPAREN, CHECK_OK);
@@ -2939,7 +2930,7 @@ Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) {
if (!top_scope_->is_classic_mode()) {
// Assignment to eval or arguments is disallowed in strict mode.
- CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK);
+ CheckStrictModeLValue(expression, CHECK_OK);
}
MarkAsLValue(expression);
@@ -3219,7 +3210,7 @@ Expression* Parser::ParseUnaryExpression(bool* ok) {
if (!top_scope_->is_classic_mode()) {
// Prefix expression operand in strict mode may not be eval or arguments.
- CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK);
+ CheckStrictModeLValue(expression, CHECK_OK);
}
MarkAsLValue(expression);
@@ -3253,7 +3244,7 @@ Expression* Parser::ParsePostfixExpression(bool* ok) {
if (!top_scope_->is_classic_mode()) {
// Postfix expression operand in strict mode may not be eval or arguments.
- CheckStrictModeLValue(expression, "strict_lhs_postfix", CHECK_OK);
+ CheckStrictModeLValue(expression, CHECK_OK);
}
MarkAsLValue(expression);
@@ -3563,7 +3554,8 @@ Expression* Parser::ParsePrimaryExpression(bool* ok) {
case Token::IDENTIFIER:
case Token::YIELD:
case Token::FUTURE_STRICT_RESERVED_WORD: {
- Handle<String> name = ParseIdentifier(CHECK_OK);
+ // Using eval or arguments in this context is OK even in strict mode.
+ Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
if (fni_ != NULL) fni_->PushVariableName(name);
// The name may refer to a module instance object, so its type is unknown.
#ifdef DEBUG
@@ -4303,13 +4295,13 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
if (!top_scope_->is_classic_mode()) {
if (IsEvalOrArguments(function_name)) {
ReportMessageAt(function_name_location,
- "strict_function_name",
+ "strict_eval_arguments",
Vector<const char*>::empty());
*ok = false;
return NULL;
}
if (name_loc.IsValid()) {
- ReportMessageAt(name_loc, "strict_param_name",
+ ReportMessageAt(name_loc, "strict_eval_arguments",
Vector<const char*>::empty());
*ok = false;
return NULL;
@@ -4398,7 +4390,8 @@ Expression* Parser::ParseV8Intrinsic(bool* ok) {
int pos = peek_position();
Expect(Token::MOD, CHECK_OK);
- Handle<String> name = ParseIdentifier(CHECK_OK);
+ // Allow "eval" or "arguments" for backward compatibility.
+ Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
if (extension_ != NULL) {
@@ -4505,13 +4498,25 @@ Literal* Parser::GetLiteralTheHole(int position) {
// Parses an identifier that is valid for the current scope, in particular it
-// fails on strict mode future reserved keywords in a strict scope.
-Handle<String> Parser::ParseIdentifier(bool* ok) {
+// fails on strict mode future reserved keywords in a strict scope. If
+// allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or
+// "arguments" as identifier even in strict mode (this is needed in cases like
+// "var foo = eval;").
+Handle<String> Parser::ParseIdentifier(
+ AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments,
+ bool* ok) {
Token::Value next = Next();
- if (next == Token::IDENTIFIER ||
- (top_scope_->is_classic_mode() &&
- (next == Token::FUTURE_STRICT_RESERVED_WORD ||
- (next == Token::YIELD && !is_generator())))) {
+ if (next == Token::IDENTIFIER) {
+ Handle<String> name = GetSymbol();
+ if (allow_eval_or_arguments == kDontAllowEvalOrArguments &&
+ !top_scope_->is_classic_mode() && IsEvalOrArguments(name)) {
+ ReportMessage("strict_eval_arguments", Vector<const char*>::empty());
+ *ok = false;
+ }
+ return name;
+ } else if (top_scope_->is_classic_mode() &&
+ (next == Token::FUTURE_STRICT_RESERVED_WORD ||
+ (next == Token::YIELD && !is_generator()))) {
return GetSymbol();
} else {
ReportUnexpectedToken(next);
@@ -4566,7 +4571,6 @@ void Parser::MarkAsLValue(Expression* expression) {
// Checks LHS expression for assignment and prefix/postfix increment/decrement
// in strict mode.
void Parser::CheckStrictModeLValue(Expression* expression,
- const char* error,
bool* ok) {
ASSERT(!top_scope_->is_classic_mode());
VariableProxy* lhs = expression != NULL
@@ -4574,7 +4578,7 @@ void Parser::CheckStrictModeLValue(Expression* expression,
: NULL;
if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) {
- ReportMessage(error, Vector<const char*>::empty());
+ ReportMessage("strict_eval_arguments", Vector<const char*>::empty());
*ok = false;
}
}
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698