| Index: src/parser.cc
|
| diff --git a/src/parser.cc b/src/parser.cc
|
| index 816849748869720029796504e4d282dc6ca1bb2e..95ff7ed270773f526558d76d9e97d670d59c2747 100644
|
| --- a/src/parser.cc
|
| +++ b/src/parser.cc
|
| @@ -3222,14 +3222,21 @@ Statement* Parser::DesugarLexicalBindingsInForStatement(
|
| // let/const x = i;
|
| // temp_x = x;
|
| // first = 1;
|
| + // undefined;
|
| // outer: for (;;) {
|
| - // let/const x = temp_x;
|
| - // if (first == 1) {
|
| - // first = 0;
|
| - // } else {
|
| - // next;
|
| + // { // This block's only function is to ensure that the statements it
|
| + // // contains do not affect the normal completion value. This is
|
| + // // accomplished by setting its ignore_completion_value bit.
|
| + // // No new lexical scope is introduced, so lexically scoped variables
|
| + // // declared here will be scoped to the outer for loop.
|
| + // let/const x = temp_x;
|
| + // if (first == 1) {
|
| + // first = 0;
|
| + // } else {
|
| + // next;
|
| + // }
|
| + // flag = 1;
|
| // }
|
| - // flag = 1;
|
| // labels: for (; flag == 1; flag = 0, temp_x = x) {
|
| // if (cond) {
|
| // body
|
| @@ -3282,6 +3289,13 @@ Statement* Parser::DesugarLexicalBindingsInForStatement(
|
| outer_block->AddStatement(assignment_statement, zone());
|
| }
|
|
|
| + // make statement: undefined;
|
| + outer_block->AddStatement(
|
| + factory()->NewExpressionStatement(
|
| + factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
|
| + RelocInfo::kNoPosition),
|
| + zone());
|
| +
|
| // Make statement: outer: for (;;)
|
| // Note that we don't actually create the label, or set this loop up as an
|
| // explicit break target, instead handing it directly to those nodes that
|
| @@ -3294,8 +3308,10 @@ Statement* Parser::DesugarLexicalBindingsInForStatement(
|
| outer_block->set_scope(for_scope);
|
| scope_ = inner_scope;
|
|
|
| - Block* inner_block = factory()->NewBlock(NULL, names->length() + 4, false,
|
| - RelocInfo::kNoPosition);
|
| + Block* inner_block =
|
| + factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition);
|
| + Block* ignore_completion_block = factory()->NewBlock(
|
| + NULL, names->length() + 2, true, RelocInfo::kNoPosition);
|
| ZoneList<Variable*> inner_vars(names->length(), zone());
|
| // For each let variable x:
|
| // make statement: let/const x = temp_x.
|
| @@ -3314,7 +3330,7 @@ Statement* Parser::DesugarLexicalBindingsInForStatement(
|
| factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
|
| DCHECK(init->position() != RelocInfo::kNoPosition);
|
| proxy->var()->set_initializer_position(init->position());
|
| - inner_block->AddStatement(assignment_statement, zone());
|
| + ignore_completion_block->AddStatement(assignment_statement, zone());
|
| }
|
|
|
| // Make statement: if (first == 1) { first = 0; } else { next; }
|
| @@ -3340,7 +3356,7 @@ Statement* Parser::DesugarLexicalBindingsInForStatement(
|
| }
|
| Statement* clear_first_or_next = factory()->NewIfStatement(
|
| compare, clear_first, next, RelocInfo::kNoPosition);
|
| - inner_block->AddStatement(clear_first_or_next, zone());
|
| + ignore_completion_block->AddStatement(clear_first_or_next, zone());
|
| }
|
|
|
| Variable* flag = scope_->DeclarationScope()->NewTemporary(temp_name);
|
| @@ -3352,9 +3368,9 @@ Statement* Parser::DesugarLexicalBindingsInForStatement(
|
| Token::ASSIGN, flag_proxy, const1, RelocInfo::kNoPosition);
|
| Statement* assignment_statement =
|
| factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
|
| - inner_block->AddStatement(assignment_statement, zone());
|
| + ignore_completion_block->AddStatement(assignment_statement, zone());
|
| }
|
| -
|
| + inner_block->AddStatement(ignore_completion_block, zone());
|
| // Make cond expression for main loop: flag == 1.
|
| Expression* flag_cond = NULL;
|
| {
|
| @@ -3402,7 +3418,7 @@ Statement* Parser::DesugarLexicalBindingsInForStatement(
|
| }
|
|
|
| // Make statement: labels: for (; flag == 1; flag = 0, temp_x = x)
|
| - // Note that we re-use the original loop node, which retains it labels
|
| + // Note that we re-use the original loop node, which retains its labels
|
| // and ensures that any break or continue statements in body point to
|
| // the right place.
|
| loop->Initialize(NULL, flag_cond, compound_next_statement, body_or_stop);
|
|
|