Index: src/parsing/parser.cc |
diff --git a/src/parsing/parser.cc b/src/parsing/parser.cc |
index 46f6bc22f2582c1f45aad8fa81e3cbedee41ce01..9daee95600d6424a0621c32d727fe89c0f126a88 100644 |
--- a/src/parsing/parser.cc |
+++ b/src/parsing/parser.cc |
@@ -6740,6 +6740,7 @@ Statement* ParserTraits::FinalizeForOfStatement(ForOfStatement* loop, int pos) { |
// This function replaces the loop with the following wrapping: |
// |
// let completion = BODY_COMPLETED; |
+ // let each; |
// try { |
// #loop; |
// } catch(e) { |
@@ -6754,10 +6755,16 @@ Statement* ParserTraits::FinalizeForOfStatement(ForOfStatement* loop, int pos) { |
// where the loop's body is wrapped as follows: |
// |
// { |
- // {{completion = BODY_ABORTED;}} |
// #loop-body |
// {{completion = BODY_COMPLETED;}} |
// } |
+ // |
+ // and assign_each is wrapped as follows |
+ // |
+ // do { |
+ // {{completion = BODY_ABORTED;}} |
+ // #assign-each |
+ // } into each |
const int nopos = RelocInfo::kNoPosition; |
auto factory = parser_->factory(); |
@@ -6777,6 +6784,18 @@ Statement* ParserTraits::FinalizeForOfStatement(ForOfStatement* loop, int pos) { |
factory->NewExpressionStatement(assignment, nopos); |
} |
+ // let each; |
+ Variable* var_each = scope->NewTemporary(avfactory->empty_string()); |
+ Statement* initialize_each; |
+ { |
+ Expression* proxy = factory->NewVariableProxy(var_each); |
+ Expression* assignment = factory->NewAssignment( |
+ Token::ASSIGN, proxy, |
+ factory->NewUndefinedLiteral(nopos), nopos); |
+ initialize_each = |
+ factory->NewExpressionStatement(assignment, nopos); |
+ } |
+ |
// if (completion === BODY_ABORTED) completion = BODY_THREW; |
Statement* set_completion_throw; |
{ |
@@ -6858,29 +6877,17 @@ Statement* ParserTraits::FinalizeForOfStatement(ForOfStatement* loop, int pos) { |
} |
// #initialize_completion; |
+ // #initialize_each; |
// #try_finally; |
Statement* final_loop; |
{ |
Block* block = factory->NewBlock(nullptr, 2, false, nopos); |
block->statements()->Add(initialize_completion, zone); |
+ block->statements()->Add(initialize_each, zone); |
block->statements()->Add(try_finally, zone); |
final_loop = block; |
} |
- // {{completion = BODY_ABORTED;}} |
- Statement* set_completion_break; |
- { |
- Expression* proxy = factory->NewVariableProxy(var_completion); |
- Expression* assignment = factory->NewAssignment( |
- Token::ASSIGN, proxy, |
- factory->NewSmiLiteral(BODY_ABORTED, nopos), nopos); |
- |
- Block* block = factory->NewBlock(nullptr, 1, true, nopos); |
- block->statements()->Add( |
- factory->NewExpressionStatement(assignment, nopos), zone); |
- set_completion_break = block; |
- } |
- |
// {{completion = BODY_COMPLETED;}} |
Statement* set_completion_normal; |
{ |
@@ -6895,13 +6902,37 @@ Statement* ParserTraits::FinalizeForOfStatement(ForOfStatement* loop, int pos) { |
set_completion_normal = block; |
} |
- // { #set_completion_break; #loop-body; #set_completion_normal } |
+ // { #loop-body; #set_completion_normal } |
Block* new_body = factory->NewBlock(nullptr, 2, false, nopos); |
- new_body->statements()->Add(set_completion_break, zone); |
new_body->statements()->Add(loop->body(), zone); |
new_body->statements()->Add(set_completion_normal, zone); |
loop->set_body(new_body); |
+ |
+ // {{completion = BODY_ABORTED;}} |
+ Statement* set_completion_break; |
+ { |
+ Expression* proxy = factory->NewVariableProxy(var_completion); |
+ Expression* assignment = factory->NewAssignment( |
+ Token::ASSIGN, proxy, factory->NewSmiLiteral(BODY_ABORTED, nopos), |
+ nopos); |
+ |
+ Block* block = factory->NewBlock(nullptr, 1, true, nopos); |
+ block->statements()->Add(factory->NewExpressionStatement(assignment, nopos), |
+ zone); |
+ set_completion_break = block; |
+ } |
+ |
+ // { #set_completion_break; #assign-each } |
+ Block* new_assign_each = factory->NewBlock(nullptr, 2, false, nopos); |
+ new_assign_each->statements()->Add(set_completion_break, zone); |
+ new_assign_each->statements()->Add( |
+ factory->NewExpressionStatement(loop->assign_each(), nopos), zone); |
+ |
+ Expression* do_each = |
+ factory->NewDoExpression(new_assign_each, var_each, nopos); |
+ loop->set_assign_each(do_each); |
+ |
return final_loop; |
} |