| 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,
|
|
|