Fix legacy const for-of/in destructuring

Previously, using legacy const in for-of/in loops led to a check-fail
in the parser. This was due to the fact that the destructuring bind
led to an undefined initialization to undefined in the parser, which
caused the for loop code to go down a strange path. This patch
eliminates the undefined initialization in variables declared in
for-in/of loops, so that that path is not used and the error is
fixed.

BUG=v8:4461
LOG=Y
R=adamk

Review URL: https://codereview.chromium.org/1385913003

Cr-Commit-Position: refs/heads/master@{#31117}
This commit is contained in:
littledan 2015-10-05 15:36:19 -07:00 committed by Commit bot
parent dcbab0f5fb
commit 38465598c8
3 changed files with 10 additions and 2 deletions

View File

@ -2557,7 +2557,9 @@ void Parser::ParseVariableDeclarations(VariableDeclarationContext var_context,
is_for_iteration_variable =
var_context == kForStatement &&
(peek() == Token::IN || PeekContextualKeyword(CStrVector("of")));
if (is_for_iteration_variable && parsing_result->descriptor.mode == CONST) {
if (is_for_iteration_variable &&
(parsing_result->descriptor.mode == CONST ||
parsing_result->descriptor.mode == CONST_LEGACY)) {
parsing_result->descriptor.needs_init = false;
}

View File

@ -175,7 +175,7 @@ void Parser::PatternRewriter::VisitVariableProxy(VariableProxy* pattern) {
factory()->NewExpressionStatement(initialize, RelocInfo::kNoPosition),
zone());
}
} else if (value != nullptr && (descriptor_->needs_init ||
} else if (value != nullptr && (descriptor_->mode == CONST_LEGACY ||
IsLexicalVariableMode(descriptor_->mode))) {
// Constant initializations always assign to the declared constant which
// is always at the function scope level. This is only relevant for

View File

@ -1097,3 +1097,9 @@
assertThrows(
function(){ eval("(class{foo(a, {}) {'use strict';}});") }, SyntaxError);
})();
(function TestLegacyConstDestructuringInForLoop() {
var result;
for (const {foo} of [{foo: 1}]) { result = foo; }
assertEquals(1, result);
})();