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

Side by Side Diff: src/parsing/pattern-rewriter.cc

Issue 1772793002: Implement iterator finalization in array destructuring. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase Created 4 years, 9 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/parsing/parser.cc ('k') | test/cctest/interpreter/bytecode_expectations/ForOf.golden » ('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 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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/ast/ast.h" 5 #include "src/ast/ast.h"
6 #include "src/messages.h" 6 #include "src/messages.h"
7 #include "src/parsing/parameter-initializer-rewriter.h" 7 #include "src/parsing/parameter-initializer-rewriter.h"
8 #include "src/parsing/parser.h" 8 #include "src/parsing/parser.h"
9 9
10 namespace v8 { 10 namespace v8 {
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 402
403 403
404 void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* node) { 404 void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* node) {
405 Variable* temp_var = nullptr; 405 Variable* temp_var = nullptr;
406 VisitObjectLiteral(node, &temp_var); 406 VisitObjectLiteral(node, &temp_var);
407 } 407 }
408 408
409 409
410 void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node, 410 void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node,
411 Variable** temp_var) { 411 Variable** temp_var) {
412 DCHECK(block_->ignore_completion_value());
413
412 auto temp = *temp_var = CreateTempVar(current_value_); 414 auto temp = *temp_var = CreateTempVar(current_value_);
413
414 block_->statements()->Add(parser_->BuildAssertIsCoercible(temp), zone());
415
416 auto iterator = CreateTempVar(parser_->GetIterator( 415 auto iterator = CreateTempVar(parser_->GetIterator(
417 factory()->NewVariableProxy(temp), factory(), RelocInfo::kNoPosition)); 416 factory()->NewVariableProxy(temp), factory(), RelocInfo::kNoPosition));
418 auto done = CreateTempVar( 417 auto done = CreateTempVar(
419 factory()->NewBooleanLiteral(false, RelocInfo::kNoPosition)); 418 factory()->NewBooleanLiteral(false, RelocInfo::kNoPosition));
420 auto result = CreateTempVar(); 419 auto result = CreateTempVar();
421 auto v = CreateTempVar(); 420 auto v = CreateTempVar();
421 auto completion = CreateTempVar();
422 auto nopos = RelocInfo::kNoPosition;
423
424 // For the purpose of iterator finalization, we temporarily set block_ to a
425 // new block. In the main body of this function, we write to block_ (both
426 // explicitly and implicitly via recursion). At the end of the function, we
427 // wrap this new block in a try-finally statement, restore block_ to its
428 // original value, and add the try-finally statement to block_.
429 auto target = block_;
430 if (FLAG_harmony_iterator_close) {
431 block_ = factory()->NewBlock(nullptr, 8, true, nopos);
432 }
422 433
423 Spread* spread = nullptr; 434 Spread* spread = nullptr;
424 for (Expression* value : *node->values()) { 435 for (Expression* value : *node->values()) {
425 if (value->IsSpread()) { 436 if (value->IsSpread()) {
426 spread = value->AsSpread(); 437 spread = value->AsSpread();
427 break; 438 break;
428 } 439 }
429 440
430 PatternContext context = SetInitializerContextIfNeeded(value); 441 PatternContext context = SetInitializerContextIfNeeded(value);
442
431 // if (!done) { 443 // if (!done) {
444 // done = true; // If .next, .done or .value throws, don't close.
432 // result = IteratorNext(iterator); 445 // result = IteratorNext(iterator);
433 // v = (done = result.done) ? undefined : result.value; 446 // v = (done = result.done) ? undefined : result.value;
434 // } 447 // }
435 auto next_block = 448 Statement* if_statement;
436 factory()->NewBlock(nullptr, 2, true, RelocInfo::kNoPosition); 449 {
437 next_block->statements()->Add(factory()->NewExpressionStatement( 450 auto next_block =
438 parser_->BuildIteratorNextResult( 451 factory()->NewBlock(nullptr, 3, true, RelocInfo::kNoPosition);
439 factory()->NewVariableProxy(iterator),
440 result, RelocInfo::kNoPosition),
441 RelocInfo::kNoPosition),
442 zone());
443 452
444 auto assign_to_done = factory()->NewAssignment( 453 next_block->statements()->Add(
445 Token::ASSIGN, factory()->NewVariableProxy(done), 454 factory()->NewExpressionStatement(
446 factory()->NewProperty( 455 factory()->NewAssignment(
447 factory()->NewVariableProxy(result), 456 Token::ASSIGN, factory()->NewVariableProxy(done),
448 factory()->NewStringLiteral(ast_value_factory()->done_string(), 457 factory()->NewBooleanLiteral(true, nopos), nopos),
449 RelocInfo::kNoPosition), 458 nopos),
450 RelocInfo::kNoPosition), 459 zone());
451 RelocInfo::kNoPosition);
452 auto next_value = factory()->NewConditional(
453 assign_to_done, factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
454 factory()->NewProperty(
455 factory()->NewVariableProxy(result),
456 factory()->NewStringLiteral(ast_value_factory()->value_string(),
457 RelocInfo::kNoPosition),
458 RelocInfo::kNoPosition),
459 RelocInfo::kNoPosition);
460 next_block->statements()->Add(
461 factory()->NewExpressionStatement(
462 factory()->NewAssignment(Token::ASSIGN,
463 factory()->NewVariableProxy(v), next_value,
464 RelocInfo::kNoPosition),
465 RelocInfo::kNoPosition),
466 zone());
467 460
468 auto if_statement = factory()->NewIfStatement( 461 next_block->statements()->Add(
469 factory()->NewUnaryOperation(Token::NOT, 462 factory()->NewExpressionStatement(
470 factory()->NewVariableProxy(done), 463 parser_->BuildIteratorNextResult(
471 RelocInfo::kNoPosition), 464 factory()->NewVariableProxy(iterator), result,
472 next_block, factory()->NewEmptyStatement(RelocInfo::kNoPosition), 465 RelocInfo::kNoPosition),
473 RelocInfo::kNoPosition); 466 RelocInfo::kNoPosition),
467 zone());
468
469 auto assign_to_done = factory()->NewAssignment(
470 Token::ASSIGN, factory()->NewVariableProxy(done),
471 factory()->NewProperty(
472 factory()->NewVariableProxy(result),
473 factory()->NewStringLiteral(ast_value_factory()->done_string(),
474 RelocInfo::kNoPosition),
475 RelocInfo::kNoPosition),
476 RelocInfo::kNoPosition);
477 auto next_value = factory()->NewConditional(
478 assign_to_done,
479 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
480 factory()->NewProperty(
481 factory()->NewVariableProxy(result),
482 factory()->NewStringLiteral(ast_value_factory()->value_string(),
483 RelocInfo::kNoPosition),
484 RelocInfo::kNoPosition),
485 RelocInfo::kNoPosition);
486 next_block->statements()->Add(
487 factory()->NewExpressionStatement(
488 factory()->NewAssignment(Token::ASSIGN,
489 factory()->NewVariableProxy(v),
490 next_value, RelocInfo::kNoPosition),
491 RelocInfo::kNoPosition),
492 zone());
493
494 if_statement = factory()->NewIfStatement(
495 factory()->NewUnaryOperation(Token::NOT,
496 factory()->NewVariableProxy(done),
497 RelocInfo::kNoPosition),
498 next_block, factory()->NewEmptyStatement(RelocInfo::kNoPosition),
499 RelocInfo::kNoPosition);
500 }
474 block_->statements()->Add(if_statement, zone()); 501 block_->statements()->Add(if_statement, zone());
475 502
476 if (!(value->IsLiteral() && value->AsLiteral()->raw_value()->IsTheHole())) { 503 if (!(value->IsLiteral() && value->AsLiteral()->raw_value()->IsTheHole())) {
504 if (FLAG_harmony_iterator_close) {
505 // completion = kAbruptCompletion;
506 Expression* proxy = factory()->NewVariableProxy(completion);
507 Expression* assignment = factory()->NewAssignment(
508 Token::ASSIGN, proxy,
509 factory()->NewSmiLiteral(kAbruptCompletion, nopos), nopos);
510 block_->statements()->Add(
511 factory()->NewExpressionStatement(assignment, nopos), zone());
512 }
513
477 RecurseIntoSubpattern(value, factory()->NewVariableProxy(v)); 514 RecurseIntoSubpattern(value, factory()->NewVariableProxy(v));
515
516 if (FLAG_harmony_iterator_close) {
517 // completion = kNormalCompletion;
518 Expression* proxy = factory()->NewVariableProxy(completion);
519 Expression* assignment = factory()->NewAssignment(
520 Token::ASSIGN, proxy,
521 factory()->NewSmiLiteral(kNormalCompletion, nopos), nopos);
522 block_->statements()->Add(
523 factory()->NewExpressionStatement(assignment, nopos), zone());
524 }
478 } 525 }
479 set_context(context); 526 set_context(context);
480 } 527 }
481 528
482 if (spread != nullptr) { 529 if (spread != nullptr) {
483 // array = []; 530 // A spread can only occur as the last component. It is not handled by
531 // RecurseIntoSubpattern above.
532
533 // let array = [];
484 // if (!done) %concat_iterable_to_array(array, iterator); 534 // if (!done) %concat_iterable_to_array(array, iterator);
535 // done = true;
536
485 auto empty_exprs = new (zone()) ZoneList<Expression*>(0, zone()); 537 auto empty_exprs = new (zone()) ZoneList<Expression*>(0, zone());
486 auto array = CreateTempVar(factory()->NewArrayLiteral( 538 auto array = CreateTempVar(factory()->NewArrayLiteral(
487 empty_exprs, 539 empty_exprs,
488 // Reuse pattern's literal index - it is unused since there is no 540 // Reuse pattern's literal index - it is unused since there is no
489 // actual literal allocated. 541 // actual literal allocated.
490 node->literal_index(), RelocInfo::kNoPosition)); 542 node->literal_index(), RelocInfo::kNoPosition));
491 543
492 auto arguments = new (zone()) ZoneList<Expression*>(2, zone()); 544 auto arguments = new (zone()) ZoneList<Expression*>(2, zone());
493 arguments->Add(factory()->NewVariableProxy(array), zone()); 545 arguments->Add(factory()->NewVariableProxy(array), zone());
494 arguments->Add(factory()->NewVariableProxy(iterator), zone()); 546 arguments->Add(factory()->NewVariableProxy(iterator), zone());
495 auto spread_into_array_call = 547 auto spread_into_array_call =
496 factory()->NewCallRuntime(Context::CONCAT_ITERABLE_TO_ARRAY_INDEX, 548 factory()->NewCallRuntime(Context::CONCAT_ITERABLE_TO_ARRAY_INDEX,
497 arguments, RelocInfo::kNoPosition); 549 arguments, RelocInfo::kNoPosition);
498 550
499 auto if_statement = factory()->NewIfStatement( 551 auto if_statement = factory()->NewIfStatement(
500 factory()->NewUnaryOperation(Token::NOT, 552 factory()->NewUnaryOperation(Token::NOT,
501 factory()->NewVariableProxy(done), 553 factory()->NewVariableProxy(done),
502 RelocInfo::kNoPosition), 554 RelocInfo::kNoPosition),
503 factory()->NewExpressionStatement(spread_into_array_call, 555 factory()->NewExpressionStatement(spread_into_array_call,
504 RelocInfo::kNoPosition), 556 RelocInfo::kNoPosition),
505 factory()->NewEmptyStatement(RelocInfo::kNoPosition), 557 factory()->NewEmptyStatement(RelocInfo::kNoPosition),
506 RelocInfo::kNoPosition); 558 RelocInfo::kNoPosition);
507 block_->statements()->Add(if_statement, zone()); 559 block_->statements()->Add(if_statement, zone());
508 560
561 auto set_done = factory()->NewAssignment(
562 Token::ASSIGN, factory()->NewVariableProxy(done),
563 factory()->NewBooleanLiteral(true, nopos), nopos);
564 block_->statements()->Add(
565 factory()->NewExpressionStatement(set_done, nopos), zone());
566
509 RecurseIntoSubpattern(spread->expression(), 567 RecurseIntoSubpattern(spread->expression(),
510 factory()->NewVariableProxy(array)); 568 factory()->NewVariableProxy(array));
511 } 569 }
570
571 if (FLAG_harmony_iterator_close) {
572 Expression* closing_condition = factory()->NewUnaryOperation(
573 Token::NOT, factory()->NewVariableProxy(done), nopos);
574 parser_->FinalizeIteratorUse(completion, closing_condition, iterator,
575 block_, target);
576 block_ = target;
577 }
512 } 578 }
513 579
514 580
515 void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node) { 581 void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node) {
516 Variable* temp_var = nullptr; 582 Variable* temp_var = nullptr;
517 VisitArrayLiteral(node, &temp_var); 583 VisitArrayLiteral(node, &temp_var);
518 } 584 }
519 585
520 586
521 void Parser::PatternRewriter::VisitAssignment(Assignment* node) { 587 void Parser::PatternRewriter::VisitAssignment(Assignment* node) {
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
617 NOT_A_PATTERN(TryFinallyStatement) 683 NOT_A_PATTERN(TryFinallyStatement)
618 NOT_A_PATTERN(UnaryOperation) 684 NOT_A_PATTERN(UnaryOperation)
619 NOT_A_PATTERN(VariableDeclaration) 685 NOT_A_PATTERN(VariableDeclaration)
620 NOT_A_PATTERN(WhileStatement) 686 NOT_A_PATTERN(WhileStatement)
621 NOT_A_PATTERN(WithStatement) 687 NOT_A_PATTERN(WithStatement)
622 NOT_A_PATTERN(Yield) 688 NOT_A_PATTERN(Yield)
623 689
624 #undef NOT_A_PATTERN 690 #undef NOT_A_PATTERN
625 } // namespace internal 691 } // namespace internal
626 } // namespace v8 692 } // namespace v8
OLDNEW
« no previous file with comments | « src/parsing/parser.cc ('k') | test/cctest/interpreter/bytecode_expectations/ForOf.golden » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698