Chromium Code Reviews| 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/interpreter/bytecode-generator.h" | 5 #include "src/interpreter/bytecode-generator.h" |
| 6 | 6 |
| 7 #include "src/compiler.h" | 7 #include "src/compiler.h" |
| 8 #include "src/interpreter/control-flow-builders.h" | 8 #include "src/interpreter/control-flow-builders.h" |
| 9 #include "src/objects.h" | 9 #include "src/objects.h" |
| 10 #include "src/parser.h" | 10 #include "src/parser.h" |
| (...skipping 575 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 586 } else { | 586 } else { |
| 587 builder()->Jump(&body_label); | 587 builder()->Jump(&body_label); |
| 588 } | 588 } |
| 589 builder()->Bind(&done_label); | 589 builder()->Bind(&done_label); |
| 590 | 590 |
| 591 loop_builder.SetBreakTarget(done_label); | 591 loop_builder.SetBreakTarget(done_label); |
| 592 loop_builder.SetContinueTarget(next_label); | 592 loop_builder.SetContinueTarget(next_label); |
| 593 } | 593 } |
| 594 | 594 |
| 595 | 595 |
| 596 void BytecodeGenerator::VisitForInAssignment(Expression* expr, | |
| 597 FeedbackVectorSlot slot) { | |
| 598 DCHECK(expr->IsValidReferenceExpression()); | |
| 599 | |
| 600 // Evaluate assignment starting with the value to be stored in the | |
| 601 // accumulator. | |
| 602 Property* property = expr->AsProperty(); | |
| 603 LhsKind assign_type = Property::GetAssignType(property); | |
| 604 switch (assign_type) { | |
| 605 case VARIABLE: { | |
| 606 Variable* variable = expr->AsVariableProxy()->var(); | |
| 607 VisitVariableAssignment(variable, slot); | |
| 608 break; | |
| 609 } | |
| 610 case NAMED_PROPERTY: { | |
| 611 TemporaryRegisterScope temporary_register_scope(builder()); | |
| 612 Register value = temporary_register_scope.NewRegister(); | |
|
rmcilroy
2015/10/26 14:04:01
nit - use expression_result()->NewRegister() ?
oth
2015/10/28 11:53:12
This would cause us to allocate an extra register
| |
| 613 builder()->StoreAccumulatorInRegister(value); | |
| 614 Register object = VisitForRegisterValue(property->obj()); | |
| 615 size_t name_index = builder()->GetConstantPoolEntry( | |
| 616 property->key()->AsLiteral()->AsPropertyName()); | |
| 617 builder()->StoreNamedProperty(object, name_index, feedback_index(slot), | |
| 618 language_mode()); | |
| 619 break; | |
| 620 } | |
| 621 case KEYED_PROPERTY: { | |
| 622 TemporaryRegisterScope temporary_register_scope(builder()); | |
| 623 Register value = temporary_register_scope.NewRegister(); | |
|
rmcilroy
2015/10/26 14:04:01
ditto
oth
2015/10/28 11:53:12
This would cause us to allocate an extra register
| |
| 624 builder()->StoreAccumulatorInRegister(value); | |
| 625 Register object = VisitForRegisterValue(property->obj()); | |
| 626 Register key = VisitForRegisterValue(property->key()); | |
| 627 builder()->LoadAccumulatorWithRegister(value); | |
| 628 builder()->StoreKeyedProperty(object, key, feedback_index(slot), | |
| 629 language_mode()); | |
| 630 break; | |
| 631 } | |
| 632 case NAMED_SUPER_PROPERTY: | |
| 633 case KEYED_SUPER_PROPERTY: | |
| 634 UNIMPLEMENTED(); | |
| 635 } | |
| 636 } | |
| 637 | |
| 638 | |
| 596 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) { | 639 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) { |
| 597 UNIMPLEMENTED(); | 640 EffectResultScope result_scope(this); |
|
rmcilroy
2015/10/26 14:04:01
Is this needed? Shouldn't we just be using VisitFo
oth
2015/10/28 11:53:12
This is needed. RegisterResultScope can allocate a
| |
| 641 | |
| 642 if (stmt->subject()->IsNullLiteral() || | |
| 643 stmt->subject()->IsUndefinedLiteral(isolate())) { | |
| 644 // ForIn generates lots of code, skip if it wouldn't produce any effects. | |
| 645 return; | |
| 646 } | |
| 647 | |
| 648 TemporaryRegisterScope temporary_register_scope(builder()); | |
| 649 LoopBuilder loop_builder(builder()); | |
| 650 ControlScopeForIteration control_scope(this, stmt, &loop_builder); | |
| 651 | |
| 652 // Prepare the state for executing ForIn. | |
| 653 builder()->EnterBlock(); | |
| 654 VisitForAccumulatorValue(stmt->subject()); | |
| 655 builder()->ForInPrepare(); | |
| 656 Register for_in_state = temporary_register_scope.NewRegister(); | |
|
rmcilroy
2015/10/26 14:04:01
nit - move this up (and use execution_result()->Ne
oth
2015/10/28 11:53:11
Done.
| |
| 657 builder()->StoreAccumulatorInRegister(for_in_state); | |
|
rmcilroy
2015/10/26 14:04:01
nit - use builder chaining?
oth
2015/10/28 11:53:11
Done-ish. Changed to chain in blocks that are logi
| |
| 658 builder()->LoadUndefined(); | |
| 659 builder()->CompareOperation(Token::Value::EQ_STRICT, for_in_state, | |
| 660 Strength::WEAK); | |
|
rmcilroy
2015/10/26 14:04:01
/s/Strength::WEAK/language_mode_strength()
oth
2015/10/28 11:53:12
Done.
| |
| 661 loop_builder.BreakIfTrue(); | |
| 662 | |
| 663 // The loop | |
|
rmcilroy
2015/10/26 14:04:01
nit -full stop
oth
2015/10/28 11:53:11
Done.
| |
| 664 BytecodeLabel condition_label, break_label, continue_label; | |
| 665 | |
| 666 Register index = temporary_register_scope.NewRegister(); | |
| 667 builder()->LoadLiteral(Smi::FromInt(0)); | |
| 668 builder()->StoreAccumulatorInRegister(index); | |
| 669 | |
| 670 // Check loop termination (accumulator holds index). | |
| 671 builder()->Bind(&condition_label); | |
| 672 builder()->ForInDone(for_in_state); | |
| 673 loop_builder.BreakIfTrue(); | |
| 674 | |
| 675 // Get next item | |
|
rmcilroy
2015/10/26 14:04:01
nit - full stop
oth
2015/10/28 11:53:11
Done.
| |
| 676 builder()->LoadAccumulatorWithRegister(index); | |
| 677 builder()->ForInNext(for_in_state); | |
| 678 | |
| 679 // Start again if item is undefined. | |
| 680 Register value = temporary_register_scope.NewRegister(); | |
| 681 builder()->StoreAccumulatorInRegister(value); | |
| 682 builder()->LoadUndefined(); | |
|
rmcilroy
2015/10/26 14:04:01
Would it be worth maintaining a temprorary registe
oth
2015/10/28 11:53:11
This is superb! Done.
| |
| 683 builder()->CompareOperation(Token::Value::EQ_STRICT, value, Strength::WEAK); | |
| 684 loop_builder.ContinueIfTrue(); | |
| 685 builder()->LoadAccumulatorWithRegister(value); | |
| 686 | |
| 687 // Store the value in the each variable. | |
| 688 VisitForInAssignment(stmt->each(), stmt->EachFeedbackSlot()); | |
| 689 // NB the user's loop variable will be assigned the value of each so | |
| 690 // even an empty body will have this assignment. | |
| 691 Visit(stmt->body()); | |
| 692 | |
| 693 // Increment index and start loop again. | |
| 694 builder()->Bind(&continue_label); | |
| 695 builder()->LoadLiteral(Smi::FromInt(1)); | |
| 696 builder()->BinaryOperation(Token::Value::ADD, index, Strength::WEAK); | |
|
rmcilroy
2015/10/26 14:04:01
You could use builder()->CountOperation(Token::Val
oth
2015/10/28 11:53:12
Done.
| |
| 697 builder()->StoreAccumulatorInRegister(index); | |
| 698 builder()->Jump(&condition_label); | |
| 699 | |
| 700 // End of loop | |
| 701 builder()->Bind(&break_label); | |
| 702 builder()->LeaveBlock(); | |
| 703 | |
| 704 loop_builder.SetBreakTarget(break_label); | |
| 705 loop_builder.SetContinueTarget(continue_label); | |
| 598 } | 706 } |
| 599 | 707 |
| 600 | 708 |
| 601 void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { | 709 void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { |
| 602 UNIMPLEMENTED(); | 710 UNIMPLEMENTED(); |
| 603 } | 711 } |
| 604 | 712 |
| 605 | 713 |
| 606 void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { | 714 void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { |
| 607 if (FLAG_ignition_fake_try_catch) { | 715 if (FLAG_ignition_fake_try_catch) { |
| (...skipping 1208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1816 } | 1924 } |
| 1817 | 1925 |
| 1818 | 1926 |
| 1819 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 1927 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
| 1820 return info()->feedback_vector()->GetIndex(slot); | 1928 return info()->feedback_vector()->GetIndex(slot); |
| 1821 } | 1929 } |
| 1822 | 1930 |
| 1823 } // namespace interpreter | 1931 } // namespace interpreter |
| 1824 } // namespace internal | 1932 } // namespace internal |
| 1825 } // namespace v8 | 1933 } // namespace v8 |
| OLD | NEW |