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

Side by Side Diff: src/parsing/parser.cc

Issue 1583453003: [parser cleanup] Use BlockState consistently in Parser (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Remove final scope_ assignment Created 4 years, 11 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 | « no previous file | no next file » | 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/parsing/parser.h" 5 #include "src/parsing/parser.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/ast/ast.h" 8 #include "src/ast/ast.h"
9 #include "src/ast/ast-expression-visitor.h" 9 #include "src/ast/ast-expression-visitor.h"
10 #include "src/ast/ast-literal-reindexer.h" 10 #include "src/ast/ast-literal-reindexer.h"
(...skipping 3299 matching lines...) Expand 10 before | Expand all | Expand 10 after
3310 // labels: for (; flag == 1; flag = 0, temp_x = x) { 3310 // labels: for (; flag == 1; flag = 0, temp_x = x) {
3311 // body 3311 // body
3312 // } 3312 // }
3313 // {{ if (flag == 1) // Body used break. 3313 // {{ if (flag == 1) // Body used break.
3314 // break; 3314 // break;
3315 // }} 3315 // }}
3316 // } 3316 // }
3317 // } 3317 // }
3318 3318
3319 DCHECK(names->length() > 0); 3319 DCHECK(names->length() > 0);
3320 Scope* for_scope = scope_;
3321 ZoneList<Variable*> temps(names->length(), zone()); 3320 ZoneList<Variable*> temps(names->length(), zone());
3322 3321
3323 Block* outer_block = factory()->NewBlock(NULL, names->length() + 4, false, 3322 Block* outer_block = factory()->NewBlock(NULL, names->length() + 4, false,
3324 RelocInfo::kNoPosition); 3323 RelocInfo::kNoPosition);
3325 3324
3326 // Add statement: let/const x = i. 3325 // Add statement: let/const x = i.
3327 outer_block->statements()->Add(init, zone()); 3326 outer_block->statements()->Add(init, zone());
3328 3327
3329 const AstRawString* temp_name = ast_value_factory()->dot_for_string(); 3328 const AstRawString* temp_name = ast_value_factory()->dot_for_string();
3330 3329
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
3363 zone()); 3362 zone());
3364 3363
3365 // Make statement: outer: for (;;) 3364 // Make statement: outer: for (;;)
3366 // Note that we don't actually create the label, or set this loop up as an 3365 // Note that we don't actually create the label, or set this loop up as an
3367 // explicit break target, instead handing it directly to those nodes that 3366 // explicit break target, instead handing it directly to those nodes that
3368 // need to know about it. This should be safe because we don't run any code 3367 // need to know about it. This should be safe because we don't run any code
3369 // in this function that looks up break targets. 3368 // in this function that looks up break targets.
3370 ForStatement* outer_loop = 3369 ForStatement* outer_loop =
3371 factory()->NewForStatement(NULL, RelocInfo::kNoPosition); 3370 factory()->NewForStatement(NULL, RelocInfo::kNoPosition);
3372 outer_block->statements()->Add(outer_loop, zone()); 3371 outer_block->statements()->Add(outer_loop, zone());
3373 3372 outer_block->set_scope(scope_);
3374 outer_block->set_scope(for_scope);
3375 scope_ = inner_scope;
3376 3373
3377 Block* inner_block = 3374 Block* inner_block =
3378 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition); 3375 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition);
3379 Block* ignore_completion_block = factory()->NewBlock( 3376 {
3380 NULL, names->length() + 3, true, RelocInfo::kNoPosition); 3377 BlockState block_state(&scope_, inner_scope);
3381 ZoneList<Variable*> inner_vars(names->length(), zone());
3382 // For each let variable x:
3383 // make statement: let/const x = temp_x.
3384 VariableMode mode = is_const ? CONST : LET;
3385 for (int i = 0; i < names->length(); i++) {
3386 VariableProxy* proxy = NewUnresolved(names->at(i), mode);
3387 Declaration* declaration = factory()->NewVariableDeclaration(
3388 proxy, mode, scope_, RelocInfo::kNoPosition);
3389 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
3390 inner_vars.Add(declaration->proxy()->var(), zone());
3391 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
3392 Assignment* assignment = factory()->NewAssignment(
3393 Token::INIT, proxy, temp_proxy, RelocInfo::kNoPosition);
3394 Statement* assignment_statement =
3395 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3396 DCHECK(init->position() != RelocInfo::kNoPosition);
3397 proxy->var()->set_initializer_position(init->position());
3398 ignore_completion_block->statements()->Add(assignment_statement, zone());
3399 }
3400 3378
3401 // Make statement: if (first == 1) { first = 0; } else { next; } 3379 Block* ignore_completion_block = factory()->NewBlock(
3402 if (next) { 3380 NULL, names->length() + 3, true, RelocInfo::kNoPosition);
3403 DCHECK(first); 3381 ZoneList<Variable*> inner_vars(names->length(), zone());
3404 Expression* compare = NULL; 3382 // For each let variable x:
3405 // Make compare expression: first == 1. 3383 // make statement: let/const x = temp_x.
3406 { 3384 VariableMode mode = is_const ? CONST : LET;
3407 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); 3385 for (int i = 0; i < names->length(); i++) {
3408 VariableProxy* first_proxy = factory()->NewVariableProxy(first); 3386 VariableProxy* proxy = NewUnresolved(names->at(i), mode);
3409 compare = factory()->NewCompareOperation(Token::EQ, first_proxy, const1, 3387 Declaration* declaration = factory()->NewVariableDeclaration(
3410 RelocInfo::kNoPosition); 3388 proxy, mode, scope_, RelocInfo::kNoPosition);
3389 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
3390 inner_vars.Add(declaration->proxy()->var(), zone());
3391 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
3392 Assignment* assignment = factory()->NewAssignment(
3393 Token::INIT, proxy, temp_proxy, RelocInfo::kNoPosition);
3394 Statement* assignment_statement =
3395 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3396 DCHECK(init->position() != RelocInfo::kNoPosition);
3397 proxy->var()->set_initializer_position(init->position());
3398 ignore_completion_block->statements()->Add(assignment_statement, zone());
3411 } 3399 }
3412 Statement* clear_first = NULL; 3400
3413 // Make statement: first = 0. 3401 // Make statement: if (first == 1) { first = 0; } else { next; }
3414 { 3402 if (next) {
3415 VariableProxy* first_proxy = factory()->NewVariableProxy(first); 3403 DCHECK(first);
3416 Expression* const0 = factory()->NewSmiLiteral(0, RelocInfo::kNoPosition); 3404 Expression* compare = NULL;
3417 Assignment* assignment = factory()->NewAssignment( 3405 // Make compare expression: first == 1.
3418 Token::ASSIGN, first_proxy, const0, RelocInfo::kNoPosition); 3406 {
3419 clear_first = 3407 Expression* const1 =
3420 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition); 3408 factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3409 VariableProxy* first_proxy = factory()->NewVariableProxy(first);
3410 compare = factory()->NewCompareOperation(Token::EQ, first_proxy, const1,
3411 RelocInfo::kNoPosition);
3412 }
3413 Statement* clear_first = NULL;
3414 // Make statement: first = 0.
3415 {
3416 VariableProxy* first_proxy = factory()->NewVariableProxy(first);
3417 Expression* const0 =
3418 factory()->NewSmiLiteral(0, RelocInfo::kNoPosition);
3419 Assignment* assignment = factory()->NewAssignment(
3420 Token::ASSIGN, first_proxy, const0, RelocInfo::kNoPosition);
3421 clear_first = factory()->NewExpressionStatement(assignment,
3422 RelocInfo::kNoPosition);
3423 }
3424 Statement* clear_first_or_next = factory()->NewIfStatement(
3425 compare, clear_first, next, RelocInfo::kNoPosition);
3426 ignore_completion_block->statements()->Add(clear_first_or_next, zone());
3421 } 3427 }
3422 Statement* clear_first_or_next = factory()->NewIfStatement(
3423 compare, clear_first, next, RelocInfo::kNoPosition);
3424 ignore_completion_block->statements()->Add(clear_first_or_next, zone());
3425 }
3426 3428
3427 Variable* flag = scope_->NewTemporary(temp_name); 3429 Variable* flag = scope_->NewTemporary(temp_name);
3428 // Make statement: flag = 1. 3430 // Make statement: flag = 1.
3429 {
3430 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3431 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3432 Assignment* assignment = factory()->NewAssignment(
3433 Token::ASSIGN, flag_proxy, const1, RelocInfo::kNoPosition);
3434 Statement* assignment_statement =
3435 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3436 ignore_completion_block->statements()->Add(assignment_statement, zone());
3437 }
3438
3439 // Make statement: if (!cond) break.
3440 if (cond) {
3441 Statement* stop =
3442 factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition);
3443 Statement* noop = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
3444 ignore_completion_block->statements()->Add(
3445 factory()->NewIfStatement(cond, noop, stop, cond->position()), zone());
3446 }
3447
3448 inner_block->statements()->Add(ignore_completion_block, zone());
3449 // Make cond expression for main loop: flag == 1.
3450 Expression* flag_cond = NULL;
3451 {
3452 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3453 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3454 flag_cond = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
3455 RelocInfo::kNoPosition);
3456 }
3457
3458 // Create chain of expressions "flag = 0, temp_x = x, ..."
3459 Statement* compound_next_statement = NULL;
3460 {
3461 Expression* compound_next = NULL;
3462 // Make expression: flag = 0.
3463 { 3431 {
3464 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); 3432 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3465 Expression* const0 = factory()->NewSmiLiteral(0, RelocInfo::kNoPosition); 3433 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3466 compound_next = factory()->NewAssignment(Token::ASSIGN, flag_proxy, 3434 Assignment* assignment = factory()->NewAssignment(
3467 const0, RelocInfo::kNoPosition); 3435 Token::ASSIGN, flag_proxy, const1, RelocInfo::kNoPosition);
3436 Statement* assignment_statement =
3437 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3438 ignore_completion_block->statements()->Add(assignment_statement, zone());
3468 } 3439 }
3469 3440
3470 // Make the comma-separated list of temp_x = x assignments. 3441 // Make statement: if (!cond) break.
3471 int inner_var_proxy_pos = scanner()->location().beg_pos; 3442 if (cond) {
3472 for (int i = 0; i < names->length(); i++) { 3443 Statement* stop =
3473 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i)); 3444 factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition);
3474 VariableProxy* proxy = 3445 Statement* noop = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
3475 factory()->NewVariableProxy(inner_vars.at(i), inner_var_proxy_pos); 3446 ignore_completion_block->statements()->Add(
3476 Assignment* assignment = factory()->NewAssignment( 3447 factory()->NewIfStatement(cond, noop, stop, cond->position()),
3477 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition); 3448 zone());
3478 compound_next = factory()->NewBinaryOperation(
3479 Token::COMMA, compound_next, assignment, RelocInfo::kNoPosition);
3480 } 3449 }
3481 3450
3482 compound_next_statement = factory()->NewExpressionStatement( 3451 inner_block->statements()->Add(ignore_completion_block, zone());
3483 compound_next, RelocInfo::kNoPosition); 3452 // Make cond expression for main loop: flag == 1.
3484 } 3453 Expression* flag_cond = NULL;
3485
3486 // Make statement: labels: for (; flag == 1; flag = 0, temp_x = x)
3487 // Note that we re-use the original loop node, which retains its labels
3488 // and ensures that any break or continue statements in body point to
3489 // the right place.
3490 loop->Initialize(NULL, flag_cond, compound_next_statement, body);
3491 inner_block->statements()->Add(loop, zone());
3492
3493 // Make statement: {{if (flag == 1) break;}}
3494 {
3495 Expression* compare = NULL;
3496 // Make compare expresion: flag == 1.
3497 { 3454 {
3498 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); 3455 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3499 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); 3456 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3500 compare = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1, 3457 flag_cond = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
3501 RelocInfo::kNoPosition); 3458 RelocInfo::kNoPosition);
3502 } 3459 }
3503 Statement* stop = 3460
3504 factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition); 3461 // Create chain of expressions "flag = 0, temp_x = x, ..."
3505 Statement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition); 3462 Statement* compound_next_statement = NULL;
3506 Statement* if_flag_break = 3463 {
3507 factory()->NewIfStatement(compare, stop, empty, RelocInfo::kNoPosition); 3464 Expression* compound_next = NULL;
3508 Block* ignore_completion_block = 3465 // Make expression: flag = 0.
3509 factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition); 3466 {
3510 ignore_completion_block->statements()->Add(if_flag_break, zone()); 3467 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3511 inner_block->statements()->Add(ignore_completion_block, zone()); 3468 Expression* const0 =
3469 factory()->NewSmiLiteral(0, RelocInfo::kNoPosition);
3470 compound_next = factory()->NewAssignment(
3471 Token::ASSIGN, flag_proxy, const0, RelocInfo::kNoPosition);
3472 }
3473
3474 // Make the comma-separated list of temp_x = x assignments.
3475 int inner_var_proxy_pos = scanner()->location().beg_pos;
3476 for (int i = 0; i < names->length(); i++) {
3477 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
3478 VariableProxy* proxy =
3479 factory()->NewVariableProxy(inner_vars.at(i), inner_var_proxy_pos);
3480 Assignment* assignment = factory()->NewAssignment(
3481 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition);
3482 compound_next = factory()->NewBinaryOperation(
3483 Token::COMMA, compound_next, assignment, RelocInfo::kNoPosition);
3484 }
3485
3486 compound_next_statement = factory()->NewExpressionStatement(
3487 compound_next, RelocInfo::kNoPosition);
3488 }
3489
3490 // Make statement: labels: for (; flag == 1; flag = 0, temp_x = x)
3491 // Note that we re-use the original loop node, which retains its labels
3492 // and ensures that any break or continue statements in body point to
3493 // the right place.
3494 loop->Initialize(NULL, flag_cond, compound_next_statement, body);
3495 inner_block->statements()->Add(loop, zone());
3496
3497 // Make statement: {{if (flag == 1) break;}}
3498 {
3499 Expression* compare = NULL;
3500 // Make compare expresion: flag == 1.
3501 {
3502 Expression* const1 =
3503 factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3504 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3505 compare = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
3506 RelocInfo::kNoPosition);
3507 }
3508 Statement* stop =
3509 factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition);
3510 Statement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
3511 Statement* if_flag_break = factory()->NewIfStatement(
3512 compare, stop, empty, RelocInfo::kNoPosition);
3513 Block* ignore_completion_block =
3514 factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition);
3515 ignore_completion_block->statements()->Add(if_flag_break, zone());
3516 inner_block->statements()->Add(ignore_completion_block, zone());
3517 }
3518
3519 inner_scope->set_end_position(scanner()->location().end_pos);
3520 inner_block->set_scope(inner_scope);
3512 } 3521 }
3513 3522
3514 inner_scope->set_end_position(scanner()->location().end_pos);
3515 inner_block->set_scope(inner_scope);
3516 scope_ = for_scope;
3517
3518 outer_loop->Initialize(NULL, NULL, NULL, inner_block); 3523 outer_loop->Initialize(NULL, NULL, NULL, inner_block);
3519 return outer_block; 3524 return outer_block;
3520 } 3525 }
3521 3526
3522 3527
3523 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, 3528 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
3524 bool* ok) { 3529 bool* ok) {
3525 // ForStatement :: 3530 // ForStatement ::
3526 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement 3531 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
3527 3532
3528 int stmt_pos = peek_position(); 3533 int stmt_pos = peek_position();
3529 bool is_const = false; 3534 bool is_const = false;
3530 Statement* init = NULL; 3535 Statement* init = NULL;
3531 ZoneList<const AstRawString*> lexical_bindings(1, zone()); 3536 ZoneList<const AstRawString*> lexical_bindings(1, zone());
3532 3537
3533 // Create an in-between scope for let-bound iteration variables. 3538 // Create an in-between scope for let-bound iteration variables.
3534 Scope* saved_scope = scope_;
3535 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); 3539 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE);
3536 scope_ = for_scope; 3540
3541 BlockState block_state(&scope_, for_scope);
3537 Expect(Token::FOR, CHECK_OK); 3542 Expect(Token::FOR, CHECK_OK);
3538 Expect(Token::LPAREN, CHECK_OK); 3543 Expect(Token::LPAREN, CHECK_OK);
3539 for_scope->set_start_position(scanner()->location().beg_pos); 3544 for_scope->set_start_position(scanner()->location().beg_pos);
3540 bool is_let_identifier_expression = false; 3545 bool is_let_identifier_expression = false;
3541 DeclarationParsingResult parsing_result; 3546 DeclarationParsingResult parsing_result;
3542 if (peek() != Token::SEMICOLON) { 3547 if (peek() != Token::SEMICOLON) {
3543 if (peek() == Token::VAR || (peek() == Token::CONST && allow_const()) || 3548 if (peek() == Token::VAR || (peek() == Token::CONST && allow_const()) ||
3544 (peek() == Token::LET && IsNextLetKeyword())) { 3549 (peek() == Token::LET && IsNextLetKeyword())) {
3545 ParseVariableDeclarations(kForStatement, &parsing_result, CHECK_OK); 3550 ParseVariableDeclarations(kForStatement, &parsing_result, CHECK_OK);
3546 is_const = parsing_result.descriptor.mode == CONST; 3551 is_const = parsing_result.descriptor.mode == CONST;
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
3609 // { 3614 // {
3610 // <let x' be a temporary variable> 3615 // <let x' be a temporary variable>
3611 // for (x' in/of e) { 3616 // for (x' in/of e) {
3612 // let/const/var x; 3617 // let/const/var x;
3613 // x = x'; 3618 // x = x';
3614 // b; 3619 // b;
3615 // } 3620 // }
3616 // let x; // for TDZ 3621 // let x; // for TDZ
3617 // } 3622 // }
3618 3623
3619 Variable* temp = scope_->NewTemporary( 3624 Variable* temp =
3620 ast_value_factory()->dot_for_string()); 3625 scope_->NewTemporary(ast_value_factory()->dot_for_string());
3621 ForEachStatement* loop = 3626 ForEachStatement* loop =
3622 factory()->NewForEachStatement(mode, labels, stmt_pos); 3627 factory()->NewForEachStatement(mode, labels, stmt_pos);
3623 Target target(&this->target_stack_, loop); 3628 Target target(&this->target_stack_, loop);
3624 3629
3625 Expression* enumerable = ParseExpression(true, CHECK_OK); 3630 Expression* enumerable = ParseExpression(true, CHECK_OK);
3626 3631
3627 Expect(Token::RPAREN, CHECK_OK); 3632 Expect(Token::RPAREN, CHECK_OK);
3628 3633
3629 Scope* body_scope = NewScope(scope_, BLOCK_SCOPE); 3634 Scope* body_scope = NewScope(scope_, BLOCK_SCOPE);
3630 body_scope->set_start_position(scanner()->location().beg_pos); 3635 body_scope->set_start_position(scanner()->location().beg_pos);
3631 scope_ = body_scope;
3632
3633 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3634 3636
3635 Block* body_block = 3637 Block* body_block =
3636 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition); 3638 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition);
3637 3639
3638 auto each_initialization_block =
3639 factory()->NewBlock(nullptr, 1, true, RelocInfo::kNoPosition);
3640 { 3640 {
3641 auto descriptor = parsing_result.descriptor; 3641 BlockState block_state(&scope_, body_scope);
3642 descriptor.declaration_pos = RelocInfo::kNoPosition;
3643 descriptor.initialization_pos = RelocInfo::kNoPosition;
3644 decl.initializer = factory()->NewVariableProxy(temp);
3645 3642
3646 PatternRewriter::DeclareAndInitializeVariables( 3643 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3647 each_initialization_block, &descriptor, &decl, 3644
3648 IsLexicalVariableMode(descriptor.mode) ? &lexical_bindings 3645 auto each_initialization_block =
3649 : nullptr, 3646 factory()->NewBlock(nullptr, 1, true, RelocInfo::kNoPosition);
3650 CHECK_OK); 3647 {
3648 auto descriptor = parsing_result.descriptor;
3649 descriptor.declaration_pos = RelocInfo::kNoPosition;
3650 descriptor.initialization_pos = RelocInfo::kNoPosition;
3651 decl.initializer = factory()->NewVariableProxy(temp);
3652
3653 PatternRewriter::DeclareAndInitializeVariables(
3654 each_initialization_block, &descriptor, &decl,
3655 IsLexicalVariableMode(descriptor.mode) ? &lexical_bindings
3656 : nullptr,
3657 CHECK_OK);
3658 }
3659
3660 body_block->statements()->Add(each_initialization_block, zone());
3661 body_block->statements()->Add(body, zone());
3662 VariableProxy* temp_proxy =
3663 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos);
3664 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block,
3665 false);
3651 } 3666 }
3652
3653 body_block->statements()->Add(each_initialization_block, zone());
3654 body_block->statements()->Add(body, zone());
3655 VariableProxy* temp_proxy =
3656 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos);
3657 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block,
3658 false);
3659 scope_ = for_scope;
3660 body_scope->set_end_position(scanner()->location().end_pos); 3667 body_scope->set_end_position(scanner()->location().end_pos);
3661 body_scope = body_scope->FinalizeBlockScope(); 3668 body_scope = body_scope->FinalizeBlockScope();
3662 if (body_scope != nullptr) {
3663 body_block->set_scope(body_scope); 3669 body_block->set_scope(body_scope);
3664 }
3665 3670
3666 // Create a TDZ for any lexically-bound names. 3671 // Create a TDZ for any lexically-bound names.
3667 if (IsLexicalVariableMode(parsing_result.descriptor.mode)) { 3672 if (IsLexicalVariableMode(parsing_result.descriptor.mode)) {
3668 DCHECK_NULL(init_block); 3673 DCHECK_NULL(init_block);
3669 3674
3670 init_block = 3675 init_block =
3671 factory()->NewBlock(nullptr, 1, false, RelocInfo::kNoPosition); 3676 factory()->NewBlock(nullptr, 1, false, RelocInfo::kNoPosition);
3672 3677
3673 for (int i = 0; i < lexical_bindings.length(); ++i) { 3678 for (int i = 0; i < lexical_bindings.length(); ++i) {
3674 // TODO(adamk): This needs to be some sort of special 3679 // TODO(adamk): This needs to be some sort of special
3675 // INTERNAL variable that's invisible to the debugger 3680 // INTERNAL variable that's invisible to the debugger
3676 // but visible to everything else. 3681 // but visible to everything else.
3677 VariableProxy* tdz_proxy = NewUnresolved(lexical_bindings[i], LET); 3682 VariableProxy* tdz_proxy =
3678 Declaration* tdz_decl = factory()->NewVariableDeclaration( 3683 NewUnresolved(lexical_bindings[i], LET);
3679 tdz_proxy, LET, scope_, RelocInfo::kNoPosition); 3684 Declaration* tdz_decl = factory()->NewVariableDeclaration(
3680 Variable* tdz_var = Declare(tdz_decl, DeclarationDescriptor::NORMAL, 3685 tdz_proxy, LET, scope_, RelocInfo::kNoPosition);
3681 true, CHECK_OK); 3686 Variable* tdz_var = Declare(
3682 tdz_var->set_initializer_position(position()); 3687 tdz_decl, DeclarationDescriptor::NORMAL, true, CHECK_OK);
3688 tdz_var->set_initializer_position(position());
3689 }
3683 } 3690 }
3684 }
3685 3691
3686 scope_ = saved_scope;
3687 for_scope->set_end_position(scanner()->location().end_pos); 3692 for_scope->set_end_position(scanner()->location().end_pos);
3688 for_scope = for_scope->FinalizeBlockScope(); 3693 for_scope = for_scope->FinalizeBlockScope();
3689 // Parsed for-in loop w/ variable declarations. 3694 // Parsed for-in loop w/ variable declarations.
3690 if (init_block != nullptr) { 3695 if (init_block != nullptr) {
3691 init_block->statements()->Add(loop, zone()); 3696 init_block->statements()->Add(loop, zone());
3692 if (for_scope != nullptr) { 3697 init_block->set_scope(for_scope);
3693 init_block->set_scope(for_scope);
3694 }
3695 return init_block; 3698 return init_block;
3696 } else { 3699 } else {
3697 DCHECK_NULL(for_scope); 3700 DCHECK_NULL(for_scope);
3698 return loop; 3701 return loop;
3699 } 3702 }
3700 } else { 3703 } else {
3701 init = parsing_result.BuildInitializationBlock( 3704 init = parsing_result.BuildInitializationBlock(
3702 IsLexicalVariableMode(parsing_result.descriptor.mode) 3705 IsLexicalVariableMode(parsing_result.descriptor.mode)
3703 ? &lexical_bindings 3706 ? &lexical_bindings
3704 : nullptr, 3707 : nullptr,
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
3741 Expression* enumerable = ParseExpression(true, CHECK_OK); 3744 Expression* enumerable = ParseExpression(true, CHECK_OK);
3742 Expect(Token::RPAREN, CHECK_OK); 3745 Expect(Token::RPAREN, CHECK_OK);
3743 3746
3744 // Make a block around the statement in case a lexical binding 3747 // Make a block around the statement in case a lexical binding
3745 // is introduced, e.g. by a FunctionDeclaration. 3748 // is introduced, e.g. by a FunctionDeclaration.
3746 // This block must not use for_scope as its scope because if a 3749 // This block must not use for_scope as its scope because if a
3747 // lexical binding is introduced which overlaps with the for-in/of, 3750 // lexical binding is introduced which overlaps with the for-in/of,
3748 // expressions in head of the loop should actually have variables 3751 // expressions in head of the loop should actually have variables
3749 // resolved in the outer scope. 3752 // resolved in the outer scope.
3750 Scope* body_scope = NewScope(for_scope, BLOCK_SCOPE); 3753 Scope* body_scope = NewScope(for_scope, BLOCK_SCOPE);
3751 scope_ = body_scope; 3754 BlockState block_state(&scope_, body_scope);
3752 Block* block = 3755 Block* block =
3753 factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); 3756 factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
3754 Statement* body = ParseSubStatement(NULL, CHECK_OK); 3757 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3755 block->statements()->Add(body, zone()); 3758 block->statements()->Add(body, zone());
3756 InitializeForEachStatement(loop, expression, enumerable, block, 3759 InitializeForEachStatement(loop, expression, enumerable, block,
3757 is_destructuring); 3760 is_destructuring);
3758 scope_ = saved_scope;
3759 body_scope->set_end_position(scanner()->location().end_pos); 3761 body_scope->set_end_position(scanner()->location().end_pos);
3760 body_scope = body_scope->FinalizeBlockScope(); 3762 body_scope = body_scope->FinalizeBlockScope();
3761 if (body_scope != nullptr) { 3763 block->set_scope(body_scope);
3762 block->set_scope(body_scope);
3763 }
3764 for_scope->set_end_position(scanner()->location().end_pos); 3764 for_scope->set_end_position(scanner()->location().end_pos);
3765 for_scope = for_scope->FinalizeBlockScope(); 3765 for_scope = for_scope->FinalizeBlockScope();
3766 DCHECK(for_scope == nullptr); 3766 DCHECK(for_scope == nullptr);
3767 // Parsed for-in loop. 3767 // Parsed for-in loop.
3768 return loop; 3768 return loop;
3769 3769
3770 } else { 3770 } else {
3771 init = factory()->NewExpressionStatement(expression, lhs_beg_pos); 3771 init = factory()->NewExpressionStatement(expression, lhs_beg_pos);
3772 } 3772 }
3773 } 3773 }
3774 } 3774 }
3775 3775
3776 // Standard 'for' loop 3776 // Standard 'for' loop
3777 ForStatement* loop = factory()->NewForStatement(labels, stmt_pos); 3777 ForStatement* loop = factory()->NewForStatement(labels, stmt_pos);
3778 Target target(&this->target_stack_, loop); 3778 Target target(&this->target_stack_, loop);
3779 3779
3780 // Parsed initializer at this point. 3780 // Parsed initializer at this point.
3781 // Detect attempts at 'let' declarations in sloppy mode. 3781 // Detect attempts at 'let' declarations in sloppy mode.
3782 if (!allow_harmony_sloppy_let() && peek() == Token::IDENTIFIER && 3782 if (!allow_harmony_sloppy_let() && peek() == Token::IDENTIFIER &&
3783 is_sloppy(language_mode()) && is_let_identifier_expression) { 3783 is_sloppy(language_mode()) && is_let_identifier_expression) {
3784 ReportMessage(MessageTemplate::kSloppyLexical, NULL); 3784 ReportMessage(MessageTemplate::kSloppyLexical, NULL);
3785 *ok = false; 3785 *ok = false;
3786 return NULL; 3786 return NULL;
3787 } 3787 }
3788 Expect(Token::SEMICOLON, CHECK_OK); 3788 Expect(Token::SEMICOLON, CHECK_OK);
3789 3789
3790 Expression* cond = NULL;
3791 Statement* next = NULL;
3792 Statement* body = NULL;
3793
3790 // If there are let bindings, then condition and the next statement of the 3794 // If there are let bindings, then condition and the next statement of the
3791 // for loop must be parsed in a new scope. 3795 // for loop must be parsed in a new scope.
3792 Scope* inner_scope = NULL; 3796 Scope* inner_scope = scope_;
3793 if (lexical_bindings.length() > 0) { 3797 if (lexical_bindings.length() > 0) {
3794 inner_scope = NewScope(for_scope, BLOCK_SCOPE); 3798 inner_scope = NewScope(for_scope, BLOCK_SCOPE);
3795 inner_scope->set_start_position(scanner()->location().beg_pos); 3799 inner_scope->set_start_position(scanner()->location().beg_pos);
3796 scope_ = inner_scope;
3797 } 3800 }
3801 {
3802 BlockState block_state(&scope_, inner_scope);
3798 3803
3799 Expression* cond = NULL; 3804 if (peek() != Token::SEMICOLON) {
3800 if (peek() != Token::SEMICOLON) { 3805 cond = ParseExpression(true, CHECK_OK);
3801 cond = ParseExpression(true, CHECK_OK); 3806 }
3807 Expect(Token::SEMICOLON, CHECK_OK);
3808
3809 if (peek() != Token::RPAREN) {
3810 Expression* exp = ParseExpression(true, CHECK_OK);
3811 next = factory()->NewExpressionStatement(exp, exp->position());
3812 }
3813 Expect(Token::RPAREN, CHECK_OK);
3814
3815 body = ParseSubStatement(NULL, CHECK_OK);
3802 } 3816 }
3803 Expect(Token::SEMICOLON, CHECK_OK);
3804
3805 Statement* next = NULL;
3806 if (peek() != Token::RPAREN) {
3807 Expression* exp = ParseExpression(true, CHECK_OK);
3808 next = factory()->NewExpressionStatement(exp, exp->position());
3809 }
3810 Expect(Token::RPAREN, CHECK_OK);
3811
3812 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3813 3817
3814 Statement* result = NULL; 3818 Statement* result = NULL;
3815 if (lexical_bindings.length() > 0) { 3819 if (lexical_bindings.length() > 0) {
3816 scope_ = for_scope; 3820 BlockState block_state(&scope_, for_scope);
3817 result = DesugarLexicalBindingsInForStatement( 3821 result = DesugarLexicalBindingsInForStatement(
3818 inner_scope, is_const, &lexical_bindings, loop, init, cond, 3822 inner_scope, is_const, &lexical_bindings, loop, init, cond,
3819 next, body, CHECK_OK); 3823 next, body, CHECK_OK);
3820 scope_ = saved_scope;
3821 for_scope->set_end_position(scanner()->location().end_pos); 3824 for_scope->set_end_position(scanner()->location().end_pos);
3822 } else { 3825 } else {
3823 scope_ = saved_scope;
3824 for_scope->set_end_position(scanner()->location().end_pos); 3826 for_scope->set_end_position(scanner()->location().end_pos);
3825 for_scope = for_scope->FinalizeBlockScope(); 3827 for_scope = for_scope->FinalizeBlockScope();
3826 if (for_scope) { 3828 if (for_scope) {
3827 // Rewrite a for statement of the form 3829 // Rewrite a for statement of the form
3828 // for (const x = i; c; n) b 3830 // for (const x = i; c; n) b
3829 // 3831 //
3830 // into 3832 // into
3831 // 3833 //
3832 // { 3834 // {
3833 // const x = i; 3835 // const x = i;
(...skipping 1614 matching lines...) Expand 10 before | Expand all | Expand 10 after
5448 auto class_literal = value->AsClassLiteral(); 5450 auto class_literal = value->AsClassLiteral();
5449 if (class_literal->raw_name() == nullptr) { 5451 if (class_literal->raw_name() == nullptr) {
5450 class_literal->set_raw_name(name); 5452 class_literal->set_raw_name(name);
5451 } 5453 }
5452 } 5454 }
5453 } 5455 }
5454 5456
5455 5457
5456 } // namespace internal 5458 } // namespace internal
5457 } // namespace v8 5459 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698