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 |