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/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" |
| 11 #include "test/cctest/cctest.h" | 11 #include "test/cctest/cctest.h" |
| 12 #include "test/cctest/test-feedback-vector.h" | 12 #include "test/cctest/test-feedback-vector.h" |
| 13 | 13 |
| 14 namespace v8 { | 14 namespace v8 { |
| 15 namespace internal { | 15 namespace internal { |
| 16 namespace interpreter { | 16 namespace interpreter { |
| 17 | 17 |
| 18 static const InstanceType kInstanceTypeDontCare = (InstanceType)-1; | |
|
Michael Starzinger
2016/02/04 13:40:20
nit: Can we use static_cast instead of C-style cas
oth
2016/02/04 14:00:59
Done.
| |
| 19 | |
| 18 class BytecodeGeneratorHelper { | 20 class BytecodeGeneratorHelper { |
| 19 public: | 21 public: |
| 20 const char* kFunctionName = "f"; | 22 const char* kFunctionName = "f"; |
| 21 | 23 |
| 22 static const int kLastParamIndex = | 24 static const int kLastParamIndex = |
| 23 -InterpreterFrameConstants::kLastParamFromRegisterPointer / kPointerSize; | 25 -InterpreterFrameConstants::kLastParamFromRegisterPointer / kPointerSize; |
| 24 | 26 |
| 25 BytecodeGeneratorHelper() { | 27 BytecodeGeneratorHelper() { |
| 26 i::FLAG_ignition = true; | 28 i::FLAG_ignition = true; |
| 27 i::FLAG_ignition_filter = StrDup(kFunctionName); | 29 i::FLAG_ignition_filter = StrDup(kFunctionName); |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 184 CHECK(String::cast(actual)->Equals(*expected_string)); | 186 CHECK(String::cast(actual)->Equals(*expected_string)); |
| 185 } | 187 } |
| 186 | 188 |
| 187 | 189 |
| 188 static void CheckConstant(Handle<Object> expected, Object* actual) { | 190 static void CheckConstant(Handle<Object> expected, Object* actual) { |
| 189 CHECK(actual == *expected || expected->StrictEquals(actual)); | 191 CHECK(actual == *expected || expected->StrictEquals(actual)); |
| 190 } | 192 } |
| 191 | 193 |
| 192 | 194 |
| 193 static void CheckConstant(InstanceType expected, Object* actual) { | 195 static void CheckConstant(InstanceType expected, Object* actual) { |
| 194 CHECK_EQ(expected, HeapObject::cast(actual)->map()->instance_type()); | 196 if (expected != kInstanceTypeDontCare) { |
| 197 CHECK_EQ(expected, HeapObject::cast(actual)->map()->instance_type()); | |
| 198 } | |
| 195 } | 199 } |
| 196 | 200 |
| 197 | 201 |
| 198 template <typename T, int C> | 202 template <typename T, int C> |
| 199 static void CheckBytecodeArrayEqual(const ExpectedSnippet<T, C>& expected, | 203 static void CheckBytecodeArrayEqual(const ExpectedSnippet<T, C>& expected, |
| 200 Handle<BytecodeArray> actual) { | 204 Handle<BytecodeArray> actual) { |
| 201 CHECK_EQ(expected.frame_size, actual->frame_size()); | 205 CHECK_EQ(expected.frame_size, actual->frame_size()); |
| 202 CHECK_EQ(expected.parameter_count, actual->parameter_count()); | 206 CHECK_EQ(expected.parameter_count, actual->parameter_count()); |
| 203 CHECK_EQ(expected.bytecode_length, actual->length()); | 207 CHECK_EQ(expected.bytecode_length, actual->length()); |
| 204 if (expected.constant_count == 0) { | 208 if (expected.constant_count == 0) { |
| (...skipping 7483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7688 }; | 7692 }; |
| 7689 | 7693 |
| 7690 for (size_t i = 0; i < arraysize(snippets); i++) { | 7694 for (size_t i = 0; i < arraysize(snippets); i++) { |
| 7691 Handle<BytecodeArray> bytecode_array = | 7695 Handle<BytecodeArray> bytecode_array = |
| 7692 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | 7696 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); |
| 7693 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | 7697 CheckBytecodeArrayEqual(snippets[i], bytecode_array); |
| 7694 } | 7698 } |
| 7695 FLAG_harmony_do_expressions = old_flag; | 7699 FLAG_harmony_do_expressions = old_flag; |
| 7696 } | 7700 } |
| 7697 | 7701 |
| 7702 | |
| 7698 TEST(WithStatement) { | 7703 TEST(WithStatement) { |
| 7699 InitializedHandleScope handle_scope; | 7704 InitializedHandleScope handle_scope; |
| 7700 BytecodeGeneratorHelper helper; | 7705 BytecodeGeneratorHelper helper; |
| 7701 | 7706 |
| 7702 int deep_elements_flags = | 7707 int deep_elements_flags = |
| 7703 ObjectLiteral::kFastElements | ObjectLiteral::kDisableMementos; | 7708 ObjectLiteral::kFastElements | ObjectLiteral::kDisableMementos; |
| 7704 int context = Register::current_context().index(); | 7709 int context = Register::current_context().index(); |
| 7705 int closure = Register::function_closure().index(); | 7710 int closure = Register::function_closure().index(); |
| 7706 int new_target = Register::new_target().index(); | 7711 int new_target = Register::new_target().index(); |
| 7707 | 7712 |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 7737 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | 7742 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, |
| 7738 }; | 7743 }; |
| 7739 | 7744 |
| 7740 for (size_t i = 0; i < arraysize(snippets); i++) { | 7745 for (size_t i = 0; i < arraysize(snippets); i++) { |
| 7741 Handle<BytecodeArray> bytecode_array = | 7746 Handle<BytecodeArray> bytecode_array = |
| 7742 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | 7747 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); |
| 7743 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | 7748 CheckBytecodeArrayEqual(snippets[i], bytecode_array); |
| 7744 } | 7749 } |
| 7745 } | 7750 } |
| 7746 | 7751 |
| 7752 | |
| 7753 TEST(ClassDeclarations) { | |
| 7754 InitializedHandleScope handle_scope; | |
| 7755 BytecodeGeneratorHelper helper; | |
| 7756 | |
| 7757 int closure = Register::function_closure().index(); | |
| 7758 int context = Register::current_context().index(); | |
| 7759 | |
| 7760 ExpectedSnippet<InstanceType, 12> snippets[] = { | |
| 7761 {"class Person {\n" | |
| 7762 " constructor(name) { this.name = name; }\n" | |
| 7763 " speak() { console.log(this.name + ' is speaking.'); }\n" | |
| 7764 "}\n", | |
| 7765 8 * kPointerSize, | |
| 7766 1, | |
| 7767 60, | |
| 7768 { | |
| 7769 B(LdaTheHole), // | |
| 7770 B(Star), R(1), // | |
| 7771 B(LdaTheHole), // | |
| 7772 B(Star), R(0), // | |
| 7773 B(LdaTheHole), // | |
| 7774 B(Star), R(2), // | |
| 7775 B(CreateClosure), U8(0), U8(0), // | |
| 7776 B(Star), R(3), // | |
| 7777 B(LdaSmi8), U8(15), // | |
| 7778 B(Star), R(4), // | |
| 7779 B(LdaConstant), U8(1), // | |
| 7780 B(Star), R(5), // | |
| 7781 B(CallRuntime), U16(Runtime::kDefineClass), R(2), U8(4), // | |
| 7782 B(Star), R(2), // | |
| 7783 B(LdaInitialMap), // | |
| 7784 B(Star), R(3), // | |
| 7785 B(Mov), R(3), R(4), // | |
| 7786 B(LdaConstant), U8(2), // | |
| 7787 B(Star), R(5), // | |
| 7788 B(CreateClosure), U8(3), U8(0), // | |
| 7789 B(Star), R(6), // | |
| 7790 B(CallRuntime), U16(Runtime::kDefineClassMethod), R(4), U8(3), // | |
| 7791 B(CallRuntime), U16(Runtime::kFinalizeClassDefinition), R(2), U8(2), // | |
| 7792 B(Star), R(0), // | |
| 7793 B(Star), R(1), // | |
| 7794 B(LdaUndefined), // | |
| 7795 B(Return) // | |
| 7796 }, | |
| 7797 4, | |
| 7798 { InstanceType::SHARED_FUNCTION_INFO_TYPE, kInstanceTypeDontCare, | |
| 7799 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
| 7800 InstanceType::SHARED_FUNCTION_INFO_TYPE}}, | |
| 7801 {"var n0 = 'a';" | |
| 7802 "var n1 = 'b';" | |
| 7803 "class N {\n" | |
| 7804 " [n0]() { return n0; }\n" | |
| 7805 " static [n1]() { return n1; }\n" | |
| 7806 "}\n", | |
| 7807 9 * kPointerSize, | |
| 7808 1, | |
| 7809 109, | |
| 7810 { | |
| 7811 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // | |
| 7812 /* */ U8(1), // | |
| 7813 B(PushContext), R(2), // | |
| 7814 B(LdaTheHole), // | |
| 7815 B(Star), R(1), // | |
| 7816 B(LdaConstant), U8(0), // | |
| 7817 B(StaContextSlot), R(context), U8(4), // | |
| 7818 B(LdaConstant), U8(1), // | |
| 7819 B(StaContextSlot), R(context), U8(5), // | |
| 7820 B(LdaTheHole), // | |
| 7821 B(Star), R(0), // | |
| 7822 B(LdaTheHole), // | |
| 7823 B(Star), R(3), // | |
| 7824 B(CreateClosure), U8(2), U8(0), // | |
| 7825 B(Star), R(4), // | |
| 7826 B(LdaSmi8), U8(41), // | |
| 7827 B(Star), R(5), // | |
| 7828 B(LdaSmi8), U8(107), // | |
| 7829 B(Star), R(6), // | |
| 7830 B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(4), // | |
| 7831 B(Star), R(3), // | |
| 7832 B(LdaInitialMap), // | |
| 7833 B(Star), R(4), // | |
| 7834 B(Mov), R(4), R(5), // | |
| 7835 B(LdaContextSlot), R(context), U8(4), // | |
| 7836 B(ToName), // | |
| 7837 B(Star), R(6), // | |
| 7838 B(CreateClosure), U8(3), U8(0), // | |
| 7839 B(Star), R(7), // | |
| 7840 B(CallRuntime), U16(Runtime::kDefineClassMethod), R(5), U8(3), // | |
| 7841 B(Mov), R(3), R(5), // | |
| 7842 B(LdaContextSlot), R(context), U8(5), // | |
| 7843 B(ToName), // | |
| 7844 B(Star), R(6), // | |
| 7845 B(LdaConstant), U8(4), // | |
| 7846 B(TestEqualStrict), R(6), // | |
| 7847 B(JumpIfFalse), U8(7), // | |
| 7848 B(CallRuntime), U16(Runtime::kThrowStaticPrototypeError), // | |
| 7849 /* */ R(0), U8(0), // | |
| 7850 B(CreateClosure), U8(5), U8(0), // | |
| 7851 B(Star), R(7), // | |
| 7852 B(CallRuntime), U16(Runtime::kDefineClassMethod), R(5), U8(3), // | |
| 7853 B(CallRuntime), U16(Runtime::kFinalizeClassDefinition), R(3), U8(2), // | |
| 7854 B(Star), R(0), // | |
| 7855 B(Star), R(1), // | |
| 7856 B(LdaUndefined), // | |
| 7857 B(Return), // | |
| 7858 }, | |
| 7859 6, | |
| 7860 { InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
| 7861 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
| 7862 InstanceType::SHARED_FUNCTION_INFO_TYPE, | |
| 7863 InstanceType::SHARED_FUNCTION_INFO_TYPE, | |
| 7864 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
| 7865 InstanceType::SHARED_FUNCTION_INFO_TYPE}}, | |
| 7866 {"class Person {\n" | |
| 7867 "}\n" | |
| 7868 "class Cyborg extends Person {\n" | |
| 7869 " constructor() { this.battery_ = 0; }" | |
| 7870 " get battery() { return battery_; }" | |
| 7871 " set battery(new_level) { battery_ = new_level; }" | |
| 7872 " charge() { battery(100); }" | |
| 7873 " static diet() { return 'metal bolts'; }\n" | |
| 7874 "}\n" | |
| 7875 "return new Cyborg();\n", | |
| 7876 10 * kPointerSize, | |
| 7877 1, | |
| 7878 156, | |
| 7879 { | |
| 7880 B(LdaTheHole), // | |
| 7881 B(Star), R(2), // | |
| 7882 B(LdaTheHole), // | |
| 7883 B(Star), R(3), // | |
| 7884 B(LdaTheHole), // | |
| 7885 B(Star), R(0), // | |
| 7886 B(LdaTheHole), // | |
| 7887 B(Star), R(4), // | |
| 7888 B(CreateClosure), U8(0), U8(0), // | |
| 7889 B(Star), R(5), // | |
| 7890 B(LdaSmi8), U8(15), // | |
| 7891 B(Star), R(6), // | |
| 7892 B(LdaSmi8), U8(31), // | |
| 7893 B(Star), R(7), // | |
| 7894 B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(4), // | |
| 7895 B(Star), R(4), // | |
| 7896 B(LdaInitialMap), // | |
| 7897 B(Star), R(5), // | |
| 7898 B(CallRuntime), U16(Runtime::kFinalizeClassDefinition), R(4), U8(2), // | |
| 7899 B(Star), R(0), // | |
| 7900 B(Star), R(2), // | |
| 7901 B(LdaTheHole), // | |
| 7902 B(Star), R(1), // | |
| 7903 B(Ldar), R(2), // | |
| 7904 B(Star), R(4), // | |
| 7905 B(CreateClosure), U8(1), U8(0), // | |
| 7906 B(Star), R(5), // | |
| 7907 B(LdaSmi8), U8(32), // | |
| 7908 B(Star), R(6), // | |
| 7909 B(LdaConstant), U8(2), // | |
| 7910 B(Star), R(7), // | |
| 7911 B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(4), // | |
| 7912 B(Star), R(4), // | |
| 7913 B(LdaInitialMap), // | |
| 7914 B(Star), R(5), // | |
| 7915 B(Mov), R(5), R(6), // | |
| 7916 B(LdaConstant), U8(3), // | |
| 7917 B(Star), R(7), // | |
| 7918 B(CreateClosure), U8(4), U8(0), // | |
| 7919 B(Star), R(8), // | |
| 7920 B(LdaSmi8), U8(2), // | |
| 7921 B(Star), R(9), // | |
| 7922 B(CallRuntime), U16(Runtime::kDefineGetterPropertyUnchecked), // | |
| 7923 /* */ R(6), U8(4), // | |
| 7924 B(LdaConstant), U8(3), // | |
| 7925 B(Star), R(7), // | |
| 7926 B(CreateClosure), U8(5), U8(0), // | |
| 7927 B(Star), R(8), // | |
| 7928 B(CallRuntime), U16(Runtime::kDefineSetterPropertyUnchecked), // | |
| 7929 /* */ R(6), U8(4), // | |
| 7930 B(LdaConstant), U8(6), // | |
| 7931 B(Star), R(7), // | |
| 7932 B(CreateClosure), U8(7), U8(0), // | |
| 7933 B(Star), R(8), // | |
| 7934 B(CallRuntime), U16(Runtime::kDefineClassMethod), R(6), U8(3), // | |
| 7935 B(Mov), R(4), R(6), // | |
| 7936 B(LdaConstant), U8(8), // | |
| 7937 B(Star), R(7), // | |
| 7938 B(CreateClosure), U8(9), U8(0), // | |
| 7939 B(Star), R(8), // | |
| 7940 B(CallRuntime), U16(Runtime::kDefineClassMethod), R(6), U8(3), // | |
| 7941 B(CallRuntime), U16(Runtime::kFinalizeClassDefinition), R(4), U8(2), // | |
| 7942 B(Star), R(1), // | |
| 7943 B(Star), R(3), // | |
| 7944 B(Star), R(4), // | |
| 7945 B(New), R(4), R(0), U8(0), // | |
| 7946 B(Return), // | |
| 7947 }, | |
| 7948 10, | |
| 7949 { InstanceType::SHARED_FUNCTION_INFO_TYPE, | |
| 7950 InstanceType::SHARED_FUNCTION_INFO_TYPE, | |
| 7951 kInstanceTypeDontCare, | |
| 7952 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
| 7953 InstanceType::SHARED_FUNCTION_INFO_TYPE, | |
| 7954 InstanceType::SHARED_FUNCTION_INFO_TYPE, | |
| 7955 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
| 7956 InstanceType::SHARED_FUNCTION_INFO_TYPE, | |
| 7957 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
| 7958 InstanceType::SHARED_FUNCTION_INFO_TYPE, | |
| 7959 } | |
| 7960 }, | |
| 7961 {"var count = 0;\n" | |
| 7962 "class C { constructor() { count++; }}\n" | |
| 7963 "return new C();\n", | |
| 7964 9 * kPointerSize, | |
| 7965 1, | |
| 7966 59, | |
| 7967 { | |
| 7968 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1), // | |
| 7969 B(PushContext), R(2), // | |
| 7970 B(LdaTheHole), // | |
| 7971 B(Star), R(1), // | |
| 7972 B(LdaZero), // | |
| 7973 B(StaContextSlot), R(context), U8(4), // | |
| 7974 B(LdaTheHole), // | |
| 7975 B(Star), R(0), // | |
| 7976 B(LdaTheHole), // | |
| 7977 B(Star), R(3), // | |
| 7978 B(CreateClosure), U8(0), U8(0), // | |
| 7979 B(Star), R(4), // | |
| 7980 B(LdaSmi8), U8(30), // | |
| 7981 B(Star), R(5), // | |
| 7982 B(LdaSmi8), U8(67), // | |
| 7983 B(Star), R(6), // | |
| 7984 B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(4), // | |
| 7985 B(Star), R(3), // | |
| 7986 B(LdaInitialMap), // | |
| 7987 B(Star), R(4), // | |
| 7988 B(CallRuntime), U16(Runtime::kFinalizeClassDefinition), R(3), U8(2), // | |
| 7989 B(Star), R(0), // | |
| 7990 B(Star), R(1), // | |
| 7991 B(Star), R(3), // | |
| 7992 B(New), R(3), R(0), U8(0), // | |
| 7993 B(Return), // | |
| 7994 }, | |
| 7995 1, | |
| 7996 { InstanceType::SHARED_FUNCTION_INFO_TYPE}}, | |
| 7997 }; | |
| 7998 | |
| 7999 for (size_t i = 0; i < arraysize(snippets); i++) { | |
| 8000 Handle<BytecodeArray> bytecode_array = | |
| 8001 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
| 8002 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
| 8003 } | |
| 8004 } | |
| 8005 | |
| 7747 } // namespace interpreter | 8006 } // namespace interpreter |
| 7748 } // namespace internal | 8007 } // namespace internal |
| 7749 } // namespace v8 | 8008 } // namespace v8 |
| OLD | NEW |