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 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 Handle<BytecodeArray> MakeBytecode(const char* script, const char* filter, | 58 Handle<BytecodeArray> MakeBytecode(const char* script, const char* filter, |
59 const char* function_name) { | 59 const char* function_name) { |
60 const char* old_ignition_filter = i::FLAG_ignition_filter; | 60 const char* old_ignition_filter = i::FLAG_ignition_filter; |
61 i::FLAG_ignition_filter = filter; | 61 i::FLAG_ignition_filter = filter; |
62 Handle<BytecodeArray> return_val = MakeBytecode(script, function_name); | 62 Handle<BytecodeArray> return_val = MakeBytecode(script, function_name); |
63 i::FLAG_ignition_filter = old_ignition_filter; | 63 i::FLAG_ignition_filter = old_ignition_filter; |
64 return return_val; | 64 return return_val; |
65 } | 65 } |
66 | 66 |
67 Handle<BytecodeArray> MakeBytecodeForFunctionBody(const char* body) { | 67 Handle<BytecodeArray> MakeBytecodeForFunctionBody(const char* body) { |
68 ScopedVector<char> program(3072); | 68 static const char kFormat[] = "function %s() { %s }\n%s();"; |
69 SNPrintF(program, "function %s() { %s }\n%s();", kFunctionName, body, | 69 static const int kFormatLength = arraysize(kFormat); |
70 kFunctionName); | 70 int length = kFormatLength + 2 * StrLength(kFunctionName) + StrLength(body); |
| 71 ScopedVector<char> program(length); |
| 72 length = SNPrintF(program, kFormat, kFunctionName, body, kFunctionName); |
| 73 CHECK_GT(length, 0); |
71 return MakeBytecode(program.start(), kFunctionName); | 74 return MakeBytecode(program.start(), kFunctionName); |
72 } | 75 } |
73 | 76 |
74 Handle<BytecodeArray> MakeBytecodeForFunction(const char* function) { | 77 Handle<BytecodeArray> MakeBytecodeForFunction(const char* function) { |
75 ScopedVector<char> program(3072); | 78 ScopedVector<char> program(3072); |
76 SNPrintF(program, "%s\n%s();", function, kFunctionName); | 79 SNPrintF(program, "%s\n%s();", function, kFunctionName); |
77 return MakeBytecode(program.start(), kFunctionName); | 80 return MakeBytecode(program.start(), kFunctionName); |
78 } | 81 } |
79 | 82 |
80 Handle<BytecodeArray> MakeBytecodeForFunctionNoFilter(const char* function) { | 83 Handle<BytecodeArray> MakeBytecodeForFunctionNoFilter(const char* function) { |
81 ScopedVector<char> program(3072); | 84 ScopedVector<char> program(3072); |
82 SNPrintF(program, "%s\n%s();", function, kFunctionName); | 85 SNPrintF(program, "%s\n%s();", function, kFunctionName); |
83 return MakeBytecode(program.start(), "*", kFunctionName); | 86 return MakeBytecode(program.start(), "*", kFunctionName); |
84 } | 87 } |
85 }; | 88 }; |
86 | 89 |
87 | 90 |
88 // Helper macros for handcrafting bytecode sequences. | 91 // Helper macros for handcrafting bytecode sequences. |
89 #define B(x) static_cast<uint8_t>(Bytecode::k##x) | 92 #define B(x) static_cast<uint8_t>(Bytecode::k##x) |
90 #define U8(x) static_cast<uint8_t>((x) & 0xff) | 93 #define U8(x) static_cast<uint8_t>((x) & 0xff) |
91 #define R(x) static_cast<uint8_t>(-(x) & 0xff) | 94 #define R(x) static_cast<uint8_t>(-(x) & 0xff) |
92 #define A(x, n) R(helper.kLastParamIndex - (n) + 1 + (x)) | 95 #define A(x, n) R(helper.kLastParamIndex - (n) + 1 + (x)) |
93 #define THIS(n) A(0, n) | 96 #define THIS(n) A(0, n) |
94 #if defined(V8_TARGET_LITTLE_ENDIAN) | 97 #if defined(V8_TARGET_LITTLE_ENDIAN) |
95 #define U16(x) static_cast<uint8_t>((x) & 0xff), \ | 98 #define U16(x) static_cast<uint8_t>((x) & 0xff), \ |
96 static_cast<uint8_t>(((x) >> kBitsPerByte) & 0xff) | 99 static_cast<uint8_t>(((x) >> kBitsPerByte) & 0xff) |
| 100 #define U16I(x) static_cast<uint8_t>((x) & 0xff), \ |
| 101 static_cast<uint8_t>(((x++) >> kBitsPerByte) & 0xff) |
97 #elif defined(V8_TARGET_BIG_ENDIAN) | 102 #elif defined(V8_TARGET_BIG_ENDIAN) |
98 #define U16(x) static_cast<uint8_t>(((x) >> kBitsPerByte) & 0xff), \ | 103 #define U16(x) static_cast<uint8_t>(((x) >> kBitsPerByte) & 0xff), \ |
99 static_cast<uint8_t>((x) & 0xff) | 104 static_cast<uint8_t>((x) & 0xff) |
| 105 #define U16I(x) static_cast<uint8_t>(((x) >> kBitsPerByte) & 0xff), \ |
| 106 static_cast<uint8_t>((x++) & 0xff) |
100 #else | 107 #else |
101 #error Unknown byte ordering | 108 #error Unknown byte ordering |
102 #endif | 109 #endif |
103 | 110 |
104 #define COMMA() , | 111 #define COMMA() , |
105 #define SPACE() | 112 #define SPACE() |
106 | 113 |
107 #define REPEAT_2(SEP, ...) \ | 114 #define REPEAT_2(SEP, ...) \ |
108 __VA_ARGS__ SEP() __VA_ARGS__ | 115 __VA_ARGS__ SEP() __VA_ARGS__ |
109 #define REPEAT_4(SEP, ...) \ | 116 #define REPEAT_4(SEP, ...) \ |
110 REPEAT_2(SEP, __VA_ARGS__) SEP() REPEAT_2(SEP, __VA_ARGS__) | 117 REPEAT_2(SEP, __VA_ARGS__) SEP() REPEAT_2(SEP, __VA_ARGS__) |
111 #define REPEAT_8(SEP, ...) \ | 118 #define REPEAT_8(SEP, ...) \ |
112 REPEAT_4(SEP, __VA_ARGS__) SEP() REPEAT_4(SEP, __VA_ARGS__) | 119 REPEAT_4(SEP, __VA_ARGS__) SEP() REPEAT_4(SEP, __VA_ARGS__) |
113 #define REPEAT_16(SEP, ...) \ | 120 #define REPEAT_16(SEP, ...) \ |
114 REPEAT_8(SEP, __VA_ARGS__) SEP() REPEAT_8(SEP, __VA_ARGS__) | 121 REPEAT_8(SEP, __VA_ARGS__) SEP() REPEAT_8(SEP, __VA_ARGS__) |
115 #define REPEAT_32(SEP, ...) \ | 122 #define REPEAT_32(SEP, ...) \ |
116 REPEAT_16(SEP, __VA_ARGS__) SEP() REPEAT_16(SEP, __VA_ARGS__) | 123 REPEAT_16(SEP, __VA_ARGS__) SEP() REPEAT_16(SEP, __VA_ARGS__) |
117 #define REPEAT_64(SEP, ...) \ | 124 #define REPEAT_64(SEP, ...) \ |
(...skipping 2505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2623 }; | 2630 }; |
2624 | 2631 |
2625 for (size_t i = 0; i < arraysize(snippets); i++) { | 2632 for (size_t i = 0; i < arraysize(snippets); i++) { |
2626 Handle<BytecodeArray> bytecode_array = | 2633 Handle<BytecodeArray> bytecode_array = |
2627 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | 2634 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); |
2628 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | 2635 CheckBytecodeArrayEqual(snippets[i], bytecode_array); |
2629 } | 2636 } |
2630 } | 2637 } |
2631 | 2638 |
2632 | 2639 |
| 2640 TEST(JumpsRequiringConstantWideOperands) { |
| 2641 InitializedHandleScope handle_scope; |
| 2642 BytecodeGeneratorHelper helper; |
| 2643 |
| 2644 int constant_count = 0; |
| 2645 ExpectedSnippet<Handle<Object>, 315> snippets[] = { |
| 2646 { |
| 2647 REPEAT_256(SPACE, "var x = 0.1;") |
| 2648 REPEAT_32(SPACE, "var x = 0.2;") |
| 2649 REPEAT_16(SPACE, "var x = 0.3;") |
| 2650 REPEAT_8(SPACE, "var x = 0.4;") |
| 2651 "for (var i = 0; i < 3; i++) {\n" |
| 2652 " if (i == 1) continue;\n" |
| 2653 " if (i == 2) break;\n" |
| 2654 "}\n" |
| 2655 "return 3;", |
| 2656 kPointerSize * 3, |
| 2657 1, |
| 2658 1347, |
| 2659 { |
| 2660 #define L(c) B(LdaConstant), U8(c), B(Star), R(0) |
| 2661 REPEAT_256(COMMA, L(constant_count++)), |
| 2662 #undef L |
| 2663 #define LW(c) B(LdaConstantWide), U16I(c), B(Star), R(0) |
| 2664 REPEAT_32(COMMA, LW(constant_count)), |
| 2665 REPEAT_16(COMMA, LW(constant_count)), |
| 2666 REPEAT_8(COMMA, LW(constant_count)), |
| 2667 #undef LW |
| 2668 B(LdaZero), // |
| 2669 B(Star), R(1), // |
| 2670 B(LdaSmi8), U8(3), // |
| 2671 B(TestLessThan), R(1), // |
| 2672 B(JumpIfFalseConstantWide), U16(313), // |
| 2673 B(LdaSmi8), U8(1), // |
| 2674 B(TestEqual), R(1), // |
| 2675 B(JumpIfFalseConstantWide), U16(312), // |
| 2676 B(JumpConstantWide), U16(314), // |
| 2677 B(LdaSmi8), U8(2), // |
| 2678 B(TestEqual), R(1), // |
| 2679 B(JumpIfFalseConstantWide), U16(312), // |
| 2680 B(JumpConstantWide), U16(314), // |
| 2681 B(Ldar), R(1), // |
| 2682 B(ToNumber), // |
| 2683 B(Star), R(2), // |
| 2684 B(Inc), // |
| 2685 B(Star), R(1), // |
| 2686 B(Jump), U8(-35), // |
| 2687 B(LdaSmi8), U8(3), // |
| 2688 B(Return) // |
| 2689 }, |
| 2690 315, |
| 2691 { |
| 2692 #define S(x) CcTest::i_isolate()->factory()->NewNumber(x) |
| 2693 REPEAT_256(COMMA, S(0.1)), |
| 2694 REPEAT_32(COMMA, S(0.2)), |
| 2695 REPEAT_16(COMMA, S(0.3)), |
| 2696 REPEAT_8(COMMA, S(0.4)), |
| 2697 #undef S |
| 2698 #define N(x) CcTest::i_isolate()->factory()->NewNumberFromInt(x) |
| 2699 N(6), N(33), N(13), |
| 2700 #undef N |
| 2701 }}}; |
| 2702 |
| 2703 for (size_t i = 0; i < arraysize(snippets); i++) { |
| 2704 Handle<BytecodeArray> bytecode_array = |
| 2705 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); |
| 2706 CheckBytecodeArrayEqual(snippets[i], bytecode_array); |
| 2707 } |
| 2708 } |
| 2709 |
| 2710 |
2633 TEST(UnaryOperators) { | 2711 TEST(UnaryOperators) { |
2634 InitializedHandleScope handle_scope; | 2712 InitializedHandleScope handle_scope; |
2635 BytecodeGeneratorHelper helper; | 2713 BytecodeGeneratorHelper helper; |
2636 | 2714 |
2637 ExpectedSnippet<int> snippets[] = { | 2715 ExpectedSnippet<int> snippets[] = { |
2638 {"var x = 0;" | 2716 {"var x = 0;" |
2639 "while (x != 10) {" | 2717 "while (x != 10) {" |
2640 " x = x + 10;" | 2718 " x = x + 10;" |
2641 "}" | 2719 "}" |
2642 "return x;", | 2720 "return x;", |
(...skipping 3250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5893 std::string(function_epilogue); | 5971 std::string(function_epilogue); |
5894 Handle<BytecodeArray> bytecode_array = | 5972 Handle<BytecodeArray> bytecode_array = |
5895 helper.MakeBytecode(script.c_str(), "t", "f"); | 5973 helper.MakeBytecode(script.c_str(), "t", "f"); |
5896 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | 5974 CheckBytecodeArrayEqual(snippets[i], bytecode_array); |
5897 } | 5975 } |
5898 } | 5976 } |
5899 | 5977 |
5900 } // namespace interpreter | 5978 } // namespace interpreter |
5901 } // namespace internal | 5979 } // namespace internal |
5902 } // namespace v8 | 5980 } // namespace v8 |
OLD | NEW |