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

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: 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
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 3315 matching lines...) Expand 10 before | Expand all | Expand 10 after
3326 } else { 3326 } else {
3327 stmt->Initialize(each, subject, body); 3327 stmt->Initialize(each, subject, body);
3328 } 3328 }
3329 } 3329 }
3330 3330
3331 3331
3332 Statement* Parser::DesugarLexicalBindingsInForStatement( 3332 Statement* Parser::DesugarLexicalBindingsInForStatement(
3333 Scope* inner_scope, bool is_const, ZoneList<const AstRawString*>* names, 3333 Scope* inner_scope, bool is_const, ZoneList<const AstRawString*>* names,
3334 ForStatement* loop, Statement* init, Expression* cond, Statement* next, 3334 ForStatement* loop, Statement* init, Expression* cond, Statement* next,
3335 Statement* body, bool* ok) { 3335 Statement* body, bool* ok) {
3336 // ES6 13.6.3.4 specifies that on each loop iteration the let variables are 3336 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are
3337 // copied into a new environment. After copying, the "next" statement of the 3337 // copied into a new environment. After copying, the "next" statement of the
3338 // loop is executed to update the loop variables. The loop condition is 3338 // loop is executed to update the loop variables. The loop condition is
3339 // checked and the loop body is executed. 3339 // checked and the loop body is executed.
3340 // 3340 //
3341 // We rewrite a for statement of the form 3341 // We rewrite a for statement of the form
3342 // 3342 //
3343 // labels: for (let/const x = i; cond; next) body 3343 // labels: for (let/const x = i; cond; next) body
3344 // 3344 //
3345 // into 3345 // into
3346 // 3346 //
3347 // { 3347 // {
3348 // let/const x = i; 3348 // let/const x = i;
3349 // temp_x = x; 3349 // temp_x = x;
3350 // first = 1; 3350 // first = 1;
3351 // undefined; 3351 // undefined;
3352 // outer: for (;;) { 3352 // outer: for (;;) {
3353 // { // This block's only function is to ensure that the statements it 3353 // {{ // No new lexical scope is introduced, so lexically scoped
3354 // // contains do not affect the normal completion value. This is 3354 // // variables declared here will be scoped to the outer for loop.
3355 // // accomplished by setting its ignore_completion_value bit. 3355 // 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.
3356 // // No new lexical scope is introduced, so lexically scoped variables 3356 // if (first == 1) {
3357 // // declared here will be scoped to the outer for loop. 3357 // first = 0;
3358 // let/const x = temp_x; 3358 // } else {
3359 // if (first == 1) { 3359 // next;
3360 // first = 0; 3360 // }
3361 // } else { 3361 // flag = 1;
3362 // next; 3362 // if (!cond) break;
3363 // } 3363 // }}
3364 // flag = 1; 3364 // labels: for (; flag == 1; flag = 0, temp_x = x) {
3365 // body
3365 // } 3366 // }
3366 // labels: for (; flag == 1; flag = 0, temp_x = x) { 3367 // {{ if (flag == 1) // Body used break.
3367 // if (cond) { 3368 // break;
3368 // body 3369 // }}
3369 // } else {
3370 // break outer;
3371 // }
3372 // }
3373 // if (flag == 1) {
3374 // break;
3375 // }
3376 // } 3370 // }
3377 // } 3371 // }
3372 //
3373 // 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.
3378 3374
3379 DCHECK(names->length() > 0); 3375 DCHECK(names->length() > 0);
3380 Scope* for_scope = scope_; 3376 Scope* for_scope = scope_;
3381 ZoneList<Variable*> temps(names->length(), zone()); 3377 ZoneList<Variable*> temps(names->length(), zone());
3382 3378
3383 Block* outer_block = factory()->NewBlock(NULL, names->length() + 3, false, 3379 Block* outer_block = factory()->NewBlock(NULL, names->length() + 3, false,
3384 RelocInfo::kNoPosition); 3380 RelocInfo::kNoPosition);
3385 3381
3386 // Add statement: let/const x = i. 3382 // Add statement: let/const x = i.
3387 outer_block->statements()->Add(init, zone()); 3383 outer_block->statements()->Add(init, zone());
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
3430 ForStatement* outer_loop = 3426 ForStatement* outer_loop =
3431 factory()->NewForStatement(NULL, RelocInfo::kNoPosition); 3427 factory()->NewForStatement(NULL, RelocInfo::kNoPosition);
3432 outer_block->statements()->Add(outer_loop, zone()); 3428 outer_block->statements()->Add(outer_loop, zone());
3433 3429
3434 outer_block->set_scope(for_scope); 3430 outer_block->set_scope(for_scope);
3435 scope_ = inner_scope; 3431 scope_ = inner_scope;
3436 3432
3437 Block* inner_block = 3433 Block* inner_block =
3438 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition); 3434 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition);
3439 Block* ignore_completion_block = factory()->NewBlock( 3435 Block* ignore_completion_block = factory()->NewBlock(
3440 NULL, names->length() + 2, true, RelocInfo::kNoPosition); 3436 NULL, names->length() + 3, true, RelocInfo::kNoPosition);
3441 ZoneList<Variable*> inner_vars(names->length(), zone()); 3437 ZoneList<Variable*> inner_vars(names->length(), zone());
3442 // For each let variable x: 3438 // For each let variable x:
3443 // make statement: let/const x = temp_x. 3439 // make statement: let/const x = temp_x.
3444 VariableMode mode = is_const ? CONST : LET; 3440 VariableMode mode = is_const ? CONST : LET;
3445 for (int i = 0; i < names->length(); i++) { 3441 for (int i = 0; i < names->length(); i++) {
3446 VariableProxy* proxy = NewUnresolved(names->at(i), mode); 3442 VariableProxy* proxy = NewUnresolved(names->at(i), mode);
3447 Declaration* declaration = factory()->NewVariableDeclaration( 3443 Declaration* declaration = factory()->NewVariableDeclaration(
3448 proxy, mode, scope_, RelocInfo::kNoPosition); 3444 proxy, mode, scope_, RelocInfo::kNoPosition);
3449 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); 3445 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
3450 inner_vars.Add(declaration->proxy()->var(), zone()); 3446 inner_vars.Add(declaration->proxy()->var(), zone());
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
3489 // Make statement: flag = 1. 3485 // Make statement: flag = 1.
3490 { 3486 {
3491 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); 3487 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3492 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); 3488 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3493 Assignment* assignment = factory()->NewAssignment( 3489 Assignment* assignment = factory()->NewAssignment(
3494 Token::ASSIGN, flag_proxy, const1, RelocInfo::kNoPosition); 3490 Token::ASSIGN, flag_proxy, const1, RelocInfo::kNoPosition);
3495 Statement* assignment_statement = 3491 Statement* assignment_statement =
3496 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition); 3492 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3497 ignore_completion_block->statements()->Add(assignment_statement, zone()); 3493 ignore_completion_block->statements()->Add(assignment_statement, zone());
3498 } 3494 }
3495
3496 // Make statement: if (!cond) break.
3497 if (cond) {
3498 Statement* stop =
3499 factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition);
3500 Statement* noop = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
3501 ignore_completion_block->statements()->Add(
3502 factory()->NewIfStatement(cond, noop, stop, cond->position()), zone());
3503 }
3504
3499 inner_block->statements()->Add(ignore_completion_block, zone()); 3505 inner_block->statements()->Add(ignore_completion_block, zone());
3500 // Make cond expression for main loop: flag == 1. 3506 // Make cond expression for main loop: flag == 1.
3501 Expression* flag_cond = NULL; 3507 Expression* flag_cond = NULL;
3502 { 3508 {
3503 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); 3509 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3504 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); 3510 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3505 flag_cond = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1, 3511 flag_cond = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
3506 RelocInfo::kNoPosition); 3512 RelocInfo::kNoPosition);
3507 } 3513 }
3508 3514
(...skipping 18 matching lines...) Expand all
3527 Assignment* assignment = factory()->NewAssignment( 3533 Assignment* assignment = factory()->NewAssignment(
3528 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition); 3534 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition);
3529 compound_next = factory()->NewBinaryOperation( 3535 compound_next = factory()->NewBinaryOperation(
3530 Token::COMMA, compound_next, assignment, RelocInfo::kNoPosition); 3536 Token::COMMA, compound_next, assignment, RelocInfo::kNoPosition);
3531 } 3537 }
3532 3538
3533 compound_next_statement = factory()->NewExpressionStatement( 3539 compound_next_statement = factory()->NewExpressionStatement(
3534 compound_next, RelocInfo::kNoPosition); 3540 compound_next, RelocInfo::kNoPosition);
3535 } 3541 }
3536 3542
3537 // Make statement: if (cond) { body; } else { break outer; }
3538 Statement* body_or_stop = body;
3539 if (cond) {
3540 Statement* stop =
3541 factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition);
3542 body_or_stop =
3543 factory()->NewIfStatement(cond, body, stop, cond->position());
3544 }
3545
3546 // Make statement: labels: for (; flag == 1; flag = 0, temp_x = x) 3543 // Make statement: labels: for (; flag == 1; flag = 0, temp_x = x)
3547 // Note that we re-use the original loop node, which retains its labels 3544 // Note that we re-use the original loop node, which retains its labels
3548 // and ensures that any break or continue statements in body point to 3545 // and ensures that any break or continue statements in body point to
3549 // the right place. 3546 // the right place.
3550 loop->Initialize(NULL, flag_cond, compound_next_statement, body_or_stop); 3547 loop->Initialize(NULL, flag_cond, compound_next_statement, body);
3551 inner_block->statements()->Add(loop, zone()); 3548 inner_block->statements()->Add(loop, zone());
3552 3549
3553 // Make statement: if (flag == 1) { break; } 3550 // Make statement: {{if (flag == 1) break;}}
3554 { 3551 {
3555 Expression* compare = NULL; 3552 Expression* compare = NULL;
3556 // Make compare expresion: flag == 1. 3553 // Make compare expresion: flag == 1.
3557 { 3554 {
3558 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); 3555 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3559 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); 3556 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3560 compare = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1, 3557 compare = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
3561 RelocInfo::kNoPosition); 3558 RelocInfo::kNoPosition);
3562 } 3559 }
3563 Statement* stop = 3560 Statement* stop =
3564 factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition); 3561 factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition);
3565 Statement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition); 3562 Statement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
3566 Statement* if_flag_break = 3563 Statement* if_flag_break =
3567 factory()->NewIfStatement(compare, stop, empty, RelocInfo::kNoPosition); 3564 factory()->NewIfStatement(compare, stop, empty, RelocInfo::kNoPosition);
3568 inner_block->statements()->Add(if_flag_break, zone()); 3565 Block* ignore_completion_block =
3566 factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition);
3567 ignore_completion_block->statements()->Add(if_flag_break, zone());
3568 inner_block->statements()->Add(ignore_completion_block, zone());
3569 } 3569 }
3570 3570
3571 inner_scope->set_end_position(scanner()->location().end_pos); 3571 inner_scope->set_end_position(scanner()->location().end_pos);
3572 inner_block->set_scope(inner_scope); 3572 inner_block->set_scope(inner_scope);
3573 scope_ = for_scope; 3573 scope_ = for_scope;
3574 3574
3575 outer_loop->Initialize(NULL, NULL, NULL, inner_block); 3575 outer_loop->Initialize(NULL, NULL, NULL, inner_block);
3576 return outer_block; 3576 return outer_block;
3577 } 3577 }
3578 3578
(...skipping 2740 matching lines...) Expand 10 before | Expand all | Expand 10 after
6319 6319
6320 Expression* Parser::SpreadCallNew(Expression* function, 6320 Expression* Parser::SpreadCallNew(Expression* function,
6321 ZoneList<v8::internal::Expression*>* args, 6321 ZoneList<v8::internal::Expression*>* args,
6322 int pos) { 6322 int pos) {
6323 args->InsertAt(0, function, zone()); 6323 args->InsertAt(0, function, zone());
6324 6324
6325 return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos); 6325 return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos);
6326 } 6326 }
6327 } // namespace internal 6327 } // namespace internal
6328 } // namespace v8 6328 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698