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 17 matching lines...) Expand all Loading... |
28 i::FLAG_ignition_fake_try_catch = true; | 28 i::FLAG_ignition_fake_try_catch = true; |
29 i::FLAG_ignition_filter = StrDup(kFunctionName); | 29 i::FLAG_ignition_filter = StrDup(kFunctionName); |
30 i::FLAG_always_opt = false; | 30 i::FLAG_always_opt = false; |
31 i::FLAG_allow_natives_syntax = true; | 31 i::FLAG_allow_natives_syntax = true; |
32 CcTest::i_isolate()->interpreter()->Initialize(); | 32 CcTest::i_isolate()->interpreter()->Initialize(); |
33 } | 33 } |
34 | 34 |
35 Isolate* isolate() { return CcTest::i_isolate(); } | 35 Isolate* isolate() { return CcTest::i_isolate(); } |
36 Factory* factory() { return CcTest::i_isolate()->factory(); } | 36 Factory* factory() { return CcTest::i_isolate()->factory(); } |
37 | 37 |
38 | |
39 Handle<BytecodeArray> MakeTopLevelBytecode(const char* source) { | 38 Handle<BytecodeArray> MakeTopLevelBytecode(const char* source) { |
40 const char* old_ignition_filter = i::FLAG_ignition_filter; | 39 const char* old_ignition_filter = i::FLAG_ignition_filter; |
41 i::FLAG_ignition_filter = "*"; | 40 i::FLAG_ignition_filter = "*"; |
42 Local<v8::Script> script = v8_compile(source); | 41 Local<v8::Script> script = v8_compile(source); |
43 i::FLAG_ignition_filter = old_ignition_filter; | 42 i::FLAG_ignition_filter = old_ignition_filter; |
44 i::Handle<i::JSFunction> js_function = v8::Utils::OpenHandle(*script); | 43 i::Handle<i::JSFunction> js_function = v8::Utils::OpenHandle(*script); |
45 return handle(js_function->shared()->bytecode_array(), CcTest::i_isolate()); | 44 return handle(js_function->shared()->bytecode_array(), CcTest::i_isolate()); |
46 } | 45 } |
47 | 46 |
48 | |
49 Handle<BytecodeArray> MakeBytecode(const char* script, | 47 Handle<BytecodeArray> MakeBytecode(const char* script, |
50 const char* function_name) { | 48 const char* function_name) { |
51 CompileRun(script); | 49 CompileRun(script); |
52 Local<Function> function = | 50 Local<Function> function = |
53 Local<Function>::Cast(CcTest::global()->Get(v8_str(function_name))); | 51 Local<Function>::Cast(CcTest::global()->Get(v8_str(function_name))); |
54 i::Handle<i::JSFunction> js_function = v8::Utils::OpenHandle(*function); | 52 i::Handle<i::JSFunction> js_function = v8::Utils::OpenHandle(*function); |
55 return handle(js_function->shared()->bytecode_array(), CcTest::i_isolate()); | 53 return handle(js_function->shared()->bytecode_array(), CcTest::i_isolate()); |
56 } | 54 } |
57 | 55 |
58 | |
59 Handle<BytecodeArray> MakeBytecodeForFunctionBody(const char* body) { | 56 Handle<BytecodeArray> MakeBytecodeForFunctionBody(const char* body) { |
60 ScopedVector<char> program(1024); | 57 ScopedVector<char> program(1024); |
61 SNPrintF(program, "function %s() { %s }\n%s();", kFunctionName, body, | 58 SNPrintF(program, "function %s() { %s }\n%s();", kFunctionName, body, |
62 kFunctionName); | 59 kFunctionName); |
63 return MakeBytecode(program.start(), kFunctionName); | 60 return MakeBytecode(program.start(), kFunctionName); |
64 } | 61 } |
65 | 62 |
66 Handle<BytecodeArray> MakeBytecodeForFunction(const char* function) { | 63 Handle<BytecodeArray> MakeBytecodeForFunction(const char* function) { |
67 ScopedVector<char> program(1024); | 64 ScopedVector<char> program(1024); |
68 SNPrintF(program, "%s\n%s();", function, kFunctionName); | 65 SNPrintF(program, "%s\n%s();", function, kFunctionName); |
69 return MakeBytecode(program.start(), kFunctionName); | 66 return MakeBytecode(program.start(), kFunctionName); |
70 } | 67 } |
| 68 |
| 69 Handle<BytecodeArray> MakeBytecodeForFunctionNoFilter(const char* function) { |
| 70 const char* old_ignition_filter = i::FLAG_ignition_filter; |
| 71 i::FLAG_ignition_filter = "*"; |
| 72 ScopedVector<char> program(1024); |
| 73 SNPrintF(program, "%s\n%s();", function, kFunctionName); |
| 74 Handle<BytecodeArray> return_val = |
| 75 MakeBytecode(program.start(), kFunctionName); |
| 76 i::FLAG_ignition_filter = old_ignition_filter; |
| 77 return return_val; |
| 78 } |
71 }; | 79 }; |
72 | 80 |
73 | 81 |
74 // Helper macros for handcrafting bytecode sequences. | 82 // Helper macros for handcrafting bytecode sequences. |
75 #define B(x) static_cast<uint8_t>(Bytecode::k##x) | 83 #define B(x) static_cast<uint8_t>(Bytecode::k##x) |
76 #define U8(x) static_cast<uint8_t>((x) & 0xff) | 84 #define U8(x) static_cast<uint8_t>((x) & 0xff) |
77 #define R(x) static_cast<uint8_t>(-(x) & 0xff) | 85 #define R(x) static_cast<uint8_t>(-(x) & 0xff) |
78 #define A(x, n) R(helper.kLastParamIndex - (n) + 1 + (x)) | 86 #define A(x, n) R(helper.kLastParamIndex - (n) + 1 + (x)) |
79 #define THIS(n) A(0, n) | 87 #define THIS(n) A(0, n) |
80 #if defined(V8_TARGET_LITTLE_ENDIAN) | 88 #if defined(V8_TARGET_LITTLE_ENDIAN) |
(...skipping 2820 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2901 }; | 2909 }; |
2902 | 2910 |
2903 for (size_t i = 0; i < arraysize(snippets); i++) { | 2911 for (size_t i = 0; i < arraysize(snippets); i++) { |
2904 Handle<BytecodeArray> bytecode_array = | 2912 Handle<BytecodeArray> bytecode_array = |
2905 helper.MakeBytecodeForFunction(snippets[i].code_snippet); | 2913 helper.MakeBytecodeForFunction(snippets[i].code_snippet); |
2906 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | 2914 CheckBytecodeArrayEqual(snippets[i], bytecode_array); |
2907 } | 2915 } |
2908 } | 2916 } |
2909 | 2917 |
2910 | 2918 |
| 2919 TEST(OuterContextVariables) { |
| 2920 InitializedHandleScope handle_scope; |
| 2921 BytecodeGeneratorHelper helper; |
| 2922 |
| 2923 int context = Register::function_context().index(); |
| 2924 int first_context_slot = Context::MIN_CONTEXT_SLOTS; |
| 2925 |
| 2926 ExpectedSnippet<InstanceType> snippets[] = { |
| 2927 {"function Outer() {" |
| 2928 " var outerVar = 1;" |
| 2929 " function Inner(innerArg) {" |
| 2930 " this.innerFunc = function() { return outerVar * innerArg; }" |
| 2931 " }" |
| 2932 " this.getInnerFunc = function() { return new Inner(1).innerFunc; }" |
| 2933 "}" |
| 2934 "var f = new Outer().getInnerFunc();", |
| 2935 2 * kPointerSize, |
| 2936 1, |
| 2937 20, |
| 2938 { |
| 2939 B(Ldar), R(context), // |
| 2940 B(Star), R(0), // |
| 2941 B(LdaContextSlot), R(0), U8(Context::PREVIOUS_INDEX), // |
| 2942 B(Star), R(0), // |
| 2943 B(LdaContextSlot), R(0), U8(first_context_slot), // |
| 2944 B(Star), R(1), // |
| 2945 B(LdaContextSlot), R(context), U8(first_context_slot), // |
| 2946 B(Mul), R(1), // |
| 2947 B(Return), // |
| 2948 }}, |
| 2949 {"function Outer() {" |
| 2950 " var outerVar = 1;" |
| 2951 " function Inner(innerArg) {" |
| 2952 " this.innerFunc = function() { outerVar = innerArg; }" |
| 2953 " }" |
| 2954 " this.getInnerFunc = function() { return new Inner(1).innerFunc; }" |
| 2955 "}" |
| 2956 "var f = new Outer().getInnerFunc();", |
| 2957 2 * kPointerSize, |
| 2958 1, |
| 2959 21, |
| 2960 { |
| 2961 B(LdaContextSlot), R(context), U8(first_context_slot), // |
| 2962 B(Star), R(0), // |
| 2963 B(Ldar), R(context), // |
| 2964 B(Star), R(1), // |
| 2965 B(LdaContextSlot), R(1), U8(Context::PREVIOUS_INDEX), // |
| 2966 B(Star), R(1), // |
| 2967 B(Ldar), R(0), // |
| 2968 B(StaContextSlot), R(1), U8(first_context_slot), // |
| 2969 B(LdaUndefined), // |
| 2970 B(Return), // |
| 2971 }}, |
| 2972 }; |
| 2973 |
| 2974 for (size_t i = 0; i < arraysize(snippets); i++) { |
| 2975 Handle<BytecodeArray> bytecode_array = |
| 2976 helper.MakeBytecodeForFunctionNoFilter(snippets[i].code_snippet); |
| 2977 CheckBytecodeArrayEqual(snippets[i], bytecode_array); |
| 2978 } |
| 2979 } |
| 2980 |
| 2981 |
2911 TEST(CountOperators) { | 2982 TEST(CountOperators) { |
2912 InitializedHandleScope handle_scope; | 2983 InitializedHandleScope handle_scope; |
2913 BytecodeGeneratorHelper helper; | 2984 BytecodeGeneratorHelper helper; |
2914 Zone zone; | 2985 Zone zone; |
2915 | 2986 |
2916 FeedbackVectorSpec feedback_spec(&zone); | 2987 FeedbackVectorSpec feedback_spec(&zone); |
2917 FeedbackVectorSlot slot1 = feedback_spec.AddLoadICSlot(); | 2988 FeedbackVectorSlot slot1 = feedback_spec.AddLoadICSlot(); |
2918 FeedbackVectorSlot slot2 = feedback_spec.AddStoreICSlot(); | 2989 FeedbackVectorSlot slot2 = feedback_spec.AddStoreICSlot(); |
2919 | 2990 |
2920 Handle<i::TypeFeedbackVector> vector = | 2991 Handle<i::TypeFeedbackVector> vector = |
(...skipping 613 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3534 for (size_t i = 0; i < arraysize(snippets); i++) { | 3605 for (size_t i = 0; i < arraysize(snippets); i++) { |
3535 Handle<BytecodeArray> bytecode_array = | 3606 Handle<BytecodeArray> bytecode_array = |
3536 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | 3607 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); |
3537 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | 3608 CheckBytecodeArrayEqual(snippets[i], bytecode_array); |
3538 } | 3609 } |
3539 } | 3610 } |
3540 | 3611 |
3541 } // namespace interpreter | 3612 } // namespace interpreter |
3542 } // namespace internal | 3613 } // namespace internal |
3543 } // namespace v8 | 3614 } // namespace v8 |
OLD | NEW |