From 707ed29a51ae5c140f394a10fbaadb1811f75e4e Mon Sep 17 00:00:00 2001 From: "dslomov@chromium.org" Date: Thu, 23 Oct 2014 11:55:19 +0000 Subject: [PATCH] Revert "harmony-scoping: Allow 'const' iteration variables in strict mode." This reverts commit r24834 for breaking debug tests. TBR=bmeurer@chromium.org Review URL: https://codereview.chromium.org/672193002 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24839 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/parser.cc | 30 +++++--------- src/preparser.cc | 13 ++---- src/preparser.h | 8 +--- test/cctest/test-parsing.cc | 39 ------------------ test/mjsunit/regress/regress-2506.js | 78 ------------------------------------ 5 files changed, 15 insertions(+), 153 deletions(-) delete mode 100644 test/mjsunit/regress/regress-2506.js diff --git a/src/parser.cc b/src/parser.cc index b63d76d..bec0a4b 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -2156,7 +2156,6 @@ Block* Parser::ParseVariableDeclarations( Block* block = factory()->NewBlock(NULL, 1, true, pos); int nvars = 0; // the number of variables declared const AstRawString* name = NULL; - bool is_for_iteration_variable; do { if (fni_ != NULL) fni_->Enter(); @@ -2180,13 +2179,6 @@ Block* Parser::ParseVariableDeclarations( // For let/const declarations in harmony mode, we can also immediately // pre-resolve the proxy because it resides in the same scope as the // declaration. - is_for_iteration_variable = - var_context == kForStatement && - (peek() == Token::IN || PeekContextualKeyword(CStrVector("of"))); - if (is_for_iteration_variable && mode == CONST) { - needs_init = false; - } - Interface* interface = is_const ? Interface::NewConst() : Interface::NewValue(); VariableProxy* proxy = NewUnresolved(name, mode, interface); @@ -2232,8 +2224,7 @@ Block* Parser::ParseVariableDeclarations( Expression* value = NULL; int pos = -1; // Harmony consts have non-optional initializers. - if (peek() == Token::ASSIGN || - (mode == CONST && !is_for_iteration_variable)) { + if (peek() == Token::ASSIGN || mode == CONST) { Expect(Token::ASSIGN, CHECK_OK); pos = position(); value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); @@ -2366,7 +2357,7 @@ Block* Parser::ParseVariableDeclarations( // If there was a single non-const declaration, return it in the output // parameter for possible use by for/in. - if (nvars == 1 && (!is_const || is_for_iteration_variable)) { + if (nvars == 1 && !is_const) { *out = name; } @@ -3103,8 +3094,7 @@ Statement* Parser::ParseForStatement(ZoneList* labels, Expect(Token::LPAREN, CHECK_OK); for_scope->set_start_position(scanner()->location().beg_pos); if (peek() != Token::SEMICOLON) { - if (peek() == Token::VAR || - (peek() == Token::CONST && strict_mode() == SLOPPY)) { + if (peek() == Token::VAR || peek() == Token::CONST) { bool is_const = peek() == Token::CONST; const AstRawString* name = NULL; VariableDeclarationProperties decl_props = kHasNoInitializers; @@ -3141,10 +3131,8 @@ Statement* Parser::ParseForStatement(ZoneList* labels, } else { init = variable_statement; } - } else if ((peek() == Token::LET || peek() == Token::CONST) && - strict_mode() == STRICT) { + } else if (peek() == Token::LET && strict_mode() == STRICT) { DCHECK(allow_harmony_scoping()); - bool is_const = peek() == Token::CONST; const AstRawString* name = NULL; VariableDeclarationProperties decl_props = kHasNoInitializers; Block* variable_statement = @@ -3157,13 +3145,13 @@ Statement* Parser::ParseForStatement(ZoneList* labels, if (accept_IN && CheckInOrOf(accept_OF, &mode)) { // Rewrite a for-in statement of the form // - // for (let/const x in e) b + // for (let x in e) b // // into // // // for (x' in e) { - // let/const x; + // let x; // x = x'; // b; // } @@ -3183,13 +3171,13 @@ Statement* Parser::ParseForStatement(ZoneList* labels, scope_ = for_scope; Expect(Token::RPAREN, CHECK_OK); - VariableProxy* each = scope_->NewUnresolved(factory(), name); + VariableProxy* each = + scope_->NewUnresolved(factory(), name, Interface::NewValue()); Statement* body = ParseStatement(NULL, CHECK_OK); Block* body_block = factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition); - Token::Value init_op = is_const ? Token::INIT_CONST : Token::ASSIGN; Assignment* assignment = factory()->NewAssignment( - init_op, each, temp_proxy, RelocInfo::kNoPosition); + Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition); Statement* assignment_statement = factory()->NewExpressionStatement( assignment, RelocInfo::kNoPosition); body_block->AddStatement(variable_statement, zone()); diff --git a/src/preparser.cc b/src/preparser.cc index 316f129..987900a 100644 --- a/src/preparser.cc +++ b/src/preparser.cc @@ -409,7 +409,6 @@ PreParser::Statement PreParser::ParseVariableDeclarations( // ConstBinding :: // BindingPattern '=' AssignmentExpression bool require_initializer = false; - bool is_strict_const = false; if (peek() == Token::VAR) { Consume(Token::VAR); } else if (peek() == Token::CONST) { @@ -431,8 +430,7 @@ PreParser::Statement PreParser::ParseVariableDeclarations( *ok = false; return Statement::Default(); } - is_strict_const = true; - require_initializer = var_context != kForStatement; + require_initializer = true; } else { Scanner::Location location = scanner()->peek_location(); ReportMessageAt(location, "strict_const"); @@ -462,9 +460,7 @@ PreParser::Statement PreParser::ParseVariableDeclarations( if (nvars > 0) Consume(Token::COMMA); ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); nvars++; - if (peek() == Token::ASSIGN || require_initializer || - // require initializers for multiple consts. - (is_strict_const && peek() == Token::COMMA)) { + if (peek() == Token::ASSIGN || require_initializer) { Expect(Token::ASSIGN, CHECK_OK); ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); if (decl_props != NULL) *decl_props = kHasInitializers; @@ -682,14 +678,13 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) { if (peek() != Token::SEMICOLON) { if (peek() == Token::VAR || peek() == Token::CONST || (peek() == Token::LET && strict_mode() == STRICT)) { - bool is_lexical = peek() == Token::LET || - (peek() == Token::CONST && strict_mode() == STRICT); + bool is_let = peek() == Token::LET; int decl_count; VariableDeclarationProperties decl_props = kHasNoInitializers; ParseVariableDeclarations( kForStatement, &decl_props, &decl_count, CHECK_OK); bool has_initializers = decl_props == kHasInitializers; - bool accept_IN = decl_count == 1 && !(is_lexical && has_initializers); + bool accept_IN = decl_count == 1 && !(is_let && has_initializers); bool accept_OF = !has_initializers; if (accept_IN && CheckInOrOf(accept_OF)) { ParseExpression(true, CHECK_OK); diff --git a/src/preparser.h b/src/preparser.h index a53abfe..fd82651 100644 --- a/src/preparser.h +++ b/src/preparser.h @@ -344,18 +344,14 @@ class ParserBase : public Traits { } bool CheckContextualKeyword(Vector keyword) { - if (PeekContextualKeyword(keyword)) { + if (peek() == Token::IDENTIFIER && + scanner()->is_next_contextual_keyword(keyword)) { Consume(Token::IDENTIFIER); return true; } return false; } - bool PeekContextualKeyword(Vector keyword) { - return peek() == Token::IDENTIFIER && - scanner()->is_next_contextual_keyword(keyword); - } - void ExpectContextualKeyword(Vector keyword, bool* ok) { Expect(Token::IDENTIFIER, ok); if (!*ok) return; diff --git a/test/cctest/test-parsing.cc b/test/cctest/test-parsing.cc index 7ab4722..700d104 100644 --- a/test/cctest/test-parsing.cc +++ b/test/cctest/test-parsing.cc @@ -4205,42 +4205,3 @@ TEST(ObjectLiteralPropertyShorthandYieldInGeneratorError) { RunParserSyncTest(context_data, name_data, kError, NULL, 0, always_flags, arraysize(always_flags)); } - - -TEST(ConstParsingInForIn) { - const char* context_data[][2] = {{"'use strict';", ""}, - {"function foo(){ 'use strict';", "}"}, - {NULL, NULL}}; - - const char* data[] = { - "for(const x = 1; ; ) {}", - "for(const x = 1, y = 2;;){}", - "for(const x in [1,2,3]) {}", - "for(const x of [1,2,3]) {}", - NULL}; - static const ParserFlag always_flags[] = {kAllowHarmonyScoping}; - RunParserSyncTest(context_data, data, kSuccess, NULL, 0, always_flags, - arraysize(always_flags)); -} - - -TEST(ConstParsingInForInError) { - const char* context_data[][2] = {{"'use strict';", ""}, - {"function foo(){ 'use strict';", "}"}, - {NULL, NULL}}; - - const char* data[] = { - "for(const x,y = 1; ; ) {}", - "for(const x = 4 in [1,2,3]) {}", - "for(const x = 4, y in [1,2,3]) {}", - "for(const x = 4 of [1,2,3]) {}", - "for(const x = 4, y of [1,2,3]) {}", - "for(const x = 1, y = 2 in []) {}", - "for(const x,y in []) {}", - "for(const x = 1, y = 2 of []) {}", - "for(const x,y of []) {}", - NULL}; - static const ParserFlag always_flags[] = {kAllowHarmonyScoping}; - RunParserSyncTest(context_data, data, kError, NULL, 0, always_flags, - arraysize(always_flags)); -} diff --git a/test/mjsunit/regress/regress-2506.js b/test/mjsunit/regress/regress-2506.js deleted file mode 100644 index e6b37d3..0000000 --- a/test/mjsunit/regress/regress-2506.js +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2014 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Flags: --harmony-scoping - -'use strict'; - -// Top-level code -let s = 0; -let f = [undefined, undefined, undefined] -for (const x of [1,2,3]) { - s += x; - f[x-1] = function() { return x; } -} -assertEquals(6, s); -assertEquals(1, f[0]()); -assertEquals(2, f[1]()); -assertEquals(3, f[2]()); - -let x = 1; -s = 0; -for (const x of [x, x+1, x+2]) { - s += x; -} -assertEquals(6, s); - -s = 0; -var q = 1; -for (const q of [q, q+1, q+2]) { - s += q; -} -assertEquals(6, s); - -let z = 1; -s = 0; -for (const x = 1; z < 2; z++) { - s += x + z; -} -assertEquals(2, s); - - -s = ""; -for (const x in [1,2,3]) { - s += x; -} -assertEquals("012", s); - -assertThrows(function() { for(const x in [1,2,3]) { x++ } }, SyntaxError); - -// Function scope -(function() { - let s = 0; - for (const x of [1,2,3]) { - s += x; - } - assertEquals(6, s); - - let x = 1; - s = 0; - for (const x of [x, x+1, x+2]) { - s += x; - } - assertEquals(6, s); - - s = 0; - var q = 1; - for (const q of [q, q+1, q+2]) { - s += q; - } - assertEquals(6, s); - - s = ""; - for (const x in [1,2,3]) { - s += x; - } - assertEquals("012", s); -}()); -- 2.7.4