Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1262)

Unified Diff: src/parser.cc

Issue 1361403003: Implement ES6 completion semantics (--harmony-completion). (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/parser.cc
diff --git a/src/parser.cc b/src/parser.cc
index f122d9aa5e4b57ff1459cfa48e060c666bd407ff..c1408048cb3dda1f45b58fdf98a59f1a5e7ddfdc 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -3333,7 +3333,7 @@ Statement* Parser::DesugarLexicalBindingsInForStatement(
Scope* inner_scope, bool is_const, ZoneList<const AstRawString*>* names,
ForStatement* loop, Statement* init, Expression* cond, Statement* next,
Statement* body, bool* ok) {
- // ES6 13.6.3.4 specifies that on each loop iteration the let variables are
+ // ES6 13.7.4.8 specifies that on each loop iteration the let variables are
// copied into a new environment. After copying, the "next" statement of the
// loop is executed to update the loop variables. The loop condition is
// checked and the loop body is executed.
@@ -3350,31 +3350,27 @@ Statement* Parser::DesugarLexicalBindingsInForStatement(
// first = 1;
// undefined;
// outer: for (;;) {
- // { // 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;
- // }
+ // {{ // 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;
rossberg 2015/10/05 11:33:00 Can you just move this declaration out of the bloc
neis 2015/10/07 11:58:40 Done.
+ // if (first == 1) {
+ // first = 0;
+ // } else {
+ // next;
+ // }
+ // flag = 1;
+ // if (!cond) break;
+ // }}
// labels: for (; flag == 1; flag = 0, temp_x = x) {
- // if (cond) {
- // body
- // } else {
- // break outer;
- // }
- // }
- // if (flag == 1) {
- // break;
+ // body
// }
+ // {{ if (flag == 1) // Body used break.
+ // break;
+ // }}
// }
// }
+ //
+ // We write {{ ... }} for blocks whose completion value is ignored.
rossberg 2015/10/05 11:33:00 Nit: move this comment to the top, since it's easy
neis 2015/10/07 11:58:40 Done.
DCHECK(names->length() > 0);
Scope* for_scope = scope_;
@@ -3437,7 +3433,7 @@ Statement* Parser::DesugarLexicalBindingsInForStatement(
Block* inner_block =
factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition);
Block* ignore_completion_block = factory()->NewBlock(
- NULL, names->length() + 2, true, RelocInfo::kNoPosition);
+ NULL, names->length() + 3, true, RelocInfo::kNoPosition);
ZoneList<Variable*> inner_vars(names->length(), zone());
// For each let variable x:
// make statement: let/const x = temp_x.
@@ -3496,6 +3492,16 @@ Statement* Parser::DesugarLexicalBindingsInForStatement(
factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
ignore_completion_block->statements()->Add(assignment_statement, zone());
}
+
+ // Make statement: if (!cond) break.
+ if (cond) {
+ Statement* stop =
+ factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition);
+ Statement* noop = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
+ ignore_completion_block->statements()->Add(
+ factory()->NewIfStatement(cond, noop, stop, cond->position()), zone());
+ }
+
inner_block->statements()->Add(ignore_completion_block, zone());
// Make cond expression for main loop: flag == 1.
Expression* flag_cond = NULL;
@@ -3534,23 +3540,14 @@ Statement* Parser::DesugarLexicalBindingsInForStatement(
compound_next, RelocInfo::kNoPosition);
}
- // Make statement: if (cond) { body; } else { break outer; }
- Statement* body_or_stop = body;
- if (cond) {
- Statement* stop =
- factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition);
- body_or_stop =
- factory()->NewIfStatement(cond, body, stop, cond->position());
- }
-
// Make statement: labels: for (; flag == 1; flag = 0, temp_x = x)
// 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);
+ loop->Initialize(NULL, flag_cond, compound_next_statement, body);
inner_block->statements()->Add(loop, zone());
- // Make statement: if (flag == 1) { break; }
+ // Make statement: {{if (flag == 1) break;}}
{
Expression* compare = NULL;
// Make compare expresion: flag == 1.
@@ -3565,7 +3562,10 @@ Statement* Parser::DesugarLexicalBindingsInForStatement(
Statement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
Statement* if_flag_break =
factory()->NewIfStatement(compare, stop, empty, RelocInfo::kNoPosition);
- inner_block->statements()->Add(if_flag_break, zone());
+ Block* ignore_completion_block =
+ factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition);
+ ignore_completion_block->statements()->Add(if_flag_break, zone());
+ inner_block->statements()->Add(ignore_completion_block, zone());
}
inner_scope->set_end_position(scanner()->location().end_pos);

Powered by Google App Engine
This is Rietveld 408576698