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/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/compiler.h" | 7 #include "src/compiler.h" |
8 #include "src/interpreter/bytecode-array-iterator.h" | 8 #include "src/interpreter/bytecode-array-iterator.h" |
9 #include "src/interpreter/bytecode-generator.h" | 9 #include "src/interpreter/bytecode-generator.h" |
10 #include "src/interpreter/interpreter.h" | 10 #include "src/interpreter/interpreter.h" |
(...skipping 5582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5593 }; | 5593 }; |
5594 | 5594 |
5595 for (size_t i = 0; i < arraysize(snippets); i++) { | 5595 for (size_t i = 0; i < arraysize(snippets); i++) { |
5596 Handle<BytecodeArray> bytecode_array = | 5596 Handle<BytecodeArray> bytecode_array = |
5597 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | 5597 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); |
5598 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | 5598 CheckBytecodeArrayEqual(snippets[i], bytecode_array); |
5599 } | 5599 } |
5600 } | 5600 } |
5601 | 5601 |
5602 | 5602 |
| 5603 TEST(ForOf) { |
| 5604 InitializedHandleScope handle_scope; |
| 5605 BytecodeGeneratorHelper helper; |
| 5606 Zone zone; |
| 5607 |
| 5608 int array_literal_flags = |
| 5609 ArrayLiteral::kDisableMementos | ArrayLiteral::kShallowElements; |
| 5610 int object_literal_flags = |
| 5611 ObjectLiteral::kFastElements | ObjectLiteral::kDisableMementos; |
| 5612 |
| 5613 FeedbackVectorSpec feedback_spec(&zone); |
| 5614 FeedbackVectorSlot slot1 = feedback_spec.AddCallICSlot(); |
| 5615 FeedbackVectorSlot slot2 = feedback_spec.AddKeyedLoadICSlot(); |
| 5616 FeedbackVectorSlot slot3 = feedback_spec.AddCallICSlot(); |
| 5617 FeedbackVectorSlot slot4 = feedback_spec.AddLoadICSlot(); |
| 5618 FeedbackVectorSlot slot5 = feedback_spec.AddLoadICSlot(); |
| 5619 FeedbackVectorSlot slot6 = feedback_spec.AddLoadICSlot(); |
| 5620 FeedbackVectorSlot slot7 = feedback_spec.AddStoreICSlot(); |
| 5621 FeedbackVectorSlot slot8 = feedback_spec.AddLoadICSlot(); |
| 5622 Handle<i::TypeFeedbackVector> vector = |
| 5623 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); |
| 5624 |
| 5625 ExpectedSnippet<InstanceType, 8> snippets[] = { |
| 5626 {"for (var p of [0, 1, 2]) {}", |
| 5627 7 * kPointerSize, |
| 5628 1, |
| 5629 82, |
| 5630 { |
| 5631 B(CreateArrayLiteral), U8(0), U8(0), U8(array_literal_flags), // |
| 5632 B(Star), R(5), // |
| 5633 B(LdaConstant), U8(1), // |
| 5634 B(KeyedLoadICSloppy), R(5), U8(vector->GetIndex(slot2)), // |
| 5635 B(Star), R(4), // |
| 5636 B(Call), R(4), R(5), U8(0), U8(vector->GetIndex(slot1)), // |
| 5637 B(Star), R(1), // |
| 5638 B(Ldar), R(1), // |
| 5639 B(Star), R(6), // |
| 5640 B(LoadICSloppy), R(6), U8(2), U8(vector->GetIndex(slot4)), // |
| 5641 B(Star), R(5), // |
| 5642 B(Call), R(5), R(6), U8(0), U8(vector->GetIndex(slot3)), // |
| 5643 B(Star), R(2), // |
| 5644 B(Star), R(4), // |
| 5645 B(CallRuntime), U16(Runtime::kInlineIsJSReceiver), R(4), U8(1), // |
| 5646 B(LogicalNot), // |
| 5647 B(JumpIfFalse), U8(11), // |
| 5648 B(Ldar), R(2), // |
| 5649 B(Star), R(4), // |
| 5650 B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), // |
| 5651 R(4), U8(1), // |
| 5652 B(Ldar), R(2), // |
| 5653 B(Star), R(4), // |
| 5654 B(LoadICSloppy), R(4), U8(3), U8(vector->GetIndex(slot5)), // |
| 5655 B(JumpIfToBooleanTrue), U8(16), // |
| 5656 B(Ldar), R(2), // |
| 5657 B(Star), R(4), // |
| 5658 B(LoadICSloppy), R(4), U8(4), U8(vector->GetIndex(slot6)), // |
| 5659 B(Star), R(0), // |
| 5660 B(Star), R(3), // |
| 5661 B(Jump), U8(-58), // |
| 5662 B(LdaUndefined), // |
| 5663 B(Return), // |
| 5664 }, |
| 5665 5, |
| 5666 {InstanceType::FIXED_ARRAY_TYPE, InstanceType::SYMBOL_TYPE, |
| 5667 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, |
| 5668 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, |
| 5669 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, |
| 5670 {"var x = 'potatoes';\n" |
| 5671 "for (var p of x) { return p; }", |
| 5672 8 * kPointerSize, |
| 5673 1, |
| 5674 81, |
| 5675 { |
| 5676 B(LdaConstant), U8(0), // |
| 5677 B(Star), R(3), // |
| 5678 B(Star), R(6), // |
| 5679 B(LdaConstant), U8(1), // |
| 5680 B(KeyedLoadICSloppy), R(6), U8(vector->GetIndex(slot2)), // |
| 5681 B(Star), R(5), // |
| 5682 B(Call), R(5), R(6), U8(0), U8(vector->GetIndex(slot1)), // |
| 5683 B(Star), R(1), // |
| 5684 B(Ldar), R(1), // |
| 5685 B(Star), R(7), // |
| 5686 B(LoadICSloppy), R(7), U8(2), U8(vector->GetIndex(slot4)), // |
| 5687 B(Star), R(6), // |
| 5688 B(Call), R(6), R(7), U8(0), U8(vector->GetIndex(slot3)), // |
| 5689 B(Star), R(2), // |
| 5690 B(Star), R(5), // |
| 5691 B(CallRuntime), U16(Runtime::kInlineIsJSReceiver), R(5), U8(1), // |
| 5692 B(LogicalNot), // |
| 5693 B(JumpIfFalse), U8(11), // |
| 5694 B(Ldar), R(2), // |
| 5695 B(Star), R(5), // |
| 5696 B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), // |
| 5697 R(5), U8(1), // |
| 5698 B(Ldar), R(2), // |
| 5699 B(Star), R(5), // |
| 5700 B(LoadICSloppy), R(5), U8(3), U8(vector->GetIndex(slot5)), // |
| 5701 B(JumpIfToBooleanTrue), U8(15), // |
| 5702 B(Ldar), R(2), // |
| 5703 B(Star), R(5), // |
| 5704 B(LoadICSloppy), R(5), U8(4), U8(vector->GetIndex(slot6)), // |
| 5705 B(Star), R(0), // |
| 5706 B(Star), R(4), // |
| 5707 B(Return), // |
| 5708 B(LdaUndefined), // |
| 5709 B(Return), // |
| 5710 }, |
| 5711 5, |
| 5712 {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, |
| 5713 InstanceType::SYMBOL_TYPE, |
| 5714 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, |
| 5715 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, |
| 5716 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, |
| 5717 {"for (var x of [10, 20, 30]) {\n" |
| 5718 " if (x == 10) continue;\n" |
| 5719 " if (x == 20) break;\n" |
| 5720 "}", |
| 5721 7 * kPointerSize, |
| 5722 1, |
| 5723 104, |
| 5724 { |
| 5725 B(CreateArrayLiteral), U8(0), U8(0), U8(array_literal_flags), // |
| 5726 B(Star), R(5), // |
| 5727 B(LdaConstant), U8(1), // |
| 5728 B(KeyedLoadICSloppy), R(5), U8(vector->GetIndex(slot2)), // |
| 5729 B(Star), R(4), // |
| 5730 B(Call), R(4), R(5), U8(0), U8(vector->GetIndex(slot1)), // |
| 5731 B(Star), R(1), // |
| 5732 B(Ldar), R(1), // |
| 5733 B(Star), R(6), // |
| 5734 B(LoadICSloppy), R(6), U8(2), U8(vector->GetIndex(slot4)), // |
| 5735 B(Star), R(5), // |
| 5736 B(Call), R(5), R(6), U8(0), U8(vector->GetIndex(slot3)), // |
| 5737 B(Star), R(2), // |
| 5738 B(Star), R(4), // |
| 5739 B(CallRuntime), U16(Runtime::kInlineIsJSReceiver), R(4), U8(1), // |
| 5740 B(LogicalNot), // |
| 5741 B(JumpIfFalse), U8(11), // |
| 5742 B(Ldar), R(2), // |
| 5743 B(Star), R(4), // |
| 5744 B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), // |
| 5745 R(4), U8(1), // |
| 5746 B(Ldar), R(2), // |
| 5747 B(Star), R(4), // |
| 5748 B(LoadICSloppy), R(4), U8(3), U8(vector->GetIndex(slot5)), // |
| 5749 B(JumpIfToBooleanTrue), U8(38), // |
| 5750 B(Ldar), R(2), // |
| 5751 B(Star), R(4), // |
| 5752 B(LoadICSloppy), R(4), U8(4), U8(vector->GetIndex(slot6)), // |
| 5753 B(Star), R(0), // |
| 5754 B(Star), R(3), // |
| 5755 B(Star), R(4), // |
| 5756 B(LdaSmi8), U8(10), // |
| 5757 B(TestEqual), R(4), // |
| 5758 B(JumpIfFalse), U8(4), // |
| 5759 B(Jump), U8(-66), // |
| 5760 B(Ldar), R(3), // |
| 5761 B(Star), R(4), // |
| 5762 B(LdaSmi8), U8(20), // |
| 5763 B(TestEqual), R(4), // |
| 5764 B(JumpIfFalse), U8(4), // |
| 5765 B(Jump), U8(4), // |
| 5766 B(Jump), U8(-80), // |
| 5767 B(LdaUndefined), // |
| 5768 B(Return), // |
| 5769 }, |
| 5770 5, |
| 5771 {InstanceType::FIXED_ARRAY_TYPE, InstanceType::SYMBOL_TYPE, |
| 5772 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, |
| 5773 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, |
| 5774 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, |
| 5775 {"var x = { 'a': 1, 'b': 2 };\n" |
| 5776 "for (x['a'] of [1,2,3]) { return x['a']; }", |
| 5777 6 * kPointerSize, |
| 5778 1, |
| 5779 101, |
| 5780 { |
| 5781 B(CreateObjectLiteral), U8(0), U8(0), U8(object_literal_flags), // |
| 5782 B(Star), R(3), // |
| 5783 B(Star), R(2), // |
| 5784 B(CreateArrayLiteral), U8(1), U8(1), U8(array_literal_flags), // |
| 5785 B(Star), R(4), // |
| 5786 B(LdaConstant), U8(2), // |
| 5787 B(KeyedLoadICSloppy), R(4), U8(vector->GetIndex(slot2)), // |
| 5788 B(Star), R(3), // |
| 5789 B(Call), R(3), R(4), U8(0), U8(vector->GetIndex(slot1)), // |
| 5790 B(Star), R(0), // |
| 5791 B(Ldar), R(0), // |
| 5792 B(Star), R(5), // |
| 5793 B(LoadICSloppy), R(5), U8(3), U8(vector->GetIndex(slot4)), // |
| 5794 B(Star), R(4), // |
| 5795 B(Call), R(4), R(5), U8(0), U8(vector->GetIndex(slot3)), // |
| 5796 B(Star), R(1), // |
| 5797 B(Star), R(3), // |
| 5798 B(CallRuntime), U16(Runtime::kInlineIsJSReceiver), R(3), U8(1), // |
| 5799 B(LogicalNot), // |
| 5800 B(JumpIfFalse), U8(11), // |
| 5801 B(Ldar), R(1), // |
| 5802 B(Star), R(3), // |
| 5803 B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), // |
| 5804 R(3), U8(1), // |
| 5805 B(Ldar), R(1), // |
| 5806 B(Star), R(3), // |
| 5807 B(LoadICSloppy), R(3), U8(4), U8(vector->GetIndex(slot5)), // |
| 5808 B(JumpIfToBooleanTrue), U8(27), // |
| 5809 B(Ldar), R(2), // |
| 5810 B(Star), R(3), // |
| 5811 B(Ldar), R(1), // |
| 5812 B(Star), R(4), // |
| 5813 B(LoadICSloppy), R(4), U8(5), U8(vector->GetIndex(slot6)), // |
| 5814 B(StoreICSloppy), R(3), U8(6), U8(vector->GetIndex(slot7)), // |
| 5815 B(Ldar), R(2), // |
| 5816 B(Star), R(3), // |
| 5817 B(LoadICSloppy), R(3), U8(6), U8(vector->GetIndex(slot8)), // |
| 5818 B(Return), // |
| 5819 B(LdaUndefined), // |
| 5820 B(Return), // |
| 5821 }, |
| 5822 7, |
| 5823 {InstanceType::FIXED_ARRAY_TYPE, |
| 5824 InstanceType::FIXED_ARRAY_TYPE, |
| 5825 InstanceType::SYMBOL_TYPE, |
| 5826 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, |
| 5827 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, |
| 5828 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, |
| 5829 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, |
| 5830 }; |
| 5831 |
| 5832 for (size_t i = 0; i < arraysize(snippets); i++) { |
| 5833 Handle<BytecodeArray> bytecode_array = |
| 5834 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); |
| 5835 CheckBytecodeArrayEqual(snippets[i], bytecode_array); |
| 5836 } |
| 5837 } |
| 5838 |
| 5839 |
5603 TEST(Conditional) { | 5840 TEST(Conditional) { |
5604 InitializedHandleScope handle_scope; | 5841 InitializedHandleScope handle_scope; |
5605 BytecodeGeneratorHelper helper; | 5842 BytecodeGeneratorHelper helper; |
5606 | 5843 |
5607 ExpectedSnippet<int> snippets[] = { | 5844 ExpectedSnippet<int> snippets[] = { |
5608 {"return 1 ? 2 : 3;", | 5845 {"return 1 ? 2 : 3;", |
5609 0, | 5846 0, |
5610 1, | 5847 1, |
5611 11, | 5848 11, |
5612 { | 5849 { |
(...skipping 1283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6896 std::string(function_epilogue); | 7133 std::string(function_epilogue); |
6897 Handle<BytecodeArray> bytecode_array = | 7134 Handle<BytecodeArray> bytecode_array = |
6898 helper.MakeBytecode(script.c_str(), "*", "f"); | 7135 helper.MakeBytecode(script.c_str(), "*", "f"); |
6899 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | 7136 CheckBytecodeArrayEqual(snippets[i], bytecode_array); |
6900 } | 7137 } |
6901 } | 7138 } |
6902 | 7139 |
6903 } // namespace interpreter | 7140 } // namespace interpreter |
6904 } // namespace internal | 7141 } // namespace internal |
6905 } // namespace v8 | 7142 } // namespace v8 |
OLD | NEW |