OLD | NEW |
---|---|
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 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
400 | 400 |
401 | 401 |
402 void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* node) { | 402 void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* node) { |
403 Variable* temp_var = nullptr; | 403 Variable* temp_var = nullptr; |
404 VisitObjectLiteral(node, &temp_var); | 404 VisitObjectLiteral(node, &temp_var); |
405 } | 405 } |
406 | 406 |
407 | 407 |
408 void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node, | 408 void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node, |
409 Variable** temp_var) { | 409 Variable** temp_var) { |
410 // TODO(neis): Enable after rebase: | |
411 // DCHECK(block_->ignore_completion_value()); | |
412 | |
410 auto temp = *temp_var = CreateTempVar(current_value_); | 413 auto temp = *temp_var = CreateTempVar(current_value_); |
411 | |
412 block_->statements()->Add(parser_->BuildAssertIsCoercible(temp), zone()); | |
413 | |
414 auto iterator = CreateTempVar(parser_->GetIterator( | 414 auto iterator = CreateTempVar(parser_->GetIterator( |
415 factory()->NewVariableProxy(temp), factory(), RelocInfo::kNoPosition)); | 415 factory()->NewVariableProxy(temp), factory(), RelocInfo::kNoPosition)); |
416 auto done = CreateTempVar( | 416 auto done = CreateTempVar( |
417 factory()->NewBooleanLiteral(false, RelocInfo::kNoPosition)); | 417 factory()->NewBooleanLiteral(false, RelocInfo::kNoPosition)); |
418 auto result = CreateTempVar(); | 418 auto result = CreateTempVar(); |
419 auto v = CreateTempVar(); | 419 auto v = CreateTempVar(); |
420 auto completion = CreateTempVar(); | |
421 auto nopos = RelocInfo::kNoPosition; | |
422 | |
423 // For the purpose of iterator finalization, we temporarily set block_ to a | |
424 // new block. In the main body of this function, we write to block_ (both | |
425 // explicitly and implicitly via recursion). At the end of the function, we | |
426 // wrap this new block in a try-finally statement, restore block_ to its | |
427 // original value, and add the try-finally statement to block_. | |
428 auto target = block_; | |
429 if (FLAG_harmony_iterator_close) { | |
430 block_ = factory()->NewBlock(nullptr, 8, true, nopos); | |
431 } | |
420 | 432 |
421 Spread* spread = nullptr; | 433 Spread* spread = nullptr; |
422 for (Expression* value : *node->values()) { | 434 for (Expression* value : *node->values()) { |
423 if (value->IsSpread()) { | 435 if (value->IsSpread()) { |
424 spread = value->AsSpread(); | 436 spread = value->AsSpread(); |
425 break; | 437 break; |
426 } | 438 } |
427 | 439 |
428 PatternContext context = SetInitializerContextIfNeeded(value); | 440 PatternContext context = SetInitializerContextIfNeeded(value); |
441 | |
429 // if (!done) { | 442 // if (!done) { |
443 // done = true; // If .next, .done or .value throws, don't close. | |
430 // result = IteratorNext(iterator); | 444 // result = IteratorNext(iterator); |
431 // v = (done = result.done) ? undefined : result.value; | 445 // v = (done = result.done) ? undefined : result.value; |
432 // } | 446 // } |
433 auto next_block = | 447 Statement* if_statement; |
434 factory()->NewBlock(nullptr, 2, true, RelocInfo::kNoPosition); | 448 { |
435 next_block->statements()->Add(factory()->NewExpressionStatement( | 449 auto next_block = |
436 parser_->BuildIteratorNextResult( | 450 factory()->NewBlock(nullptr, 2, true, RelocInfo::kNoPosition); |
adamk
2016/03/08 18:41:13
This block now contains 3 statements.
| |
437 factory()->NewVariableProxy(iterator), | |
438 result, RelocInfo::kNoPosition), | |
439 RelocInfo::kNoPosition), | |
440 zone()); | |
441 | 451 |
442 auto assign_to_done = factory()->NewAssignment( | 452 next_block->statements()->Add( |
443 Token::ASSIGN, factory()->NewVariableProxy(done), | 453 factory()->NewExpressionStatement( |
444 factory()->NewProperty( | 454 factory()->NewAssignment( |
445 factory()->NewVariableProxy(result), | 455 Token::ASSIGN, factory()->NewVariableProxy(done), |
446 factory()->NewStringLiteral(ast_value_factory()->done_string(), | 456 factory()->NewBooleanLiteral(true, nopos), nopos), |
447 RelocInfo::kNoPosition), | 457 nopos), |
448 RelocInfo::kNoPosition), | 458 zone()); |
449 RelocInfo::kNoPosition); | |
450 auto next_value = factory()->NewConditional( | |
451 assign_to_done, factory()->NewUndefinedLiteral(RelocInfo::kNoPosition), | |
452 factory()->NewProperty( | |
453 factory()->NewVariableProxy(result), | |
454 factory()->NewStringLiteral(ast_value_factory()->value_string(), | |
455 RelocInfo::kNoPosition), | |
456 RelocInfo::kNoPosition), | |
457 RelocInfo::kNoPosition); | |
458 next_block->statements()->Add( | |
459 factory()->NewExpressionStatement( | |
460 factory()->NewAssignment(Token::ASSIGN, | |
461 factory()->NewVariableProxy(v), next_value, | |
462 RelocInfo::kNoPosition), | |
463 RelocInfo::kNoPosition), | |
464 zone()); | |
465 | 459 |
466 auto if_statement = factory()->NewIfStatement( | 460 next_block->statements()->Add( |
467 factory()->NewUnaryOperation(Token::NOT, | 461 factory()->NewExpressionStatement( |
468 factory()->NewVariableProxy(done), | 462 parser_->BuildIteratorNextResult( |
469 RelocInfo::kNoPosition), | 463 factory()->NewVariableProxy(iterator), result, |
470 next_block, factory()->NewEmptyStatement(RelocInfo::kNoPosition), | 464 RelocInfo::kNoPosition), |
471 RelocInfo::kNoPosition); | 465 RelocInfo::kNoPosition), |
466 zone()); | |
467 | |
468 auto assign_to_done = factory()->NewAssignment( | |
469 Token::ASSIGN, factory()->NewVariableProxy(done), | |
470 factory()->NewProperty( | |
471 factory()->NewVariableProxy(result), | |
472 factory()->NewStringLiteral(ast_value_factory()->done_string(), | |
473 RelocInfo::kNoPosition), | |
474 RelocInfo::kNoPosition), | |
475 RelocInfo::kNoPosition); | |
476 auto next_value = factory()->NewConditional( | |
477 assign_to_done, | |
478 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition), | |
479 factory()->NewProperty( | |
480 factory()->NewVariableProxy(result), | |
481 factory()->NewStringLiteral(ast_value_factory()->value_string(), | |
482 RelocInfo::kNoPosition), | |
483 RelocInfo::kNoPosition), | |
484 RelocInfo::kNoPosition); | |
485 next_block->statements()->Add( | |
486 factory()->NewExpressionStatement( | |
487 factory()->NewAssignment( | |
488 Token::ASSIGN, factory()->NewVariableProxy(v), next_value, | |
489 RelocInfo::kNoPosition), | |
490 RelocInfo::kNoPosition), | |
491 zone()); | |
492 | |
493 if_statement = factory()->NewIfStatement( | |
494 factory()->NewUnaryOperation(Token::NOT, | |
495 factory()->NewVariableProxy(done), | |
496 RelocInfo::kNoPosition), | |
497 next_block, factory()->NewEmptyStatement(RelocInfo::kNoPosition), | |
498 RelocInfo::kNoPosition); | |
499 } | |
472 block_->statements()->Add(if_statement, zone()); | 500 block_->statements()->Add(if_statement, zone()); |
473 | 501 |
474 if (!(value->IsLiteral() && value->AsLiteral()->raw_value()->IsTheHole())) { | 502 if (!(value->IsLiteral() && value->AsLiteral()->raw_value()->IsTheHole())) { |
503 if (FLAG_harmony_iterator_close) { | |
504 // completion = ABRUPT; | |
505 Expression* proxy = factory()->NewVariableProxy(completion); | |
506 Expression* assignment = factory()->NewAssignment( | |
507 Token::ASSIGN, proxy, | |
508 factory()->NewSmiLiteral(ABRUPT, nopos), | |
509 nopos); | |
510 block_->statements()->Add( | |
511 factory()->NewExpressionStatement(assignment, nopos), zone()); | |
512 } | |
513 | |
475 RecurseIntoSubpattern(value, factory()->NewVariableProxy(v)); | 514 RecurseIntoSubpattern(value, factory()->NewVariableProxy(v)); |
515 | |
516 if (FLAG_harmony_iterator_close) { | |
517 // completion = NORMAL; | |
518 Expression* proxy = factory()->NewVariableProxy(completion); | |
519 Expression* assignment = factory()->NewAssignment( | |
520 Token::ASSIGN, proxy, factory()->NewSmiLiteral(NORMAL, nopos), | |
521 nopos); | |
522 block_->statements()->Add( | |
523 factory()->NewExpressionStatement(assignment, nopos), zone()); | |
524 } | |
476 } | 525 } |
477 set_context(context); | 526 set_context(context); |
478 } | 527 } |
479 | 528 |
480 if (spread != nullptr) { | 529 if (spread != nullptr) { |
481 // array = []; | 530 // A spread can only occur as the last component. It is not handled by |
531 // RecurseIntoSubpattern above. | |
532 | |
533 // let array = []; | |
482 // if (!done) %concat_iterable_to_array(array, iterator); | 534 // if (!done) %concat_iterable_to_array(array, iterator); |
535 // done = true; | |
536 | |
483 auto empty_exprs = new (zone()) ZoneList<Expression*>(0, zone()); | 537 auto empty_exprs = new (zone()) ZoneList<Expression*>(0, zone()); |
484 auto array = CreateTempVar(factory()->NewArrayLiteral( | 538 auto array = CreateTempVar(factory()->NewArrayLiteral( |
485 empty_exprs, | 539 empty_exprs, |
486 // 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 |
487 // actual literal allocated. | 541 // actual literal allocated. |
488 node->literal_index(), RelocInfo::kNoPosition)); | 542 node->literal_index(), RelocInfo::kNoPosition)); |
489 | 543 |
490 auto arguments = new (zone()) ZoneList<Expression*>(2, zone()); | 544 auto arguments = new (zone()) ZoneList<Expression*>(2, zone()); |
491 arguments->Add(factory()->NewVariableProxy(array), zone()); | 545 arguments->Add(factory()->NewVariableProxy(array), zone()); |
492 arguments->Add(factory()->NewVariableProxy(iterator), zone()); | 546 arguments->Add(factory()->NewVariableProxy(iterator), zone()); |
493 auto spread_into_array_call = | 547 auto spread_into_array_call = |
494 factory()->NewCallRuntime(Context::CONCAT_ITERABLE_TO_ARRAY_INDEX, | 548 factory()->NewCallRuntime(Context::CONCAT_ITERABLE_TO_ARRAY_INDEX, |
495 arguments, RelocInfo::kNoPosition); | 549 arguments, RelocInfo::kNoPosition); |
496 | 550 |
497 auto if_statement = factory()->NewIfStatement( | 551 auto if_statement = factory()->NewIfStatement( |
498 factory()->NewUnaryOperation(Token::NOT, | 552 factory()->NewUnaryOperation(Token::NOT, |
499 factory()->NewVariableProxy(done), | 553 factory()->NewVariableProxy(done), |
500 RelocInfo::kNoPosition), | 554 RelocInfo::kNoPosition), |
501 factory()->NewExpressionStatement(spread_into_array_call, | 555 factory()->NewExpressionStatement(spread_into_array_call, |
502 RelocInfo::kNoPosition), | 556 RelocInfo::kNoPosition), |
503 factory()->NewEmptyStatement(RelocInfo::kNoPosition), | 557 factory()->NewEmptyStatement(RelocInfo::kNoPosition), |
504 RelocInfo::kNoPosition); | 558 RelocInfo::kNoPosition); |
505 block_->statements()->Add(if_statement, zone()); | 559 block_->statements()->Add(if_statement, zone()); |
506 | 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 | |
507 RecurseIntoSubpattern(spread->expression(), | 567 RecurseIntoSubpattern(spread->expression(), |
508 factory()->NewVariableProxy(array)); | 568 factory()->NewVariableProxy(array)); |
509 } | 569 } |
570 | |
571 if (FLAG_harmony_iterator_close) { | |
572 Expression* closing_condition = factory()->NewUnaryOperation( | |
573 Token::NOT, factory()->NewVariableProxy(done), nopos); | |
574 parser_->FinalizeIteratorUse( | |
575 completion, closing_condition, iterator, block_, target); | |
576 block_ = target; | |
577 } | |
510 } | 578 } |
511 | 579 |
512 | 580 |
513 void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node) { | 581 void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node) { |
514 Variable* temp_var = nullptr; | 582 Variable* temp_var = nullptr; |
515 VisitArrayLiteral(node, &temp_var); | 583 VisitArrayLiteral(node, &temp_var); |
516 } | 584 } |
517 | 585 |
518 | 586 |
519 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 Loading... | |
615 NOT_A_PATTERN(TryFinallyStatement) | 683 NOT_A_PATTERN(TryFinallyStatement) |
616 NOT_A_PATTERN(UnaryOperation) | 684 NOT_A_PATTERN(UnaryOperation) |
617 NOT_A_PATTERN(VariableDeclaration) | 685 NOT_A_PATTERN(VariableDeclaration) |
618 NOT_A_PATTERN(WhileStatement) | 686 NOT_A_PATTERN(WhileStatement) |
619 NOT_A_PATTERN(WithStatement) | 687 NOT_A_PATTERN(WithStatement) |
620 NOT_A_PATTERN(Yield) | 688 NOT_A_PATTERN(Yield) |
621 | 689 |
622 #undef NOT_A_PATTERN | 690 #undef NOT_A_PATTERN |
623 } // namespace internal | 691 } // namespace internal |
624 } // namespace v8 | 692 } // namespace v8 |
OLD | NEW |