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

Side by Side 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: Proper rebase. 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 unified diff | Download patch
« no previous file with comments | « src/flag-definitions.h ('k') | src/rewriter.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/parser.h" 5 #include "src/parser.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/ast.h" 8 #include "src/ast.h"
9 #include "src/ast-literal-reindexer.h" 9 #include "src/ast-literal-reindexer.h"
10 #include "src/bailout-reason.h" 10 #include "src/bailout-reason.h"
(...skipping 3321 matching lines...) Expand 10 before | Expand all | Expand 10 after
3332 } else { 3332 } else {
3333 stmt->Initialize(each, subject, body); 3333 stmt->Initialize(each, subject, body);
3334 } 3334 }
3335 } 3335 }
3336 3336
3337 3337
3338 Statement* Parser::DesugarLexicalBindingsInForStatement( 3338 Statement* Parser::DesugarLexicalBindingsInForStatement(
3339 Scope* inner_scope, bool is_const, ZoneList<const AstRawString*>* names, 3339 Scope* inner_scope, bool is_const, ZoneList<const AstRawString*>* names,
3340 ForStatement* loop, Statement* init, Expression* cond, Statement* next, 3340 ForStatement* loop, Statement* init, Expression* cond, Statement* next,
3341 Statement* body, bool* ok) { 3341 Statement* body, bool* ok) {
3342 // ES6 13.6.3.4 specifies that on each loop iteration the let variables are 3342 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are
3343 // copied into a new environment. After copying, the "next" statement of the 3343 // copied into a new environment. Moreover, the "next" statement must be
3344 // loop is executed to update the loop variables. The loop condition is 3344 // evaluated not in the environment of the just completed iteration but in
3345 // checked and the loop body is executed. 3345 // that of the upcoming one. We achieve this with the following desugaring.
3346 // Extra care is needed to preserve the completion value of the original loop.
3346 // 3347 //
3347 // We rewrite a for statement of the form 3348 // We are given a for statement of the form
3348 // 3349 //
3349 // labels: for (let/const x = i; cond; next) body 3350 // labels: for (let/const x = i; cond; next) body
3350 // 3351 //
3351 // into 3352 // and rewrite it as follows. Here we write {{ ... }} for init-blocks, ie.,
3353 // blocks whose ignore_completion_value_ flag is set.
3352 // 3354 //
3353 // { 3355 // {
3354 // let/const x = i; 3356 // let/const x = i;
3355 // temp_x = x; 3357 // temp_x = x;
3356 // first = 1; 3358 // first = 1;
3357 // undefined; 3359 // undefined;
3358 // outer: for (;;) { 3360 // outer: for (;;) {
3359 // { // This block's only function is to ensure that the statements it 3361 // let/const x = temp_x;
3360 // // contains do not affect the normal completion value. This is 3362 // {{ if (first == 1) {
3361 // // accomplished by setting its ignore_completion_value bit. 3363 // first = 0;
3362 // // No new lexical scope is introduced, so lexically scoped variables 3364 // } else {
3363 // // declared here will be scoped to the outer for loop. 3365 // next;
3364 // let/const x = temp_x; 3366 // }
3365 // if (first == 1) { 3367 // flag = 1;
3366 // first = 0; 3368 // if (!cond) break;
3367 // } else { 3369 // }}
3368 // next; 3370 // labels: for (; flag == 1; flag = 0, temp_x = x) {
3369 // } 3371 // body
3370 // flag = 1;
3371 // } 3372 // }
3372 // labels: for (; flag == 1; flag = 0, temp_x = x) { 3373 // {{ if (flag == 1) // Body used break.
3373 // if (cond) { 3374 // break;
3374 // body 3375 // }}
3375 // } else {
3376 // break outer;
3377 // }
3378 // }
3379 // if (flag == 1) {
3380 // break;
3381 // }
3382 // } 3376 // }
3383 // } 3377 // }
3384 3378
3385 DCHECK(names->length() > 0); 3379 DCHECK(names->length() > 0);
3386 Scope* for_scope = scope_; 3380 Scope* for_scope = scope_;
3387 ZoneList<Variable*> temps(names->length(), zone()); 3381 ZoneList<Variable*> temps(names->length(), zone());
3388 3382
3389 Block* outer_block = factory()->NewBlock(NULL, names->length() + 3, false, 3383 Block* outer_block = factory()->NewBlock(NULL, names->length() + 4, false,
3390 RelocInfo::kNoPosition); 3384 RelocInfo::kNoPosition);
3391 3385
3392 // Add statement: let/const x = i. 3386 // Add statement: let/const x = i.
3393 outer_block->statements()->Add(init, zone()); 3387 outer_block->statements()->Add(init, zone());
3394 3388
3395 const AstRawString* temp_name = ast_value_factory()->dot_for_string(); 3389 const AstRawString* temp_name = ast_value_factory()->dot_for_string();
3396 3390
3397 // For each lexical variable x: 3391 // For each lexical variable x:
3398 // make statement: temp_x = x. 3392 // make statement: temp_x = x.
3399 for (int i = 0; i < names->length(); i++) { 3393 for (int i = 0; i < names->length(); i++) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
3436 ForStatement* outer_loop = 3430 ForStatement* outer_loop =
3437 factory()->NewForStatement(NULL, RelocInfo::kNoPosition); 3431 factory()->NewForStatement(NULL, RelocInfo::kNoPosition);
3438 outer_block->statements()->Add(outer_loop, zone()); 3432 outer_block->statements()->Add(outer_loop, zone());
3439 3433
3440 outer_block->set_scope(for_scope); 3434 outer_block->set_scope(for_scope);
3441 scope_ = inner_scope; 3435 scope_ = inner_scope;
3442 3436
3443 Block* inner_block = 3437 Block* inner_block =
3444 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition); 3438 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition);
3445 Block* ignore_completion_block = factory()->NewBlock( 3439 Block* ignore_completion_block = factory()->NewBlock(
3446 NULL, names->length() + 2, true, RelocInfo::kNoPosition); 3440 NULL, names->length() + 3, true, RelocInfo::kNoPosition);
3447 ZoneList<Variable*> inner_vars(names->length(), zone()); 3441 ZoneList<Variable*> inner_vars(names->length(), zone());
3448 // For each let variable x: 3442 // For each let variable x:
3449 // make statement: let/const x = temp_x. 3443 // make statement: let/const x = temp_x.
3450 VariableMode mode = is_const ? CONST : LET; 3444 VariableMode mode = is_const ? CONST : LET;
3451 for (int i = 0; i < names->length(); i++) { 3445 for (int i = 0; i < names->length(); i++) {
3452 VariableProxy* proxy = NewUnresolved(names->at(i), mode); 3446 VariableProxy* proxy = NewUnresolved(names->at(i), mode);
3453 Declaration* declaration = factory()->NewVariableDeclaration( 3447 Declaration* declaration = factory()->NewVariableDeclaration(
3454 proxy, mode, scope_, RelocInfo::kNoPosition); 3448 proxy, mode, scope_, RelocInfo::kNoPosition);
3455 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); 3449 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
3456 inner_vars.Add(declaration->proxy()->var(), zone()); 3450 inner_vars.Add(declaration->proxy()->var(), zone());
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
3495 // Make statement: flag = 1. 3489 // Make statement: flag = 1.
3496 { 3490 {
3497 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); 3491 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3498 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); 3492 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3499 Assignment* assignment = factory()->NewAssignment( 3493 Assignment* assignment = factory()->NewAssignment(
3500 Token::ASSIGN, flag_proxy, const1, RelocInfo::kNoPosition); 3494 Token::ASSIGN, flag_proxy, const1, RelocInfo::kNoPosition);
3501 Statement* assignment_statement = 3495 Statement* assignment_statement =
3502 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition); 3496 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3503 ignore_completion_block->statements()->Add(assignment_statement, zone()); 3497 ignore_completion_block->statements()->Add(assignment_statement, zone());
3504 } 3498 }
3499
3500 // Make statement: if (!cond) break.
3501 if (cond) {
3502 Statement* stop =
3503 factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition);
3504 Statement* noop = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
3505 ignore_completion_block->statements()->Add(
3506 factory()->NewIfStatement(cond, noop, stop, cond->position()), zone());
3507 }
3508
3505 inner_block->statements()->Add(ignore_completion_block, zone()); 3509 inner_block->statements()->Add(ignore_completion_block, zone());
3506 // Make cond expression for main loop: flag == 1. 3510 // Make cond expression for main loop: flag == 1.
3507 Expression* flag_cond = NULL; 3511 Expression* flag_cond = NULL;
3508 { 3512 {
3509 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); 3513 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3510 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); 3514 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3511 flag_cond = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1, 3515 flag_cond = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
3512 RelocInfo::kNoPosition); 3516 RelocInfo::kNoPosition);
3513 } 3517 }
3514 3518
(...skipping 18 matching lines...) Expand all
3533 Assignment* assignment = factory()->NewAssignment( 3537 Assignment* assignment = factory()->NewAssignment(
3534 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition); 3538 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition);
3535 compound_next = factory()->NewBinaryOperation( 3539 compound_next = factory()->NewBinaryOperation(
3536 Token::COMMA, compound_next, assignment, RelocInfo::kNoPosition); 3540 Token::COMMA, compound_next, assignment, RelocInfo::kNoPosition);
3537 } 3541 }
3538 3542
3539 compound_next_statement = factory()->NewExpressionStatement( 3543 compound_next_statement = factory()->NewExpressionStatement(
3540 compound_next, RelocInfo::kNoPosition); 3544 compound_next, RelocInfo::kNoPosition);
3541 } 3545 }
3542 3546
3543 // Make statement: if (cond) { body; } else { break outer; }
3544 Statement* body_or_stop = body;
3545 if (cond) {
3546 Statement* stop =
3547 factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition);
3548 body_or_stop =
3549 factory()->NewIfStatement(cond, body, stop, cond->position());
3550 }
3551
3552 // Make statement: labels: for (; flag == 1; flag = 0, temp_x = x) 3547 // Make statement: labels: for (; flag == 1; flag = 0, temp_x = x)
3553 // Note that we re-use the original loop node, which retains its labels 3548 // Note that we re-use the original loop node, which retains its labels
3554 // and ensures that any break or continue statements in body point to 3549 // and ensures that any break or continue statements in body point to
3555 // the right place. 3550 // the right place.
3556 loop->Initialize(NULL, flag_cond, compound_next_statement, body_or_stop); 3551 loop->Initialize(NULL, flag_cond, compound_next_statement, body);
3557 inner_block->statements()->Add(loop, zone()); 3552 inner_block->statements()->Add(loop, zone());
3558 3553
3559 // Make statement: if (flag == 1) { break; } 3554 // Make statement: {{if (flag == 1) break;}}
3560 { 3555 {
3561 Expression* compare = NULL; 3556 Expression* compare = NULL;
3562 // Make compare expresion: flag == 1. 3557 // Make compare expresion: flag == 1.
3563 { 3558 {
3564 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); 3559 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3565 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); 3560 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3566 compare = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1, 3561 compare = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
3567 RelocInfo::kNoPosition); 3562 RelocInfo::kNoPosition);
3568 } 3563 }
3569 Statement* stop = 3564 Statement* stop =
3570 factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition); 3565 factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition);
3571 Statement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition); 3566 Statement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
3572 Statement* if_flag_break = 3567 Statement* if_flag_break =
3573 factory()->NewIfStatement(compare, stop, empty, RelocInfo::kNoPosition); 3568 factory()->NewIfStatement(compare, stop, empty, RelocInfo::kNoPosition);
3574 inner_block->statements()->Add(if_flag_break, zone()); 3569 Block* ignore_completion_block =
3570 factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition);
3571 ignore_completion_block->statements()->Add(if_flag_break, zone());
3572 inner_block->statements()->Add(ignore_completion_block, zone());
3575 } 3573 }
3576 3574
3577 inner_scope->set_end_position(scanner()->location().end_pos); 3575 inner_scope->set_end_position(scanner()->location().end_pos);
3578 inner_block->set_scope(inner_scope); 3576 inner_block->set_scope(inner_scope);
3579 scope_ = for_scope; 3577 scope_ = for_scope;
3580 3578
3581 outer_loop->Initialize(NULL, NULL, NULL, inner_block); 3579 outer_loop->Initialize(NULL, NULL, NULL, inner_block);
3582 return outer_block; 3580 return outer_block;
3583 } 3581 }
3584 3582
(...skipping 2757 matching lines...) Expand 10 before | Expand all | Expand 10 after
6342 6340
6343 Expression* Parser::SpreadCallNew(Expression* function, 6341 Expression* Parser::SpreadCallNew(Expression* function,
6344 ZoneList<v8::internal::Expression*>* args, 6342 ZoneList<v8::internal::Expression*>* args,
6345 int pos) { 6343 int pos) {
6346 args->InsertAt(0, function, zone()); 6344 args->InsertAt(0, function, zone());
6347 6345
6348 return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos); 6346 return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos);
6349 } 6347 }
6350 } // namespace internal 6348 } // namespace internal
6351 } // namespace v8 6349 } // namespace v8
OLDNEW
« no previous file with comments | « src/flag-definitions.h ('k') | src/rewriter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698