Index: src/parser.cc |
diff --git a/src/parser.cc b/src/parser.cc |
index 339206b1346726330632ff918ecdfbd5b6148369..46077458376fac3ecb479d3113d3357350186b38 100644 |
--- a/src/parser.cc |
+++ b/src/parser.cc |
@@ -1263,6 +1263,7 @@ Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { |
return ParseBlock(labels, ok); |
case Token::CONST: // fall through |
+ case Token::LET: |
case Token::VAR: |
stmt = ParseVariableStatement(kStatement, ok); |
break; |
@@ -1704,6 +1705,16 @@ Block* Parser::ParseVariableDeclarations( |
if (peek() == Token::VAR) { |
Consume(Token::VAR); |
} else if (peek() == Token::CONST) { |
+ // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads: |
+ // |
+ // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';' |
+ // |
+ // * It is a Syntax Error if the code that matches this production is not |
+ // contained in extended code. |
+ // |
+ // However disallowing const in classic mode will break compatibility with |
+ // existing pages. Therefore we keep allowing const with the old |
+ // non-harmony semantics in classic mode. |
Consume(Token::CONST); |
switch (top_scope_->language_mode()) { |
case CLASSIC_MODE: |
@@ -1729,7 +1740,17 @@ Block* Parser::ParseVariableDeclarations( |
is_const = true; |
needs_init = true; |
} else if (peek() == Token::LET) { |
- ASSERT(top_scope_->is_extended_mode()); |
+ // ES6 Draft Rev4 section 12.2.1: |
+ // |
+ // LetDeclaration : let LetBindingList ; |
+ // |
+ // * It is a Syntax Error if the code that matches this production is not |
+ // contained in extended code. |
+ if (!is_extended_mode()) { |
+ ReportMessage("illegal_let", Vector<const char*>::empty()); |
+ *ok = false; |
+ return NULL; |
+ } |
Consume(Token::LET); |
if (var_context != kSourceElement && |
var_context != kForStatement) { |
@@ -2668,6 +2689,7 @@ Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
// Assignment to eval or arguments is disallowed in strict mode. |
CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK); |
} |
+ MarkAsLValue(expression); |
Token::Value op = Next(); // Get assignment operator. |
int pos = scanner().location().beg_pos; |
@@ -2901,6 +2923,7 @@ Expression* Parser::ParseUnaryExpression(bool* ok) { |
// Prefix expression operand in strict mode may not be eval or arguments. |
CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); |
} |
+ MarkAsLValue(expression); |
int position = scanner().location().beg_pos; |
return new(zone()) CountOperation(isolate(), |
@@ -2936,6 +2959,7 @@ Expression* Parser::ParsePostfixExpression(bool* ok) { |
// Postfix expression operand in strict mode may not be eval or arguments. |
CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); |
} |
+ MarkAsLValue(expression); |
Token::Value next = Next(); |
int position = scanner().location().beg_pos; |
@@ -4294,6 +4318,15 @@ Handle<String> Parser::ParseIdentifierName(bool* ok) { |
} |
+void Parser::MarkAsLValue(Expression* expression) { |
+ VariableProxy* proxy = expression != NULL |
+ ? expression->AsVariableProxy() |
+ : NULL; |
+ |
+ if (proxy != NULL) proxy->MarkAsLValue(); |
+} |
+ |
+ |
// Checks LHS expression for assignment and prefix/postfix increment/decrement |
// in strict mode. |
void Parser::CheckStrictModeLValue(Expression* expression, |