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 <fstream> |
| 6 |
5 #include "src/v8.h" | 7 #include "src/v8.h" |
6 | 8 |
7 #include "src/compiler.h" | 9 #include "src/compiler.h" |
8 #include "src/interpreter/bytecode-array-iterator.h" | 10 #include "src/interpreter/bytecode-array-iterator.h" |
9 #include "src/interpreter/bytecode-generator.h" | 11 #include "src/interpreter/bytecode-generator.h" |
10 #include "src/interpreter/interpreter.h" | 12 #include "src/interpreter/interpreter.h" |
11 #include "test/cctest/cctest.h" | 13 #include "test/cctest/cctest.h" |
| 14 #include "test/cctest/interpreter/bytecode-expectations-printer.h" |
12 #include "test/cctest/test-feedback-vector.h" | 15 #include "test/cctest/test-feedback-vector.h" |
13 | 16 |
14 namespace v8 { | 17 namespace v8 { |
15 namespace internal { | 18 namespace internal { |
16 namespace interpreter { | 19 namespace interpreter { |
17 | 20 |
18 static const InstanceType kInstanceTypeDontCare = static_cast<InstanceType>(-1); | 21 #define XSTR(A) #A |
19 | 22 #define STR(A) XSTR(A) |
20 class BytecodeGeneratorHelper { | 23 |
| 24 #define UNIQUE_VAR() "var a" STR(__COUNTER__) " = 0;\n" |
| 25 |
| 26 #define REPEAT_2(...) __VA_ARGS__ __VA_ARGS__ |
| 27 #define REPEAT_4(...) REPEAT_2(__VA_ARGS__) REPEAT_2(__VA_ARGS__) |
| 28 #define REPEAT_8(...) REPEAT_4(__VA_ARGS__) REPEAT_4(__VA_ARGS__) |
| 29 #define REPEAT_16(...) REPEAT_8(__VA_ARGS__) REPEAT_8(__VA_ARGS__) |
| 30 #define REPEAT_32(...) REPEAT_16(__VA_ARGS__) REPEAT_16(__VA_ARGS__) |
| 31 #define REPEAT_64(...) REPEAT_32(__VA_ARGS__) REPEAT_32(__VA_ARGS__) |
| 32 #define REPEAT_128(...) REPEAT_64(__VA_ARGS__) REPEAT_64(__VA_ARGS__) |
| 33 #define REPEAT_256(...) REPEAT_128(__VA_ARGS__) REPEAT_128(__VA_ARGS__) |
| 34 |
| 35 #define REPEAT_127(...) \ |
| 36 REPEAT_64(__VA_ARGS__) \ |
| 37 REPEAT_32(__VA_ARGS__) \ |
| 38 REPEAT_16(__VA_ARGS__) \ |
| 39 REPEAT_8(__VA_ARGS__) \ |
| 40 REPEAT_4(__VA_ARGS__) \ |
| 41 REPEAT_2(__VA_ARGS__) \ |
| 42 __VA_ARGS__ |
| 43 |
| 44 #define REPEAT_249(...) \ |
| 45 REPEAT_127(__VA_ARGS__) \ |
| 46 REPEAT_64(__VA_ARGS__) \ |
| 47 REPEAT_32(__VA_ARGS__) \ |
| 48 REPEAT_16(__VA_ARGS__) \ |
| 49 REPEAT_8(__VA_ARGS__) \ |
| 50 REPEAT_2(__VA_ARGS__) |
| 51 |
| 52 #define REPEAT_2_UNIQUE_VARS() UNIQUE_VAR() UNIQUE_VAR() |
| 53 #define REPEAT_4_UNIQUE_VARS() REPEAT_2_UNIQUE_VARS() REPEAT_2_UNIQUE_VARS() |
| 54 #define REPEAT_8_UNIQUE_VARS() REPEAT_4_UNIQUE_VARS() REPEAT_4_UNIQUE_VARS() |
| 55 #define REPEAT_16_UNIQUE_VARS() REPEAT_8_UNIQUE_VARS() REPEAT_8_UNIQUE_VARS() |
| 56 #define REPEAT_32_UNIQUE_VARS() REPEAT_16_UNIQUE_VARS() REPEAT_16_UNIQUE_VARS() |
| 57 #define REPEAT_64_UNIQUE_VARS() REPEAT_32_UNIQUE_VARS() REPEAT_32_UNIQUE_VARS() |
| 58 #define REPEAT_128_UNIQUE_VARS() REPEAT_64_UNIQUE_VARS() REPEAT_64_UNIQUE_VARS() |
| 59 |
| 60 #define REPEAT_249_UNIQUE_VARS() \ |
| 61 REPEAT_128_UNIQUE_VARS() \ |
| 62 REPEAT_64_UNIQUE_VARS() \ |
| 63 REPEAT_32_UNIQUE_VARS() \ |
| 64 REPEAT_16_UNIQUE_VARS() \ |
| 65 REPEAT_8_UNIQUE_VARS() \ |
| 66 UNIQUE_VAR() |
| 67 |
| 68 static const char* kGoldenFileDirectory = |
| 69 "test/cctest/interpreter/bytecode_expectations/"; |
| 70 |
| 71 class InitializedIgnitionHandleScope : public InitializedHandleScope { |
21 public: | 72 public: |
22 const char* kFunctionName = "f"; | 73 InitializedIgnitionHandleScope() { |
23 | |
24 static const int kLastParamIndex = | |
25 -InterpreterFrameConstants::kLastParamFromRegisterPointer / kPointerSize; | |
26 | |
27 BytecodeGeneratorHelper() { | |
28 i::FLAG_ignition = true; | 74 i::FLAG_ignition = true; |
29 i::FLAG_ignition_filter = StrDup(kFunctionName); | |
30 i::FLAG_always_opt = false; | 75 i::FLAG_always_opt = false; |
31 i::FLAG_allow_natives_syntax = true; | 76 i::FLAG_allow_natives_syntax = true; |
32 CcTest::i_isolate()->interpreter()->Initialize(); | 77 CcTest::i_isolate()->interpreter()->Initialize(); |
33 } | 78 } |
34 | 79 }; |
35 Isolate* isolate() { return CcTest::i_isolate(); } | 80 |
36 Factory* factory() { return CcTest::i_isolate()->factory(); } | 81 void SkipGoldenFileHeader(std::istream& stream) { // NOLINT |
37 | 82 std::string line; |
38 Handle<BytecodeArray> MakeTopLevelBytecode(const char* source) { | 83 int separators_seen = 0; |
39 const char* old_ignition_filter = i::FLAG_ignition_filter; | 84 while (std::getline(stream, line)) { |
40 i::FLAG_ignition_filter = "*"; | 85 if (line == "---") separators_seen += 1; |
41 Local<v8::Script> script = v8_compile(source); | 86 if (separators_seen == 2) return; |
42 i::FLAG_ignition_filter = old_ignition_filter; | |
43 i::Handle<i::JSFunction> js_function = v8::Utils::OpenHandle(*script); | |
44 return handle(js_function->shared()->bytecode_array(), CcTest::i_isolate()); | |
45 } | 87 } |
46 | 88 } |
47 Handle<BytecodeArray> MakeBytecode(const char* script, | 89 |
48 const char* function_name) { | 90 std::string LoadGolden(const std::string& golden_filename) { |
49 CompileRun(script); | 91 std::ifstream expected_file((kGoldenFileDirectory + golden_filename).c_str()); |
50 v8::Local<v8::Context> context = | 92 CHECK(expected_file.is_open()); |
51 v8::Isolate::GetCurrent()->GetCurrentContext(); | 93 SkipGoldenFileHeader(expected_file); |
52 Local<Function> function = Local<Function>::Cast( | 94 std::ostringstream expected_stream; |
53 CcTest::global()->Get(context, v8_str(function_name)).ToLocalChecked()); | 95 // Restore the first separator, which was consumed by SkipGoldenFileHeader |
54 i::Handle<i::JSFunction> js_function = | 96 expected_stream << "---\n" << expected_file.rdbuf(); |
55 i::Handle<i::JSFunction>::cast(v8::Utils::OpenHandle(*function)); | 97 return expected_stream.str(); |
56 return handle(js_function->shared()->bytecode_array(), CcTest::i_isolate()); | 98 } |
| 99 |
| 100 template <size_t N> |
| 101 std::string BuildActual(const BytecodeExpectationsPrinter& printer, |
| 102 const char* (&snippet_list)[N], |
| 103 const char* prologue = nullptr, |
| 104 const char* epilogue = nullptr) { |
| 105 std::ostringstream actual_stream; |
| 106 for (const char* snippet : snippet_list) { |
| 107 std::string source_code; |
| 108 if (prologue) source_code += prologue; |
| 109 source_code += snippet; |
| 110 if (epilogue) source_code += epilogue; |
| 111 printer.PrintExpectation(actual_stream, source_code); |
57 } | 112 } |
58 | 113 return actual_stream.str(); |
59 Handle<BytecodeArray> MakeBytecode(const char* script, const char* filter, | 114 } |
60 const char* function_name) { | 115 |
61 const char* old_ignition_filter = i::FLAG_ignition_filter; | 116 using ConstantPoolType = BytecodeExpectationsPrinter::ConstantPoolType; |
62 i::FLAG_ignition_filter = filter; | |
63 Handle<BytecodeArray> return_val = MakeBytecode(script, function_name); | |
64 i::FLAG_ignition_filter = old_ignition_filter; | |
65 return return_val; | |
66 } | |
67 | |
68 Handle<BytecodeArray> MakeBytecodeForFunctionBody(const char* body) { | |
69 static const char kFormat[] = "function %s() { %s }\n%s();"; | |
70 static const int kFormatLength = arraysize(kFormat); | |
71 int length = kFormatLength + 2 * StrLength(kFunctionName) + StrLength(body); | |
72 ScopedVector<char> program(length); | |
73 length = SNPrintF(program, kFormat, kFunctionName, body, kFunctionName); | |
74 CHECK_GT(length, 0); | |
75 return MakeBytecode(program.start(), kFunctionName); | |
76 } | |
77 | |
78 Handle<BytecodeArray> MakeBytecodeForFunction(const char* function) { | |
79 ScopedVector<char> program(3072); | |
80 SNPrintF(program, "%s\n%s();", function, kFunctionName); | |
81 return MakeBytecode(program.start(), kFunctionName); | |
82 } | |
83 | |
84 Handle<BytecodeArray> MakeBytecodeForFunctionNoFilter(const char* function) { | |
85 ScopedVector<char> program(3072); | |
86 SNPrintF(program, "%s\n%s();", function, kFunctionName); | |
87 return MakeBytecode(program.start(), "*", kFunctionName); | |
88 } | |
89 }; | |
90 | |
91 | |
92 // Helper macros for handcrafting bytecode sequences. | |
93 #define B(x) static_cast<uint8_t>(Bytecode::k##x) | |
94 #define U8(x) static_cast<uint8_t>((x) & 0xff) | |
95 #define R(x) static_cast<uint8_t>(-(x) & 0xff) | |
96 #define R16(x) U16(-(x)) | |
97 #define A(x, n) R(helper.kLastParamIndex - (n) + 1 + (x)) | |
98 #define THIS(n) A(0, n) | |
99 #if defined(V8_TARGET_LITTLE_ENDIAN) | |
100 #define U16(x) static_cast<uint8_t>((x) & 0xff), \ | |
101 static_cast<uint8_t>(((x) >> kBitsPerByte) & 0xff) | |
102 #define U16I(x) static_cast<uint8_t>((x) & 0xff), \ | |
103 static_cast<uint8_t>(((x++) >> kBitsPerByte) & 0xff) | |
104 #elif defined(V8_TARGET_BIG_ENDIAN) | |
105 #define U16(x) static_cast<uint8_t>(((x) >> kBitsPerByte) & 0xff), \ | |
106 static_cast<uint8_t>((x) & 0xff) | |
107 #define U16I(x) static_cast<uint8_t>(((x) >> kBitsPerByte) & 0xff), \ | |
108 static_cast<uint8_t>((x++) & 0xff) | |
109 #else | |
110 #error Unknown byte ordering | |
111 #endif | |
112 | |
113 #define XSTR(A) #A | |
114 #define STR(A) XSTR(A) | |
115 | |
116 #define COMMA() , | |
117 #define SPACE() | |
118 #define UNIQUE_VAR() "var a" STR(__COUNTER__) " = 0;\n" | |
119 | |
120 #define REPEAT_2(SEP, ...) \ | |
121 __VA_ARGS__ SEP() __VA_ARGS__ | |
122 #define REPEAT_4(SEP, ...) \ | |
123 REPEAT_2(SEP, __VA_ARGS__) SEP() REPEAT_2(SEP, __VA_ARGS__) | |
124 #define REPEAT_8(SEP, ...) \ | |
125 REPEAT_4(SEP, __VA_ARGS__) SEP() REPEAT_4(SEP, __VA_ARGS__) | |
126 #define REPEAT_16(SEP, ...) \ | |
127 REPEAT_8(SEP, __VA_ARGS__) SEP() REPEAT_8(SEP, __VA_ARGS__) | |
128 #define REPEAT_32(SEP, ...) \ | |
129 REPEAT_16(SEP, __VA_ARGS__) SEP() REPEAT_16(SEP, __VA_ARGS__) | |
130 #define REPEAT_64(SEP, ...) \ | |
131 REPEAT_32(SEP, __VA_ARGS__) SEP() REPEAT_32(SEP, __VA_ARGS__) | |
132 #define REPEAT_128(SEP, ...) \ | |
133 REPEAT_64(SEP, __VA_ARGS__) SEP() REPEAT_64(SEP, __VA_ARGS__) | |
134 #define REPEAT_256(SEP, ...) \ | |
135 REPEAT_128(SEP, __VA_ARGS__) SEP() REPEAT_128(SEP, __VA_ARGS__) | |
136 | |
137 #define REPEAT_127(SEP, ...) \ | |
138 REPEAT_64(SEP, __VA_ARGS__) SEP() REPEAT_32(SEP, __VA_ARGS__) SEP() \ | |
139 REPEAT_16(SEP, __VA_ARGS__) SEP() REPEAT_8(SEP, __VA_ARGS__) SEP() \ | |
140 REPEAT_4(SEP, __VA_ARGS__) SEP() REPEAT_2(SEP, __VA_ARGS__) SEP() \ | |
141 __VA_ARGS__ | |
142 | |
143 #define REPEAT_249(SEP, ...) \ | |
144 REPEAT_127(SEP, __VA_ARGS__) SEP() REPEAT_64(SEP, __VA_ARGS__) SEP() \ | |
145 REPEAT_32(SEP, __VA_ARGS__) SEP() REPEAT_16(SEP, __VA_ARGS__) SEP() \ | |
146 REPEAT_8(SEP, __VA_ARGS__) SEP() REPEAT_2(SEP, __VA_ARGS__) | |
147 | |
148 #define REPEAT_249_UNIQUE_VARS() \ | |
149 UNIQUE_VAR() REPEAT_127(UNIQUE_VAR) UNIQUE_VAR() REPEAT_64(UNIQUE_VAR) \ | |
150 UNIQUE_VAR() REPEAT_32(UNIQUE_VAR) UNIQUE_VAR() REPEAT_16(UNIQUE_VAR) \ | |
151 UNIQUE_VAR() REPEAT_8(UNIQUE_VAR) UNIQUE_VAR() REPEAT_2(UNIQUE_VAR) | |
152 | |
153 // Structure for containing expected bytecode snippets. | |
154 template<typename T, int C = 6> | |
155 struct ExpectedSnippet { | |
156 const char* code_snippet; | |
157 int frame_size; | |
158 int parameter_count; | |
159 int bytecode_length; | |
160 const uint8_t bytecode[2048]; | |
161 int constant_count; | |
162 T constants[C]; | |
163 int handler_count; | |
164 struct { | |
165 int start; | |
166 int end; | |
167 int handler; | |
168 } handlers[C]; | |
169 }; | |
170 | |
171 | |
172 static void CheckConstant(int expected, Object* actual) { | |
173 CHECK_EQ(expected, Smi::cast(actual)->value()); | |
174 } | |
175 | |
176 | |
177 static void CheckConstant(double expected, Object* actual) { | |
178 CHECK_EQ(expected, HeapNumber::cast(actual)->value()); | |
179 } | |
180 | |
181 | |
182 static void CheckConstant(const char* expected, Object* actual) { | |
183 Handle<String> expected_string = | |
184 CcTest::i_isolate()->factory()->NewStringFromAsciiChecked(expected); | |
185 CHECK(String::cast(actual)->Equals(*expected_string)); | |
186 } | |
187 | |
188 | |
189 static void CheckConstant(Handle<Object> expected, Object* actual) { | |
190 CHECK(actual == *expected || expected->StrictEquals(actual)); | |
191 } | |
192 | |
193 | |
194 static void CheckConstant(InstanceType expected, Object* actual) { | |
195 if (expected != kInstanceTypeDontCare) { | |
196 CHECK_EQ(expected, HeapObject::cast(actual)->map()->instance_type()); | |
197 } | |
198 } | |
199 | |
200 | |
201 template <typename T, int C> | |
202 static void CheckBytecodeArrayEqual(const ExpectedSnippet<T, C>& expected, | |
203 Handle<BytecodeArray> actual) { | |
204 CHECK_EQ(expected.frame_size, actual->frame_size()); | |
205 CHECK_EQ(expected.parameter_count, actual->parameter_count()); | |
206 CHECK_EQ(expected.bytecode_length, actual->length()); | |
207 if (expected.constant_count == 0) { | |
208 CHECK_EQ(CcTest::heap()->empty_fixed_array(), actual->constant_pool()); | |
209 } else { | |
210 CHECK_EQ(expected.constant_count, actual->constant_pool()->length()); | |
211 for (int i = 0; i < expected.constant_count; i++) { | |
212 CheckConstant(expected.constants[i], actual->constant_pool()->get(i)); | |
213 } | |
214 } | |
215 if (expected.handler_count == 0) { | |
216 CHECK_EQ(CcTest::heap()->empty_fixed_array(), actual->handler_table()); | |
217 } else { | |
218 HandlerTable* table = HandlerTable::cast(actual->handler_table()); | |
219 CHECK_EQ(expected.handler_count, table->NumberOfRangeEntries()); | |
220 for (int i = 0; i < expected.handler_count; i++) { | |
221 CHECK_EQ(expected.handlers[i].start, table->GetRangeStart(i)); | |
222 CHECK_EQ(expected.handlers[i].end, table->GetRangeEnd(i)); | |
223 CHECK_EQ(expected.handlers[i].handler, table->GetRangeHandler(i)); | |
224 } | |
225 } | |
226 | |
227 BytecodeArrayIterator iterator(actual); | |
228 int i = 0; | |
229 while (!iterator.done()) { | |
230 int bytecode_index = i++; | |
231 Bytecode bytecode = iterator.current_bytecode(); | |
232 if (Bytecodes::ToByte(bytecode) != expected.bytecode[bytecode_index]) { | |
233 std::ostringstream stream; | |
234 stream << "Check failed: expected bytecode [" << bytecode_index | |
235 << "] to be " << Bytecodes::ToString(static_cast<Bytecode>( | |
236 expected.bytecode[bytecode_index])) | |
237 << " but got " << Bytecodes::ToString(bytecode); | |
238 FATAL(stream.str().c_str()); | |
239 } | |
240 for (int j = 0; j < Bytecodes::NumberOfOperands(bytecode); ++j) { | |
241 OperandType operand_type = Bytecodes::GetOperandType(bytecode, j); | |
242 int operand_index = i; | |
243 i += static_cast<int>(Bytecodes::SizeOfOperand(operand_type)); | |
244 uint32_t raw_operand = iterator.GetRawOperand(j, operand_type); | |
245 uint32_t expected_operand; | |
246 switch (Bytecodes::SizeOfOperand(operand_type)) { | |
247 case OperandSize::kNone: | |
248 UNREACHABLE(); | |
249 return; | |
250 case OperandSize::kByte: | |
251 expected_operand = | |
252 static_cast<uint32_t>(expected.bytecode[operand_index]); | |
253 break; | |
254 case OperandSize::kShort: | |
255 expected_operand = | |
256 ReadUnalignedUInt16(&expected.bytecode[operand_index]); | |
257 break; | |
258 default: | |
259 UNREACHABLE(); | |
260 return; | |
261 } | |
262 if (raw_operand != expected_operand) { | |
263 std::ostringstream stream; | |
264 stream << "Check failed: expected operand [" << j << "] for bytecode [" | |
265 << bytecode_index << "] to be " | |
266 << static_cast<unsigned int>(expected_operand) << " but got " | |
267 << static_cast<unsigned int>(raw_operand); | |
268 FATAL(stream.str().c_str()); | |
269 } | |
270 } | |
271 iterator.Advance(); | |
272 } | |
273 } | |
274 | |
275 | 117 |
276 TEST(PrimitiveReturnStatements) { | 118 TEST(PrimitiveReturnStatements) { |
277 InitializedHandleScope handle_scope; | 119 InitializedIgnitionHandleScope scope; |
278 BytecodeGeneratorHelper helper; | 120 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
279 | 121 ConstantPoolType::kNumber); |
280 // clang-format off | 122 const char* snippets[] = { |
281 ExpectedSnippet<int> snippets[] = { | 123 "", |
282 {"", | 124 |
283 0, | 125 "return;", |
284 1, | 126 |
285 3, | 127 "return null;", |
286 { | 128 |
287 B(StackCheck), // | 129 "return true;", |
288 B(LdaUndefined), // | 130 |
289 B(Return) // | 131 "return false;", |
290 }, | 132 |
291 0}, | 133 "return 0;", |
292 {"return;", | 134 |
293 0, | 135 "return +1;", |
294 1, | 136 |
295 3, | 137 "return -1;", |
296 { | 138 |
297 B(StackCheck), // | 139 "return +127;", |
298 B(LdaUndefined), // | 140 |
299 B(Return) // | 141 "return -128;", |
300 }, | 142 }; |
301 0}, | 143 |
302 {"return null;", | 144 CHECK_EQ(BuildActual(printer, snippets), |
303 0, | 145 LoadGolden("PrimitiveReturnStatements.golden")); |
304 1, | 146 } |
305 3, | |
306 { | |
307 B(StackCheck), // | |
308 B(LdaNull), // | |
309 B(Return) // | |
310 }, | |
311 0}, | |
312 {"return true;", | |
313 0, | |
314 1, | |
315 3, | |
316 { | |
317 B(StackCheck), // | |
318 B(LdaTrue), // | |
319 B(Return) // | |
320 }, | |
321 0}, | |
322 {"return false;", | |
323 0, | |
324 1, | |
325 3, | |
326 { | |
327 B(StackCheck), // | |
328 B(LdaFalse), // | |
329 B(Return) // | |
330 }, | |
331 0}, | |
332 {"return 0;", | |
333 0, | |
334 1, | |
335 3, | |
336 { | |
337 B(StackCheck), // | |
338 B(LdaZero), // | |
339 B(Return) // | |
340 }, | |
341 0}, | |
342 {"return +1;", | |
343 0, | |
344 1, | |
345 4, | |
346 { | |
347 B(StackCheck), // | |
348 B(LdaSmi8), U8(1), // | |
349 B(Return) // | |
350 }, | |
351 0}, | |
352 {"return -1;", | |
353 0, | |
354 1, | |
355 4, | |
356 { | |
357 B(StackCheck), // | |
358 B(LdaSmi8), U8(-1), // | |
359 B(Return) // | |
360 }, | |
361 0}, | |
362 {"return +127;", | |
363 0, | |
364 1, | |
365 4, | |
366 { | |
367 B(StackCheck), // | |
368 B(LdaSmi8), U8(127), // | |
369 B(Return) // | |
370 }, | |
371 0}, | |
372 {"return -128;", | |
373 0, | |
374 1, | |
375 4, | |
376 { | |
377 B(StackCheck), // | |
378 B(LdaSmi8), U8(-128), // | |
379 B(Return) // | |
380 }, | |
381 0}, | |
382 }; | |
383 // clang-format on | |
384 | |
385 for (size_t i = 0; i < arraysize(snippets); i++) { | |
386 Handle<BytecodeArray> bytecode_array = | |
387 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
388 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
389 } | |
390 } | |
391 | |
392 | 147 |
393 TEST(PrimitiveExpressions) { | 148 TEST(PrimitiveExpressions) { |
394 InitializedHandleScope handle_scope; | 149 InitializedIgnitionHandleScope scope; |
395 BytecodeGeneratorHelper helper; | 150 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
396 | 151 ConstantPoolType::kNumber); |
397 // clang-format off | 152 const char* snippets[] = { |
398 ExpectedSnippet<int> snippets[] = { | 153 "var x = 0; return x;", |
399 {"var x = 0; return x;", | 154 |
400 kPointerSize, | 155 "var x = 0; return x + 3;", |
401 1, | 156 |
402 5, | 157 "var x = 0; return x - 3;", |
403 {B(StackCheck), // | 158 |
404 B(LdaZero), // | 159 "var x = 4; return x * 3;", |
405 B(Star), R(0), // | 160 |
406 B(Return)}, | 161 "var x = 4; return x / 3;", |
407 0}, | 162 |
408 {"var x = 0; return x + 3;", | 163 "var x = 4; return x % 3;", |
409 2 * kPointerSize, | 164 |
410 1, | 165 "var x = 1; return x | 2;", |
411 11, | 166 |
412 {B(StackCheck), // | 167 "var x = 1; return x ^ 2;", |
413 B(LdaZero), // | 168 |
414 B(Star), R(0), // | 169 "var x = 1; return x & 2;", |
415 B(Star), R(1), // | 170 |
416 B(LdaSmi8), U8(3), // | 171 "var x = 10; return x << 3;", |
417 B(Add), R(1), // | 172 |
418 B(Return)}, | 173 "var x = 10; return x >> 3;", |
419 0}, | 174 |
420 {"var x = 0; return x - 3;", | 175 "var x = 10; return x >>> 3;", |
421 2 * kPointerSize, | 176 |
422 1, | 177 "var x = 0; return (x, 3);", |
423 11, | 178 }; |
424 {B(StackCheck), // | 179 |
425 B(LdaZero), // | 180 CHECK_EQ(BuildActual(printer, snippets), |
426 B(Star), R(0), // | 181 LoadGolden("PrimitiveExpressions.golden")); |
427 B(Star), R(1), // | 182 } |
428 B(LdaSmi8), U8(3), // | |
429 B(Sub), R(1), // | |
430 B(Return)}, | |
431 0}, | |
432 {"var x = 4; return x * 3;", | |
433 2 * kPointerSize, | |
434 1, | |
435 12, | |
436 {B(StackCheck), // | |
437 B(LdaSmi8), U8(4), // | |
438 B(Star), R(0), // | |
439 B(Star), R(1), // | |
440 B(LdaSmi8), U8(3), // | |
441 B(Mul), R(1), // | |
442 B(Return)}, | |
443 0}, | |
444 {"var x = 4; return x / 3;", | |
445 2 * kPointerSize, | |
446 1, | |
447 12, | |
448 {B(StackCheck), // | |
449 B(LdaSmi8), U8(4), // | |
450 B(Star), R(0), // | |
451 B(Star), R(1), // | |
452 B(LdaSmi8), U8(3), // | |
453 B(Div), R(1), // | |
454 B(Return)}, | |
455 0}, | |
456 {"var x = 4; return x % 3;", | |
457 2 * kPointerSize, | |
458 1, | |
459 12, | |
460 {B(StackCheck), // | |
461 B(LdaSmi8), U8(4), // | |
462 B(Star), R(0), // | |
463 B(Star), R(1), // | |
464 B(LdaSmi8), U8(3), // | |
465 B(Mod), R(1), // | |
466 B(Return)}, | |
467 0}, | |
468 {"var x = 1; return x | 2;", | |
469 2 * kPointerSize, | |
470 1, | |
471 12, | |
472 {B(StackCheck), // | |
473 B(LdaSmi8), U8(1), // | |
474 B(Star), R(0), // | |
475 B(Star), R(1), // | |
476 B(LdaSmi8), U8(2), // | |
477 B(BitwiseOr), R(1), // | |
478 B(Return)}, | |
479 0}, | |
480 {"var x = 1; return x ^ 2;", | |
481 2 * kPointerSize, | |
482 1, | |
483 12, | |
484 {B(StackCheck), // | |
485 B(LdaSmi8), U8(1), // | |
486 B(Star), R(0), // | |
487 B(Star), R(1), // | |
488 B(LdaSmi8), U8(2), // | |
489 B(BitwiseXor), R(1), // | |
490 B(Return)}, | |
491 0}, | |
492 {"var x = 1; return x & 2;", | |
493 2 * kPointerSize, | |
494 1, | |
495 12, | |
496 {B(StackCheck), // | |
497 B(LdaSmi8), U8(1), // | |
498 B(Star), R(0), // | |
499 B(Star), R(1), // | |
500 B(LdaSmi8), U8(2), // | |
501 B(BitwiseAnd), R(1), // | |
502 B(Return)}, | |
503 0}, | |
504 {"var x = 10; return x << 3;", | |
505 2 * kPointerSize, | |
506 1, | |
507 12, | |
508 {B(StackCheck), // | |
509 B(LdaSmi8), U8(10), // | |
510 B(Star), R(0), // | |
511 B(Star), R(1), // | |
512 B(LdaSmi8), U8(3), // | |
513 B(ShiftLeft), R(1), // | |
514 B(Return)}, | |
515 0}, | |
516 {"var x = 10; return x >> 3;", | |
517 2 * kPointerSize, | |
518 1, | |
519 12, | |
520 {B(StackCheck), // | |
521 B(LdaSmi8), U8(10), // | |
522 B(Star), R(0), // | |
523 B(Star), R(1), // | |
524 B(LdaSmi8), U8(3), // | |
525 B(ShiftRight), R(1), // | |
526 B(Return)}, | |
527 0}, | |
528 {"var x = 10; return x >>> 3;", | |
529 2 * kPointerSize, | |
530 1, | |
531 12, | |
532 {B(StackCheck), // | |
533 B(LdaSmi8), U8(10), // | |
534 B(Star), R(0), // | |
535 B(Star), R(1), // | |
536 B(LdaSmi8), U8(3), // | |
537 B(ShiftRightLogical), R(1), // | |
538 B(Return)}, | |
539 0}, | |
540 {"var x = 0; return (x, 3);", | |
541 1 * kPointerSize, | |
542 1, | |
543 7, | |
544 {B(StackCheck), // | |
545 B(LdaZero), // | |
546 B(Star), R(0), // | |
547 B(LdaSmi8), U8(3), // | |
548 B(Return)}, | |
549 0}, | |
550 }; | |
551 // clang-format on | |
552 | |
553 for (size_t i = 0; i < arraysize(snippets); i++) { | |
554 Handle<BytecodeArray> bytecode_array = | |
555 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
556 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
557 } | |
558 } | |
559 | |
560 | 183 |
561 TEST(LogicalExpressions) { | 184 TEST(LogicalExpressions) { |
562 InitializedHandleScope handle_scope; | 185 InitializedIgnitionHandleScope scope; |
563 BytecodeGeneratorHelper helper; | 186 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
564 | 187 ConstantPoolType::kNumber); |
565 // clang-format off | 188 const char* snippets[] = { |
566 ExpectedSnippet<int> snippets[] = { | 189 "var x = 0; return x || 3;", |
567 {"var x = 0; return x || 3;", | 190 |
568 1 * kPointerSize, | 191 "var x = 0; return (x == 1) || 3;", |
569 1, | 192 |
570 9, | 193 "var x = 0; return x && 3;", |
571 {B(StackCheck), // | 194 |
572 B(LdaZero), // | 195 "var x = 0; return (x == 0) && 3;", |
573 B(Star), R(0), // | 196 |
574 B(JumpIfToBooleanTrue), U8(4), // | 197 "var x = 0; return x || (1, 2, 3);", |
575 B(LdaSmi8), U8(3), // | 198 |
576 B(Return)}, | 199 "var a = 2, b = 3, c = 4; return a || (a, b, a, b, c = 5, 3);", |
577 0}, | 200 |
578 {"var x = 0; return (x == 1) || 3;", | 201 "var x = 1; var a = 2, b = 3; return x || (" // |
579 2 * kPointerSize, | 202 REPEAT_32("\n a = 1, b = 2, ") // |
580 1, | 203 "3);", |
581 15, | 204 |
582 {B(StackCheck), // | 205 "var x = 0; var a = 2, b = 3; return x && (" // |
583 B(LdaZero), // | 206 REPEAT_32("\n a = 1, b = 2, ") // |
584 B(Star), R(0), // | 207 "3);", |
585 B(Star), R(1), // | 208 |
586 B(LdaSmi8), U8(1), // | 209 "var x = 1; var a = 2, b = 3; return (x > 3) || (" // |
587 B(TestEqual), R(1), // | 210 REPEAT_32("\n a = 1, b = 2, ") // |
588 B(JumpIfTrue), U8(4), // | 211 "3);", |
589 B(LdaSmi8), U8(3), // | 212 |
590 B(Return)}, | 213 "var x = 0; var a = 2, b = 3; return (x < 5) && (" // |
591 0}, | 214 REPEAT_32("\n a = 1, b = 2, ") // |
592 {"var x = 0; return x && 3;", | 215 "3);", |
593 1 * kPointerSize, | 216 |
594 1, | 217 "return 0 && 3;", |
595 9, | 218 |
596 {B(StackCheck), // | 219 "return 1 || 3;", |
597 B(LdaZero), // | 220 |
598 B(Star), R(0), // | 221 "var x = 1; return x && 3 || 0, 1;", |
599 B(JumpIfToBooleanFalse), U8(4), // | 222 }; |
600 B(LdaSmi8), U8(3), // | 223 |
601 B(Return)}, | 224 CHECK_EQ(BuildActual(printer, snippets), |
602 0}, | 225 LoadGolden("LogicalExpressions.golden")); |
603 {"var x = 0; return (x == 0) && 3;", | 226 } |
604 2 * kPointerSize, | |
605 1, | |
606 14, | |
607 {B(StackCheck), // | |
608 B(LdaZero), // | |
609 B(Star), R(0), // | |
610 B(Star), R(1), // | |
611 B(LdaZero), // | |
612 B(TestEqual), R(1), // | |
613 B(JumpIfFalse), U8(4), // | |
614 B(LdaSmi8), U8(3), // | |
615 B(Return)}, | |
616 0}, | |
617 {"var x = 0; return x || (1, 2, 3);", | |
618 1 * kPointerSize, | |
619 1, | |
620 9, | |
621 {B(StackCheck), // | |
622 B(LdaZero), // | |
623 B(Star), R(0), // | |
624 B(JumpIfToBooleanTrue), U8(4), // | |
625 B(LdaSmi8), U8(3), // | |
626 B(Return)}, | |
627 0}, | |
628 {"var a = 2, b = 3, c = 4; return a || (a, b, a, b, c = 5, 3);", | |
629 3 * kPointerSize, | |
630 1, | |
631 32, | |
632 {B(StackCheck), // | |
633 B(LdaSmi8), U8(2), // | |
634 B(Star), R(0), // | |
635 B(LdaSmi8), U8(3), // | |
636 B(Star), R(1), // | |
637 B(LdaSmi8), U8(4), // | |
638 B(Star), R(2), // | |
639 B(Ldar), R(0), // | |
640 B(JumpIfToBooleanTrue), U8(16), // | |
641 B(Ldar), R(0), // | |
642 B(Ldar), R(1), // | |
643 B(Ldar), R(0), // | |
644 B(Ldar), R(1), // | |
645 B(LdaSmi8), U8(5), // | |
646 B(Star), R(2), // | |
647 B(LdaSmi8), U8(3), // | |
648 B(Return)}, | |
649 0}, | |
650 {"var x = 1; var a = 2, b = 3; return x || (" | |
651 REPEAT_32(SPACE, "a = 1, b = 2, ") | |
652 "3);", | |
653 3 * kPointerSize, | |
654 1, | |
655 276, | |
656 {B(StackCheck), // | |
657 B(LdaSmi8), U8(1), // | |
658 B(Star), R(0), // | |
659 B(LdaSmi8), U8(2), // | |
660 B(Star), R(1), // | |
661 B(LdaSmi8), U8(3), // | |
662 B(Star), R(2), // | |
663 B(Ldar), R(0), // | |
664 B(JumpIfToBooleanTrueConstant), U8(0), // | |
665 REPEAT_32(COMMA, // | |
666 B(LdaSmi8), U8(1), // | |
667 B(Star), R(1), // | |
668 B(LdaSmi8), U8(2), // | |
669 B(Star), R(2)), // | |
670 B(LdaSmi8), U8(3), // | |
671 B(Return)}, | |
672 1, | |
673 {260, 0, 0, 0}}, | |
674 {"var x = 0; var a = 2, b = 3; return x && (" | |
675 REPEAT_32(SPACE, "a = 1, b = 2, ") | |
676 "3);", | |
677 3 * kPointerSize, | |
678 1, | |
679 275, | |
680 {B(StackCheck), // | |
681 B(LdaZero), // | |
682 B(Star), R(0), // | |
683 B(LdaSmi8), U8(2), // | |
684 B(Star), R(1), // | |
685 B(LdaSmi8), U8(3), // | |
686 B(Star), R(2), // | |
687 B(Ldar), R(0), // | |
688 B(JumpIfToBooleanFalseConstant), U8(0), // | |
689 REPEAT_32(COMMA, // | |
690 B(LdaSmi8), U8(1), // | |
691 B(Star), R(1), // | |
692 B(LdaSmi8), U8(2), // | |
693 B(Star), R(2)), // | |
694 B(LdaSmi8), U8(3), // | |
695 B(Return)}, // | |
696 1, | |
697 {260, 0, 0, 0}}, | |
698 {"var x = 1; var a = 2, b = 3; return (x > 3) || (" | |
699 REPEAT_32(SPACE, "a = 1, b = 2, ") | |
700 "3);", | |
701 4 * kPointerSize, | |
702 1, | |
703 282, | |
704 {B(StackCheck), // | |
705 B(LdaSmi8), U8(1), // | |
706 B(Star), R(0), // | |
707 B(LdaSmi8), U8(2), // | |
708 B(Star), R(1), // | |
709 B(LdaSmi8), U8(3), // | |
710 B(Star), R(2), // | |
711 B(Ldar), R(0), // | |
712 B(Star), R(3), // | |
713 B(LdaSmi8), U8(3), // | |
714 B(TestGreaterThan), R(3), // | |
715 B(JumpIfTrueConstant), U8(0), // | |
716 REPEAT_32(COMMA, // | |
717 B(LdaSmi8), U8(1), // | |
718 B(Star), R(1), // | |
719 B(LdaSmi8), U8(2), // | |
720 B(Star), R(2)), // | |
721 B(LdaSmi8), U8(3), // | |
722 B(Return)}, | |
723 1, | |
724 {260, 0, 0, 0}}, | |
725 {"var x = 0; var a = 2, b = 3; return (x < 5) && (" | |
726 REPEAT_32(SPACE, "a = 1, b = 2, ") | |
727 "3);", | |
728 4 * kPointerSize, | |
729 1, | |
730 281, | |
731 {B(StackCheck), // | |
732 B(LdaZero), // | |
733 B(Star), R(0), // | |
734 B(LdaSmi8), U8(2), // | |
735 B(Star), R(1), // | |
736 B(LdaSmi8), U8(3), // | |
737 B(Star), R(2), // | |
738 B(Ldar), R(0), // | |
739 B(Star), R(3), // | |
740 B(LdaSmi8), U8(5), // | |
741 B(TestLessThan), R(3), // | |
742 B(JumpIfFalseConstant), U8(0), // | |
743 REPEAT_32(COMMA, // | |
744 B(LdaSmi8), U8(1), // | |
745 B(Star), R(1), // | |
746 B(LdaSmi8), U8(2), // | |
747 B(Star), R(2)), // | |
748 B(LdaSmi8), U8(3), // | |
749 B(Return)}, | |
750 1, | |
751 {260, 0, 0, 0}}, | |
752 {"return 0 && 3;", | |
753 0 * kPointerSize, | |
754 1, | |
755 3, | |
756 {B(StackCheck), // | |
757 B(LdaZero), // | |
758 B(Return)}, | |
759 0}, | |
760 {"return 1 || 3;", | |
761 0 * kPointerSize, | |
762 1, | |
763 4, | |
764 {B(StackCheck), // | |
765 B(LdaSmi8), U8(1), // | |
766 B(Return)}, | |
767 0}, | |
768 {"var x = 1; return x && 3 || 0, 1;", | |
769 1 * kPointerSize, | |
770 1, | |
771 15, | |
772 {B(StackCheck), // | |
773 B(LdaSmi8), U8(1), // | |
774 B(Star), R(0), // | |
775 B(JumpIfToBooleanFalse), U8(4), // | |
776 B(LdaSmi8), U8(3), // | |
777 B(JumpIfToBooleanTrue), U8(3), // | |
778 B(LdaZero), // | |
779 B(LdaSmi8), U8(1), // | |
780 B(Return)}, | |
781 0} | |
782 }; | |
783 // clang-format on | |
784 | |
785 for (size_t i = 0; i < arraysize(snippets); i++) { | |
786 Handle<BytecodeArray> bytecode_array = | |
787 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
788 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
789 } | |
790 } | |
791 | |
792 | 227 |
793 TEST(Parameters) { | 228 TEST(Parameters) { |
794 InitializedHandleScope handle_scope; | 229 InitializedIgnitionHandleScope scope; |
795 BytecodeGeneratorHelper helper; | 230 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
796 | 231 ConstantPoolType::kNumber); |
797 // clang-format off | 232 printer.set_wrap(false); |
798 ExpectedSnippet<int> snippets[] = { | 233 printer.set_test_function_name("f"); |
799 {"function f() { return this; }", | 234 |
800 0, | 235 const char* snippets[] = { |
801 1, | 236 "function f() { return this; }", |
802 4, | 237 |
803 {B(StackCheck), // | 238 "function f(arg1) { return arg1; }", |
804 B(Ldar), THIS(1), // | 239 |
805 B(Return)}, | 240 "function f(arg1) { return this; }", |
806 0}, | 241 |
807 {"function f(arg1) { return arg1; }", | 242 "function f(arg1, arg2, arg3, arg4, arg5, arg6, arg7) { return arg4; }", |
808 0, | 243 |
809 2, | 244 "function f(arg1, arg2, arg3, arg4, arg5, arg6, arg7) { return this; }", |
810 4, | 245 |
811 {B(StackCheck), // | 246 "function f(arg1) { arg1 = 1; }", |
812 B(Ldar), A(1, 2), // | 247 |
813 B(Return)}, | 248 "function f(arg1, arg2, arg3, arg4) { arg2 = 1; }", |
814 0}, | 249 }; |
815 {"function f(arg1) { return this; }", | 250 |
816 0, | 251 CHECK_EQ(BuildActual(printer, snippets, "", "\nf();"), |
817 2, | 252 LoadGolden("Parameters.golden")); |
818 4, | 253 } |
819 {B(StackCheck), // | |
820 B(Ldar), THIS(2), // | |
821 B(Return)}, | |
822 0}, | |
823 {"function f(arg1, arg2, arg3, arg4, arg5, arg6, arg7) { return arg4; }", | |
824 0, | |
825 8, | |
826 4, | |
827 {B(StackCheck), // | |
828 B(Ldar), A(4, 8), // | |
829 B(Return)}, | |
830 0}, | |
831 {"function f(arg1, arg2, arg3, arg4, arg5, arg6, arg7) { return this; }", | |
832 0, | |
833 8, | |
834 4, | |
835 {B(StackCheck), // | |
836 B(Ldar), THIS(8), // | |
837 B(Return)}, | |
838 0}, | |
839 {"function f(arg1) { arg1 = 1; }", | |
840 0, | |
841 2, | |
842 7, | |
843 {B(StackCheck), // | |
844 B(LdaSmi8), U8(1), // | |
845 B(Star), A(1, 2), // | |
846 B(LdaUndefined), // | |
847 B(Return)}, | |
848 0}, | |
849 {"function f(arg1, arg2, arg3, arg4) { arg2 = 1; }", | |
850 0, | |
851 5, | |
852 7, | |
853 {B(StackCheck), // | |
854 B(LdaSmi8), U8(1), // | |
855 B(Star), A(2, 5), // | |
856 B(LdaUndefined), // | |
857 B(Return)}, | |
858 0}, | |
859 }; | |
860 // clang-format on | |
861 | |
862 for (size_t i = 0; i < arraysize(snippets); i++) { | |
863 Handle<BytecodeArray> bytecode_array = | |
864 helper.MakeBytecodeForFunction(snippets[i].code_snippet); | |
865 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
866 } | |
867 } | |
868 | |
869 | 254 |
870 TEST(IntegerConstants) { | 255 TEST(IntegerConstants) { |
871 InitializedHandleScope handle_scope; | 256 InitializedIgnitionHandleScope scope; |
872 BytecodeGeneratorHelper helper; | 257 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
873 | 258 ConstantPoolType::kNumber); |
874 // clang-format off | 259 const char* snippets[] = { |
875 ExpectedSnippet<int> snippets[] = { | 260 "return 12345678;", |
876 {"return 12345678;", | 261 |
877 0, | 262 "var a = 1234; return 5678;", |
878 1, | 263 |
879 4, | 264 "var a = 1234; return 1234;", |
880 { | 265 }; |
881 B(StackCheck), // | 266 |
882 B(LdaConstant), U8(0), // | 267 CHECK_EQ(BuildActual(printer, snippets), |
883 B(Return) // | 268 LoadGolden("IntegerConstants.golden")); |
884 }, | 269 } |
885 1, | |
886 {12345678}}, | |
887 {"var a = 1234; return 5678;", | |
888 1 * kPointerSize, | |
889 1, | |
890 8, | |
891 { | |
892 B(StackCheck), // | |
893 B(LdaConstant), U8(0), // | |
894 B(Star), R(0), // | |
895 B(LdaConstant), U8(1), // | |
896 B(Return) // | |
897 }, | |
898 2, | |
899 {1234, 5678}}, | |
900 {"var a = 1234; return 1234;", | |
901 1 * kPointerSize, | |
902 1, | |
903 8, | |
904 { | |
905 B(StackCheck), // | |
906 B(LdaConstant), U8(0), // | |
907 B(Star), R(0), // | |
908 B(LdaConstant), U8(0), // | |
909 B(Return) // | |
910 }, | |
911 1, | |
912 {1234}} | |
913 }; | |
914 // clang-format on | |
915 | |
916 for (size_t i = 0; i < arraysize(snippets); i++) { | |
917 Handle<BytecodeArray> bytecode_array = | |
918 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
919 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
920 } | |
921 } | |
922 | |
923 | 270 |
924 TEST(HeapNumberConstants) { | 271 TEST(HeapNumberConstants) { |
925 InitializedHandleScope handle_scope; | 272 InitializedIgnitionHandleScope scope; |
926 BytecodeGeneratorHelper helper; | 273 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
927 | 274 ConstantPoolType::kNumber); |
928 int wide_idx = 0; | 275 const char* snippets[] = { |
929 | 276 "return 1.2;", |
930 // clang-format off | 277 |
931 ExpectedSnippet<double, 257> snippets[] = { | 278 "var a = 1.2; return 2.6;", |
932 {"return 1.2;", | 279 |
933 0, | 280 "var a = 3.14; return 3.14;", |
934 1, | 281 |
935 4, | 282 "var a;" // |
936 { | 283 REPEAT_256("\na = 1.414;") // |
937 B(StackCheck), // | 284 " a = 3.14;", |
938 B(LdaConstant), U8(0), // | 285 }; |
939 B(Return) // | 286 |
940 }, | 287 CHECK_EQ(BuildActual(printer, snippets), |
941 1, | 288 LoadGolden("HeapNumberConstants.golden")); |
942 {1.2}}, | 289 } |
943 {"var a = 1.2; return 2.6;", | |
944 1 * kPointerSize, | |
945 1, | |
946 8, | |
947 { | |
948 B(StackCheck), // | |
949 B(LdaConstant), U8(0), // | |
950 B(Star), R(0), // | |
951 B(LdaConstant), U8(1), // | |
952 B(Return) // | |
953 }, | |
954 2, | |
955 {1.2, 2.6}}, | |
956 {"var a = 3.14; return 3.14;", | |
957 1 * kPointerSize, | |
958 1, | |
959 8, | |
960 { | |
961 B(StackCheck), // | |
962 B(LdaConstant), U8(0), // | |
963 B(Star), R(0), // | |
964 B(LdaConstant), U8(1), // | |
965 B(Return) // | |
966 }, | |
967 2, | |
968 {3.14, 3.14}}, | |
969 {"var a;" | |
970 REPEAT_256(SPACE, " a = 1.414;") | |
971 " a = 3.14;", | |
972 1 * kPointerSize, | |
973 1, | |
974 1032, | |
975 { | |
976 B(StackCheck), // | |
977 REPEAT_256(COMMA, // | |
978 B(LdaConstant), U8(wide_idx++), // | |
979 B(Star), R(0)), // | |
980 B(LdaConstantWide), U16(wide_idx), // | |
981 B(Star), R(0), // | |
982 B(LdaUndefined), // | |
983 B(Return), // | |
984 }, | |
985 257, | |
986 {REPEAT_256(COMMA, 1.414), | |
987 3.14}} | |
988 }; | |
989 // clang-format on | |
990 | |
991 for (size_t i = 0; i < arraysize(snippets); i++) { | |
992 Handle<BytecodeArray> bytecode_array = | |
993 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
994 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
995 } | |
996 } | |
997 | |
998 | 290 |
999 TEST(StringConstants) { | 291 TEST(StringConstants) { |
1000 InitializedHandleScope handle_scope; | 292 InitializedIgnitionHandleScope scope; |
1001 BytecodeGeneratorHelper helper; | 293 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
1002 | 294 ConstantPoolType::kString); |
1003 // clang-format off | 295 const char* snippets[] = { |
1004 ExpectedSnippet<const char*> snippets[] = { | 296 "return \"This is a string\";", |
1005 {"return \"This is a string\";", | 297 |
1006 0, | 298 "var a = \"First string\"; return \"Second string\";", |
1007 1, | 299 |
1008 4, | 300 "var a = \"Same string\"; return \"Same string\";", |
1009 { | 301 }; |
1010 B(StackCheck), // | 302 |
1011 B(LdaConstant), U8(0), // | 303 CHECK_EQ(BuildActual(printer, snippets), |
1012 B(Return) // | 304 LoadGolden("StringConstants.golden")); |
1013 }, | 305 } |
1014 1, | |
1015 {"This is a string"}}, | |
1016 {"var a = \"First string\"; return \"Second string\";", | |
1017 1 * kPointerSize, | |
1018 1, | |
1019 8, | |
1020 { | |
1021 B(StackCheck), // | |
1022 B(LdaConstant), U8(0), // | |
1023 B(Star), R(0), // | |
1024 B(LdaConstant), U8(1), // | |
1025 B(Return) // | |
1026 }, | |
1027 2, | |
1028 {"First string", "Second string"}}, | |
1029 {"var a = \"Same string\"; return \"Same string\";", | |
1030 1 * kPointerSize, | |
1031 1, | |
1032 8, | |
1033 { | |
1034 B(StackCheck), // | |
1035 B(LdaConstant), U8(0), // | |
1036 B(Star), R(0), // | |
1037 B(LdaConstant), U8(0), // | |
1038 B(Return) // | |
1039 }, | |
1040 1, | |
1041 {"Same string"}} | |
1042 }; | |
1043 // clang-format on | |
1044 | |
1045 for (size_t i = 0; i < arraysize(snippets); i++) { | |
1046 Handle<BytecodeArray> bytecode_array = | |
1047 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
1048 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
1049 } | |
1050 } | |
1051 | |
1052 | 306 |
1053 TEST(PropertyLoads) { | 307 TEST(PropertyLoads) { |
1054 InitializedHandleScope handle_scope; | 308 InitializedIgnitionHandleScope scope; |
1055 BytecodeGeneratorHelper helper; | 309 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
1056 Zone zone; | 310 ConstantPoolType::kString); |
1057 | 311 printer.set_wrap(false); |
1058 FeedbackVectorSpec feedback_spec(&zone); | 312 printer.set_test_function_name("f"); |
1059 FeedbackVectorSlot slot1 = feedback_spec.AddLoadICSlot(); | 313 |
1060 FeedbackVectorSlot slot2 = feedback_spec.AddLoadICSlot(); | 314 const char* snippets[] = { |
1061 | 315 "function f(a) { return a.name; }\n" |
1062 Handle<i::TypeFeedbackVector> vector = | 316 "f({name : \"test\"});", |
1063 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); | 317 |
1064 | 318 "function f(a) { return a[\"key\"]; }\n" |
1065 // These are a hack used by the LoadICXXXWide tests below. | 319 "f({key : \"test\"});", |
1066 int wide_idx_1 = vector->GetIndex(slot1) - 2; | 320 |
1067 int wide_idx_2 = vector->GetIndex(slot1) - 2; | 321 "function f(a) { return a[100]; }\n" |
1068 | 322 "f({100 : \"test\"});", |
1069 // clang-format off | 323 |
1070 ExpectedSnippet<const char*> snippets[] = { | 324 "function f(a, b) { return a[b]; }\n" |
1071 {"function f(a) { return a.name; }\nf({name : \"test\"})", | 325 "f({arg : \"test\"}, \"arg\");", |
1072 1 * kPointerSize, | 326 |
1073 2, | 327 "function f(a) { var b = a.name; return a[-124]; }\n" |
1074 10, | 328 "f({\"-124\" : \"test\", name : 123 })", |
1075 { | 329 |
1076 B(StackCheck), // | 330 "function f(a) {\n" |
1077 B(Ldar), A(1, 2), // | 331 " var b;\n" |
1078 B(Star), R(0), // | 332 " b = a.name;\n" |
1079 B(LoadIC), R(0), U8(0), U8(vector->GetIndex(slot1)), // | 333 REPEAT_127(" b = a.name;\n") |
1080 B(Return), // | 334 " return a.name;\n" |
1081 }, | 335 "}\n" |
1082 1, | 336 "f({name : \"test\"})\n", |
1083 {"name"}}, | 337 |
1084 {"function f(a) { return a[\"key\"]; }\nf({key : \"test\"})", | 338 "function f(a, b) {\n" |
1085 1 * kPointerSize, | 339 " var c;\n" |
1086 2, | 340 " c = a[b];\n" |
1087 10, | 341 REPEAT_127(" c = a[b];\n") |
1088 { | 342 " return a[b];\n" |
1089 B(StackCheck), // | 343 "}\n" |
1090 B(Ldar), A(1, 2), // | 344 "f({name : \"test\"}, \"name\")\n", |
1091 B(Star), R(0), // | 345 }; |
1092 B(LoadIC), R(0), U8(0), U8(vector->GetIndex(slot1)), // | 346 |
1093 B(Return) // | 347 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("PropertyLoads.golden")); |
1094 }, | 348 } |
1095 1, | |
1096 {"key"}}, | |
1097 {"function f(a) { return a[100]; }\nf({100 : \"test\"})", | |
1098 1 * kPointerSize, | |
1099 2, | |
1100 11, | |
1101 { | |
1102 B(StackCheck), // | |
1103 B(Ldar), A(1, 2), // | |
1104 B(Star), R(0), // | |
1105 B(LdaSmi8), U8(100), // | |
1106 B(KeyedLoadIC), R(0), U8(vector->GetIndex(slot1)), // | |
1107 B(Return) // | |
1108 }, | |
1109 0}, | |
1110 {"function f(a, b) { return a[b]; }\nf({arg : \"test\"}, \"arg\")", | |
1111 1 * kPointerSize, | |
1112 3, | |
1113 11, | |
1114 { | |
1115 B(StackCheck), // | |
1116 B(Ldar), A(1, 3), // | |
1117 B(Star), R(0), // | |
1118 B(Ldar), A(1, 2), // | |
1119 B(KeyedLoadIC), R(0), U8(vector->GetIndex(slot1)), // | |
1120 B(Return) // | |
1121 }, | |
1122 0}, | |
1123 {"function f(a) { var b = a.name; return a[-124]; }\n" | |
1124 "f({\"-124\" : \"test\", name : 123 })", | |
1125 2 * kPointerSize, | |
1126 2, | |
1127 21, | |
1128 { | |
1129 B(StackCheck), // | |
1130 B(Ldar), A(1, 2), // | |
1131 B(Star), R(1), // | |
1132 B(LoadIC), R(1), U8(0), U8(vector->GetIndex(slot1)), // | |
1133 B(Star), R(0), // | |
1134 B(Ldar), A(1, 2), // | |
1135 B(Star), R(1), // | |
1136 B(LdaSmi8), U8(-124), // | |
1137 B(KeyedLoadIC), R(1), U8(vector->GetIndex(slot2)), // | |
1138 B(Return), // | |
1139 }, | |
1140 1, | |
1141 {"name"}}, | |
1142 {"function f(a) {\n" | |
1143 " var b;\n" | |
1144 "b = a.name;" | |
1145 REPEAT_127(SPACE, " b = a.name; ") | |
1146 " return a.name; }\n" | |
1147 "f({name : \"test\"})\n", | |
1148 2 * kPointerSize, | |
1149 2, | |
1150 1292, | |
1151 { | |
1152 B(StackCheck), // | |
1153 B(Ldar), A(1, 2), // | |
1154 B(Star), R(1), // | |
1155 B(LoadIC), R(1), U8(0), U8(wide_idx_1 += 2), // | |
1156 B(Star), R(0), // | |
1157 REPEAT_127(COMMA, // | |
1158 B(Ldar), A(1, 2), // | |
1159 B(Star), R(1), // | |
1160 B(LoadIC), R(1), U8(0), // | |
1161 U8((wide_idx_1 += 2)), // | |
1162 B(Star), R(0)), // | |
1163 B(Ldar), A(1, 2), // | |
1164 B(Star), R(1), // | |
1165 B(LoadICWide), R(1), U16(0), U16(wide_idx_1 + 2), // | |
1166 B(Return), // | |
1167 }, | |
1168 1, | |
1169 {"name"}}, | |
1170 {"function f(a, b) {\n" | |
1171 " var c;\n" | |
1172 " c = a[b];" | |
1173 REPEAT_127(SPACE, " c = a[b]; ") | |
1174 " return a[b]; }\n" | |
1175 "f({name : \"test\"}, \"name\")\n", | |
1176 2 * kPointerSize, | |
1177 3, | |
1178 1420, | |
1179 { | |
1180 B(StackCheck), // | |
1181 B(Ldar), A(1, 3), // | |
1182 B(Star), R(1), // | |
1183 B(Ldar), A(2, 3), // | |
1184 B(KeyedLoadIC), R(1), U8((wide_idx_2 += 2)), // | |
1185 B(Star), R(0), // | |
1186 REPEAT_127(COMMA, // | |
1187 B(Ldar), A(1, 3), // | |
1188 B(Star), R(1), // | |
1189 B(Ldar), A(2, 3), // | |
1190 B(KeyedLoadIC), R(1), U8((wide_idx_2 += 2)), // | |
1191 B(Star), R(0)), // | |
1192 B(Ldar), A(1, 3), // | |
1193 B(Star), R(1), // | |
1194 B(Ldar), A(2, 3), // | |
1195 B(KeyedLoadICWide), R(1), U16(wide_idx_2 + 2), // | |
1196 B(Return), // | |
1197 }}, | |
1198 }; | |
1199 // clang-format on | |
1200 | |
1201 for (size_t i = 0; i < arraysize(snippets); i++) { | |
1202 Handle<BytecodeArray> bytecode_array = | |
1203 helper.MakeBytecode(snippets[i].code_snippet, helper.kFunctionName); | |
1204 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
1205 } | |
1206 } | |
1207 | |
1208 | 349 |
1209 TEST(PropertyStores) { | 350 TEST(PropertyStores) { |
1210 InitializedHandleScope handle_scope; | 351 InitializedIgnitionHandleScope scope; |
1211 BytecodeGeneratorHelper helper; | 352 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
1212 Zone zone; | 353 ConstantPoolType::kString); |
1213 | 354 printer.set_wrap(false); |
1214 FeedbackVectorSpec feedback_spec(&zone); | 355 printer.set_test_function_name("f"); |
1215 FeedbackVectorSlot slot1 = feedback_spec.AddStoreICSlot(); | 356 |
1216 FeedbackVectorSlot slot2 = feedback_spec.AddStoreICSlot(); | 357 const char* snippets[] = { |
1217 | 358 "function f(a) { a.name = \"val\"; }\n" |
1218 Handle<i::TypeFeedbackVector> vector = | 359 "f({name : \"test\"})", |
1219 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); | 360 |
1220 | 361 "function f(a) { a[\"key\"] = \"val\"; }\n" |
1221 // These are a hack used by the StoreICXXXWide tests below. | 362 "f({key : \"test\"})", |
1222 int wide_idx_1 = vector->GetIndex(slot1) - 2; | 363 |
1223 int wide_idx_2 = vector->GetIndex(slot1) - 2; | 364 "function f(a) { a[100] = \"val\"; }\n" |
1224 int wide_idx_3 = vector->GetIndex(slot1) - 2; | 365 "f({100 : \"test\"})", |
1225 int wide_idx_4 = vector->GetIndex(slot1) - 2; | 366 |
1226 | 367 "function f(a, b) { a[b] = \"val\"; }\n" |
1227 // clang-format off | 368 "f({arg : \"test\"}, \"arg\")", |
1228 ExpectedSnippet<const char*> snippets[] = { | 369 |
1229 {"function f(a) { a.name = \"val\"; }\nf({name : \"test\"})", | 370 "function f(a) { a.name = a[-124]; }\n" |
1230 kPointerSize, | 371 "f({\"-124\" : \"test\", name : 123 })", |
1231 2, | 372 |
1232 13, | 373 "function f(a) { \"use strict\"; a.name = \"val\"; }\n" |
1233 { | 374 "f({name : \"test\"})", |
1234 B(StackCheck), // | 375 |
1235 B(Ldar), A(1, 2), // | 376 "function f(a, b) { \"use strict\"; a[b] = \"val\"; }\n" |
1236 B(Star), R(0), // | 377 "f({arg : \"test\"}, \"arg\")", |
1237 B(LdaConstant), U8(0), // | 378 |
1238 B(StoreICSloppy), R(0), U8(1), U8(vector->GetIndex(slot1)), // | 379 "function f(a) {\n" |
1239 B(LdaUndefined), // | 380 " a.name = 1;\n" |
1240 B(Return), // | 381 REPEAT_127(" a.name = 1;\n") |
1241 }, | 382 " a.name = 2;\n" |
1242 2, | 383 "}\n" |
1243 {"val", "name"}}, | 384 "f({name : \"test\"})\n", |
1244 {"function f(a) { a[\"key\"] = \"val\"; }\nf({key : \"test\"})", | 385 |
1245 kPointerSize, | 386 "function f(a) {\n" |
1246 2, | 387 " 'use strict';\n" |
1247 13, | 388 " a.name = 1;\n" |
1248 { | 389 REPEAT_127(" a.name = 1;\n") |
1249 B(StackCheck), // | 390 " a.name = 2;\n" |
1250 B(Ldar), A(1, 2), // | 391 "}\n" |
1251 B(Star), R(0), // | 392 "f({name : \"test\"})\n", |
1252 B(LdaConstant), U8(0), // | 393 |
1253 B(StoreICSloppy), R(0), U8(1), U8(vector->GetIndex(slot1)), // | 394 "function f(a, b) {\n" |
1254 B(LdaUndefined), // | 395 " a[b] = 1;\n" |
1255 B(Return), // | 396 REPEAT_127(" a[b] = 1;\n") |
1256 }, | 397 " a[b] = 2;\n" |
1257 2, | 398 "}\n" |
1258 {"val", "key"}}, | 399 "f({name : \"test\"})\n", |
1259 {"function f(a) { a[100] = \"val\"; }\nf({100 : \"test\"})", | 400 |
1260 2 * kPointerSize, | 401 "function f(a, b) {\n" |
1261 2, | 402 " 'use strict';\n" |
1262 17, | 403 " a[b] = 1;\n" |
1263 { | 404 REPEAT_127(" a[b] = 1;\n") |
1264 B(StackCheck), // | 405 " a[b] = 2;\n" |
1265 B(Ldar), A(1, 2), // | 406 "}\n" |
1266 B(Star), R(0), // | 407 "f({name : \"test\"})\n", |
1267 B(LdaSmi8), U8(100), // | 408 }; |
1268 B(Star), R(1), // | 409 |
1269 B(LdaConstant), U8(0), // | 410 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("PropertyStores.golden")); |
1270 B(KeyedStoreICSloppy), R(0), R(1), // | 411 } |
1271 U8(vector->GetIndex(slot1)), // | |
1272 B(LdaUndefined), // | |
1273 B(Return), // | |
1274 }, | |
1275 1, | |
1276 {"val"}}, | |
1277 {"function f(a, b) { a[b] = \"val\"; }\nf({arg : \"test\"}, \"arg\")", | |
1278 2 * kPointerSize, | |
1279 3, | |
1280 17, | |
1281 { | |
1282 B(StackCheck), // | |
1283 B(Ldar), A(1, 3), // | |
1284 B(Star), R(0), // | |
1285 B(Ldar), A(2, 3), // | |
1286 B(Star), R(1), // | |
1287 B(LdaConstant), U8(0), // | |
1288 B(KeyedStoreICSloppy), R(0), R(1), // | |
1289 U8(vector->GetIndex(slot1)), // | |
1290 B(LdaUndefined), // | |
1291 B(Return), // | |
1292 }, | |
1293 1, | |
1294 {"val"}}, | |
1295 {"function f(a) { a.name = a[-124]; }\n" | |
1296 "f({\"-124\" : \"test\", name : 123 })", | |
1297 2 * kPointerSize, | |
1298 2, | |
1299 20, | |
1300 { | |
1301 B(StackCheck), // | |
1302 B(Ldar), A(1, 2), // | |
1303 B(Star), R(0), // | |
1304 B(Ldar), A(1, 2), // | |
1305 B(Star), R(1), // | |
1306 B(LdaSmi8), U8(-124), // | |
1307 B(KeyedLoadIC), R(1), U8(vector->GetIndex(slot1)), // | |
1308 B(StoreICSloppy), R(0), U8(0), U8(vector->GetIndex(slot2)), // | |
1309 B(LdaUndefined), // | |
1310 B(Return), // | |
1311 }, | |
1312 1, | |
1313 {"name"}}, | |
1314 {"function f(a) { \"use strict\"; a.name = \"val\"; }\n" | |
1315 "f({name : \"test\"})", | |
1316 kPointerSize, | |
1317 2, | |
1318 13, | |
1319 { | |
1320 B(StackCheck), // | |
1321 B(Ldar), A(1, 2), // | |
1322 B(Star), R(0), // | |
1323 B(LdaConstant), U8(0), // | |
1324 B(StoreICStrict), R(0), U8(1), U8(vector->GetIndex(slot1)), // | |
1325 B(LdaUndefined), // | |
1326 B(Return), // | |
1327 }, | |
1328 2, | |
1329 {"val", "name"}}, | |
1330 {"function f(a, b) { \"use strict\"; a[b] = \"val\"; }\n" | |
1331 "f({arg : \"test\"}, \"arg\")", | |
1332 2 * kPointerSize, | |
1333 3, | |
1334 17, | |
1335 { | |
1336 B(StackCheck), // | |
1337 B(Ldar), A(1, 3), // | |
1338 B(Star), R(0), // | |
1339 B(Ldar), A(2, 3), // | |
1340 B(Star), R(1), // | |
1341 B(LdaConstant), U8(0), // | |
1342 B(KeyedStoreICStrict), R(0), R(1), U8(vector->GetIndex(slot1)), // | |
1343 B(LdaUndefined), // | |
1344 B(Return), // | |
1345 }, | |
1346 1, | |
1347 {"val"}}, | |
1348 {"function f(a) {\n" | |
1349 "a.name = 1;" | |
1350 REPEAT_127(SPACE, " a.name = 1; ") | |
1351 " a.name = 2; }\n" | |
1352 "f({name : \"test\"})\n", | |
1353 kPointerSize, | |
1354 2, | |
1355 1295, | |
1356 { | |
1357 B(StackCheck), // | |
1358 B(Ldar), A(1, 2), // | |
1359 B(Star), R(0), // | |
1360 B(LdaSmi8), U8(1), // | |
1361 B(StoreICSloppy), R(0), U8(0), U8((wide_idx_1 += 2)), // | |
1362 REPEAT_127(COMMA, // | |
1363 B(Ldar), A(1, 2), // | |
1364 B(Star), R(0), // | |
1365 B(LdaSmi8), U8(1), // | |
1366 B(StoreICSloppy), R(0), U8(0), // | |
1367 U8((wide_idx_1 += 2))), // | |
1368 B(Ldar), A(1, 2), // | |
1369 B(Star), R(0), // | |
1370 B(LdaSmi8), U8(2), // | |
1371 B(StoreICSloppyWide), R(0), U16(0), U16(wide_idx_1 + 2), // | |
1372 B(LdaUndefined), // | |
1373 B(Return), // | |
1374 }, | |
1375 1, | |
1376 {"name"}}, | |
1377 {"function f(a) {\n" | |
1378 " 'use strict';\n" | |
1379 " a.name = 1;" | |
1380 REPEAT_127(SPACE, " a.name = 1; ") | |
1381 " a.name = 2; }\n" | |
1382 "f({name : \"test\"})\n", | |
1383 kPointerSize, | |
1384 2, | |
1385 1295, | |
1386 { | |
1387 B(StackCheck), // | |
1388 B(Ldar), A(1, 2), // | |
1389 B(Star), R(0), // | |
1390 B(LdaSmi8), U8(1), // | |
1391 B(StoreICStrict), R(0), U8(0), U8(wide_idx_2 += 2), // | |
1392 REPEAT_127(COMMA, // | |
1393 B(Ldar), A(1, 2), // | |
1394 B(Star), R(0), // | |
1395 B(LdaSmi8), U8(1), // | |
1396 B(StoreICStrict), R(0), U8(0), // | |
1397 U8((wide_idx_2 += 2))), // | |
1398 B(Ldar), A(1, 2), // | |
1399 B(Star), R(0), // | |
1400 B(LdaSmi8), U8(2), // | |
1401 B(StoreICStrictWide), R(0), U16(0), U16(wide_idx_2 + 2), // | |
1402 B(LdaUndefined), // | |
1403 B(Return), // | |
1404 }, | |
1405 1, | |
1406 {"name"}}, | |
1407 {"function f(a, b) {\n" | |
1408 " a[b] = 1;" | |
1409 REPEAT_127(SPACE, " a[b] = 1; ") | |
1410 " a[b] = 2; }\n" | |
1411 "f({name : \"test\"})\n", | |
1412 2 * kPointerSize, | |
1413 3, | |
1414 1810, | |
1415 { | |
1416 B(StackCheck), // | |
1417 B(Ldar), A(1, 3), // | |
1418 B(Star), R(0), // | |
1419 B(Ldar), A(2, 3), // | |
1420 B(Star), R(1), // | |
1421 B(LdaSmi8), U8(1), // | |
1422 B(KeyedStoreICSloppy), R(0), R(1), U8(wide_idx_3 += 2), // | |
1423 REPEAT_127(COMMA, // | |
1424 B(Ldar), A(1, 3), // | |
1425 B(Star), R(0), // | |
1426 B(Ldar), A(2, 3), // | |
1427 B(Star), R(1), // | |
1428 B(LdaSmi8), U8(1), // | |
1429 B(KeyedStoreICSloppy), R(0), R(1), // | |
1430 U8((wide_idx_3 += 2))), // | |
1431 B(Ldar), A(1, 3), // | |
1432 B(Star), R(0), // | |
1433 B(Ldar), A(2, 3), // | |
1434 B(Star), R(1), // | |
1435 B(LdaSmi8), U8(2), // | |
1436 B(KeyedStoreICSloppyWide), R(0), R(1), U16(wide_idx_3 + 2), // | |
1437 B(LdaUndefined), // | |
1438 B(Return), // | |
1439 }}, | |
1440 {"function f(a, b) {\n" | |
1441 " 'use strict';\n" | |
1442 " a[b] = 1;" | |
1443 REPEAT_127(SPACE, " a[b] = 1; ") | |
1444 " a[b] = 2; }\n" | |
1445 "f({name : \"test\"})\n", | |
1446 2 * kPointerSize, | |
1447 3, | |
1448 1810, | |
1449 { | |
1450 B(StackCheck), // | |
1451 B(Ldar), A(1, 3), // | |
1452 B(Star), R(0), // | |
1453 B(Ldar), A(2, 3), // | |
1454 B(Star), R(1), // | |
1455 B(LdaSmi8), U8(1), // | |
1456 B(KeyedStoreICStrict), R(0), R(1), U8(wide_idx_4 += 2), // | |
1457 REPEAT_127(COMMA, // | |
1458 B(Ldar), A(1, 3), // | |
1459 B(Star), R(0), // | |
1460 B(Ldar), A(2, 3), // | |
1461 B(Star), R(1), // | |
1462 B(LdaSmi8), U8(1), // | |
1463 B(KeyedStoreICStrict), R(0), R(1), // | |
1464 U8((wide_idx_4 += 2))), // | |
1465 B(Ldar), A(1, 3), // | |
1466 B(Star), R(0), // | |
1467 B(Ldar), A(2, 3), // | |
1468 B(Star), R(1), // | |
1469 B(LdaSmi8), U8(2), // | |
1470 B(KeyedStoreICStrictWide), R(0), R(1), U16(wide_idx_4 + 2), // | |
1471 B(LdaUndefined), // | |
1472 B(Return), // | |
1473 }} | |
1474 }; | |
1475 // clang-format on | |
1476 | |
1477 for (size_t i = 0; i < arraysize(snippets); i++) { | |
1478 Handle<BytecodeArray> bytecode_array = | |
1479 helper.MakeBytecode(snippets[i].code_snippet, helper.kFunctionName); | |
1480 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
1481 } | |
1482 } | |
1483 | |
1484 | 412 |
1485 #define FUNC_ARG "new (function Obj() { this.func = function() { return; }})()" | 413 #define FUNC_ARG "new (function Obj() { this.func = function() { return; }})()" |
1486 | 414 |
1487 | |
1488 TEST(PropertyCall) { | 415 TEST(PropertyCall) { |
1489 InitializedHandleScope handle_scope; | 416 InitializedIgnitionHandleScope scope; |
1490 BytecodeGeneratorHelper helper; | 417 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
1491 Zone zone; | 418 ConstantPoolType::kString); |
1492 | 419 printer.set_wrap(false); |
1493 FeedbackVectorSpec feedback_spec(&zone); | 420 printer.set_test_function_name("f"); |
1494 FeedbackVectorSlot slot1 = feedback_spec.AddCallICSlot(); | 421 |
1495 FeedbackVectorSlot slot2 = feedback_spec.AddLoadICSlot(); | 422 const char* snippets[] = { |
1496 | 423 "function f(a) { return a.func(); }\n" |
1497 Handle<i::TypeFeedbackVector> vector = | 424 "f(" FUNC_ARG ")", |
1498 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); | 425 |
1499 | 426 "function f(a, b, c) { return a.func(b, c); }\n" |
1500 // These are a hack used by the CallWide test below. | 427 "f(" FUNC_ARG ", 1, 2)", |
1501 int wide_idx = vector->GetIndex(slot1) - 2; | 428 |
1502 | 429 "function f(a, b) { return a.func(b + b, b); }\n" |
1503 // clang-format off | 430 "f(" FUNC_ARG ", 1)", |
1504 ExpectedSnippet<const char*> snippets[] = { | 431 |
1505 {"function f(a) { return a.func(); }\nf(" FUNC_ARG ")", | 432 "function f(a) {\n" |
1506 2 * kPointerSize, | 433 " a.func;\n" // |
1507 2, | 434 REPEAT_127(" a.func;\n") // |
1508 17, | 435 " return a.func(); }\n" |
1509 { | 436 "f(" FUNC_ARG ")", |
1510 B(StackCheck), // | 437 }; |
1511 B(Ldar), A(1, 2), // | 438 |
1512 B(Star), R(1), // | 439 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("PropertyCall.golden")); |
1513 B(LoadIC), R(1), U8(0), U8(vector->GetIndex(slot2)), // | 440 } |
1514 B(Star), R(0), // | |
1515 B(Call), R(0), R(1), U8(1), U8(vector->GetIndex(slot1)), // | |
1516 B(Return), // | |
1517 }, | |
1518 1, | |
1519 {"func"}}, | |
1520 {"function f(a, b, c) { return a.func(b, c); }\nf(" FUNC_ARG ", 1, 2)", | |
1521 4 * kPointerSize, | |
1522 4, | |
1523 25, | |
1524 { | |
1525 B(StackCheck), // | |
1526 B(Ldar), A(1, 4), // | |
1527 B(Star), R(1), // | |
1528 B(LoadIC), R(1), U8(0), U8(vector->GetIndex(slot2)), // | |
1529 B(Star), R(0), // | |
1530 B(Ldar), A(2, 4), // | |
1531 B(Star), R(2), // | |
1532 B(Ldar), A(3, 4), // | |
1533 B(Star), R(3), // | |
1534 B(Call), R(0), R(1), U8(3), U8(vector->GetIndex(slot1)), // | |
1535 B(Return) // | |
1536 }, | |
1537 1, | |
1538 {"func"}}, | |
1539 {"function f(a, b) { return a.func(b + b, b); }\nf(" FUNC_ARG ", 1)", | |
1540 4 * kPointerSize, | |
1541 3, | |
1542 31, | |
1543 { | |
1544 B(StackCheck), // | |
1545 B(Ldar), A(1, 3), // | |
1546 B(Star), R(1), // | |
1547 B(LoadIC), R(1), U8(0), U8(vector->GetIndex(slot2)), // | |
1548 B(Star), R(0), // | |
1549 B(Ldar), A(2, 3), // | |
1550 B(Star), R(3), // | |
1551 B(Ldar), A(2, 3), // | |
1552 B(Add), R(3), // | |
1553 B(Star), R(2), // | |
1554 B(Ldar), A(2, 3), // | |
1555 B(Star), R(3), // | |
1556 B(Call), R(0), R(1), U8(3), U8(vector->GetIndex(slot1)), // | |
1557 B(Return), // | |
1558 }, | |
1559 1, | |
1560 {"func"}}, | |
1561 {"function f(a) {\n" | |
1562 " a.func;\n" REPEAT_127( | |
1563 SPACE, " a.func;\n") " return a.func(); }\nf(" FUNC_ARG ")", | |
1564 2 * kPointerSize, | |
1565 2, | |
1566 1047, | |
1567 { | |
1568 B(StackCheck), // | |
1569 B(Ldar), A(1, 2), // | |
1570 B(Star), R(0), // | |
1571 B(LoadIC), R(0), U8(0), U8(wide_idx += 2), // | |
1572 REPEAT_127(COMMA, // | |
1573 B(Ldar), A(1, 2), // | |
1574 B(Star), R(0), // | |
1575 B(LoadIC), R(0), U8(0), U8((wide_idx += 2))), // | |
1576 B(Ldar), A(1, 2), // | |
1577 B(Star), R(1), // | |
1578 B(LoadICWide), R(1), U16(0), U16(wide_idx + 4), // | |
1579 B(Star), R(0), // | |
1580 B(CallWide), R16(0), R16(1), U16(1), U16(wide_idx + 2), // | |
1581 B(Return), // | |
1582 }, | |
1583 1, | |
1584 {"func"}}, | |
1585 }; | |
1586 // clang-format on | |
1587 | |
1588 for (size_t i = 0; i < arraysize(snippets); i++) { | |
1589 Handle<BytecodeArray> bytecode_array = | |
1590 helper.MakeBytecode(snippets[i].code_snippet, helper.kFunctionName); | |
1591 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
1592 } | |
1593 } | |
1594 | |
1595 | 441 |
1596 TEST(LoadGlobal) { | 442 TEST(LoadGlobal) { |
1597 InitializedHandleScope handle_scope; | 443 InitializedIgnitionHandleScope scope; |
1598 BytecodeGeneratorHelper helper; | 444 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
1599 Zone zone; | 445 ConstantPoolType::kString); |
1600 | 446 printer.set_wrap(false); |
1601 FeedbackVectorSpec feedback_spec(&zone); | 447 printer.set_test_function_name("f"); |
1602 FeedbackVectorSlot slot = feedback_spec.AddLoadICSlot(); | 448 |
1603 | 449 const char* snippets[] = { |
1604 Handle<i::TypeFeedbackVector> vector = | 450 "var a = 1;\n" |
1605 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); | 451 "function f() { return a; }\n" |
1606 | 452 "f()", |
1607 // These are a hack used by the LdaGlobalXXXWide tests below. | 453 |
1608 int wide_idx_1 = vector->GetIndex(slot) - 2; | 454 "function t() { }\n" |
1609 | 455 "function f() { return t; }\n" |
1610 // clang-format off | 456 "f()", |
1611 ExpectedSnippet<const char*> snippets[] = { | 457 |
1612 {"var a = 1;\nfunction f() { return a; }\nf()", | 458 "a = 1;\n" |
1613 0, | 459 "function f() { return a; }\n" |
1614 1, | 460 "f()", |
1615 5, | 461 |
1616 { | 462 "a = 1;\n" |
1617 B(StackCheck), // | 463 "function f(b) {\n" |
1618 B(LdaGlobal), U8(0), U8(vector->GetIndex(slot)), // | 464 " b.name;\n" |
1619 B(Return) // | 465 REPEAT_127(" b.name;\n") |
1620 }, | 466 " return a;\n" |
1621 1, | 467 "}\n" |
1622 {"a"}}, | 468 "f({name: 1});", |
1623 {"function t() { }\nfunction f() { return t; }\nf()", | 469 }; |
1624 0, | 470 |
1625 1, | 471 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("LoadGlobal.golden")); |
1626 5, | 472 } |
1627 { | |
1628 B(StackCheck), // | |
1629 B(LdaGlobal), U8(0), U8(vector->GetIndex(slot)), // | |
1630 B(Return) // | |
1631 }, | |
1632 1, | |
1633 {"t"}}, | |
1634 {"a = 1;\nfunction f() { return a; }\nf()", | |
1635 0, | |
1636 1, | |
1637 5, | |
1638 { | |
1639 B(StackCheck), // | |
1640 B(LdaGlobal), U8(0), U8(vector->GetIndex(slot)), // | |
1641 B(Return) // | |
1642 }, | |
1643 1, | |
1644 {"a"}}, | |
1645 {"a = 1;" | |
1646 "function f(b) {\n" | |
1647 " b.name;\n" | |
1648 REPEAT_127(SPACE, "b.name; ") | |
1649 " return a;" | |
1650 "}\nf({name: 1});", | |
1651 kPointerSize, | |
1652 2, | |
1653 1031, | |
1654 { | |
1655 B(StackCheck), // | |
1656 B(Ldar), A(1, 2), // | |
1657 B(Star), R(0), // | |
1658 B(LoadIC), R(0), U8(0), U8(wide_idx_1 += 2), // | |
1659 REPEAT_127(COMMA, // | |
1660 B(Ldar), A(1, 2), // | |
1661 B(Star), R(0), // | |
1662 B(LoadIC), R(0), U8(0), U8(wide_idx_1 += 2)), // | |
1663 B(LdaGlobalWide), U16(1), U16(wide_idx_1 + 2), // | |
1664 B(Return), // | |
1665 }, | |
1666 2, | |
1667 {"name", "a"}}, | |
1668 }; | |
1669 // clang-format on | |
1670 | |
1671 for (size_t i = 0; i < arraysize(snippets); i++) { | |
1672 Handle<BytecodeArray> bytecode_array = | |
1673 helper.MakeBytecode(snippets[i].code_snippet, "f"); | |
1674 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
1675 } | |
1676 } | |
1677 | |
1678 | 473 |
1679 TEST(StoreGlobal) { | 474 TEST(StoreGlobal) { |
1680 InitializedHandleScope handle_scope; | 475 InitializedIgnitionHandleScope scope; |
1681 BytecodeGeneratorHelper helper; | 476 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
1682 Zone zone; | 477 ConstantPoolType::kString); |
1683 | 478 printer.set_wrap(false); |
1684 FeedbackVectorSpec feedback_spec(&zone); | 479 printer.set_test_function_name("f"); |
1685 FeedbackVectorSlot slot = feedback_spec.AddStoreICSlot(); | 480 |
1686 | 481 const char* snippets[] = { |
1687 Handle<i::TypeFeedbackVector> vector = | 482 "var a = 1;\n" |
1688 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); | 483 "function f() { a = 2; }\n" |
1689 | 484 "f();", |
1690 // These are a hack used by the StaGlobalXXXWide tests below. | 485 |
1691 int wide_idx_1 = vector->GetIndex(slot) - 2; | 486 "var a = \"test\"; function f(b) { a = b; }\n" |
1692 int wide_idx_2 = vector->GetIndex(slot) - 2; | 487 "f(\"global\");", |
1693 | 488 |
1694 // clang-format off | 489 "'use strict'; var a = 1;\n" |
1695 ExpectedSnippet<const char*> snippets[] = { | 490 "function f() { a = 2; }\n" |
1696 {"var a = 1;\nfunction f() { a = 2; }\nf()", | 491 "f();", |
1697 0, | 492 |
1698 1, | 493 "a = 1;\n" |
1699 8, | 494 "function f() { a = 2; }\n" |
1700 { | 495 "f();", |
1701 B(StackCheck), // | 496 |
1702 B(LdaSmi8), U8(2), // | 497 "a = 1;\n" |
1703 B(StaGlobalSloppy), U8(0), U8(vector->GetIndex(slot)), // | 498 "function f(b) {\n" |
1704 B(LdaUndefined), // | 499 " b.name;\n" |
1705 B(Return) // | 500 REPEAT_127(" b.name;\n") |
1706 }, | 501 " a = 2;\n" |
1707 1, | 502 "}\n" |
1708 {"a"}}, | 503 "f({name: 1});", |
1709 {"var a = \"test\"; function f(b) { a = b; }\nf(\"global\")", | 504 |
1710 0, | 505 "a = 1;\n" |
1711 2, | 506 "function f(b) {\n" |
1712 8, | 507 " 'use strict';\n" |
1713 { | 508 " b.name;\n" |
1714 B(StackCheck), // | 509 REPEAT_127(" b.name;\n") |
1715 B(Ldar), R(helper.kLastParamIndex), // | 510 " a = 2;\n" |
1716 B(StaGlobalSloppy), U8(0), U8(vector->GetIndex(slot)), // | 511 "}\n" |
1717 B(LdaUndefined), // | 512 "f({name: 1});", |
1718 B(Return) // | 513 }; |
1719 }, | 514 |
1720 1, | 515 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("StoreGlobal.golden")); |
1721 {"a"}}, | 516 } |
1722 {"'use strict'; var a = 1;\nfunction f() { a = 2; }\nf()", | |
1723 0, | |
1724 1, | |
1725 8, | |
1726 { | |
1727 B(StackCheck), // | |
1728 B(LdaSmi8), U8(2), // | |
1729 B(StaGlobalStrict), U8(0), U8(vector->GetIndex(slot)), // | |
1730 B(LdaUndefined), // | |
1731 B(Return) // | |
1732 }, | |
1733 1, | |
1734 {"a"}}, | |
1735 {"a = 1;\nfunction f() { a = 2; }\nf()", | |
1736 0, | |
1737 1, | |
1738 8, | |
1739 { | |
1740 B(StackCheck), // | |
1741 B(LdaSmi8), U8(2), // | |
1742 B(StaGlobalSloppy), U8(0), U8(vector->GetIndex(slot)), // | |
1743 B(LdaUndefined), // | |
1744 B(Return) // | |
1745 }, | |
1746 1, | |
1747 {"a"}}, | |
1748 {"a = 1;" | |
1749 "function f(b) {" | |
1750 " b.name;\n" | |
1751 REPEAT_127(SPACE, "b.name; ") | |
1752 " a = 2; }\n" | |
1753 "f({name: 1});", | |
1754 kPointerSize, | |
1755 2, | |
1756 1034, | |
1757 { | |
1758 B(StackCheck), // | |
1759 B(Ldar), A(1, 2), // | |
1760 B(Star), R(0), // | |
1761 B(LoadIC), R(0), U8(0), U8(wide_idx_1 += 2), // | |
1762 REPEAT_127(COMMA, // | |
1763 B(Ldar), A(1, 2), // | |
1764 B(Star), R(0), // | |
1765 B(LoadIC), R(0), U8(0), U8(wide_idx_1 += 2)), // | |
1766 B(LdaSmi8), U8(2), // | |
1767 B(StaGlobalSloppyWide), U16(1), U16(wide_idx_1 + 2), // | |
1768 B(LdaUndefined), // | |
1769 B(Return), // | |
1770 }, | |
1771 2, | |
1772 {"name", "a"}}, | |
1773 {"a = 1;" | |
1774 "function f(b) {\n" | |
1775 " 'use strict';\n" | |
1776 " b.name;\n" | |
1777 REPEAT_127(SPACE, "b.name; ") | |
1778 " a = 2; }\n" | |
1779 "f({name: 1});", | |
1780 kPointerSize, | |
1781 2, | |
1782 1034, | |
1783 { | |
1784 B(StackCheck), // | |
1785 B(Ldar), A(1, 2), // | |
1786 B(Star), R(0), // | |
1787 B(LoadIC), R(0), U8(0), U8(wide_idx_2 += 2), // | |
1788 REPEAT_127(COMMA, // | |
1789 B(Ldar), A(1, 2), // | |
1790 B(Star), R(0), // | |
1791 B(LoadIC), R(0), U8(0), U8(wide_idx_2 += 2)), // | |
1792 B(LdaSmi8), U8(2), // | |
1793 B(StaGlobalStrictWide), U16(1), U16(wide_idx_2 + 2), // | |
1794 B(LdaUndefined), // | |
1795 B(Return), // | |
1796 }, | |
1797 2, | |
1798 {"name", "a"}}, | |
1799 }; | |
1800 // clang-format on | |
1801 | |
1802 for (size_t i = 0; i < arraysize(snippets); i++) { | |
1803 Handle<BytecodeArray> bytecode_array = | |
1804 helper.MakeBytecode(snippets[i].code_snippet, "f"); | |
1805 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
1806 } | |
1807 } | |
1808 | |
1809 | 517 |
1810 TEST(CallGlobal) { | 518 TEST(CallGlobal) { |
1811 InitializedHandleScope handle_scope; | 519 InitializedIgnitionHandleScope scope; |
1812 BytecodeGeneratorHelper helper; | 520 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
1813 Zone zone; | 521 ConstantPoolType::kString); |
1814 | 522 printer.set_wrap(false); |
1815 FeedbackVectorSpec feedback_spec(&zone); | 523 printer.set_test_function_name("f"); |
1816 FeedbackVectorSlot slot1 = feedback_spec.AddCallICSlot(); | 524 |
1817 FeedbackVectorSlot slot2 = feedback_spec.AddLoadICSlot(); | 525 const char* snippets[] = { |
1818 | 526 "function t() { }\n" |
1819 Handle<i::TypeFeedbackVector> vector = | 527 "function f() { return t(); }\n" |
1820 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); | 528 "f();", |
1821 | 529 |
1822 // clang-format off | 530 "function t(a, b, c) { }\n" |
1823 ExpectedSnippet<const char*> snippets[] = { | 531 "function f() { return t(1, 2, 3); }\n" |
1824 {"function t() { }\nfunction f() { return t(); }\nf()", | 532 "f();", |
1825 2 * kPointerSize, | 533 }; |
1826 1, | 534 |
1827 15, | 535 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("CallGlobal.golden")); |
1828 { | 536 } |
1829 B(StackCheck), // | |
1830 B(LdaUndefined), // | |
1831 B(Star), R(1), // | |
1832 B(LdaGlobal), U8(0), U8(vector->GetIndex(slot2)), // | |
1833 B(Star), R(0), // | |
1834 B(Call), R(0), R(1), U8(1), U8(vector->GetIndex(slot1)), // | |
1835 B(Return) // | |
1836 }, | |
1837 1, | |
1838 {"t"}}, | |
1839 {"function t(a, b, c) { }\nfunction f() { return t(1, 2, 3); }\nf()", | |
1840 5 * kPointerSize, | |
1841 1, | |
1842 27, | |
1843 { | |
1844 B(StackCheck), // | |
1845 B(LdaUndefined), // | |
1846 B(Star), R(1), // | |
1847 B(LdaGlobal), U8(0), U8(vector->GetIndex(slot2)), // | |
1848 B(Star), R(0), // | |
1849 B(LdaSmi8), U8(1), // | |
1850 B(Star), R(2), // | |
1851 B(LdaSmi8), U8(2), // | |
1852 B(Star), R(3), // | |
1853 B(LdaSmi8), U8(3), // | |
1854 B(Star), R(4), // | |
1855 B(Call), R(0), R(1), U8(4), U8(vector->GetIndex(slot1)), // | |
1856 B(Return) // | |
1857 }, | |
1858 1, | |
1859 {"t"}}, | |
1860 }; | |
1861 // clang-format on | |
1862 | |
1863 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); | |
1864 for (size_t i = 0; i < num_snippets; i++) { | |
1865 Handle<BytecodeArray> bytecode_array = | |
1866 helper.MakeBytecode(snippets[i].code_snippet, "f"); | |
1867 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
1868 } | |
1869 } | |
1870 | |
1871 | 537 |
1872 TEST(CallRuntime) { | 538 TEST(CallRuntime) { |
1873 InitializedHandleScope handle_scope; | 539 InitializedIgnitionHandleScope scope; |
1874 BytecodeGeneratorHelper helper; | 540 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
1875 | 541 ConstantPoolType::kMixed); |
1876 // clang-format off | 542 printer.set_wrap(false); |
1877 ExpectedSnippet<InstanceType> snippets[] = { | 543 printer.set_test_function_name("f"); |
1878 { | 544 |
1879 "function f() { %TheHole() }\nf()", | 545 const char* snippets[] = { |
1880 0, | 546 "function f() { %TheHole() }\n" |
1881 1, | 547 "f();", |
1882 8, | 548 |
1883 { | 549 "function f(a) { return %IsArray(a) }\n" |
1884 B(StackCheck), // | 550 "f(undefined);", |
1885 B(CallRuntime), U16(Runtime::kTheHole), R(0), U8(0), // | 551 |
1886 B(LdaUndefined), // | 552 "function f() { return %Add(1, 2) }\n" |
1887 B(Return) // | 553 "f();", |
1888 }, | 554 |
1889 }, | 555 "function f() { return %spread_iterable([1]) }\n" |
1890 { | 556 "f();", |
1891 "function f(a) { return %IsArray(a) }\nf(undefined)", | 557 }; |
1892 1 * kPointerSize, | 558 |
1893 2, | 559 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("CallRuntime.golden")); |
1894 11, | 560 } |
1895 { | |
1896 B(StackCheck), // | |
1897 B(Ldar), A(1, 2), // | |
1898 B(Star), R(0), // | |
1899 B(CallRuntime), U16(Runtime::kIsArray), R(0), U8(1), // | |
1900 B(Return) // | |
1901 }, | |
1902 }, | |
1903 { | |
1904 "function f() { return %Add(1, 2) }\nf()", | |
1905 2 * kPointerSize, | |
1906 1, | |
1907 15, | |
1908 { | |
1909 B(StackCheck), // | |
1910 B(LdaSmi8), U8(1), // | |
1911 B(Star), R(0), // | |
1912 B(LdaSmi8), U8(2), // | |
1913 B(Star), R(1), // | |
1914 B(CallRuntime), U16(Runtime::kAdd), R(0), U8(2), // | |
1915 B(Return) // | |
1916 }, | |
1917 }, | |
1918 { | |
1919 "function f() { return %spread_iterable([1]) }\nf()", | |
1920 2 * kPointerSize, | |
1921 1, | |
1922 16, | |
1923 { | |
1924 B(StackCheck), // | |
1925 B(LdaUndefined), // | |
1926 B(Star), R(0), // | |
1927 B(CreateArrayLiteral), U8(0), U8(0), U8(3), // | |
1928 B(Star), R(1), // | |
1929 B(CallJSRuntime), U16(Context::SPREAD_ITERABLE_INDEX), R(0), // | |
1930 /* */ U8(2), // | |
1931 B(Return), // | |
1932 }, | |
1933 1, | |
1934 {InstanceType::FIXED_ARRAY_TYPE}, | |
1935 }, | |
1936 }; | |
1937 // clang-format on | |
1938 | |
1939 for (size_t i = 0; i < arraysize(snippets); i++) { | |
1940 Handle<BytecodeArray> bytecode_array = | |
1941 helper.MakeBytecode(snippets[i].code_snippet, "f"); | |
1942 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
1943 } | |
1944 } | |
1945 | |
1946 | 561 |
1947 TEST(IfConditions) { | 562 TEST(IfConditions) { |
1948 InitializedHandleScope handle_scope; | 563 InitializedIgnitionHandleScope scope; |
1949 BytecodeGeneratorHelper helper; | 564 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
1950 | 565 ConstantPoolType::kNumber); |
1951 Handle<Object> unused = helper.factory()->undefined_value(); | 566 printer.set_wrap(false); |
1952 | 567 printer.set_test_function_name("f"); |
1953 // clang-format off | 568 |
1954 ExpectedSnippet<Handle<Object>> snippets[] = { | 569 const char* snippets[] = { |
1955 {"function f() { if (0) { return 1; } else { return -1; } } f()", | 570 "function f() {\n" |
1956 0, | 571 " if (0) {\n" |
1957 1, | 572 " return 1;\n" |
1958 4, | 573 " } else {\n" |
1959 { | 574 " return -1;\n" |
1960 B(StackCheck), // | 575 " }\n" |
1961 B(LdaSmi8), U8(-1), // | 576 "};\n" |
1962 B(Return), // | 577 "f();", |
1963 }, | 578 |
1964 0, | 579 "function f() {\n" |
1965 {unused, unused, unused, unused, unused, unused}}, | 580 " if ('lucky') {\n" |
1966 {"function f() { if ('lucky') { return 1; } else { return -1; } } f();", | 581 " return 1;\n" |
1967 0, | 582 " } else {\n" |
1968 1, | 583 " return -1;\n" |
1969 4, | 584 " }\n" |
1970 { | 585 "};\n" |
1971 B(StackCheck), // | 586 "f();", |
1972 B(LdaSmi8), U8(1), // | 587 |
1973 B(Return), // | 588 "function f() {\n" |
1974 }, | 589 " if (false) {\n" |
1975 0, | 590 " return 1;\n" |
1976 {unused, unused, unused, unused, unused, unused}}, | 591 " } else {\n" |
1977 {"function f() { if (false) { return 1; } else { return -1; } } f();", | 592 " return -1;\n" |
1978 0, | 593 " }\n" |
1979 1, | 594 "};\n" |
1980 4, | 595 "f();", |
1981 { | 596 |
1982 B(StackCheck), // | 597 "function f() {\n" |
1983 B(LdaSmi8), U8(-1), // | 598 " if (false) {\n" |
1984 B(Return), // | 599 " return 1;\n" |
1985 }, | 600 " }\n" |
1986 0, | 601 "};\n" |
1987 {unused, unused, unused, unused, unused, unused}}, | 602 "f();", |
1988 {"function f() { if (false) { return 1; } } f();", | 603 |
1989 0, | 604 "function f() {\n" |
1990 1, | 605 " var a = 1;\n" |
1991 3, | 606 " if (a) {\n" |
1992 { | 607 " a += 1;\n" |
1993 B(StackCheck), // | 608 " } else {\n" |
1994 B(LdaUndefined), // | 609 " return 2;\n" |
1995 B(Return), // | 610 " }\n" |
1996 }, | 611 "};\n" |
1997 0, | 612 "f();", |
1998 {unused, unused, unused, unused, unused, unused}}, | 613 |
1999 {"function f() { var a = 1; if (a) { a += 1; } else { return 2; } } f();", | 614 "function f(a) {\n" |
2000 2 * kPointerSize, | 615 " if (a <= 0) {\n" |
2001 1, | 616 " return 200;\n" |
2002 24, | 617 " } else {\n" |
2003 { | 618 " return -200;\n" |
2004 B(StackCheck), // | 619 " }\n" |
2005 B(LdaSmi8), U8(1), // | 620 "};\n" |
2006 B(Star), R(0), // | 621 "f(99);", |
2007 B(JumpIfToBooleanFalse), U8(14), // | 622 |
2008 B(Ldar), R(0), // | 623 "function f(a, b) { if (a in b) { return 200; } }" |
2009 B(Star), R(1), // | 624 "f('prop', { prop: 'yes'});", |
2010 B(LdaSmi8), U8(1), // | 625 |
2011 B(Add), R(1), // | 626 "function f(z) { var a = 0; var b = 0; if (a === 0.01) {\n" |
2012 B(Star), R(0), // | 627 REPEAT_64(" b = a; a = b;\n") |
2013 B(Jump), U8(5), // | 628 " return 200; } else { return -200; } } f(0.001);", |
2014 B(LdaSmi8), U8(2), // | 629 |
2015 B(Return), // | 630 "function f() {\n" |
2016 B(LdaUndefined), // | 631 " var a = 0; var b = 0;\n" |
2017 B(Return), // | 632 " if (a) {\n" |
2018 }, | 633 REPEAT_64(" b = a; a = b;\n") |
2019 0, | 634 " return 200; } else { return -200; }\n" |
2020 {unused, unused, unused, unused, unused, unused}}, | 635 "};\n" |
2021 {"function f(a) { if (a <= 0) { return 200; } else { return -200; } }" | 636 "f();", |
2022 "f(99);", | 637 |
2023 kPointerSize, | 638 "function f(a, b) {\n" |
2024 2, | 639 " if (a == b) { return 1; }\n" |
2025 18, | 640 " if (a === b) { return 1; }\n" |
2026 { | 641 " if (a < b) { return 1; }\n" |
2027 B(StackCheck), // | 642 " if (a > b) { return 1; }\n" |
2028 B(Ldar), A(1, 2), // | 643 " if (a <= b) { return 1; }\n" |
2029 B(Star), R(0), // | 644 " if (a >= b) { return 1; }\n" |
2030 B(LdaZero), // | 645 " if (a in b) { return 1; }\n" |
2031 B(TestLessThanOrEqual), R(0), // | 646 " if (a instanceof b) { return 1; }\n" |
2032 B(JumpIfFalse), U8(5), // | 647 " return 0;\n" |
2033 B(LdaConstant), U8(0), // | 648 "}\n" |
2034 B(Return), // | 649 "f(1, 1);", |
2035 B(LdaConstant), U8(1), // | 650 |
2036 B(Return), // | 651 "function f() {\n" |
2037 B(LdaUndefined), // | 652 " var a = 0;\n" |
2038 B(Return), // | 653 " if (a) {\n" |
2039 }, | 654 " return 20;\n" |
2040 2, | 655 " } else {\n" |
2041 {helper.factory()->NewNumberFromInt(200), | 656 " return -20;\n" |
2042 helper.factory()->NewNumberFromInt(-200), unused, unused, unused, | 657 " }\n" |
2043 unused}}, | 658 "};\n" |
2044 {"function f(a, b) { if (a in b) { return 200; } }" | 659 "f();", |
2045 "f('prop', { prop: 'yes'});", | 660 }; |
2046 kPointerSize, | 661 |
2047 3, | 662 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("IfConditions.golden")); |
2048 16, | 663 } |
2049 { | |
2050 B(StackCheck), // | |
2051 B(Ldar), A(1, 3), // | |
2052 B(Star), R(0), // | |
2053 B(Ldar), A(2, 3), // | |
2054 B(TestIn), R(0), // | |
2055 B(JumpIfFalse), U8(5), // | |
2056 B(LdaConstant), U8(0), // | |
2057 B(Return), // | |
2058 B(LdaUndefined), // | |
2059 B(Return), // | |
2060 }, | |
2061 1, | |
2062 {helper.factory()->NewNumberFromInt(200), unused, unused, unused, unused, | |
2063 unused}}, | |
2064 {"function f(z) { var a = 0; var b = 0; if (a === 0.01) { " | |
2065 REPEAT_64(SPACE, "b = a; a = b; ") | |
2066 " return 200; } else { return -200; } } f(0.001)", | |
2067 3 * kPointerSize, | |
2068 2, | |
2069 283, | |
2070 { | |
2071 B(StackCheck), // | |
2072 B(LdaZero), // | |
2073 B(Star), R(0), // | |
2074 B(LdaZero), // | |
2075 B(Star), R(1), // | |
2076 B(Ldar), R(0), // | |
2077 B(Star), R(2), // | |
2078 B(LdaConstant), U8(0), // | |
2079 B(TestEqualStrict), R(2), // | |
2080 B(JumpIfFalseConstant), U8(2), // | |
2081 B(Ldar), R(0), // | |
2082 REPEAT_64(COMMA, // | |
2083 B(Star), R(1), // | |
2084 B(Star), R(0)), // | |
2085 B(LdaConstant), U8(1), // | |
2086 B(Return), // | |
2087 B(LdaConstant), U8(3), // | |
2088 B(Return), // | |
2089 B(LdaUndefined), // | |
2090 B(Return)}, // | |
2091 4, | |
2092 {helper.factory()->NewHeapNumber(0.01), | |
2093 helper.factory()->NewNumberFromInt(200), | |
2094 helper.factory()->NewNumberFromInt(263), | |
2095 helper.factory()->NewNumberFromInt(-200), unused, unused}}, | |
2096 {"function f() { var a = 0; var b = 0; if (a) { " | |
2097 REPEAT_64(SPACE, "b = a; a = b; ") | |
2098 " return 200; } else { return -200; } } f()", | |
2099 2 * kPointerSize, | |
2100 1, | |
2101 277, | |
2102 { | |
2103 B(StackCheck), // | |
2104 B(LdaZero), // | |
2105 B(Star), R(0), // | |
2106 B(LdaZero), // | |
2107 B(Star), R(1), // | |
2108 B(Ldar), R(0), // | |
2109 B(JumpIfToBooleanFalseConstant), U8(1), // | |
2110 B(Ldar), R(0), // | |
2111 REPEAT_64(COMMA, // | |
2112 B(Star), R(1), // | |
2113 B(Star), R(0)), // | |
2114 B(LdaConstant), U8(0), // | |
2115 B(Return), // | |
2116 B(LdaConstant), U8(2), // | |
2117 B(Return), // | |
2118 B(LdaUndefined), // | |
2119 B(Return)}, // | |
2120 3, | |
2121 {helper.factory()->NewNumberFromInt(200), | |
2122 helper.factory()->NewNumberFromInt(263), | |
2123 helper.factory()->NewNumberFromInt(-200), unused, unused, unused}}, | |
2124 | |
2125 {"function f(a, b) {\n" | |
2126 " if (a == b) { return 1; }\n" | |
2127 " if (a === b) { return 1; }\n" | |
2128 " if (a < b) { return 1; }\n" | |
2129 " if (a > b) { return 1; }\n" | |
2130 " if (a <= b) { return 1; }\n" | |
2131 " if (a >= b) { return 1; }\n" | |
2132 " if (a in b) { return 1; }\n" | |
2133 " if (a instanceof b) { return 1; }\n" | |
2134 " return 0;\n" | |
2135 "} f(1, 1);", | |
2136 kPointerSize, | |
2137 3, | |
2138 107, | |
2139 { | |
2140 #define IF_CONDITION_RETURN(condition) \ | |
2141 B(Ldar), A(1, 3), \ | |
2142 B(Star), R(0), \ | |
2143 B(Ldar), A(2, 3), \ | |
2144 B(condition), R(0), \ | |
2145 B(JumpIfFalse), U8(5), \ | |
2146 B(LdaSmi8), U8(1), \ | |
2147 B(Return), | |
2148 B(StackCheck), // | |
2149 IF_CONDITION_RETURN(TestEqual) // | |
2150 IF_CONDITION_RETURN(TestEqualStrict) // | |
2151 IF_CONDITION_RETURN(TestLessThan) // | |
2152 IF_CONDITION_RETURN(TestGreaterThan) // | |
2153 IF_CONDITION_RETURN(TestLessThanOrEqual) // | |
2154 IF_CONDITION_RETURN(TestGreaterThanOrEqual) // | |
2155 IF_CONDITION_RETURN(TestIn) // | |
2156 IF_CONDITION_RETURN(TestInstanceOf) // | |
2157 B(LdaZero), // | |
2158 B(Return)}, // | |
2159 #undef IF_CONDITION_RETURN | |
2160 0, | |
2161 {unused, unused, unused, unused, unused, unused}}, | |
2162 {"function f() {" | |
2163 " var a = 0;" | |
2164 " if (a) {" | |
2165 " return 20;" | |
2166 "} else {" | |
2167 " return -20;}" | |
2168 "};" | |
2169 "f();", | |
2170 1 * kPointerSize, | |
2171 1, | |
2172 14, | |
2173 { | |
2174 B(StackCheck), // | |
2175 B(LdaZero), // | |
2176 B(Star), R(0), // | |
2177 B(JumpIfToBooleanFalse), U8(5), // | |
2178 B(LdaSmi8), U8(20), // | |
2179 B(Return), // | |
2180 B(LdaSmi8), U8(-20), // | |
2181 B(Return), // | |
2182 B(LdaUndefined), // | |
2183 B(Return) | |
2184 }, | |
2185 0, | |
2186 {unused, unused, unused, unused, unused, unused}} | |
2187 }; | |
2188 // clang-format on | |
2189 | |
2190 for (size_t i = 0; i < arraysize(snippets); i++) { | |
2191 Handle<BytecodeArray> bytecode_array = | |
2192 helper.MakeBytecode(snippets[i].code_snippet, helper.kFunctionName); | |
2193 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
2194 } | |
2195 } | |
2196 | |
2197 | 664 |
2198 TEST(DeclareGlobals) { | 665 TEST(DeclareGlobals) { |
2199 InitializedHandleScope handle_scope; | 666 InitializedIgnitionHandleScope scope; |
2200 BytecodeGeneratorHelper helper; | 667 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
2201 Zone zone; | 668 ConstantPoolType::kMixed); |
2202 | 669 printer.set_wrap(false); |
2203 // Create different feedback vector specs to be precise on slot numbering. | 670 printer.set_test_function_name("f"); |
2204 FeedbackVectorSpec feedback_spec_stores(&zone); | 671 printer.set_execute(false); |
2205 FeedbackVectorSlot store_slot_1 = feedback_spec_stores.AddStoreICSlot(); | 672 printer.set_top_level(true); |
2206 FeedbackVectorSlot store_slot_2 = feedback_spec_stores.AddStoreICSlot(); | 673 |
2207 USE(store_slot_1); | 674 const char* snippets[] = { |
2208 | 675 "var a = 1;", |
2209 Handle<i::TypeFeedbackVector> store_vector = | 676 |
2210 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec_stores); | 677 "function f() {}", |
2211 | 678 |
2212 FeedbackVectorSpec feedback_spec_loads(&zone); | 679 "var a = 1;\n" |
2213 FeedbackVectorSlot load_slot_1 = feedback_spec_loads.AddLoadICSlot(); | 680 "a=2;", |
2214 FeedbackVectorSlot call_slot_1 = feedback_spec_loads.AddCallICSlot(); | 681 |
2215 | 682 "function f() {}\n" |
2216 Handle<i::TypeFeedbackVector> load_vector = | 683 "f();", |
2217 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec_loads); | 684 }; |
2218 | 685 |
2219 // clang-format off | 686 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("DeclareGlobals.golden")); |
2220 ExpectedSnippet<InstanceType> snippets[] = { | 687 } |
2221 {"var a = 1;", | |
2222 4 * kPointerSize, | |
2223 1, | |
2224 31, | |
2225 { | |
2226 B(LdaConstant), U8(0), // | |
2227 B(Star), R(1), // | |
2228 B(LdaZero), // | |
2229 B(Star), R(2), // | |
2230 B(CallRuntime), U16(Runtime::kDeclareGlobals), R(1), U8(2), // | |
2231 B(StackCheck), // | |
2232 B(LdaConstant), U8(1), // | |
2233 B(Star), R(1), // | |
2234 B(LdaZero), // | |
2235 B(Star), R(2), // | |
2236 B(LdaSmi8), U8(1), // | |
2237 B(Star), R(3), // | |
2238 B(CallRuntime), U16(Runtime::kInitializeVarGlobal), R(1), U8(3), // | |
2239 B(LdaUndefined), // | |
2240 B(Return) // | |
2241 }, | |
2242 2, | |
2243 {InstanceType::FIXED_ARRAY_TYPE, | |
2244 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
2245 {"function f() {}", | |
2246 2 * kPointerSize, | |
2247 1, | |
2248 15, | |
2249 { | |
2250 B(LdaConstant), U8(0), // | |
2251 B(Star), R(0), // | |
2252 B(LdaZero), // | |
2253 B(Star), R(1), // | |
2254 B(CallRuntime), U16(Runtime::kDeclareGlobals), R(0), U8(2), // | |
2255 B(StackCheck), // | |
2256 B(LdaUndefined), // | |
2257 B(Return) // | |
2258 }, | |
2259 1, | |
2260 {InstanceType::FIXED_ARRAY_TYPE}}, | |
2261 {"var a = 1;\na=2;", | |
2262 4 * kPointerSize, | |
2263 1, | |
2264 37, | |
2265 { | |
2266 B(LdaConstant), U8(0), // | |
2267 B(Star), R(1), // | |
2268 B(LdaZero), // | |
2269 B(Star), R(2), // | |
2270 B(CallRuntime), U16(Runtime::kDeclareGlobals), R(1), U8(2), // | |
2271 B(StackCheck), // | |
2272 B(LdaConstant), U8(1), // | |
2273 B(Star), R(1), // | |
2274 B(LdaZero), // | |
2275 B(Star), R(2), // | |
2276 B(LdaSmi8), U8(1), // | |
2277 B(Star), R(3), // | |
2278 B(CallRuntime), U16(Runtime::kInitializeVarGlobal), R(1), U8(3), // | |
2279 B(LdaSmi8), U8(2), // | |
2280 B(StaGlobalSloppy), U8(1), // | |
2281 /* */ U8(store_vector->GetIndex(store_slot_2)), // | |
2282 B(Star), R(0), // | |
2283 B(Return) // | |
2284 }, | |
2285 2, | |
2286 {InstanceType::FIXED_ARRAY_TYPE, | |
2287 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
2288 {"function f() {}\nf();", | |
2289 3 * kPointerSize, | |
2290 1, | |
2291 29, | |
2292 { | |
2293 B(LdaConstant), U8(0), // | |
2294 B(Star), R(1), // | |
2295 B(LdaZero), // | |
2296 B(Star), R(2), // | |
2297 B(CallRuntime), U16(Runtime::kDeclareGlobals), R(1), U8(2), // | |
2298 B(StackCheck), // | |
2299 B(LdaUndefined), // | |
2300 B(Star), R(2), // | |
2301 B(LdaGlobal), U8(1), U8(load_vector->GetIndex(load_slot_1)), // | |
2302 B(Star), R(1), // | |
2303 B(Call), R(1), R(2), U8(1), // | |
2304 /* */ U8(load_vector->GetIndex(call_slot_1)), // | |
2305 B(Star), R(0), // | |
2306 B(Return) // | |
2307 }, | |
2308 2, | |
2309 {InstanceType::FIXED_ARRAY_TYPE, | |
2310 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
2311 }; | |
2312 // clang-format on | |
2313 | |
2314 for (size_t i = 0; i < arraysize(snippets); i++) { | |
2315 Handle<BytecodeArray> bytecode_array = | |
2316 helper.MakeTopLevelBytecode(snippets[i].code_snippet); | |
2317 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
2318 } | |
2319 } | |
2320 | |
2321 | 688 |
2322 TEST(BreakableBlocks) { | 689 TEST(BreakableBlocks) { |
2323 InitializedHandleScope handle_scope; | 690 InitializedIgnitionHandleScope scope; |
2324 BytecodeGeneratorHelper helper; | 691 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
2325 | 692 ConstantPoolType::kMixed); |
2326 int closure = Register::function_closure().index(); | 693 |
2327 int context = Register::current_context().index(); | 694 const char* snippets[] = { |
2328 | 695 "var x = 0;\n" |
2329 // clang-format off | 696 "label: {\n" |
2330 ExpectedSnippet<InstanceType> snippets[] = { | 697 " x = x + 1;\n" |
2331 {"var x = 0;\n" | 698 " break label;\n" |
2332 "label: {\n" | 699 " x = x + 1;\n" |
2333 " x = x + 1;\n" | 700 "}\n" |
2334 " break label;\n" | 701 "return x;", |
2335 " x = x + 1;\n" | 702 |
2336 "}\n" | 703 "var sum = 0;\n" |
2337 "return x;", | 704 "outer: {\n" |
2338 2 * kPointerSize, | 705 " for (var x = 0; x < 10; ++x) {\n" |
2339 1, | 706 " for (var y = 0; y < 3; ++y) {\n" |
2340 17, | 707 " ++sum;\n" |
2341 { | 708 " if (x + y == 12) { break outer; }\n" |
2342 B(StackCheck), // | 709 " }\n" |
2343 B(LdaZero), // | 710 " }\n" |
2344 B(Star), R(0), // | 711 "}\n" |
2345 B(Star), R(1), // | 712 "return sum;", |
2346 B(LdaSmi8), U8(1), // | 713 |
2347 B(Add), R(1), // | 714 "outer: {\n" |
2348 B(Star), R(0), // | 715 " let y = 10;\n" |
2349 B(Jump), U8(2), // | 716 " function f() { return y; }\n" |
2350 B(Ldar), R(0), // | 717 " break outer;\n" |
2351 B(Return) // | 718 "}\n", |
2352 }}, | 719 |
2353 {"var sum = 0;\n" | 720 "let x = 1;\n" |
2354 "outer: {\n" | 721 "outer: {\n" |
2355 " for (var x = 0; x < 10; ++x) {\n" | 722 " inner: {\n" |
2356 " for (var y = 0; y < 3; ++y) {\n" | 723 " let y = 2;\n" |
2357 " ++sum;\n" | 724 " function f() { return x + y; }\n" |
2358 " if (x + y == 12) { break outer; }\n" | 725 " if (y) break outer;\n" |
2359 " }\n" | 726 " y = 3;\n" |
2360 " }\n" | 727 " }\n" |
2361 "}\n" | 728 "}\n" |
2362 "return sum;", | 729 "x = 4;", |
2363 5 * kPointerSize, | 730 }; |
2364 1, | 731 |
2365 75, | 732 CHECK_EQ(BuildActual(printer, snippets), |
2366 { | 733 LoadGolden("BreakableBlocks.golden")); |
2367 B(StackCheck), // | 734 } |
2368 B(LdaZero), // | |
2369 B(Star), R(0), // | |
2370 B(LdaZero), // | |
2371 B(Star), R(1), // | |
2372 B(Ldar), R(1), // | |
2373 B(Star), R(3), // | |
2374 B(LdaSmi8), U8(10), // | |
2375 B(TestLessThan), R(3), // | |
2376 B(JumpIfFalse), U8(57), // | |
2377 B(StackCheck), // | |
2378 B(LdaZero), // | |
2379 B(Star), R(2), // | |
2380 B(Ldar), R(2), // | |
2381 B(Star), R(3), // | |
2382 B(LdaSmi8), U8(3), // | |
2383 B(TestLessThan), R(3), // | |
2384 B(JumpIfFalse), U8(35), // | |
2385 B(StackCheck), // | |
2386 B(Ldar), R(0), // | |
2387 B(ToNumber), // | |
2388 B(Inc), // | |
2389 B(Star), R(0), // | |
2390 B(Ldar), R(1), // | |
2391 B(Star), R(3), // | |
2392 B(Ldar), R(2), // | |
2393 B(Add), R(3), // | |
2394 B(Star), R(4), // | |
2395 B(LdaSmi8), U8(12), // | |
2396 B(TestEqual), R(4), // | |
2397 B(JumpIfFalse), U8(4), // | |
2398 B(Jump), U8(18), // | |
2399 B(Ldar), R(2), // | |
2400 B(ToNumber), // | |
2401 B(Inc), // | |
2402 B(Star), R(2), // | |
2403 B(Jump), U8(-41), // | |
2404 B(Ldar), R(1), // | |
2405 B(ToNumber), // | |
2406 B(Inc), // | |
2407 B(Star), R(1), // | |
2408 B(Jump), U8(-63), // | |
2409 B(Ldar), R(0), // | |
2410 B(Return), // | |
2411 }}, | |
2412 {"outer: {\n" | |
2413 " let y = 10;" | |
2414 " function f() { return y; }\n" | |
2415 " break outer;\n" | |
2416 "}\n", | |
2417 5 * kPointerSize, | |
2418 1, | |
2419 51, | |
2420 { | |
2421 B(StackCheck), // | |
2422 B(LdaConstant), U8(0), // | |
2423 B(Star), R(3), // | |
2424 B(Ldar), R(closure), // | |
2425 B(Star), R(4), // | |
2426 B(CallRuntime), U16(Runtime::kPushBlockContext), R(3), U8(2), // | |
2427 B(PushContext), R(2), // | |
2428 B(LdaTheHole), // | |
2429 B(StaContextSlot), R(context), U8(4), // | |
2430 B(CreateClosure), U8(1), U8(0), // | |
2431 B(Star), R(0), // | |
2432 B(LdaSmi8), U8(10), // | |
2433 B(StaContextSlot), R(context), U8(4), // | |
2434 B(Ldar), R(0), // | |
2435 B(JumpIfNotHole), U8(11), // | |
2436 B(LdaConstant), U8(2), // | |
2437 B(Star), R(3), // | |
2438 B(CallRuntime), U16(Runtime::kThrowReferenceError), R(3), U8(1), // | |
2439 B(Star), R(1), // | |
2440 B(Jump), U8(2), // | |
2441 B(PopContext), R(2), // | |
2442 B(LdaUndefined), // | |
2443 B(Return), // | |
2444 }, | |
2445 3, | |
2446 {InstanceType::FIXED_ARRAY_TYPE, InstanceType::SHARED_FUNCTION_INFO_TYPE, | |
2447 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
2448 {"let x = 1;\n" | |
2449 "outer: {\n" | |
2450 " inner: {\n" | |
2451 " let y = 2;\n" | |
2452 " function f() { return x + y; }\n" | |
2453 " if (y) break outer;\n" | |
2454 " y = 3;\n" | |
2455 " }\n" | |
2456 "}\n" | |
2457 "x = 4;", | |
2458 6 * kPointerSize, | |
2459 1, | |
2460 131, | |
2461 { | |
2462 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // | |
2463 U8(1), // | |
2464 B(PushContext), R(2), // | |
2465 B(LdaTheHole), // | |
2466 B(StaContextSlot), R(context), U8(4), // | |
2467 B(StackCheck), // | |
2468 B(LdaSmi8), U8(1), // | |
2469 B(StaContextSlot), R(context), U8(4), // | |
2470 B(LdaConstant), U8(0), // | |
2471 B(Star), R(4), // | |
2472 B(Ldar), R(closure), // | |
2473 B(Star), R(5), // | |
2474 B(CallRuntime), U16(Runtime::kPushBlockContext), R(4), U8(2), // | |
2475 B(PushContext), R(3), // | |
2476 B(LdaTheHole), // | |
2477 B(StaContextSlot), R(context), U8(4), // | |
2478 B(CreateClosure), U8(1), U8(0), // | |
2479 B(Star), R(0), // | |
2480 B(LdaSmi8), U8(2), // | |
2481 B(StaContextSlot), R(context), U8(4), // | |
2482 B(Ldar), R(0), // | |
2483 B(JumpIfNotHole), U8(11), // | |
2484 B(LdaConstant), U8(2), // | |
2485 B(Star), R(4), // | |
2486 B(CallRuntime), U16(Runtime::kThrowReferenceError), R(4), U8(1), // | |
2487 B(Star), R(1), // | |
2488 B(LdaContextSlot), R(context), U8(4), // | |
2489 B(JumpIfNotHole), U8(11), // | |
2490 B(LdaConstant), U8(3), // | |
2491 B(Star), R(4), // | |
2492 B(CallRuntime), U16(Runtime::kThrowReferenceError), R(4), U8(1), // | |
2493 B(JumpIfToBooleanFalse), U8(6), // | |
2494 B(PopContext), R(3), // | |
2495 B(Jump), U8(27), // | |
2496 B(LdaSmi8), U8(3), // | |
2497 B(Star), R(4), // | |
2498 B(LdaContextSlot), R(context), U8(4), // | |
2499 B(JumpIfNotHole), U8(11), // | |
2500 B(LdaConstant), U8(3), // | |
2501 B(Star), R(5), // | |
2502 B(CallRuntime), U16(Runtime::kThrowReferenceError), R(5), U8(1), // | |
2503 B(Ldar), R(4), // | |
2504 B(StaContextSlot), R(context), U8(4), // | |
2505 B(PopContext), R(3), // | |
2506 B(LdaSmi8), U8(4), // | |
2507 B(Star), R(4), // | |
2508 B(LdaContextSlot), R(context), U8(4), // | |
2509 B(JumpIfNotHole), U8(11), // | |
2510 B(LdaConstant), U8(4), // | |
2511 B(Star), R(5), // | |
2512 B(CallRuntime), U16(Runtime::kThrowReferenceError), R(5), U8(1), // | |
2513 B(Ldar), R(4), // | |
2514 B(StaContextSlot), R(context), U8(4), // | |
2515 B(LdaUndefined), // | |
2516 B(Return), // | |
2517 }, | |
2518 5, | |
2519 {InstanceType::FIXED_ARRAY_TYPE, InstanceType::SHARED_FUNCTION_INFO_TYPE, | |
2520 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
2521 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
2522 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
2523 }; | |
2524 // clang-format on | |
2525 | |
2526 for (size_t i = 0; i < arraysize(snippets); i++) { | |
2527 Handle<BytecodeArray> bytecode_array = | |
2528 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
2529 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
2530 } | |
2531 } | |
2532 | |
2533 | 735 |
2534 TEST(BasicLoops) { | 736 TEST(BasicLoops) { |
2535 InitializedHandleScope handle_scope; | 737 InitializedIgnitionHandleScope scope; |
2536 BytecodeGeneratorHelper helper; | 738 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
2537 | 739 ConstantPoolType::kMixed); |
2538 int closure = Register::function_closure().index(); | 740 const char* snippets[] = { |
2539 int context = Register::current_context().index(); | 741 "var x = 0;\n" |
2540 | 742 "while (false) { x = 99; break; continue; }\n" |
2541 // clang-format off | 743 "return x;", |
2542 ExpectedSnippet<InstanceType> snippets[] = { | 744 |
2543 {"var x = 0;\n" | 745 "var x = 0;\n" |
2544 "while (false) { x = 99; break; continue; }\n" | 746 "while (false) {\n" |
2545 "return x;", | 747 " x = x + 1;\n" |
2546 1 * kPointerSize, | 748 "};\n" |
2547 1, | 749 "return x;", |
2548 5, | 750 |
2549 { | 751 "var x = 0;\n" |
2550 B(StackCheck), // | 752 "var y = 1;\n" |
2551 B(LdaZero), // | 753 "while (x < 10) {\n" |
2552 B(Star), R(0), // | 754 " y = y * 12;\n" |
2553 B(Return) // | 755 " x = x + 1;\n" |
2554 }}, | 756 " if (x == 3) continue;\n" |
2555 {"var x = 0;" | 757 " if (x == 4) break;\n" |
2556 "while (false) {" | 758 "}\n" |
2557 " x = x + 1;" | 759 "return y;", |
2558 "};" | 760 |
2559 "return x;", | 761 "var i = 0;\n" |
2560 1 * kPointerSize, | 762 "while (true) {\n" |
2561 1, | 763 " if (i < 0) continue;\n" |
2562 5, | 764 " if (i == 3) break;\n" |
2563 { | 765 " if (i == 4) break;\n" |
2564 B(StackCheck), // | 766 " if (i == 10) continue;\n" |
2565 B(LdaZero), // | 767 " if (i == 5) break;\n" |
2566 B(Star), R(0), // | 768 " i = i + 1;\n" |
2567 B(Return), // | 769 "}\n" |
2568 }, | 770 "return i;", |
2569 0}, | 771 |
2570 {"var x = 0;" | 772 "var i = 0;\n" |
2571 "var y = 1;" | 773 "while (true) {\n" |
2572 "while (x < 10) {" | 774 " while (i < 3) {\n" |
2573 " y = y * 12;" | 775 " if (i == 2) break;\n" |
2574 " x = x + 1;" | 776 " i = i + 1;\n" |
2575 " if (x == 3) continue;" | 777 " }\n" |
2576 " if (x == 4) break;" | 778 " i = i + 1;\n" |
2577 "}" | 779 " break;\n" |
2578 "return y;", | 780 "}\n" |
2579 3 * kPointerSize, | 781 "return i;", |
2580 1, | 782 |
2581 66, | 783 "var x = 10;\n" |
2582 { | 784 "var y = 1;\n" |
2583 B(StackCheck), // | 785 "while (x) {\n" |
2584 B(LdaZero), // | 786 " y = y * 12;\n" |
2585 B(Star), R(0), // | 787 " x = x - 1;\n" |
2586 B(LdaSmi8), U8(1), // | 788 "}\n" |
2587 B(Star), R(1), // | 789 "return y;", |
2588 B(Ldar), R(0), // | 790 |
2589 B(Star), R(2), // | 791 "var x = 0; var y = 1;\n" |
2590 B(LdaSmi8), U8(10), // | 792 "do {\n" |
2591 B(TestLessThan), R(2), // | 793 " y = y * 10;\n" |
2592 B(JumpIfFalse), U8(47), // | 794 " if (x == 5) break;\n" |
2593 B(StackCheck), // | 795 " if (x == 6) continue;\n" |
2594 B(Ldar), R(1), // | 796 " x = x + 1;\n" |
2595 B(Star), R(2), // | 797 "} while (x < 10);\n" |
2596 B(LdaSmi8), U8(12), // | 798 "return y;", |
2597 B(Mul), R(2), // | 799 |
2598 B(Star), R(1), // | 800 "var x = 10;\n" |
2599 B(Ldar), R(0), // | 801 "var y = 1;\n" |
2600 B(Star), R(2), // | 802 "do {\n" |
2601 B(LdaSmi8), U8(1), // | 803 " y = y * 12;\n" |
2602 B(Add), R(2), // | 804 " x = x - 1;\n" |
2603 B(Star), R(0), // | 805 "} while (x);\n" |
2604 B(Star), R(2), // | 806 "return y;", |
2605 B(LdaSmi8), U8(3), // | 807 |
2606 B(TestEqual), R(2), // | 808 "var x = 0; var y = 1;\n" |
2607 B(JumpIfFalse), U8(4), // | 809 "do {\n" |
2608 B(Jump), U8(-39), // | 810 " y = y * 10;\n" |
2609 B(Ldar), R(0), // | 811 " if (x == 5) break;\n" |
2610 B(Star), R(2), // | 812 " x = x + 1;\n" |
2611 B(LdaSmi8), U8(4), // | 813 " if (x == 6) continue;\n" |
2612 B(TestEqual), R(2), // | 814 "} while (false);\n" |
2613 B(JumpIfFalse), U8(4), // | 815 "return y;", |
2614 B(Jump), U8(4), // | 816 |
2615 B(Jump), U8(-53), // | 817 "var x = 0; var y = 1;\n" |
2616 B(Ldar), R(1), // | 818 "do {\n" |
2617 B(Return), // | 819 " y = y * 10;\n" |
2618 }, | 820 " if (x == 5) break;\n" |
2619 0}, | 821 " x = x + 1;\n" |
2620 {"var i = 0;" | 822 " if (x == 6) continue;\n" |
2621 "while (true) {" | 823 "} while (true);\n" |
2622 " if (i < 0) continue;" | 824 "return y;", |
2623 " if (i == 3) break;" | 825 |
2624 " if (i == 4) break;" | 826 "var x = 0;\n" |
2625 " if (i == 10) continue;" | 827 "for (;;) {\n" |
2626 " if (i == 5) break;" | 828 " if (x == 1) break;\n" |
2627 " i = i + 1;" | 829 " if (x == 2) continue;\n" |
2628 "}" | 830 " x = x + 1;\n" |
2629 "return i;", | 831 "}", |
2630 2 * kPointerSize, | 832 |
2631 1, | 833 "for (var x = 0;;) {\n" |
2632 79, | 834 " if (x == 1) break;\n" |
2633 { | 835 " if (x == 2) continue;\n" |
2634 B(StackCheck), // | 836 " x = x + 1;\n" |
2635 B(LdaZero), // | 837 "}", |
2636 B(Star), R(0), // | 838 |
2637 B(StackCheck), // | 839 "var x = 0;\n" |
2638 B(Ldar), R(0), // | 840 "for (;; x = x + 1) {\n" |
2639 B(Star), R(1), // | 841 " if (x == 1) break;\n" |
2640 B(LdaZero), // | 842 " if (x == 2) continue;\n" |
2641 B(TestLessThan), R(1), // | 843 "}", |
2642 B(JumpIfFalse), U8(4), // | 844 |
2643 B(Jump), U8(-10), // | 845 "for (var x = 0;; x = x + 1) {\n" |
2644 B(Ldar), R(0), // | 846 " if (x == 1) break;\n" |
2645 B(Star), R(1), // | 847 " if (x == 2) continue;\n" |
2646 B(LdaSmi8), U8(3), // | 848 "}", |
2647 B(TestEqual), R(1), // | 849 |
2648 B(JumpIfFalse), U8(4), // | 850 "var u = 0;\n" |
2649 B(Jump), U8(50), // | 851 "for (var i = 0; i < 100; i = i + 1) {\n" |
2650 B(Ldar), R(0), // | 852 " u = u + 1;\n" |
2651 B(Star), R(1), // | 853 " continue;\n" |
2652 B(LdaSmi8), U8(4), // | 854 "}", |
2653 B(TestEqual), R(1), // | 855 |
2654 B(JumpIfFalse), U8(4), // | 856 "var y = 1;\n" |
2655 B(Jump), U8(38), // | 857 "for (var x = 10; x; --x) {\n" |
2656 B(Ldar), R(0), // | 858 " y = y * 12;\n" |
2657 B(Star), R(1), // | 859 "}\n" |
2658 B(LdaSmi8), U8(10), // | 860 "return y;", |
2659 B(TestEqual), R(1), // | 861 |
2660 B(JumpIfFalse), U8(4), // | 862 "var x = 0;\n" |
2661 B(Jump), U8(-46), // | 863 "for (var i = 0; false; i++) {\n" |
2662 B(Ldar), R(0), // | 864 " x = x + 1;\n" |
2663 B(Star), R(1), // | 865 "};\n" |
2664 B(LdaSmi8), U8(5), // | 866 "return x;", |
2665 B(TestEqual), R(1), // | 867 |
2666 B(JumpIfFalse), U8(4), // | 868 "var x = 0;\n" |
2667 B(Jump), U8(14), // | 869 "for (var i = 0; true; ++i) {\n" |
2668 B(Ldar), R(0), // | 870 " x = x + 1;\n" |
2669 B(Star), R(1), // | 871 " if (x == 20) break;\n" |
2670 B(LdaSmi8), U8(1), // | 872 "};\n" |
2671 B(Add), R(1), // | 873 "return x;", |
2672 B(Star), R(0), // | 874 |
2673 B(Jump), U8(-70), // | 875 "var a = 0;\n" |
2674 B(Ldar), R(0), // | 876 "while (a) {\n" |
2675 B(Return), // | 877 " { \n" |
2676 }, | 878 " let z = 1;\n" |
2677 0}, | 879 " function f() { z = 2; }\n" |
2678 {"var i = 0;" | 880 " if (z) continue;\n" |
2679 "while (true) {" | 881 " z++;\n" |
2680 " while (i < 3) {" | 882 " }\n" |
2681 " if (i == 2) break;" | 883 "}", |
2682 " i = i + 1;" | 884 }; |
2683 " }" | 885 |
2684 " i = i + 1;" | 886 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("BasicLoops.golden")); |
2685 " break;" | 887 } |
2686 "}" | |
2687 "return i;", | |
2688 2 * kPointerSize, | |
2689 1, | |
2690 57, | |
2691 { | |
2692 B(StackCheck), // | |
2693 B(LdaZero), // | |
2694 B(Star), R(0), // | |
2695 B(StackCheck), // | |
2696 B(Ldar), R(0), // | |
2697 B(Star), R(1), // | |
2698 B(LdaSmi8), U8(3), // | |
2699 B(TestLessThan), R(1), // | |
2700 B(JumpIfFalse), U8(27), // | |
2701 B(StackCheck), // | |
2702 B(Ldar), R(0), // | |
2703 B(Star), R(1), // | |
2704 B(LdaSmi8), U8(2), // | |
2705 B(TestEqual), R(1), // | |
2706 B(JumpIfFalse), U8(4), // | |
2707 B(Jump), U8(14), // | |
2708 B(Ldar), R(0), // | |
2709 B(Star), R(1), // | |
2710 B(LdaSmi8), U8(1), // | |
2711 B(Add), R(1), // | |
2712 B(Star), R(0), // | |
2713 B(Jump), U8(-33), // | |
2714 B(Ldar), R(0), // | |
2715 B(Star), R(1), // | |
2716 B(LdaSmi8), U8(1), // | |
2717 B(Add), R(1), // | |
2718 B(Star), R(0), // | |
2719 B(Jump), U8(4), // | |
2720 B(Jump), U8(-48), // | |
2721 B(Ldar), R(0), // | |
2722 B(Return), // | |
2723 }, | |
2724 0}, | |
2725 {"var x = 10;" | |
2726 "var y = 1;" | |
2727 "while (x) {" | |
2728 " y = y * 12;" | |
2729 " x = x - 1;" | |
2730 "}" | |
2731 "return y;", | |
2732 3 * kPointerSize, | |
2733 1, | |
2734 39, | |
2735 { | |
2736 B(StackCheck), // | |
2737 B(LdaSmi8), U8(10), // | |
2738 B(Star), R(0), // | |
2739 B(LdaSmi8), U8(1), // | |
2740 B(Star), R(1), // | |
2741 B(Ldar), R(0), // | |
2742 B(JumpIfToBooleanFalse), U8(25), // | |
2743 B(StackCheck), // | |
2744 B(Ldar), R(1), // | |
2745 B(Star), R(2), // | |
2746 B(LdaSmi8), U8(12), // | |
2747 B(Mul), R(2), // | |
2748 B(Star), R(1), // | |
2749 B(Ldar), R(0), // | |
2750 B(Star), R(2), // | |
2751 B(LdaSmi8), U8(1), // | |
2752 B(Sub), R(2), // | |
2753 B(Star), R(0), // | |
2754 B(Jump), U8(-25), // | |
2755 B(Ldar), R(1), // | |
2756 B(Return), // | |
2757 }, | |
2758 0}, | |
2759 {"var x = 0; var y = 1;" | |
2760 "do {" | |
2761 " y = y * 10;" | |
2762 " if (x == 5) break;" | |
2763 " if (x == 6) continue;" | |
2764 " x = x + 1;" | |
2765 "} while (x < 10);" | |
2766 "return y;", | |
2767 3 * kPointerSize, | |
2768 1, | |
2769 66, | |
2770 { | |
2771 B(StackCheck), // | |
2772 B(LdaZero), // | |
2773 B(Star), R(0), // | |
2774 B(LdaSmi8), U8(1), // | |
2775 B(Star), R(1), // | |
2776 B(StackCheck), // | |
2777 B(Ldar), R(1), // | |
2778 B(Star), R(2), // | |
2779 B(LdaSmi8), U8(10), // | |
2780 B(Mul), R(2), // | |
2781 B(Star), R(1), // | |
2782 B(Ldar), R(0), // | |
2783 B(Star), R(2), // | |
2784 B(LdaSmi8), U8(5), // | |
2785 B(TestEqual), R(2), // | |
2786 B(JumpIfFalse), U8(4), // | |
2787 B(Jump), U8(34), // | |
2788 B(Ldar), R(0), // | |
2789 B(Star), R(2), // | |
2790 B(LdaSmi8), U8(6), // | |
2791 B(TestEqual), R(2), // | |
2792 B(JumpIfFalse), U8(4), // | |
2793 B(Jump), U8(12), // | |
2794 B(Ldar), R(0), // | |
2795 B(Star), R(2), // | |
2796 B(LdaSmi8), U8(1), // | |
2797 B(Add), R(2), // | |
2798 B(Star), R(0), // | |
2799 B(Ldar), R(0), // | |
2800 B(Star), R(2), // | |
2801 B(LdaSmi8), U8(10), // | |
2802 B(TestLessThan), R(2), // | |
2803 B(JumpIfTrue), U8(-53), // | |
2804 B(Ldar), R(1), // | |
2805 B(Return), // | |
2806 }, | |
2807 0}, | |
2808 {"var x = 10;" | |
2809 "var y = 1;" | |
2810 "do {" | |
2811 " y = y * 12;" | |
2812 " x = x - 1;" | |
2813 "} while (x);" | |
2814 "return y;", | |
2815 3 * kPointerSize, | |
2816 1, | |
2817 37, | |
2818 { | |
2819 B(StackCheck), // | |
2820 B(LdaSmi8), U8(10), // | |
2821 B(Star), R(0), // | |
2822 B(LdaSmi8), U8(1), // | |
2823 B(Star), R(1), // | |
2824 B(StackCheck), // | |
2825 B(Ldar), R(1), // | |
2826 B(Star), R(2), // | |
2827 B(LdaSmi8), U8(12), // | |
2828 B(Mul), R(2), // | |
2829 B(Star), R(1), // | |
2830 B(Ldar), R(0), // | |
2831 B(Star), R(2), // | |
2832 B(LdaSmi8), U8(1), // | |
2833 B(Sub), R(2), // | |
2834 B(Star), R(0), // | |
2835 B(Ldar), R(0), // | |
2836 B(JumpIfToBooleanTrue), U8(-23), // | |
2837 B(Ldar), R(1), // | |
2838 B(Return), // | |
2839 }, | |
2840 0}, | |
2841 {"var x = 0; var y = 1;" | |
2842 "do {" | |
2843 " y = y * 10;" | |
2844 " if (x == 5) break;" | |
2845 " x = x + 1;" | |
2846 " if (x == 6) continue;" | |
2847 "} while (false);" | |
2848 "return y;", | |
2849 3 * kPointerSize, | |
2850 1, | |
2851 54, | |
2852 { | |
2853 B(StackCheck), // | |
2854 B(LdaZero), // | |
2855 B(Star), R(0), // | |
2856 B(LdaSmi8), U8(1), // | |
2857 B(Star), R(1), // | |
2858 B(StackCheck), // | |
2859 B(Ldar), R(1), // | |
2860 B(Star), R(2), // | |
2861 B(LdaSmi8), U8(10), // | |
2862 B(Mul), R(2), // | |
2863 B(Star), R(1), // | |
2864 B(Ldar), R(0), // | |
2865 B(Star), R(2), // | |
2866 B(LdaSmi8), U8(5), // | |
2867 B(TestEqual), R(2), // | |
2868 B(JumpIfFalse), U8(4), // | |
2869 B(Jump), U8(22), // | |
2870 B(Ldar), R(0), // | |
2871 B(Star), R(2), // | |
2872 B(LdaSmi8), U8(1), // | |
2873 B(Add), R(2), // | |
2874 B(Star), R(0), // | |
2875 B(Star), R(2), // | |
2876 B(LdaSmi8), U8(6), // | |
2877 B(TestEqual), R(2), // | |
2878 B(JumpIfFalse), U8(4), // | |
2879 B(Jump), U8(2), // | |
2880 B(Ldar), R(1), // | |
2881 B(Return), // | |
2882 }, | |
2883 0}, | |
2884 {"var x = 0; var y = 1;" | |
2885 "do {" | |
2886 " y = y * 10;" | |
2887 " if (x == 5) break;" | |
2888 " x = x + 1;" | |
2889 " if (x == 6) continue;" | |
2890 "} while (true);" | |
2891 "return y;", | |
2892 3 * kPointerSize, | |
2893 1, | |
2894 56, | |
2895 { | |
2896 B(StackCheck), // | |
2897 B(LdaZero), // | |
2898 B(Star), R(0), // | |
2899 B(LdaSmi8), U8(1), // | |
2900 B(Star), R(1), // | |
2901 B(StackCheck), // | |
2902 B(Ldar), R(1), // | |
2903 B(Star), R(2), // | |
2904 B(LdaSmi8), U8(10), // | |
2905 B(Mul), R(2), // | |
2906 B(Star), R(1), // | |
2907 B(Ldar), R(0), // | |
2908 B(Star), R(2), // | |
2909 B(LdaSmi8), U8(5), // | |
2910 B(TestEqual), R(2), // | |
2911 B(JumpIfFalse), U8(4), // | |
2912 B(Jump), U8(24), // | |
2913 B(Ldar), R(0), // | |
2914 B(Star), R(2), // | |
2915 B(LdaSmi8), U8(1), // | |
2916 B(Add), R(2), // | |
2917 B(Star), R(0), // | |
2918 B(Star), R(2), // | |
2919 B(LdaSmi8), U8(6), // | |
2920 B(TestEqual), R(2), // | |
2921 B(JumpIfFalse), U8(4), // | |
2922 B(Jump), U8(-41), // | |
2923 B(Jump), U8(-43), // | |
2924 B(Ldar), R(1), // | |
2925 B(Return), // | |
2926 }, | |
2927 0}, | |
2928 {"var x = 0; " | |
2929 "for (;;) {" | |
2930 " if (x == 1) break;" | |
2931 " if (x == 2) continue;" | |
2932 " x = x + 1;" | |
2933 "}", | |
2934 2 * kPointerSize, | |
2935 1, | |
2936 43, | |
2937 { | |
2938 B(StackCheck), // | |
2939 B(LdaZero), // | |
2940 B(Star), R(0), // | |
2941 B(StackCheck), // | |
2942 B(Ldar), R(0), // | |
2943 B(Star), R(1), // | |
2944 B(LdaSmi8), U8(1), // | |
2945 B(TestEqual), R(1), // | |
2946 B(JumpIfFalse), U8(4), // | |
2947 B(Jump), U8(26), // | |
2948 B(Ldar), R(0), // | |
2949 B(Star), R(1), // | |
2950 B(LdaSmi8), U8(2), // | |
2951 B(TestEqual), R(1), // | |
2952 B(JumpIfFalse), U8(4), // | |
2953 B(Jump), U8(-23), // | |
2954 B(Ldar), R(0), // | |
2955 B(Star), R(1), // | |
2956 B(LdaSmi8), U8(1), // | |
2957 B(Add), R(1), // | |
2958 B(Star), R(0), // | |
2959 B(Jump), U8(-35), // | |
2960 B(LdaUndefined), // | |
2961 B(Return), // | |
2962 }, | |
2963 0}, | |
2964 {"for (var x = 0;;) {" | |
2965 " if (x == 1) break;" | |
2966 " if (x == 2) continue;" | |
2967 " x = x + 1;" | |
2968 "}", | |
2969 2 * kPointerSize, | |
2970 1, | |
2971 43, | |
2972 { | |
2973 B(StackCheck), // | |
2974 B(LdaZero), // | |
2975 B(Star), R(0), // | |
2976 B(StackCheck), // | |
2977 B(Ldar), R(0), // | |
2978 B(Star), R(1), // | |
2979 B(LdaSmi8), U8(1), // | |
2980 B(TestEqual), R(1), // | |
2981 B(JumpIfFalse), U8(4), // | |
2982 B(Jump), U8(26), // | |
2983 B(Ldar), R(0), // | |
2984 B(Star), R(1), // | |
2985 B(LdaSmi8), U8(2), // | |
2986 B(TestEqual), R(1), // | |
2987 B(JumpIfFalse), U8(4), // | |
2988 B(Jump), U8(-23), // | |
2989 B(Ldar), R(0), // | |
2990 B(Star), R(1), // | |
2991 B(LdaSmi8), U8(1), // | |
2992 B(Add), R(1), // | |
2993 B(Star), R(0), // | |
2994 B(Jump), U8(-35), // | |
2995 B(LdaUndefined), // | |
2996 B(Return), // | |
2997 }, | |
2998 0}, | |
2999 {"var x = 0; " | |
3000 "for (;; x = x + 1) {" | |
3001 " if (x == 1) break;" | |
3002 " if (x == 2) continue;" | |
3003 "}", | |
3004 2 * kPointerSize, | |
3005 1, | |
3006 43, | |
3007 { | |
3008 B(StackCheck), // | |
3009 B(LdaZero), // | |
3010 B(Star), R(0), // | |
3011 B(StackCheck), // | |
3012 B(Ldar), R(0), // | |
3013 B(Star), R(1), // | |
3014 B(LdaSmi8), U8(1), // | |
3015 B(TestEqual), R(1), // | |
3016 B(JumpIfFalse), U8(4), // | |
3017 B(Jump), U8(26), // | |
3018 B(Ldar), R(0), // | |
3019 B(Star), R(1), // | |
3020 B(LdaSmi8), U8(2), // | |
3021 B(TestEqual), R(1), // | |
3022 B(JumpIfFalse), U8(4), // | |
3023 B(Jump), U8(2), // | |
3024 B(Ldar), R(0), // | |
3025 B(Star), R(1), // | |
3026 B(LdaSmi8), U8(1), // | |
3027 B(Add), R(1), // | |
3028 B(Star), R(0), // | |
3029 B(Jump), U8(-35), // | |
3030 B(LdaUndefined), // | |
3031 B(Return), // | |
3032 }, | |
3033 0}, | |
3034 {"for (var x = 0;; x = x + 1) {" | |
3035 " if (x == 1) break;" | |
3036 " if (x == 2) continue;" | |
3037 "}", | |
3038 2 * kPointerSize, | |
3039 1, | |
3040 43, | |
3041 { | |
3042 B(StackCheck), // | |
3043 B(LdaZero), // | |
3044 B(Star), R(0), // | |
3045 B(StackCheck), // | |
3046 B(Ldar), R(0), // | |
3047 B(Star), R(1), // | |
3048 B(LdaSmi8), U8(1), // | |
3049 B(TestEqual), R(1), // | |
3050 B(JumpIfFalse), U8(4), // | |
3051 B(Jump), U8(26), // | |
3052 B(Ldar), R(0), // | |
3053 B(Star), R(1), // | |
3054 B(LdaSmi8), U8(2), // | |
3055 B(TestEqual), R(1), // | |
3056 B(JumpIfFalse), U8(4), // | |
3057 B(Jump), U8(2), // | |
3058 B(Ldar), R(0), // | |
3059 B(Star), R(1), // | |
3060 B(LdaSmi8), U8(1), // | |
3061 B(Add), R(1), // | |
3062 B(Star), R(0), // | |
3063 B(Jump), U8(-35), // | |
3064 B(LdaUndefined), // | |
3065 B(Return), // | |
3066 }, | |
3067 0}, | |
3068 {"var u = 0;" | |
3069 "for (var i = 0; i < 100; i = i + 1) {" | |
3070 " u = u + 1;" | |
3071 " continue;" | |
3072 "}", | |
3073 3 * kPointerSize, | |
3074 1, | |
3075 44, | |
3076 { | |
3077 B(StackCheck), // | |
3078 B(LdaZero), // | |
3079 B(Star), R(0), // | |
3080 B(LdaZero), // | |
3081 B(Star), R(1), // | |
3082 B(Ldar), R(1), // | |
3083 B(Star), R(2), // | |
3084 B(LdaSmi8), U8(100), // | |
3085 B(TestLessThan), R(2), // | |
3086 B(JumpIfFalse), U8(27), // | |
3087 B(StackCheck), // | |
3088 B(Ldar), R(0), // | |
3089 B(Star), R(2), // | |
3090 B(LdaSmi8), U8(1), // | |
3091 B(Add), R(2), // | |
3092 B(Star), R(0), // | |
3093 B(Jump), U8(2), // | |
3094 B(Ldar), R(1), // | |
3095 B(Star), R(2), // | |
3096 B(LdaSmi8), U8(1), // | |
3097 B(Add), R(2), // | |
3098 B(Star), R(1), // | |
3099 B(Jump), U8(-33), // | |
3100 B(LdaUndefined), // | |
3101 B(Return), // | |
3102 }, | |
3103 0}, | |
3104 {"var y = 1;" | |
3105 "for (var x = 10; x; --x) {" | |
3106 " y = y * 12;" | |
3107 "}" | |
3108 "return y;", | |
3109 3 * kPointerSize, | |
3110 1, | |
3111 35, | |
3112 { | |
3113 B(StackCheck), // | |
3114 B(LdaSmi8), U8(1), // | |
3115 B(Star), R(0), // | |
3116 B(LdaSmi8), U8(10), // | |
3117 B(Star), R(1), // | |
3118 B(Ldar), R(1), // | |
3119 B(JumpIfToBooleanFalse), U8(21), // | |
3120 B(StackCheck), // | |
3121 B(Ldar), R(0), // | |
3122 B(Star), R(2), // | |
3123 B(LdaSmi8), U8(12), // | |
3124 B(Mul), R(2), // | |
3125 B(Star), R(0), // | |
3126 B(Ldar), R(1), // | |
3127 B(ToNumber), // | |
3128 B(Dec), // | |
3129 B(Star), R(1), // | |
3130 B(Jump), U8(-21), // | |
3131 B(Ldar), R(0), // | |
3132 B(Return), // | |
3133 }, | |
3134 0}, | |
3135 {"var x = 0;" | |
3136 "for (var i = 0; false; i++) {" | |
3137 " x = x + 1;" | |
3138 "};" | |
3139 "return x;", | |
3140 2 * kPointerSize, | |
3141 1, | |
3142 10, | |
3143 { | |
3144 B(StackCheck), // | |
3145 B(LdaZero), // | |
3146 B(Star), R(0), // | |
3147 B(LdaZero), // | |
3148 B(Star), R(1), // | |
3149 B(Ldar), R(0), // | |
3150 B(Return), // | |
3151 }, | |
3152 0}, | |
3153 {"var x = 0;" | |
3154 "for (var i = 0; true; ++i) {" | |
3155 " x = x + 1;" | |
3156 " if (x == 20) break;" | |
3157 "};" | |
3158 "return x;", | |
3159 3 * kPointerSize, | |
3160 1, | |
3161 39, | |
3162 { | |
3163 B(StackCheck), // | |
3164 B(LdaZero), // | |
3165 B(Star), R(0), // | |
3166 B(LdaZero), // | |
3167 B(Star), R(1), // | |
3168 B(StackCheck), // | |
3169 B(Ldar), R(0), // | |
3170 B(Star), R(2), // | |
3171 B(LdaSmi8), U8(1), // | |
3172 B(Add), R(2), // | |
3173 B(Star), R(0), // | |
3174 B(Star), R(2), // | |
3175 B(LdaSmi8), U8(20), // | |
3176 B(TestEqual), R(2), // | |
3177 B(JumpIfFalse), U8(4), // | |
3178 B(Jump), U8(10), // | |
3179 B(Ldar), R(1), // | |
3180 B(ToNumber), // | |
3181 B(Inc), // | |
3182 B(Star), R(1), // | |
3183 B(Jump), U8(-27), // | |
3184 B(Ldar), R(0), // | |
3185 B(Return), // | |
3186 }, | |
3187 0}, | |
3188 {"var a = 0;\n" | |
3189 "while (a) {\n" | |
3190 " { \n" | |
3191 " let z = 1;\n" | |
3192 " function f() { z = 2; }\n" | |
3193 " if (z) continue;\n" | |
3194 " z++;\n" | |
3195 " }\n" | |
3196 "}\n", | |
3197 7 * kPointerSize, | |
3198 1, | |
3199 118, | |
3200 { | |
3201 B(StackCheck), // | |
3202 B(LdaZero), // | |
3203 B(Star), R(1), // | |
3204 B(Ldar), R(1), // | |
3205 B(JumpIfToBooleanFalse), U8(110), // | |
3206 B(StackCheck), // | |
3207 B(LdaConstant), U8(0), // | |
3208 B(Star), R(4), // | |
3209 B(Ldar), R(closure), // | |
3210 B(Star), R(5), // | |
3211 B(CallRuntime), U16(Runtime::kPushBlockContext), R(4), U8(2), // | |
3212 B(PushContext), R(3), // | |
3213 B(LdaTheHole), // | |
3214 B(StaContextSlot), R(context), U8(4), // | |
3215 B(CreateClosure), U8(1), U8(0), // | |
3216 B(Star), R(0), // | |
3217 B(LdaSmi8), U8(1), // | |
3218 B(StaContextSlot), R(context), U8(4), // | |
3219 B(Ldar), R(0), // | |
3220 B(JumpIfNotHole), U8(11), // | |
3221 B(LdaConstant), U8(2), // | |
3222 B(Star), R(4), // | |
3223 B(CallRuntime), U16(Runtime::kThrowReferenceError), R(4), U8(1), // | |
3224 B(Star), R(2), // | |
3225 B(LdaContextSlot), R(context), U8(4), // | |
3226 B(JumpIfNotHole), U8(11), // | |
3227 B(LdaConstant), U8(3), // | |
3228 B(Star), R(4), // | |
3229 B(CallRuntime), U16(Runtime::kThrowReferenceError), R(4), U8(1), // | |
3230 B(JumpIfToBooleanFalse), U8(6), // | |
3231 B(PopContext), R(3), // | |
3232 B(Jump), U8(-67), // | |
3233 B(LdaContextSlot), R(context), U8(4), // | |
3234 B(JumpIfNotHole), U8(11), // | |
3235 B(LdaConstant), U8(3), // | |
3236 B(Star), R(4), // | |
3237 B(CallRuntime), U16(Runtime::kThrowReferenceError), R(4), U8(1), // | |
3238 B(ToNumber), // | |
3239 B(Star), R(4), // | |
3240 B(Inc), // | |
3241 B(Star), R(5), // | |
3242 B(LdaContextSlot), R(context), U8(4), // | |
3243 B(JumpIfNotHole), U8(11), // | |
3244 B(LdaConstant), U8(3), // | |
3245 B(Star), R(6), // | |
3246 B(CallRuntime), U16(Runtime::kThrowReferenceError), R(6), U8(1), // | |
3247 B(Ldar), R(5), // | |
3248 B(StaContextSlot), R(context), U8(4), // | |
3249 B(PopContext), R(3), // | |
3250 B(Jump), U8(-110), // | |
3251 B(LdaUndefined), // | |
3252 B(Return), // | |
3253 }, | |
3254 4, | |
3255 {InstanceType::FIXED_ARRAY_TYPE, InstanceType::SHARED_FUNCTION_INFO_TYPE, | |
3256 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
3257 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
3258 }; | |
3259 // clang-format on | |
3260 | |
3261 for (size_t i = 0; i < arraysize(snippets); i++) { | |
3262 Handle<BytecodeArray> bytecode_array = | |
3263 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
3264 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
3265 } | |
3266 } | |
3267 | |
3268 | 888 |
3269 TEST(JumpsRequiringConstantWideOperands) { | 889 TEST(JumpsRequiringConstantWideOperands) { |
3270 InitializedHandleScope handle_scope; | 890 InitializedIgnitionHandleScope scope; |
3271 BytecodeGeneratorHelper helper; | 891 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
3272 | 892 ConstantPoolType::kNumber); |
3273 int constant_count = 0; | 893 const char* snippets[] = { |
3274 // clang-format off | 894 REPEAT_256("var x = 0.1;\n") |
3275 ExpectedSnippet<Handle<Object>, 316> snippets[] = { | 895 REPEAT_32("var x = 0.2;\n") |
3276 { | 896 REPEAT_16("var x = 0.3;\n") |
3277 REPEAT_256(SPACE, "var x = 0.1;") | 897 REPEAT_8("var x = 0.4;\n") |
3278 REPEAT_32(SPACE, "var x = 0.2;") | 898 "for (var i = 0; i < 3; i++) {\n" |
3279 REPEAT_16(SPACE, "var x = 0.3;") | 899 " if (i == 1) continue;\n" |
3280 REPEAT_8(SPACE, "var x = 0.4;") | 900 " if (i == 2) break;\n" |
3281 "for (var i = 0; i < 3; i++) {\n" | 901 "}\n" |
3282 " if (i == 1) continue;\n" | 902 "return 3;", |
3283 " if (i == 2) break;\n" | 903 }; |
3284 "}\n" | 904 |
3285 "return 3;", | 905 CHECK_EQ(BuildActual(printer, snippets), |
3286 kPointerSize * 3, | 906 LoadGolden("JumpsRequiringConstantWideOperands.golden")); |
3287 1, | 907 } |
3288 1361, | |
3289 { | |
3290 B(StackCheck), // | |
3291 #define L(c) B(LdaConstant), U8(c), B(Star), R(0) | |
3292 REPEAT_256(COMMA, L(constant_count++)), | |
3293 #undef L | |
3294 #define LW(c) B(LdaConstantWide), U16I(c), B(Star), R(0) | |
3295 REPEAT_32(COMMA, LW(constant_count)), | |
3296 REPEAT_16(COMMA, LW(constant_count)), | |
3297 REPEAT_8(COMMA, LW(constant_count)), | |
3298 #undef LW | |
3299 B(LdaZero), // | |
3300 B(Star), R(1), // | |
3301 B(Ldar), R(1), // | |
3302 B(Star), R(2), // | |
3303 B(LdaSmi8), U8(3), // | |
3304 B(TestLessThan), R(2), // | |
3305 B(JumpIfFalseConstantWide), U16(313), // | |
3306 B(StackCheck), // | |
3307 B(Ldar), R(1), // | |
3308 B(Star), R(2), // | |
3309 B(LdaSmi8), U8(1), // | |
3310 B(TestEqual), R(2), // | |
3311 B(JumpIfFalseConstantWide), U16(312), // | |
3312 B(JumpConstantWide), U16(315), // | |
3313 B(Ldar), R(1), // | |
3314 B(Star), R(2), // | |
3315 B(LdaSmi8), U8(2), // | |
3316 B(TestEqual), R(2), // | |
3317 B(JumpIfFalseConstantWide), U16(312), // | |
3318 B(JumpConstantWide), U16(314), // | |
3319 B(Ldar), R(1), // | |
3320 B(ToNumber), // | |
3321 B(Star), R(2), // | |
3322 B(Inc), // | |
3323 B(Star), R(1), // | |
3324 B(Jump), U8(-48), // | |
3325 B(LdaSmi8), U8(3), // | |
3326 B(Return) // | |
3327 }, | |
3328 316, | |
3329 { | |
3330 #define S(x) CcTest::i_isolate()->factory()->NewNumber(x) | |
3331 REPEAT_256(COMMA, S(0.1)), | |
3332 REPEAT_32(COMMA, S(0.2)), | |
3333 REPEAT_16(COMMA, S(0.3)), | |
3334 REPEAT_8(COMMA, S(0.4)), | |
3335 #undef S | |
3336 #define N(x) CcTest::i_isolate()->factory()->NewNumberFromInt(x) | |
3337 N(6), N(42), N(13), N(17) | |
3338 #undef N | |
3339 }} | |
3340 }; | |
3341 // clang-format on | |
3342 | |
3343 for (size_t i = 0; i < arraysize(snippets); i++) { | |
3344 Handle<BytecodeArray> bytecode_array = | |
3345 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
3346 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
3347 } | |
3348 } | |
3349 | |
3350 | 908 |
3351 TEST(UnaryOperators) { | 909 TEST(UnaryOperators) { |
3352 InitializedHandleScope handle_scope; | 910 InitializedIgnitionHandleScope scope; |
3353 BytecodeGeneratorHelper helper; | 911 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
3354 | 912 ConstantPoolType::kNumber); |
3355 // clang-format off | 913 const char* snippets[] = { |
3356 ExpectedSnippet<int> snippets[] = { | 914 "var x = 0;\n" |
3357 {"var x = 0;" | 915 "while (x != 10) {\n" |
3358 "while (x != 10) {" | 916 " x = x + 10;\n" |
3359 " x = x + 10;" | 917 "}\n" |
3360 "}" | 918 "return x;", |
3361 "return x;", | 919 |
3362 2 * kPointerSize, | 920 "var x = false;\n" |
3363 1, | 921 "do {\n" |
3364 31, | 922 " x = !x;\n" |
3365 { | 923 "} while(x == false);\n" |
3366 B(StackCheck), // | 924 "return x;", |
3367 B(LdaZero), // | 925 |
3368 B(Star), R(0), // | 926 "var x = 101;\n" |
3369 B(Ldar), R(0), // | 927 "return void(x * 3);", |
3370 B(Star), R(1), // | 928 |
3371 B(LdaSmi8), U8(10), // | 929 "var x = 1234;\n" |
3372 B(TestEqual), R(1), // | 930 "var y = void (x * x - 1);\n" |
3373 B(LogicalNot), // | 931 "return y;", |
3374 B(JumpIfFalse), U8(15), // | 932 |
3375 B(StackCheck), // | 933 "var x = 13;\n" |
3376 B(Ldar), R(0), // | 934 "return ~x;", |
3377 B(Star), R(1), // | 935 |
3378 B(LdaSmi8), U8(10), // | 936 "var x = 13;\n" |
3379 B(Add), R(1), // | 937 "return +x;", |
3380 B(Star), R(0), // | 938 |
3381 B(Jump), U8(-22), // | 939 "var x = 13;\n" |
3382 B(Ldar), R(0), // | 940 "return -x;", |
3383 B(Return), // | 941 }; |
3384 }, | 942 |
3385 0}, | 943 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("UnaryOperators.golden")); |
3386 {"var x = false;" | 944 } |
3387 "do {" | |
3388 " x = !x;" | |
3389 "} while(x == false);" | |
3390 "return x;", | |
3391 2 * kPointerSize, | |
3392 1, | |
3393 22, | |
3394 { | |
3395 B(StackCheck), // | |
3396 B(LdaFalse), // | |
3397 B(Star), R(0), // | |
3398 B(StackCheck), // | |
3399 B(Ldar), R(0), // | |
3400 B(LogicalNot), // | |
3401 B(Star), R(0), // | |
3402 B(Ldar), R(0), // | |
3403 B(Star), R(1), // | |
3404 B(LdaFalse), // | |
3405 B(TestEqual), R(1), // | |
3406 B(JumpIfTrue), U8(-13), // | |
3407 B(Ldar), R(0), // | |
3408 B(Return), // | |
3409 }, | |
3410 0}, | |
3411 {"var x = 101;" | |
3412 "return void(x * 3);", | |
3413 2 * kPointerSize, | |
3414 1, | |
3415 13, | |
3416 { | |
3417 B(StackCheck), // | |
3418 B(LdaSmi8), U8(101), // | |
3419 B(Star), R(0), // | |
3420 B(Star), R(1), // | |
3421 B(LdaSmi8), U8(3), // | |
3422 B(Mul), R(1), // | |
3423 B(LdaUndefined), // | |
3424 B(Return), // | |
3425 }, | |
3426 0}, | |
3427 {"var x = 1234;" | |
3428 "var y = void (x * x - 1);" | |
3429 "return y;", | |
3430 4 * kPointerSize, | |
3431 1, | |
3432 21, | |
3433 { | |
3434 B(StackCheck), // | |
3435 B(LdaConstant), U8(0), // | |
3436 B(Star), R(0), // | |
3437 B(Star), R(2), // | |
3438 B(Ldar), R(0), // | |
3439 B(Mul), R(2), // | |
3440 B(Star), R(3), // | |
3441 B(LdaSmi8), U8(1), // | |
3442 B(Sub), R(3), // | |
3443 B(LdaUndefined), // | |
3444 B(Star), R(1), // | |
3445 B(Return), // | |
3446 }, | |
3447 1, | |
3448 {1234}}, | |
3449 {"var x = 13;" | |
3450 "return ~x;", | |
3451 2 * kPointerSize, | |
3452 1, | |
3453 12, | |
3454 { | |
3455 B(StackCheck), // | |
3456 B(LdaSmi8), U8(13), // | |
3457 B(Star), R(0), // | |
3458 B(Star), R(1), // | |
3459 B(LdaSmi8), U8(-1), // | |
3460 B(BitwiseXor), R(1), // | |
3461 B(Return), // | |
3462 }, | |
3463 0}, | |
3464 {"var x = 13;" | |
3465 "return +x;", | |
3466 2 * kPointerSize, | |
3467 1, | |
3468 12, | |
3469 { | |
3470 B(StackCheck), // | |
3471 B(LdaSmi8), U8(13), // | |
3472 B(Star), R(0), // | |
3473 B(Star), R(1), // | |
3474 B(LdaSmi8), U8(1), // | |
3475 B(Mul), R(1), // | |
3476 B(Return), // | |
3477 }, | |
3478 0}, | |
3479 {"var x = 13;" | |
3480 "return -x;", | |
3481 2 * kPointerSize, | |
3482 1, | |
3483 12, | |
3484 { | |
3485 B(StackCheck), // | |
3486 B(LdaSmi8), U8(13), // | |
3487 B(Star), R(0), // | |
3488 B(Star), R(1), // | |
3489 B(LdaSmi8), U8(-1), // | |
3490 B(Mul), R(1), // | |
3491 B(Return), // | |
3492 }, | |
3493 0} | |
3494 }; | |
3495 // clang-format on | |
3496 | |
3497 for (size_t i = 0; i < arraysize(snippets); i++) { | |
3498 Handle<BytecodeArray> bytecode_array = | |
3499 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
3500 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
3501 } | |
3502 } | |
3503 | |
3504 | 945 |
3505 TEST(Typeof) { | 946 TEST(Typeof) { |
3506 InitializedHandleScope handle_scope; | 947 InitializedIgnitionHandleScope scope; |
3507 BytecodeGeneratorHelper helper; | 948 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
3508 Zone zone; | 949 ConstantPoolType::kString); |
3509 | 950 printer.set_wrap(false); |
3510 FeedbackVectorSpec feedback_spec(&zone); | 951 printer.set_test_function_name("f"); |
3511 FeedbackVectorSlot slot = feedback_spec.AddLoadICSlot(); | 952 |
3512 | 953 const char* snippets[] = { |
3513 Handle<i::TypeFeedbackVector> vector = | 954 "function f() {\n" |
3514 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); | 955 " var x = 13;\n" |
3515 | 956 " return typeof(x);\n" |
3516 // clang-format off | 957 "};", |
3517 ExpectedSnippet<const char*> snippets[] = { | 958 |
3518 {"function f() {\n" | 959 "var x = 13;\n" |
3519 " var x = 13;\n" | 960 "function f() {\n" |
3520 " return typeof(x);\n" | 961 " return typeof(x);\n" |
3521 "}; f();", | 962 "};", |
3522 kPointerSize, | 963 }; |
3523 1, | 964 |
3524 7, | 965 CHECK_EQ(BuildActual(printer, snippets, "", "\nf();"), |
3525 { | 966 LoadGolden("Typeof.golden")); |
3526 B(StackCheck), // | 967 } |
3527 B(LdaSmi8), U8(13), // | |
3528 B(Star), R(0), // | |
3529 B(TypeOf), // | |
3530 B(Return), // | |
3531 }}, | |
3532 {"var x = 13;\n" | |
3533 "function f() {\n" | |
3534 " return typeof(x);\n" | |
3535 "}; f();", | |
3536 0, | |
3537 1, | |
3538 6, | |
3539 { | |
3540 B(StackCheck), // | |
3541 B(LdaGlobalInsideTypeof), U8(0), U8(vector->GetIndex(slot)), // | |
3542 B(TypeOf), // | |
3543 B(Return), // | |
3544 }, | |
3545 1, | |
3546 {"x"}}, | |
3547 }; | |
3548 // clang-format on | |
3549 | |
3550 for (size_t i = 0; i < arraysize(snippets); i++) { | |
3551 Handle<BytecodeArray> bytecode_array = | |
3552 helper.MakeBytecodeForFunction(snippets[i].code_snippet); | |
3553 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
3554 } | |
3555 } | |
3556 | |
3557 | 968 |
3558 TEST(Delete) { | 969 TEST(Delete) { |
3559 InitializedHandleScope handle_scope; | 970 InitializedIgnitionHandleScope scope; |
3560 BytecodeGeneratorHelper helper; | 971 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
3561 | 972 ConstantPoolType::kMixed); |
3562 int deep_elements_flags = | 973 |
3563 ObjectLiteral::kFastElements | ObjectLiteral::kDisableMementos; | 974 const char* snippets[] = { |
3564 int closure = Register::function_closure().index(); | 975 "var a = {x:13, y:14}; return delete a.x;", |
3565 int context = Register::current_context().index(); | 976 |
3566 int first_context_slot = Context::MIN_CONTEXT_SLOTS; | 977 "'use strict'; var a = {x:13, y:14}; return delete a.x;", |
3567 | 978 |
3568 // clang-format off | 979 "var a = {1:13, 2:14}; return delete a[2];", |
3569 ExpectedSnippet<InstanceType> snippets[] = { | 980 |
3570 {"var a = {x:13, y:14}; return delete a.x;", | 981 "var a = 10; return delete a;", |
3571 2 * kPointerSize, | 982 |
3572 1, | 983 "'use strict';\n" |
3573 16, | 984 "var a = {1:10};\n" |
3574 { | 985 "(function f1() {return a;});\n" |
3575 B(StackCheck), // | 986 "return delete a[1];", |
3576 B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags), // | 987 |
3577 B(Star), R(1), // | 988 "return delete 'test';", |
3578 B(Star), R(0), // | 989 }; |
3579 B(Star), R(1), // | 990 |
3580 B(LdaConstant), U8(1), // | 991 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("Delete.golden")); |
3581 B(DeletePropertySloppy), R(1), // | 992 } |
3582 B(Return)}, | |
3583 2, | |
3584 {InstanceType::FIXED_ARRAY_TYPE, | |
3585 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
3586 {"'use strict'; var a = {x:13, y:14}; return delete a.x;", | |
3587 2 * kPointerSize, | |
3588 1, | |
3589 16, | |
3590 {B(StackCheck), // | |
3591 B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags), // | |
3592 B(Star), R(1), // | |
3593 B(Star), R(0), // | |
3594 B(Star), R(1), // | |
3595 B(LdaConstant), U8(1), // | |
3596 B(DeletePropertyStrict), R(1), // | |
3597 B(Return)}, | |
3598 2, | |
3599 {InstanceType::FIXED_ARRAY_TYPE, | |
3600 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
3601 {"var a = {1:13, 2:14}; return delete a[2];", | |
3602 2 * kPointerSize, | |
3603 1, | |
3604 16, | |
3605 {B(StackCheck), // | |
3606 B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags), // | |
3607 B(Star), R(1), // | |
3608 B(Star), R(0), // | |
3609 B(Star), R(1), // | |
3610 B(LdaSmi8), U8(2), // | |
3611 B(DeletePropertySloppy), R(1), // | |
3612 B(Return)}, | |
3613 1, | |
3614 {InstanceType::FIXED_ARRAY_TYPE}}, | |
3615 {"var a = 10; return delete a;", | |
3616 1 * kPointerSize, | |
3617 1, | |
3618 7, | |
3619 {B(StackCheck), // | |
3620 B(LdaSmi8), U8(10), // | |
3621 B(Star), R(0), // | |
3622 B(LdaFalse), // | |
3623 B(Return)}, | |
3624 0}, | |
3625 {"'use strict';" | |
3626 "var a = {1:10};" | |
3627 "(function f1() {return a;});" | |
3628 "return delete a[1];", | |
3629 2 * kPointerSize, | |
3630 1, | |
3631 30, | |
3632 {B(CallRuntime), U16(Runtime::kNewFunctionContext), // | |
3633 /* */ R(closure), U8(1), // | |
3634 B(PushContext), R(0), // | |
3635 B(StackCheck), // | |
3636 B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags), // | |
3637 B(Star), R(1), // | |
3638 B(StaContextSlot), R(context), U8(first_context_slot), // | |
3639 B(CreateClosure), U8(1), U8(0), // | |
3640 B(LdaContextSlot), R(context), U8(first_context_slot), // | |
3641 B(Star), R(1), // | |
3642 B(LdaSmi8), U8(1), // | |
3643 B(DeletePropertyStrict), R(1), // | |
3644 B(Return)}, | |
3645 2, | |
3646 {InstanceType::FIXED_ARRAY_TYPE, | |
3647 InstanceType::SHARED_FUNCTION_INFO_TYPE}}, | |
3648 {"return delete 'test';", | |
3649 0 * kPointerSize, | |
3650 1, | |
3651 3, | |
3652 {B(StackCheck), // | |
3653 B(LdaTrue), // | |
3654 B(Return)}, | |
3655 0}, | |
3656 }; | |
3657 // clang-format on | |
3658 | |
3659 for (size_t i = 0; i < arraysize(snippets); i++) { | |
3660 Handle<BytecodeArray> bytecode_array = | |
3661 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
3662 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
3663 } | |
3664 } | |
3665 | |
3666 | 993 |
3667 TEST(GlobalDelete) { | 994 TEST(GlobalDelete) { |
3668 InitializedHandleScope handle_scope; | 995 InitializedIgnitionHandleScope scope; |
3669 BytecodeGeneratorHelper helper; | 996 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
3670 Zone zone; | 997 ConstantPoolType::kMixed); |
3671 | 998 printer.set_wrap(false); |
3672 int context = Register::current_context().index(); | 999 printer.set_test_function_name("f"); |
3673 int native_context_index = Context::NATIVE_CONTEXT_INDEX; | 1000 |
3674 int global_context_index = Context::EXTENSION_INDEX; | 1001 const char* snippets[] = { |
3675 FeedbackVectorSpec feedback_spec(&zone); | 1002 "var a = {x:13, y:14};\n" |
3676 FeedbackVectorSlot slot = feedback_spec.AddLoadICSlot(); | 1003 "function f() {\n" |
3677 | 1004 " return delete a.x;\n" |
3678 Handle<i::TypeFeedbackVector> vector = | 1005 "};\n" |
3679 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); | 1006 "f();", |
3680 | 1007 |
3681 // clang-format off | 1008 "a = {1:13, 2:14};\n" |
3682 ExpectedSnippet<InstanceType> snippets[] = { | 1009 "function f() {\n" |
3683 {"var a = {x:13, y:14};\n function f() { return delete a.x; };\n f();", | 1010 " 'use strict';\n" |
3684 1 * kPointerSize, | 1011 " return delete a[1];\n" |
3685 1, | 1012 "};\n" |
3686 11, | 1013 "f();", |
3687 {B(StackCheck), // | 1014 |
3688 B(LdaGlobal), U8(0), U8(vector->GetIndex(slot)), // | 1015 "var a = {x:13, y:14};\n" |
3689 B(Star), R(0), // | 1016 "function f() {\n" |
3690 B(LdaConstant), U8(1), // | 1017 " return delete a;\n" |
3691 B(DeletePropertySloppy), R(0), // | 1018 "};\n" |
3692 B(Return)}, | 1019 "f();", |
3693 2, | 1020 |
3694 {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | 1021 "b = 30;\n" |
3695 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | 1022 "function f() {\n" |
3696 {"a = {1:13, 2:14};\n" | 1023 " return delete b;\n" |
3697 "function f() {'use strict'; return delete a[1];};\n f();", | 1024 "};\n" |
3698 1 * kPointerSize, | 1025 "f();", |
3699 1, | 1026 }; |
3700 11, | 1027 |
3701 {B(StackCheck), // | 1028 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("GlobalDelete.golden")); |
3702 B(LdaGlobal), U8(0), U8(vector->GetIndex(slot)), // | 1029 } |
3703 B(Star), R(0), // | |
3704 B(LdaSmi8), U8(1), // | |
3705 B(DeletePropertyStrict), R(0), // | |
3706 B(Return)}, | |
3707 1, | |
3708 {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
3709 {"var a = {x:13, y:14};\n function f() { return delete a; };\n f();", | |
3710 2 * kPointerSize, | |
3711 1, | |
3712 16, | |
3713 {B(StackCheck), // | |
3714 B(LdaContextSlot), R(context), U8(native_context_index), // | |
3715 B(Star), R(0), // | |
3716 B(LdaContextSlot), R(0), U8(global_context_index), // | |
3717 B(Star), R(1), // | |
3718 B(LdaConstant), U8(0), // | |
3719 B(DeletePropertySloppy), R(1), // | |
3720 B(Return)}, | |
3721 1, | |
3722 {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
3723 {"b = 30;\n function f() { return delete b; };\n f();", | |
3724 2 * kPointerSize, | |
3725 1, | |
3726 16, | |
3727 {B(StackCheck), // | |
3728 B(LdaContextSlot), R(context), U8(native_context_index), // | |
3729 B(Star), R(0), // | |
3730 B(LdaContextSlot), R(0), U8(global_context_index), // | |
3731 B(Star), R(1), // | |
3732 B(LdaConstant), U8(0), // | |
3733 B(DeletePropertySloppy), R(1), // | |
3734 B(Return)}, | |
3735 1, | |
3736 {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}} | |
3737 }; | |
3738 // clang-format on | |
3739 | |
3740 for (size_t i = 0; i < arraysize(snippets); i++) { | |
3741 Handle<BytecodeArray> bytecode_array = | |
3742 helper.MakeBytecode(snippets[i].code_snippet, "f"); | |
3743 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
3744 } | |
3745 } | |
3746 | |
3747 | 1030 |
3748 TEST(FunctionLiterals) { | 1031 TEST(FunctionLiterals) { |
3749 InitializedHandleScope handle_scope; | 1032 InitializedIgnitionHandleScope scope; |
3750 BytecodeGeneratorHelper helper; | 1033 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
3751 Zone zone; | 1034 ConstantPoolType::kMixed); |
3752 | 1035 |
3753 FeedbackVectorSpec feedback_spec(&zone); | 1036 const char* snippets[] = { |
3754 FeedbackVectorSlot slot = feedback_spec.AddCallICSlot(); | 1037 "return function(){ }", |
3755 | 1038 |
3756 Handle<i::TypeFeedbackVector> vector = | 1039 "return (function(){ })()", |
3757 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); | 1040 |
3758 | 1041 "return (function(x){ return x; })(1)", |
3759 // clang-format off | 1042 }; |
3760 ExpectedSnippet<InstanceType> snippets[] = { | 1043 |
3761 {"return function(){ }", | 1044 CHECK_EQ(BuildActual(printer, snippets), |
3762 0, | 1045 LoadGolden("FunctionLiterals.golden")); |
3763 1, | 1046 } |
3764 5, | |
3765 { | |
3766 B(StackCheck), // | |
3767 B(CreateClosure), U8(0), U8(0), // | |
3768 B(Return) // | |
3769 }, | |
3770 1, | |
3771 {InstanceType::SHARED_FUNCTION_INFO_TYPE}}, | |
3772 {"return (function(){ })()", | |
3773 2 * kPointerSize, | |
3774 1, | |
3775 15, | |
3776 { | |
3777 B(StackCheck), // | |
3778 B(LdaUndefined), // | |
3779 B(Star), R(1), // | |
3780 B(CreateClosure), U8(0), U8(0), // | |
3781 B(Star), R(0), // | |
3782 B(Call), R(0), R(1), U8(1), U8(vector->GetIndex(slot)), // | |
3783 B(Return) // | |
3784 }, | |
3785 1, | |
3786 {InstanceType::SHARED_FUNCTION_INFO_TYPE}}, | |
3787 {"return (function(x){ return x; })(1)", | |
3788 3 * kPointerSize, | |
3789 1, | |
3790 19, | |
3791 { | |
3792 B(StackCheck), // | |
3793 B(LdaUndefined), // | |
3794 B(Star), R(1), // | |
3795 B(CreateClosure), U8(0), U8(0), // | |
3796 B(Star), R(0), // | |
3797 B(LdaSmi8), U8(1), // | |
3798 B(Star), R(2), // | |
3799 B(Call), R(0), R(1), U8(2), U8(vector->GetIndex(slot)), // | |
3800 B(Return) // | |
3801 }, | |
3802 1, | |
3803 {InstanceType::SHARED_FUNCTION_INFO_TYPE}}, | |
3804 }; | |
3805 // clang-format on | |
3806 | |
3807 for (size_t i = 0; i < arraysize(snippets); i++) { | |
3808 Handle<BytecodeArray> bytecode_array = | |
3809 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
3810 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
3811 } | |
3812 } | |
3813 | |
3814 | 1047 |
3815 TEST(RegExpLiterals) { | 1048 TEST(RegExpLiterals) { |
3816 InitializedHandleScope handle_scope; | 1049 InitializedIgnitionHandleScope scope; |
3817 BytecodeGeneratorHelper helper; | 1050 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
3818 Zone zone; | 1051 ConstantPoolType::kString); |
3819 | 1052 |
3820 FeedbackVectorSpec feedback_spec(&zone); | 1053 const char* snippets[] = { |
3821 FeedbackVectorSlot slot1 = feedback_spec.AddCallICSlot(); | 1054 "return /ab+d/;", |
3822 FeedbackVectorSlot slot2 = feedback_spec.AddLoadICSlot(); | 1055 |
3823 uint8_t i_flags = JSRegExp::kIgnoreCase; | 1056 "return /(\\w+)\\s(\\w+)/i;", |
3824 | 1057 |
3825 Handle<i::TypeFeedbackVector> vector = | 1058 "return /ab+d/.exec('abdd');", |
3826 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); | 1059 }; |
3827 | 1060 |
3828 // clang-format off | 1061 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("RegExpLiterals.golden")); |
3829 ExpectedSnippet<const char*> snippets[] = { | 1062 } |
3830 {"return /ab+d/;", | |
3831 0 * kPointerSize, | |
3832 1, | |
3833 6, | |
3834 { | |
3835 B(StackCheck), // | |
3836 B(CreateRegExpLiteral), U8(0), U8(0), U8(0), // | |
3837 B(Return), // | |
3838 }, | |
3839 1, | |
3840 {"ab+d"}}, | |
3841 {"return /(\\w+)\\s(\\w+)/i;", | |
3842 0 * kPointerSize, | |
3843 1, | |
3844 6, | |
3845 { | |
3846 B(StackCheck), // | |
3847 B(CreateRegExpLiteral), U8(0), U8(0), U8(i_flags), // | |
3848 B(Return), // | |
3849 }, | |
3850 1, | |
3851 {"(\\w+)\\s(\\w+)"}}, | |
3852 {"return /ab+d/.exec('abdd');", | |
3853 3 * kPointerSize, | |
3854 1, | |
3855 23, | |
3856 { | |
3857 B(StackCheck), // | |
3858 B(CreateRegExpLiteral), U8(0), U8(0), U8(0), // | |
3859 B(Star), R(1), // | |
3860 B(LoadIC), R(1), U8(1), U8(vector->GetIndex(slot2)), // | |
3861 B(Star), R(0), // | |
3862 B(LdaConstant), U8(2), // | |
3863 B(Star), R(2), // | |
3864 B(Call), R(0), R(1), U8(2), U8(vector->GetIndex(slot1)), // | |
3865 B(Return), // | |
3866 }, | |
3867 3, | |
3868 {"ab+d", "exec", "abdd"}}, | |
3869 }; | |
3870 // clang-format on | |
3871 | |
3872 for (size_t i = 0; i < arraysize(snippets); i++) { | |
3873 Handle<BytecodeArray> bytecode_array = | |
3874 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
3875 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
3876 } | |
3877 } | |
3878 | |
3879 | 1063 |
3880 TEST(RegExpLiteralsWide) { | 1064 TEST(RegExpLiteralsWide) { |
3881 InitializedHandleScope handle_scope; | 1065 InitializedIgnitionHandleScope scope; |
3882 BytecodeGeneratorHelper helper; | 1066 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
3883 Zone zone; | 1067 ConstantPoolType::kMixed); |
3884 | 1068 |
3885 int wide_idx = 0; | 1069 const char* snippets[] = { |
3886 | 1070 "var a;" // |
3887 // clang-format off | 1071 REPEAT_256("\na = 1.23;") // |
3888 ExpectedSnippet<InstanceType, 257> snippets[] = { | 1072 "\nreturn /ab+d/;", |
3889 {"var a;" REPEAT_256(SPACE, "a = 1.23;") "return /ab+d/;", | 1073 }; |
3890 1 * kPointerSize, | 1074 |
3891 1, | 1075 CHECK_EQ(BuildActual(printer, snippets), |
3892 1032, | 1076 LoadGolden("RegExpLiteralsWide.golden")); |
3893 { | 1077 } |
3894 B(StackCheck), // | |
3895 REPEAT_256(COMMA, // | |
3896 B(LdaConstant), U8(wide_idx++), // | |
3897 B(Star), R(0)), // | |
3898 B(CreateRegExpLiteralWide), U16(256), U16(0), U8(0), // | |
3899 B(Return) // | |
3900 }, | |
3901 257, | |
3902 {REPEAT_256(COMMA, InstanceType::HEAP_NUMBER_TYPE), | |
3903 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
3904 }; | |
3905 // clang-format on | |
3906 | |
3907 for (size_t i = 0; i < arraysize(snippets); i++) { | |
3908 Handle<BytecodeArray> bytecode_array = | |
3909 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
3910 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
3911 } | |
3912 } | |
3913 | |
3914 | 1078 |
3915 TEST(ArrayLiterals) { | 1079 TEST(ArrayLiterals) { |
3916 InitializedHandleScope handle_scope; | 1080 InitializedIgnitionHandleScope scope; |
3917 BytecodeGeneratorHelper helper; | 1081 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
3918 Zone zone; | 1082 ConstantPoolType::kMixed); |
3919 | 1083 |
3920 FeedbackVectorSpec feedback_spec(&zone); | 1084 const char* snippets[] = { |
3921 FeedbackVectorSlot slot1 = feedback_spec.AddKeyedStoreICSlot(); | 1085 "return [ 1, 2 ];", |
3922 FeedbackVectorSlot slot2 = feedback_spec.AddKeyedStoreICSlot(); | 1086 |
3923 FeedbackVectorSlot slot3 = feedback_spec.AddKeyedStoreICSlot(); | 1087 "var a = 1; return [ a, a + 1 ];", |
3924 | 1088 |
3925 Handle<i::TypeFeedbackVector> vector = | 1089 "return [ [ 1, 2 ], [ 3 ] ];", |
3926 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); | 1090 |
3927 | 1091 "var a = 1; return [ [ a, 2 ], [ a + 2 ] ];", |
3928 int simple_flags = | 1092 }; |
3929 ArrayLiteral::kDisableMementos | ArrayLiteral::kShallowElements; | 1093 |
3930 int deep_elements_flags = ArrayLiteral::kDisableMementos; | 1094 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("ArrayLiterals.golden")); |
3931 // clang-format off | 1095 } |
3932 ExpectedSnippet<InstanceType> snippets[] = { | |
3933 {"return [ 1, 2 ];", | |
3934 0, | |
3935 1, | |
3936 6, | |
3937 { | |
3938 B(StackCheck), // | |
3939 B(CreateArrayLiteral), U8(0), U8(0), U8(simple_flags), // | |
3940 B(Return) // | |
3941 }, | |
3942 1, | |
3943 {InstanceType::FIXED_ARRAY_TYPE}}, | |
3944 {"var a = 1; return [ a, a + 1 ];", | |
3945 4 * kPointerSize, | |
3946 1, | |
3947 39, | |
3948 { | |
3949 B(StackCheck), // | |
3950 B(LdaSmi8), U8(1), // | |
3951 B(Star), R(0), // | |
3952 B(CreateArrayLiteral), U8(0), U8(0), U8(3), // | |
3953 B(Star), R(2), // | |
3954 B(LdaZero), // | |
3955 B(Star), R(1), // | |
3956 B(Ldar), R(0), // | |
3957 B(KeyedStoreICSloppy), R(2), R(1), U8(vector->GetIndex(slot1)), // | |
3958 B(LdaSmi8), U8(1), // | |
3959 B(Star), R(1), // | |
3960 B(Ldar), R(0), // | |
3961 B(Star), R(3), // | |
3962 B(LdaSmi8), U8(1), // | |
3963 B(Add), R(3), // | |
3964 B(KeyedStoreICSloppy), R(2), R(1), U8(vector->GetIndex(slot1)), // | |
3965 B(Ldar), R(2), // | |
3966 B(Return), // | |
3967 }, | |
3968 1, | |
3969 {InstanceType::FIXED_ARRAY_TYPE}}, | |
3970 {"return [ [ 1, 2 ], [ 3 ] ];", | |
3971 0, | |
3972 1, | |
3973 6, | |
3974 { | |
3975 B(StackCheck), // | |
3976 B(CreateArrayLiteral), U8(0), U8(2), U8(deep_elements_flags), // | |
3977 B(Return) // | |
3978 }, | |
3979 1, | |
3980 {InstanceType::FIXED_ARRAY_TYPE}}, | |
3981 {"var a = 1; return [ [ a, 2 ], [ a + 2 ] ];", | |
3982 6 * kPointerSize, | |
3983 1, | |
3984 69, | |
3985 { | |
3986 B(StackCheck), // | |
3987 B(LdaSmi8), U8(1), // | |
3988 B(Star), R(0), // | |
3989 B(CreateArrayLiteral), U8(0), U8(2), U8(deep_elements_flags), // | |
3990 B(Star), R(2), // | |
3991 B(LdaZero), // | |
3992 B(Star), R(1), // | |
3993 B(CreateArrayLiteral), U8(1), U8(0), U8(simple_flags), // | |
3994 B(Star), R(4), // | |
3995 B(LdaZero), // | |
3996 B(Star), R(3), // | |
3997 B(Ldar), R(0), // | |
3998 B(KeyedStoreICSloppy), R(4), R(3), U8(vector->GetIndex(slot1)), // | |
3999 B(Ldar), R(4), // | |
4000 B(KeyedStoreICSloppy), R(2), R(1), U8(vector->GetIndex(slot3)), // | |
4001 B(LdaSmi8), U8(1), // | |
4002 B(Star), R(1), // | |
4003 B(CreateArrayLiteral), U8(2), U8(1), U8(simple_flags), // | |
4004 B(Star), R(4), // | |
4005 B(LdaZero), // | |
4006 B(Star), R(3), // | |
4007 B(Ldar), R(0), // | |
4008 B(Star), R(5), // | |
4009 B(LdaSmi8), U8(2), // | |
4010 B(Add), R(5), // | |
4011 B(KeyedStoreICSloppy), R(4), R(3), U8(vector->GetIndex(slot2)), // | |
4012 B(Ldar), R(4), // | |
4013 B(KeyedStoreICSloppy), R(2), R(1), U8(vector->GetIndex(slot3)), // | |
4014 B(Ldar), R(2), // | |
4015 B(Return), // | |
4016 }, | |
4017 3, | |
4018 {InstanceType::FIXED_ARRAY_TYPE, InstanceType::FIXED_ARRAY_TYPE, | |
4019 InstanceType::FIXED_ARRAY_TYPE}}, | |
4020 }; | |
4021 // clang-format on | |
4022 | |
4023 for (size_t i = 0; i < arraysize(snippets); i++) { | |
4024 Handle<BytecodeArray> bytecode_array = | |
4025 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
4026 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
4027 } | |
4028 } | |
4029 | |
4030 | 1096 |
4031 TEST(ArrayLiteralsWide) { | 1097 TEST(ArrayLiteralsWide) { |
4032 InitializedHandleScope handle_scope; | 1098 InitializedIgnitionHandleScope scope; |
4033 BytecodeGeneratorHelper helper; | 1099 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
4034 Zone zone; | 1100 ConstantPoolType::kMixed); |
4035 | 1101 |
4036 int wide_idx = 0; | 1102 const char* snippets[] = { |
4037 int simple_flags = | 1103 "var a;" // |
4038 ArrayLiteral::kDisableMementos | ArrayLiteral::kShallowElements; | 1104 REPEAT_256("\na = 1.23;") // |
4039 | 1105 "\nreturn [ 1 , 2 ];", |
4040 // clang-format off | 1106 }; |
4041 ExpectedSnippet<InstanceType, 257> snippets[] = { | 1107 |
4042 {"var a;" REPEAT_256(SPACE, "a = 1.23;") "return [ 1 , 2 ];", | 1108 CHECK_EQ(BuildActual(printer, snippets), |
4043 1 * kPointerSize, | 1109 LoadGolden("ArrayLiteralsWide.golden")); |
4044 1, | 1110 } |
4045 1032, | |
4046 { | |
4047 B(StackCheck), // | |
4048 REPEAT_256(COMMA, // | |
4049 B(LdaConstant), U8(wide_idx++), // | |
4050 B(Star), R(0)), // | |
4051 B(CreateArrayLiteralWide), U16(256), U16(0), U8(simple_flags), // | |
4052 B(Return) // | |
4053 }, | |
4054 257, | |
4055 {REPEAT_256(COMMA, InstanceType::HEAP_NUMBER_TYPE), | |
4056 InstanceType::FIXED_ARRAY_TYPE}}, | |
4057 }; | |
4058 // clang-format on | |
4059 | |
4060 for (size_t i = 0; i < arraysize(snippets); i++) { | |
4061 Handle<BytecodeArray> bytecode_array = | |
4062 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
4063 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
4064 } | |
4065 } | |
4066 | |
4067 | 1111 |
4068 TEST(ObjectLiterals) { | 1112 TEST(ObjectLiterals) { |
4069 InitializedHandleScope handle_scope; | 1113 InitializedIgnitionHandleScope scope; |
4070 BytecodeGeneratorHelper helper; | 1114 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
4071 Zone zone; | 1115 ConstantPoolType::kMixed); |
4072 | 1116 |
4073 FeedbackVectorSpec feedback_spec(&zone); | 1117 const char* snippets[] = { |
4074 FeedbackVectorSlot slot1 = feedback_spec.AddStoreICSlot(); | 1118 "return { };", |
4075 | 1119 |
4076 Handle<i::TypeFeedbackVector> vector = | 1120 "return { name: 'string', val: 9.2 };", |
4077 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); | 1121 |
4078 | 1122 "var a = 1; return { name: 'string', val: a };", |
4079 int simple_flags = ObjectLiteral::kFastElements | | 1123 |
4080 ObjectLiteral::kShallowProperties | | 1124 "var a = 1; return { val: a, val: a + 1 };", |
4081 ObjectLiteral::kDisableMementos; | 1125 |
4082 int deep_elements_flags = | 1126 "return { func: function() { } };", |
4083 ObjectLiteral::kFastElements | ObjectLiteral::kDisableMementos; | 1127 |
4084 | 1128 "return { func(a) { return a; } };", |
4085 // clang-format off | 1129 |
4086 ExpectedSnippet<InstanceType> snippets[] = { | 1130 "return { get a() { return 2; } };", |
4087 {"return { };", | 1131 |
4088 kPointerSize, | 1132 "return { get a() { return this.x; }, set a(val) { this.x = val } };", |
4089 1, | 1133 |
4090 8, | 1134 "return { set b(val) { this.y = val } };", |
4091 { | 1135 |
4092 B(StackCheck), // | 1136 "var a = 1; return { 1: a };", |
4093 B(CreateObjectLiteral), U8(0), U8(0), U8(simple_flags), // | 1137 |
4094 B(Star), R(0), // | 1138 "return { __proto__: null };", |
4095 B(Return) // | 1139 |
4096 }, | 1140 "var a = 'test'; return { [a]: 1 };", |
4097 1, | 1141 |
4098 {InstanceType::FIXED_ARRAY_TYPE}}, | 1142 "var a = 'test'; return { val: a, [a]: 1 };", |
4099 {"return { name: 'string', val: 9.2 };", | 1143 |
4100 kPointerSize, | 1144 "var a = 'test'; return { [a]: 1, __proto__: {} };", |
4101 1, | 1145 |
4102 8, | 1146 "var n = 'name'; return { [n]: 'val', get a() { }, set a(b) {} };", |
4103 { | 1147 }; |
4104 B(StackCheck), // | 1148 |
4105 B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags), // | 1149 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("ObjectLiterals.golden")); |
4106 B(Star), R(0), // | 1150 } |
4107 B(Return) // | |
4108 }, | |
4109 1, | |
4110 {InstanceType::FIXED_ARRAY_TYPE}}, | |
4111 {"var a = 1; return { name: 'string', val: a };", | |
4112 2 * kPointerSize, | |
4113 1, | |
4114 20, | |
4115 { | |
4116 B(StackCheck), // | |
4117 B(LdaSmi8), U8(1), // | |
4118 B(Star), R(0), // | |
4119 B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags), // | |
4120 B(Star), R(1), // | |
4121 B(Ldar), R(0), // | |
4122 B(StoreICSloppy), R(1), U8(1), U8(vector->GetIndex(slot1)), // | |
4123 B(Ldar), R(1), // | |
4124 B(Return), // | |
4125 }, | |
4126 2, | |
4127 {InstanceType::FIXED_ARRAY_TYPE, | |
4128 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
4129 {"var a = 1; return { val: a, val: a + 1 };", | |
4130 3 * kPointerSize, | |
4131 1, | |
4132 26, | |
4133 { | |
4134 B(StackCheck), // | |
4135 B(LdaSmi8), U8(1), // | |
4136 B(Star), R(0), // | |
4137 B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags), // | |
4138 B(Star), R(1), // | |
4139 B(Ldar), R(0), // | |
4140 B(Star), R(2), // | |
4141 B(LdaSmi8), U8(1), // | |
4142 B(Add), R(2), // | |
4143 B(StoreICSloppy), R(1), U8(1), U8(vector->GetIndex(slot1)), // | |
4144 B(Ldar), R(1), // | |
4145 B(Return), // | |
4146 }, | |
4147 2, | |
4148 {InstanceType::FIXED_ARRAY_TYPE, | |
4149 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
4150 {"return { func: function() { } };", | |
4151 1 * kPointerSize, | |
4152 1, | |
4153 17, | |
4154 { | |
4155 B(StackCheck), // | |
4156 B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags), // | |
4157 B(Star), R(0), // | |
4158 B(CreateClosure), U8(1), U8(0), // | |
4159 B(StoreICSloppy), R(0), U8(2), U8(vector->GetIndex(slot1)), // | |
4160 B(Ldar), R(0), // | |
4161 B(Return), // | |
4162 }, | |
4163 3, | |
4164 {InstanceType::FIXED_ARRAY_TYPE, InstanceType::SHARED_FUNCTION_INFO_TYPE, | |
4165 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
4166 {"return { func(a) { return a; } };", | |
4167 1 * kPointerSize, | |
4168 1, | |
4169 17, | |
4170 { | |
4171 B(StackCheck), // | |
4172 B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags), // | |
4173 B(Star), R(0), // | |
4174 B(CreateClosure), U8(1), U8(0), // | |
4175 B(StoreICSloppy), R(0), U8(2), U8(vector->GetIndex(slot1)), // | |
4176 B(Ldar), R(0), // | |
4177 B(Return), // | |
4178 }, | |
4179 3, | |
4180 {InstanceType::FIXED_ARRAY_TYPE, InstanceType::SHARED_FUNCTION_INFO_TYPE, | |
4181 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
4182 {"return { get a() { return 2; } };", | |
4183 6 * kPointerSize, | |
4184 1, | |
4185 33, | |
4186 { | |
4187 B(StackCheck), // | |
4188 B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags), // | |
4189 B(Star), R(0), // | |
4190 B(Mov), R(0), R(1), // | |
4191 B(LdaConstant), U8(1), // | |
4192 B(Star), R(2), // | |
4193 B(CreateClosure), U8(2), U8(0), // | |
4194 B(Star), R(3), // | |
4195 B(LdaNull), // | |
4196 B(Star), R(4), // | |
4197 B(LdaZero), // | |
4198 B(Star), R(5), // | |
4199 B(CallRuntime), U16(Runtime::kDefineAccessorPropertyUnchecked), // | |
4200 /* */ R(1), U8(5), // | |
4201 B(Ldar), R(0), // | |
4202 B(Return), // | |
4203 }, | |
4204 3, | |
4205 {InstanceType::FIXED_ARRAY_TYPE, | |
4206 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
4207 InstanceType::SHARED_FUNCTION_INFO_TYPE}}, | |
4208 {"return { get a() { return this.x; }, set a(val) { this.x = val } };", | |
4209 6 * kPointerSize, | |
4210 1, | |
4211 35, | |
4212 { | |
4213 B(StackCheck), // | |
4214 B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags), // | |
4215 B(Star), R(0), // | |
4216 B(Mov), R(0), R(1), // | |
4217 B(LdaConstant), U8(1), // | |
4218 B(Star), R(2), // | |
4219 B(CreateClosure), U8(2), U8(0), // | |
4220 B(Star), R(3), // | |
4221 B(CreateClosure), U8(3), U8(0), // | |
4222 B(Star), R(4), // | |
4223 B(LdaZero), // | |
4224 B(Star), R(5), // | |
4225 B(CallRuntime), U16(Runtime::kDefineAccessorPropertyUnchecked), // | |
4226 /* */ R(1), U8(5), // | |
4227 B(Ldar), R(0), // | |
4228 B(Return), // | |
4229 }, | |
4230 4, | |
4231 {InstanceType::FIXED_ARRAY_TYPE, | |
4232 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
4233 InstanceType::SHARED_FUNCTION_INFO_TYPE, | |
4234 InstanceType::SHARED_FUNCTION_INFO_TYPE}}, | |
4235 {"return { set b(val) { this.y = val } };", | |
4236 6 * kPointerSize, | |
4237 1, | |
4238 33, | |
4239 { | |
4240 B(StackCheck), // | |
4241 B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags), // | |
4242 B(Star), R(0), // | |
4243 B(Mov), R(0), R(1), // | |
4244 B(LdaConstant), U8(1), // | |
4245 B(Star), R(2), // | |
4246 B(LdaNull), // | |
4247 B(Star), R(3), // | |
4248 B(CreateClosure), U8(2), U8(0), // | |
4249 B(Star), R(4), // | |
4250 B(LdaZero), // | |
4251 B(Star), R(5), // | |
4252 B(CallRuntime), U16(Runtime::kDefineAccessorPropertyUnchecked), // | |
4253 /* */ R(1), U8(5), // | |
4254 B(Ldar), R(0), // | |
4255 B(Return), // | |
4256 }, | |
4257 3, | |
4258 {InstanceType::FIXED_ARRAY_TYPE, | |
4259 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
4260 InstanceType::SHARED_FUNCTION_INFO_TYPE}}, | |
4261 {"var a = 1; return { 1: a };", | |
4262 6 * kPointerSize, | |
4263 1, | |
4264 33, | |
4265 { | |
4266 B(StackCheck), // | |
4267 B(LdaSmi8), U8(1), // | |
4268 B(Star), R(0), // | |
4269 B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags), // | |
4270 B(Star), R(1), // | |
4271 B(Mov), R(1), R(2), // | |
4272 B(LdaSmi8), U8(1), // | |
4273 B(Star), R(3), // | |
4274 B(Ldar), R(0), // | |
4275 B(Star), R(4), // | |
4276 B(LdaZero), // | |
4277 B(Star), R(5), // | |
4278 B(CallRuntime), U16(Runtime::kSetProperty), R(2), U8(4), // | |
4279 B(Ldar), R(1), // | |
4280 B(Return), // | |
4281 }, | |
4282 1, | |
4283 {InstanceType::FIXED_ARRAY_TYPE}}, | |
4284 {"return { __proto__: null }", | |
4285 3 * kPointerSize, | |
4286 1, | |
4287 21, | |
4288 { | |
4289 B(StackCheck), // | |
4290 B(CreateObjectLiteral), U8(0), U8(0), U8(simple_flags), // | |
4291 B(Star), R(0), // | |
4292 B(Mov), R(0), R(1), // | |
4293 B(LdaNull), B(Star), R(2), // | |
4294 B(CallRuntime), U16(Runtime::kInternalSetPrototype), R(1), U8(2), // | |
4295 B(Ldar), R(0), // | |
4296 B(Return), // | |
4297 }, | |
4298 1, | |
4299 {InstanceType::FIXED_ARRAY_TYPE}}, | |
4300 {"var a = 'test'; return { [a]: 1 }", | |
4301 7 * kPointerSize, | |
4302 1, | |
4303 37, | |
4304 { | |
4305 B(StackCheck), // | |
4306 B(LdaConstant), U8(0), // | |
4307 B(Star), R(0), // | |
4308 B(CreateObjectLiteral), U8(1), U8(0), U8(simple_flags), // | |
4309 B(Star), R(1), // | |
4310 B(Mov), R(1), R(2), // | |
4311 B(Ldar), R(0), // | |
4312 B(ToName), // | |
4313 B(Star), R(3), // | |
4314 B(LdaSmi8), U8(1), // | |
4315 B(Star), R(4), // | |
4316 B(LdaZero), // | |
4317 B(Star), R(5), // | |
4318 B(LdaZero), // | |
4319 B(Star), R(6), // | |
4320 B(CallRuntime), U16(Runtime::kDefineDataPropertyInLiteral), R(2), // | |
4321 /* */ U8(5), // | |
4322 B(Ldar), R(1), // | |
4323 B(Return), // | |
4324 }, | |
4325 2, | |
4326 {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
4327 InstanceType::FIXED_ARRAY_TYPE}}, | |
4328 {"var a = 'test'; return { val: a, [a]: 1 }", | |
4329 7 * kPointerSize, | |
4330 1, | |
4331 43, | |
4332 { | |
4333 B(StackCheck), // | |
4334 B(LdaConstant), U8(0), // | |
4335 B(Star), R(0), // | |
4336 B(CreateObjectLiteral), U8(1), U8(0), U8(deep_elements_flags), // | |
4337 B(Star), R(1), // | |
4338 B(Ldar), R(0), // | |
4339 B(StoreICSloppy), R(1), U8(2), U8(vector->GetIndex(slot1)), // | |
4340 B(Mov), R(1), R(2), // | |
4341 B(Ldar), R(0), // | |
4342 B(ToName), // | |
4343 B(Star), R(3), // | |
4344 B(LdaSmi8), U8(1), // | |
4345 B(Star), R(4), // | |
4346 B(LdaZero), // | |
4347 B(Star), R(5), // | |
4348 B(LdaZero), // | |
4349 B(Star), R(6), // | |
4350 B(CallRuntime), U16(Runtime::kDefineDataPropertyInLiteral), R(2), // | |
4351 /* */ U8(5), // | |
4352 B(Ldar), R(1), // | |
4353 B(Return), // | |
4354 }, | |
4355 3, | |
4356 {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
4357 InstanceType::FIXED_ARRAY_TYPE, | |
4358 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
4359 {"var a = 'test'; return { [a]: 1, __proto__: {} }", | |
4360 7 * kPointerSize, | |
4361 1, | |
4362 53, | |
4363 { | |
4364 B(StackCheck), // | |
4365 B(LdaConstant), U8(0), // | |
4366 B(Star), R(0), // | |
4367 B(CreateObjectLiteral), U8(1), U8(1), U8(simple_flags), // | |
4368 B(Star), R(1), // | |
4369 B(Mov), R(1), R(2), // | |
4370 B(Ldar), R(0), // | |
4371 B(ToName), // | |
4372 B(Star), R(3), // | |
4373 B(LdaSmi8), U8(1), // | |
4374 B(Star), R(4), // | |
4375 B(LdaZero), // | |
4376 B(Star), R(5), // | |
4377 B(LdaZero), // | |
4378 B(Star), R(6), // | |
4379 B(CallRuntime), U16(Runtime::kDefineDataPropertyInLiteral), R(2), // | |
4380 /* */ U8(5), // | |
4381 B(Mov), R(1), R(2), // | |
4382 B(CreateObjectLiteral), U8(1), U8(0), U8(13), // | |
4383 B(Star), R(4), // | |
4384 B(Star), R(3), // | |
4385 B(CallRuntime), U16(Runtime::kInternalSetPrototype), R(2), U8(2), // | |
4386 B(Ldar), R(1), // | |
4387 B(Return), // | |
4388 }, | |
4389 2, | |
4390 {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
4391 InstanceType::FIXED_ARRAY_TYPE}}, | |
4392 {"var n = 'name'; return { [n]: 'val', get a() { }, set a(b) {} };", | |
4393 7 * kPointerSize, | |
4394 1, | |
4395 77, | |
4396 { | |
4397 B(StackCheck), // | |
4398 B(LdaConstant), U8(0), // | |
4399 B(Star), R(0), // | |
4400 B(CreateObjectLiteral), U8(1), U8(0), U8(simple_flags), // | |
4401 B(Star), R(1), // | |
4402 B(Mov), R(1), R(2), // | |
4403 B(Ldar), R(0), // | |
4404 B(ToName), // | |
4405 B(Star), R(3), // | |
4406 B(LdaConstant), U8(2), // | |
4407 B(Star), R(4), // | |
4408 B(LdaZero), // | |
4409 B(Star), R(5), // | |
4410 B(LdaZero), // | |
4411 B(Star), R(6), // | |
4412 B(CallRuntime), U16(Runtime::kDefineDataPropertyInLiteral), R(2), // | |
4413 /* */ U8(5), // | |
4414 B(Mov), R(1), R(2), // | |
4415 B(LdaConstant), U8(3), // | |
4416 B(Star), R(3), // | |
4417 B(CreateClosure), U8(4), U8(0), // | |
4418 B(Star), R(4), // | |
4419 B(LdaZero), // | |
4420 B(Star), R(5), // | |
4421 B(CallRuntime), U16(Runtime::kDefineGetterPropertyUnchecked), // | |
4422 /* */ R(2), U8(4), // | |
4423 B(Mov), R(1), R(2), // | |
4424 B(LdaConstant), U8(3), // | |
4425 B(Star), R(3), // | |
4426 B(CreateClosure), U8(5), U8(0), // | |
4427 B(Star), R(4), // | |
4428 B(LdaZero), // | |
4429 B(Star), R(5), // | |
4430 B(CallRuntime), U16(Runtime::kDefineSetterPropertyUnchecked), // | |
4431 /* */ R(2), U8(4), // | |
4432 B(Ldar), R(1), // | |
4433 B(Return), // | |
4434 }, | |
4435 6, | |
4436 {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
4437 InstanceType::FIXED_ARRAY_TYPE, | |
4438 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
4439 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
4440 InstanceType::SHARED_FUNCTION_INFO_TYPE, | |
4441 InstanceType::SHARED_FUNCTION_INFO_TYPE}}, | |
4442 }; | |
4443 // clang-format on | |
4444 | |
4445 for (size_t i = 0; i < arraysize(snippets); i++) { | |
4446 Handle<BytecodeArray> bytecode_array = | |
4447 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
4448 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
4449 } | |
4450 } | |
4451 | |
4452 | 1151 |
4453 TEST(ObjectLiteralsWide) { | 1152 TEST(ObjectLiteralsWide) { |
4454 InitializedHandleScope handle_scope; | 1153 InitializedIgnitionHandleScope scope; |
4455 BytecodeGeneratorHelper helper; | 1154 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
4456 Zone zone; | 1155 ConstantPoolType::kMixed); |
4457 | 1156 const char* snippets[] = { |
4458 int deep_elements_flags = | 1157 "var a;" // |
4459 ObjectLiteral::kFastElements | ObjectLiteral::kDisableMementos; | 1158 REPEAT_256("\na = 1.23;") // |
4460 int wide_idx = 0; | 1159 "\nreturn { name: 'string', val: 9.2 };", |
4461 | 1160 }; |
4462 // clang-format off | 1161 |
4463 ExpectedSnippet<InstanceType, 257> snippets[] = { | 1162 CHECK_EQ(BuildActual(printer, snippets), |
4464 {"var a;" REPEAT_256(SPACE, | 1163 LoadGolden("ObjectLiteralsWide.golden")); |
4465 "a = 1.23;") "return { name: 'string', val: 9.2 };", | 1164 } |
4466 2 * kPointerSize, | |
4467 1, | |
4468 1034, | |
4469 { | |
4470 B(StackCheck), // | |
4471 REPEAT_256(COMMA, // | |
4472 B(LdaConstant), U8(wide_idx++), // | |
4473 B(Star), R(0)), // | |
4474 B(CreateObjectLiteralWide), U16(256), U16(0), // | |
4475 /* */ U8(deep_elements_flags), // | |
4476 B(Star), R(1), // | |
4477 B(Return) // | |
4478 }, | |
4479 257, | |
4480 {REPEAT_256(COMMA, InstanceType::HEAP_NUMBER_TYPE), | |
4481 InstanceType::FIXED_ARRAY_TYPE}}, | |
4482 }; | |
4483 // clang-format on | |
4484 | |
4485 for (size_t i = 0; i < arraysize(snippets); i++) { | |
4486 Handle<BytecodeArray> bytecode_array = | |
4487 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
4488 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
4489 } | |
4490 } | |
4491 | |
4492 | 1165 |
4493 TEST(TopLevelObjectLiterals) { | 1166 TEST(TopLevelObjectLiterals) { |
4494 InitializedHandleScope handle_scope; | 1167 InitializedIgnitionHandleScope scope; |
4495 BytecodeGeneratorHelper helper; | 1168 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
4496 | 1169 ConstantPoolType::kMixed); |
4497 int has_function_flags = ObjectLiteral::kFastElements | | 1170 printer.set_wrap(false); |
4498 ObjectLiteral::kHasFunction | | 1171 printer.set_test_function_name("f"); |
4499 ObjectLiteral::kDisableMementos; | 1172 printer.set_execute(false); |
4500 // clang-format off | 1173 printer.set_top_level(true); |
4501 ExpectedSnippet<InstanceType> snippets[] = { | 1174 |
4502 {"var a = { func: function() { } };", | 1175 const char* snippets[] = { |
4503 5 * kPointerSize, | 1176 "var a = { func: function() { } };", |
4504 1, | 1177 }; |
4505 49, | 1178 |
4506 { | 1179 CHECK_EQ(BuildActual(printer, snippets), |
4507 B(LdaConstant), U8(0), // | 1180 LoadGolden("TopLevelObjectLiterals.golden")); |
4508 B(Star), R(1), // | 1181 } |
4509 B(LdaZero), // | |
4510 B(Star), R(2), // | |
4511 B(CallRuntime), U16(Runtime::kDeclareGlobals), R(1), U8(2), // | |
4512 B(StackCheck), // | |
4513 B(LdaConstant), U8(1), // | |
4514 B(Star), R(1), // | |
4515 B(LdaZero), // | |
4516 B(Star), R(2), // | |
4517 B(CreateObjectLiteral), U8(2), U8(0), U8(has_function_flags), // | |
4518 B(Star), R(4), // | |
4519 B(CreateClosure), U8(3), U8(1), // | |
4520 B(StoreICSloppy), R(4), U8(4), U8(3), // | |
4521 B(CallRuntime), U16(Runtime::kToFastProperties), R(4), U8(1), // | |
4522 B(Ldar), R(4), // | |
4523 B(Star), R(3), // | |
4524 B(CallRuntime), U16(Runtime::kInitializeVarGlobal), R(1), U8(3), // | |
4525 B(LdaUndefined), // | |
4526 B(Return), // | |
4527 }, | |
4528 5, | |
4529 {InstanceType::FIXED_ARRAY_TYPE, | |
4530 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
4531 InstanceType::FIXED_ARRAY_TYPE, | |
4532 InstanceType::SHARED_FUNCTION_INFO_TYPE, | |
4533 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
4534 }; | |
4535 // clang-format on | |
4536 | |
4537 for (size_t i = 0; i < arraysize(snippets); i++) { | |
4538 Handle<BytecodeArray> bytecode_array = | |
4539 helper.MakeTopLevelBytecode(snippets[i].code_snippet); | |
4540 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
4541 } | |
4542 } | |
4543 | |
4544 | 1182 |
4545 TEST(TryCatch) { | 1183 TEST(TryCatch) { |
4546 InitializedHandleScope handle_scope; | 1184 InitializedIgnitionHandleScope scope; |
4547 BytecodeGeneratorHelper helper; | 1185 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
4548 | 1186 ConstantPoolType::kString); |
4549 int closure = Register::function_closure().index(); | 1187 |
4550 int context = Register::current_context().index(); | 1188 const char* snippets[] = { |
4551 | 1189 "try { return 1; } catch(e) { return 2; }", |
4552 // clang-format off | 1190 |
4553 ExpectedSnippet<const char*> snippets[] = { | 1191 "var a;\n" |
4554 {"try { return 1; } catch(e) { return 2; }", | 1192 "try { a = 1 } catch(e1) {};\n" |
4555 5 * kPointerSize, | 1193 "try { a = 2 } catch(e2) { a = 3 }", |
4556 1, | 1194 }; |
4557 40, | 1195 |
4558 { | 1196 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("TryCatch.golden")); |
4559 B(StackCheck), // | 1197 } |
4560 B(Mov), R(context), R(1), // | |
4561 B(LdaSmi8), U8(1), // | |
4562 B(Return), // | |
4563 B(Star), R(3), // | |
4564 B(LdaConstant), U8(0), // | |
4565 B(Star), R(2), // | |
4566 B(Ldar), R(closure), // | |
4567 B(Star), R(4), // | |
4568 B(CallRuntime), U16(Runtime::kPushCatchContext), R(2), U8(3), // | |
4569 B(Star), R(1), // | |
4570 B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), // | |
4571 /* */ R(0), U8(0), // | |
4572 B(Ldar), R(1), // | |
4573 B(PushContext), R(0), // | |
4574 B(LdaSmi8), U8(2), // | |
4575 B(PopContext), R(0), // | |
4576 B(Return), // | |
4577 // TODO(mstarzinger): Potential optimization, elide next bytes. | |
4578 B(LdaUndefined), // | |
4579 B(Return), // | |
4580 }, | |
4581 1, | |
4582 {"e"}, | |
4583 1, | |
4584 {{4, 7, 7}}}, | |
4585 {"var a; try { a = 1 } catch(e1) {}; try { a = 2 } catch(e2) { a = 3 }", | |
4586 6 * kPointerSize, | |
4587 1, | |
4588 81, | |
4589 { | |
4590 B(StackCheck), // | |
4591 B(Mov), R(context), R(2), // | |
4592 B(LdaSmi8), U8(1), // | |
4593 B(Star), R(0), // | |
4594 B(Jump), U8(30), // | |
4595 B(Star), R(4), // | |
4596 B(LdaConstant), U8(0), // | |
4597 B(Star), R(3), // | |
4598 B(Ldar), R(closure), // | |
4599 B(Star), R(5), // | |
4600 B(CallRuntime), U16(Runtime::kPushCatchContext), R(3), U8(3), // | |
4601 B(Star), R(2), // | |
4602 B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), // | |
4603 /* */ R(0), U8(0), // | |
4604 B(Ldar), R(2), // | |
4605 B(PushContext), R(1), // | |
4606 B(PopContext), R(1), // | |
4607 B(Mov), R(context), R(2), // | |
4608 B(LdaSmi8), U8(2), // | |
4609 B(Star), R(0), // | |
4610 B(Jump), U8(34), // | |
4611 B(Star), R(4), // | |
4612 B(LdaConstant), U8(1), // | |
4613 B(Star), R(3), // | |
4614 B(Ldar), R(closure), // | |
4615 B(Star), R(5), // | |
4616 B(CallRuntime), U16(Runtime::kPushCatchContext), R(3), U8(3), // | |
4617 B(Star), R(2), // | |
4618 B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), // | |
4619 /* */ R(0), U8(0), // | |
4620 B(Ldar), R(2), // | |
4621 B(PushContext), R(1), // | |
4622 B(LdaSmi8), U8(3), // | |
4623 B(Star), R(0), // | |
4624 B(PopContext), R(1), // | |
4625 B(LdaUndefined), // | |
4626 B(Return), // | |
4627 }, | |
4628 2, | |
4629 {"e1", "e2"}, | |
4630 2, | |
4631 {{4, 8, 10}, {41, 45, 47}}}, | |
4632 }; | |
4633 // clang-format on | |
4634 | |
4635 for (size_t i = 0; i < arraysize(snippets); i++) { | |
4636 Handle<BytecodeArray> bytecode_array = | |
4637 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
4638 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
4639 } | |
4640 } | |
4641 | |
4642 | 1198 |
4643 TEST(TryFinally) { | 1199 TEST(TryFinally) { |
4644 InitializedHandleScope handle_scope; | 1200 InitializedIgnitionHandleScope scope; |
4645 BytecodeGeneratorHelper helper; | 1201 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
4646 | 1202 ConstantPoolType::kString); |
4647 int closure = Register::function_closure().index(); | 1203 const char* snippets[] = { |
4648 int context = Register::current_context().index(); | 1204 "var a = 1;\n" |
4649 | 1205 "try { a = 2; } finally { a = 3; }", |
4650 // clang-format off | 1206 |
4651 ExpectedSnippet<const char*> snippets[] = { | 1207 "var a = 1;\n" |
4652 {"var a = 1; try { a = 2; } finally { a = 3; }", | 1208 "try { a = 2; } catch(e) { a = 20 } finally { a = 3; }", |
4653 4 * kPointerSize, | 1209 |
4654 1, | 1210 "var a; try {\n" |
4655 51, | 1211 " try { a = 1 } catch(e) { a = 2 }\n" |
4656 { | 1212 "} catch(e) { a = 20 } finally { a = 3; }", |
4657 B(StackCheck), // | 1213 }; |
4658 B(LdaSmi8), U8(1), // | 1214 |
4659 B(Star), R(0), // | 1215 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("TryFinally.golden")); |
4660 B(Mov), R(context), R(3), // | 1216 } |
4661 B(LdaSmi8), U8(2), // | |
4662 B(Star), R(0), // | |
4663 B(LdaSmi8), U8(-1), // | |
4664 B(Star), R(1), // | |
4665 B(Jump), U8(7), // | |
4666 B(Star), R(2), // | |
4667 B(LdaZero), // | |
4668 B(Star), R(1), // | |
4669 B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), // | |
4670 /* */ R(0), U8(0), // | |
4671 B(Star), R(3), // | |
4672 B(LdaSmi8), U8(3), // | |
4673 B(Star), R(0), // | |
4674 B(CallRuntime), U16(Runtime::kInterpreterSetPendingMessage), // | |
4675 /* */ R(3), U8(1), // | |
4676 B(LdaZero), // | |
4677 B(TestEqualStrict), R(1), // | |
4678 B(JumpIfTrue), U8(4), // | |
4679 B(Jump), U8(5), // | |
4680 B(Ldar), R(2), // | |
4681 B(ReThrow), // | |
4682 B(LdaUndefined), // | |
4683 B(Return), // | |
4684 }, | |
4685 0, | |
4686 {}, | |
4687 1, | |
4688 {{8, 12, 18}}}, | |
4689 {"var a = 1; try { a = 2; } catch(e) { a = 20 } finally { a = 3; }", | |
4690 9 * kPointerSize, | |
4691 1, | |
4692 88, | |
4693 { | |
4694 B(StackCheck), // | |
4695 B(LdaSmi8), U8(1), // | |
4696 B(Star), R(0), // | |
4697 B(Mov), R(context), R(4), // | |
4698 B(Mov), R(context), R(5), // | |
4699 B(LdaSmi8), U8(2), // | |
4700 B(Star), R(0), // | |
4701 B(Jump), U8(34), // | |
4702 B(Star), R(7), // | |
4703 B(LdaConstant), U8(0), // | |
4704 B(Star), R(6), // | |
4705 B(Ldar), R(closure), // | |
4706 B(Star), R(8), // | |
4707 B(CallRuntime), U16(Runtime::kPushCatchContext), R(6), U8(3), // | |
4708 B(Star), R(5), // | |
4709 B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), // | |
4710 /* */ R(0), U8(0), // | |
4711 B(Ldar), R(5), // | |
4712 B(PushContext), R(1), // | |
4713 B(LdaSmi8), U8(20), // | |
4714 B(Star), R(0), // | |
4715 B(PopContext), R(1), // | |
4716 B(LdaSmi8), U8(-1), // | |
4717 B(Star), R(2), // | |
4718 B(Jump), U8(7), // | |
4719 B(Star), R(3), // | |
4720 B(LdaZero), // | |
4721 B(Star), R(2), // | |
4722 B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), // | |
4723 /* */ R(0), U8(0), // | |
4724 B(Star), R(4), // | |
4725 B(LdaSmi8), U8(3), // | |
4726 B(Star), R(0), // | |
4727 B(CallRuntime), U16(Runtime::kInterpreterSetPendingMessage), // | |
4728 /* */ R(4), U8(1), // | |
4729 B(LdaZero), // | |
4730 B(TestEqualStrict), R(2), // | |
4731 B(JumpIfTrue), U8(4), // | |
4732 B(Jump), U8(5), // | |
4733 B(Ldar), R(3), // | |
4734 B(ReThrow), // | |
4735 B(LdaUndefined), // | |
4736 B(Return), // | |
4737 }, | |
4738 1, | |
4739 {"e"}, | |
4740 2, | |
4741 {{8, 49, 55}, {11, 15, 17}}}, | |
4742 {"var a; try {" | |
4743 " try { a = 1 } catch(e) { a = 2 }" | |
4744 "} catch(e) { a = 20 } finally { a = 3; }", | |
4745 10 * kPointerSize, | |
4746 1, | |
4747 121, | |
4748 { | |
4749 B(StackCheck), // | |
4750 B(Mov), R(context), R(4), // | |
4751 B(Mov), R(context), R(5), // | |
4752 B(Mov), R(context), R(6), // | |
4753 B(LdaSmi8), U8(1), // | |
4754 B(Star), R(0), // | |
4755 B(Jump), U8(34), // | |
4756 B(Star), R(8), // | |
4757 B(LdaConstant), U8(0), // | |
4758 B(Star), R(7), // | |
4759 B(Ldar), R(closure), // | |
4760 B(Star), R(9), // | |
4761 B(CallRuntime), U16(Runtime::kPushCatchContext), R(7), U8(3), // | |
4762 B(Star), R(6), // | |
4763 B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), // | |
4764 /* */ R(0), U8(0), // | |
4765 B(Ldar), R(6), // | |
4766 B(PushContext), R(1), // | |
4767 B(LdaSmi8), U8(2), // | |
4768 B(Star), R(0), // | |
4769 B(PopContext), R(1), // | |
4770 B(Jump), U8(34), // | |
4771 B(Star), R(7), // | |
4772 B(LdaConstant), U8(0), // | |
4773 B(Star), R(6), // | |
4774 B(Ldar), R(closure), // | |
4775 B(Star), R(8), // | |
4776 B(CallRuntime), U16(Runtime::kPushCatchContext), R(6), U8(3), // | |
4777 B(Star), R(5), // | |
4778 B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), // | |
4779 /* */ R(0), U8(0), // | |
4780 B(Ldar), R(5), // | |
4781 B(PushContext), R(1), // | |
4782 B(LdaSmi8), U8(20), // | |
4783 B(Star), R(0), // | |
4784 B(PopContext), R(1), // | |
4785 B(LdaSmi8), U8(-1), // | |
4786 B(Star), R(2), // | |
4787 B(Jump), U8(7), // | |
4788 B(Star), R(3), // | |
4789 B(LdaZero), // | |
4790 B(Star), R(2), // | |
4791 B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), // | |
4792 /* */ R(0), U8(0), // | |
4793 B(Star), R(4), // | |
4794 B(LdaSmi8), U8(3), // | |
4795 B(Star), R(0), // | |
4796 B(CallRuntime), U16(Runtime::kInterpreterSetPendingMessage), // | |
4797 /* */ R(4), U8(1), // | |
4798 B(LdaZero), // | |
4799 B(TestEqualStrict), R(2), // | |
4800 B(JumpIfTrue), U8(4), // | |
4801 B(Jump), U8(5), // | |
4802 B(Ldar), R(3), // | |
4803 B(ReThrow), // | |
4804 B(LdaUndefined), // | |
4805 B(Return), // | |
4806 }, | |
4807 1, | |
4808 {"e"}, | |
4809 3, | |
4810 {{4, 82, 88}, {7, 48, 50}, {10, 14, 16}}}, | |
4811 }; | |
4812 // clang-format on | |
4813 | |
4814 for (size_t i = 0; i < arraysize(snippets); i++) { | |
4815 Handle<BytecodeArray> bytecode_array = | |
4816 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
4817 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
4818 } | |
4819 } | |
4820 | |
4821 | 1217 |
4822 TEST(Throw) { | 1218 TEST(Throw) { |
4823 InitializedHandleScope handle_scope; | 1219 InitializedIgnitionHandleScope scope; |
4824 BytecodeGeneratorHelper helper; | 1220 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
4825 | 1221 ConstantPoolType::kString); |
4826 // clang-format off | 1222 const char* snippets[] = { |
4827 ExpectedSnippet<const char*> snippets[] = { | 1223 "throw 1;", |
4828 {"throw 1;", | 1224 |
4829 0, | 1225 "throw 'Error';", |
4830 1, | 1226 |
4831 4, | 1227 "var a = 1; if (a) { throw 'Error'; };", |
4832 { | 1228 }; |
4833 B(StackCheck), // | 1229 |
4834 B(LdaSmi8), U8(1), // | 1230 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("Throw.golden")); |
4835 B(Throw), // | 1231 } |
4836 }, | |
4837 0}, | |
4838 {"throw 'Error';", | |
4839 0, | |
4840 1, | |
4841 4, | |
4842 { | |
4843 B(StackCheck), // | |
4844 B(LdaConstant), U8(0), // | |
4845 B(Throw), // | |
4846 }, | |
4847 1, | |
4848 {"Error"}}, | |
4849 {"var a = 1; if (a) { throw 'Error'; };", | |
4850 1 * kPointerSize, | |
4851 1, | |
4852 12, | |
4853 { | |
4854 B(StackCheck), // | |
4855 B(LdaSmi8), U8(1), // | |
4856 B(Star), R(0), // | |
4857 B(JumpIfToBooleanFalse), U8(5), // | |
4858 B(LdaConstant), U8(0), // | |
4859 B(Throw), // | |
4860 B(LdaUndefined), // | |
4861 B(Return), // | |
4862 }, | |
4863 1, | |
4864 {"Error"}}, | |
4865 }; | |
4866 // clang-format on | |
4867 | |
4868 for (size_t i = 0; i < arraysize(snippets); i++) { | |
4869 Handle<BytecodeArray> bytecode_array = | |
4870 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
4871 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
4872 } | |
4873 } | |
4874 | |
4875 | 1232 |
4876 TEST(CallNew) { | 1233 TEST(CallNew) { |
4877 InitializedHandleScope handle_scope; | 1234 InitializedIgnitionHandleScope scope; |
4878 BytecodeGeneratorHelper helper; | 1235 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
4879 Zone zone; | 1236 ConstantPoolType::kMixed); |
4880 | 1237 printer.set_wrap(false); |
4881 FeedbackVectorSpec feedback_spec(&zone); | 1238 printer.set_test_function_name("f"); |
4882 FeedbackVectorSlot slot1 = feedback_spec.AddGeneralSlot(); | 1239 |
4883 FeedbackVectorSlot slot2 = feedback_spec.AddLoadICSlot(); | 1240 const char* snippets[] = { |
4884 USE(slot1); | 1241 "function bar() { this.value = 0; }\n" |
4885 | 1242 "function f() { return new bar(); }\n" |
4886 Handle<i::TypeFeedbackVector> vector = | 1243 "f();", |
4887 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); | 1244 |
4888 | 1245 "function bar(x) { this.value = 18; this.x = x;}\n" |
4889 // clang-format off | 1246 "function f() { return new bar(3); }\n" |
4890 ExpectedSnippet<InstanceType> snippets[] = { | 1247 "f();", |
4891 {"function bar() { this.value = 0; }\n" | 1248 |
4892 "function f() { return new bar(); }\n" | 1249 "function bar(w, x, y, z) {\n" |
4893 "f()", | 1250 " this.value = 18;\n" |
4894 1 * kPointerSize, | 1251 " this.x = x;\n" |
4895 1, | 1252 " this.y = y;\n" |
4896 11, | 1253 " this.z = z;\n" |
4897 { | 1254 "}\n" |
4898 B(StackCheck), // | 1255 "function f() { return new bar(3, 4, 5); }\n" |
4899 B(LdaGlobal), U8(0), U8(vector->GetIndex(slot2)), // | 1256 "f();", |
4900 B(Star), R(0), // | 1257 }; |
4901 B(New), R(0), R(0), U8(0), // | 1258 |
4902 B(Return), // | 1259 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("CallNew.golden")); |
4903 }, | 1260 } |
4904 1, | |
4905 {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
4906 {"function bar(x) { this.value = 18; this.x = x;}\n" | |
4907 "function f() { return new bar(3); }\n" | |
4908 "f()", | |
4909 2 * kPointerSize, | |
4910 1, | |
4911 17, | |
4912 { | |
4913 B(StackCheck), // | |
4914 B(LdaGlobal), U8(0), U8(vector->GetIndex(slot2)), // | |
4915 B(Star), R(0), // | |
4916 B(LdaSmi8), U8(3), // | |
4917 B(Star), R(1), // | |
4918 B(Ldar), R(0), // | |
4919 B(New), R(0), R(1), U8(1), // | |
4920 B(Return), // | |
4921 }, | |
4922 1, | |
4923 {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
4924 {"function bar(w, x, y, z) {\n" | |
4925 " this.value = 18;\n" | |
4926 " this.x = x;\n" | |
4927 " this.y = y;\n" | |
4928 " this.z = z;\n" | |
4929 "}\n" | |
4930 "function f() { return new bar(3, 4, 5); }\n" | |
4931 "f()", | |
4932 4 * kPointerSize, | |
4933 1, | |
4934 25, | |
4935 { | |
4936 B(StackCheck), // | |
4937 B(LdaGlobal), U8(0), U8(vector->GetIndex(slot2)), // | |
4938 B(Star), R(0), // | |
4939 B(LdaSmi8), U8(3), // | |
4940 B(Star), R(1), // | |
4941 B(LdaSmi8), U8(4), // | |
4942 B(Star), R(2), // | |
4943 B(LdaSmi8), U8(5), // | |
4944 B(Star), R(3), // | |
4945 B(Ldar), R(0), // | |
4946 B(New), R(0), R(1), U8(3), // | |
4947 B(Return), // | |
4948 }, | |
4949 1, | |
4950 {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
4951 }; | |
4952 // clang-format on | |
4953 | |
4954 for (size_t i = 0; i < arraysize(snippets); i++) { | |
4955 Handle<BytecodeArray> bytecode_array = | |
4956 helper.MakeBytecode(snippets[i].code_snippet, "f"); | |
4957 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
4958 } | |
4959 } | |
4960 | |
4961 | 1261 |
4962 TEST(ContextVariables) { | 1262 TEST(ContextVariables) { |
4963 InitializedHandleScope handle_scope; | |
4964 BytecodeGeneratorHelper helper; | |
4965 Zone zone; | |
4966 | |
4967 FeedbackVectorSpec feedback_spec(&zone); | |
4968 FeedbackVectorSlot slot = feedback_spec.AddCallICSlot(); | |
4969 | |
4970 Handle<i::TypeFeedbackVector> vector = | |
4971 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); | |
4972 | |
4973 int closure = Register::function_closure().index(); | |
4974 int context = Register::current_context().index(); | |
4975 int new_target = Register::new_target().index(); | |
4976 int first_context_slot = Context::MIN_CONTEXT_SLOTS; | |
4977 | |
4978 // The wide check below relies on MIN_CONTEXT_SLOTS + 3 + 249 == 256, if this | 1263 // The wide check below relies on MIN_CONTEXT_SLOTS + 3 + 249 == 256, if this |
4979 // ever changes, the REPEAT_XXX should be changed to output the correct number | 1264 // ever changes, the REPEAT_XXX should be changed to output the correct number |
4980 // of unique variables to trigger the wide slot load / store. | 1265 // of unique variables to trigger the wide slot load / store. |
4981 STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS + 3 + 249 == 256); | 1266 STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS + 3 + 249 == 256); |
4982 int wide_slot = first_context_slot + 3; | 1267 |
4983 | 1268 InitializedIgnitionHandleScope scope; |
4984 // clang-format off | 1269 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
4985 ExpectedSnippet<InstanceType> snippets[] = { | 1270 ConstantPoolType::kMixed); |
4986 {"var a; return function() { a = 1; };", | 1271 const char* snippets[] = { |
4987 1 * kPointerSize, | 1272 "var a; return function() { a = 1; };", |
4988 1, | 1273 |
4989 12, | 1274 "var a = 1; return function() { a = 2; };", |
4990 { | 1275 |
4991 B(CallRuntime), U16(Runtime::kNewFunctionContext), // | 1276 "var a = 1; var b = 2; return function() { a = 2; b = 3 };", |
4992 /* */ R(closure), U8(1), // | 1277 |
4993 B(PushContext), R(0), // | 1278 "var a; (function() { a = 2; })(); return a;", |
4994 B(StackCheck), // | 1279 |
4995 B(CreateClosure), U8(0), U8(0), // | 1280 "'use strict';\n" |
4996 B(Return), // | 1281 "let a = 1;\n" |
4997 }, | 1282 "{ let b = 2; return function() { a + b; }; }", |
4998 1, | 1283 |
4999 {InstanceType::SHARED_FUNCTION_INFO_TYPE}}, | 1284 "'use strict';\n" |
5000 {"var a = 1; return function() { a = 2; };", | 1285 REPEAT_249_UNIQUE_VARS() |
5001 1 * kPointerSize, | 1286 "eval();\n" |
5002 1, | 1287 "var b = 100;\n" |
5003 17, | 1288 "return b", |
5004 { | 1289 }; |
5005 B(CallRuntime), U16(Runtime::kNewFunctionContext), // | 1290 |
5006 /* */ R(closure), U8(1), // | 1291 CHECK_EQ(BuildActual(printer, snippets), |
5007 B(PushContext), R(0), // | 1292 LoadGolden("ContextVariables.golden")); |
5008 B(StackCheck), // | 1293 } |
5009 B(LdaSmi8), U8(1), // | |
5010 B(StaContextSlot), R(context), U8(first_context_slot), // | |
5011 B(CreateClosure), U8(0), U8(0), // | |
5012 B(Return), // | |
5013 }, | |
5014 1, | |
5015 {InstanceType::SHARED_FUNCTION_INFO_TYPE}}, | |
5016 {"var a = 1; var b = 2; return function() { a = 2; b = 3 };", | |
5017 1 * kPointerSize, | |
5018 1, | |
5019 22, | |
5020 { | |
5021 B(CallRuntime), U16(Runtime::kNewFunctionContext), // | |
5022 /* */ R(closure), U8(1), // | |
5023 B(PushContext), R(0), // | |
5024 B(StackCheck), // | |
5025 B(LdaSmi8), U8(1), // | |
5026 B(StaContextSlot), R(context), U8(first_context_slot), // | |
5027 B(LdaSmi8), U8(2), // | |
5028 B(StaContextSlot), R(context), U8(first_context_slot + 1), // | |
5029 B(CreateClosure), U8(0), U8(0), // | |
5030 B(Return), // | |
5031 }, | |
5032 1, | |
5033 {InstanceType::SHARED_FUNCTION_INFO_TYPE}}, | |
5034 {"var a; (function() { a = 2; })(); return a;", | |
5035 3 * kPointerSize, | |
5036 1, | |
5037 25, | |
5038 { | |
5039 B(CallRuntime), U16(Runtime::kNewFunctionContext), // | |
5040 /* */ R(closure), U8(1), // | |
5041 B(PushContext), R(0), // | |
5042 B(StackCheck), // | |
5043 B(LdaUndefined), // | |
5044 B(Star), R(2), // | |
5045 B(CreateClosure), U8(0), U8(0), // | |
5046 B(Star), R(1), // | |
5047 B(Call), R(1), R(2), U8(1), U8(vector->GetIndex(slot)), // | |
5048 B(LdaContextSlot), R(context), U8(first_context_slot), // | |
5049 B(Return), // | |
5050 }, | |
5051 1, | |
5052 {InstanceType::SHARED_FUNCTION_INFO_TYPE}}, | |
5053 {"'use strict'; let a = 1; { let b = 2; return function() { a + b; }; }", | |
5054 4 * kPointerSize, | |
5055 1, | |
5056 47, | |
5057 { | |
5058 B(CallRuntime), U16(Runtime::kNewFunctionContext), // | |
5059 /* */ R(closure), U8(1), // | |
5060 B(PushContext), R(0), // | |
5061 B(LdaTheHole), // | |
5062 B(StaContextSlot), R(context), U8(first_context_slot), // | |
5063 B(StackCheck), // | |
5064 B(LdaSmi8), U8(1), // | |
5065 B(StaContextSlot), R(context), U8(first_context_slot), // | |
5066 B(LdaConstant), U8(0), // | |
5067 B(Star), R(2), // | |
5068 B(Ldar), R(closure), // | |
5069 B(Star), R(3), // | |
5070 B(CallRuntime), U16(Runtime::kPushBlockContext), R(2), U8(2), // | |
5071 B(PushContext), R(1), // | |
5072 B(LdaTheHole), // | |
5073 B(StaContextSlot), R(context), U8(first_context_slot), // | |
5074 B(LdaSmi8), U8(2), // | |
5075 B(StaContextSlot), R(context), U8(first_context_slot), // | |
5076 B(CreateClosure), U8(1), U8(0), // | |
5077 B(PopContext), R(0), // | |
5078 B(Return), // | |
5079 }, | |
5080 2, | |
5081 {InstanceType::FIXED_ARRAY_TYPE, | |
5082 InstanceType::SHARED_FUNCTION_INFO_TYPE}}, | |
5083 {"'use strict';\n" | |
5084 REPEAT_249_UNIQUE_VARS() | |
5085 "eval();" | |
5086 "var b = 100;" | |
5087 "return b", | |
5088 3 * kPointerSize, | |
5089 1, | |
5090 1042, | |
5091 { | |
5092 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // | |
5093 /* */ U8(1), // | |
5094 B(PushContext), R(0), // | |
5095 B(Ldar), THIS(1), // | |
5096 B(StaContextSlot), R(context), U8(first_context_slot), // | |
5097 B(CreateUnmappedArguments), // | |
5098 B(StaContextSlot), R(context), U8(first_context_slot + 1), // | |
5099 B(Ldar), R(new_target), // | |
5100 B(StaContextSlot), R(context), U8(first_context_slot + 2), // | |
5101 B(StackCheck), // | |
5102 REPEAT_249(COMMA, // | |
5103 B(LdaZero), // | |
5104 B(StaContextSlot), R(context), U8(wide_slot++)), // | |
5105 B(LdaUndefined), // | |
5106 B(Star), R(2), // | |
5107 B(LdaGlobal), U8(0), U8(1), // | |
5108 B(Star), R(1), // | |
5109 B(Call), R(1), R(2), U8(1), U8(0), // | |
5110 B(LdaSmi8), U8(100), // | |
5111 B(StaContextSlotWide), R(context), U16(256), // | |
5112 B(LdaContextSlotWide), R(context), U16(256), // | |
5113 B(Return), // | |
5114 }, | |
5115 1, | |
5116 {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
5117 }; | |
5118 // clang-format on | |
5119 | |
5120 for (size_t i = 0; i < arraysize(snippets); i++) { | |
5121 Handle<BytecodeArray> bytecode_array = | |
5122 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
5123 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
5124 } | |
5125 } | |
5126 | |
5127 | 1294 |
5128 TEST(ContextParameters) { | 1295 TEST(ContextParameters) { |
5129 InitializedHandleScope handle_scope; | 1296 InitializedIgnitionHandleScope scope; |
5130 BytecodeGeneratorHelper helper; | 1297 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
5131 | 1298 ConstantPoolType::kMixed); |
5132 int closure = Register::function_closure().index(); | 1299 printer.set_wrap(false); |
5133 int context = Register::current_context().index(); | 1300 printer.set_test_function_name("f"); |
5134 int first_context_slot = Context::MIN_CONTEXT_SLOTS; | 1301 |
5135 | 1302 const char* snippets[] = { |
5136 // clang-format off | 1303 "function f(arg1) { return function() { arg1 = 2; }; }", |
5137 ExpectedSnippet<InstanceType> snippets[] = { | 1304 |
5138 {"function f(arg1) { return function() { arg1 = 2; }; }", | 1305 "function f(arg1) { var a = function() { arg1 = 2; }; return arg1; }", |
5139 1 * kPointerSize, | 1306 |
5140 2, | 1307 "function f(a1, a2, a3, a4) { return function() { a1 = a3; }; }", |
5141 17, | 1308 |
5142 { | 1309 "function f() { var self = this; return function() { self = 2; }; }", |
5143 B(CallRuntime), U16(Runtime::kNewFunctionContext), // | 1310 }; |
5144 /* */ R(closure), U8(1), // | 1311 |
5145 B(PushContext), R(0), // | 1312 CHECK_EQ(BuildActual(printer, snippets, "", "\nf();"), |
5146 B(Ldar), R(helper.kLastParamIndex), // | 1313 LoadGolden("ContextParameters.golden")); |
5147 B(StaContextSlot), R(context), U8(first_context_slot), // | 1314 } |
5148 B(StackCheck), // | |
5149 B(CreateClosure), U8(0), U8(0), // | |
5150 B(Return), // | |
5151 }, | |
5152 1, | |
5153 {InstanceType::SHARED_FUNCTION_INFO_TYPE}}, | |
5154 {"function f(arg1) { var a = function() { arg1 = 2; }; return arg1; }", | |
5155 2 * kPointerSize, | |
5156 2, | |
5157 22, | |
5158 { | |
5159 B(CallRuntime), U16(Runtime::kNewFunctionContext), // | |
5160 /* */ R(closure), U8(1), // | |
5161 B(PushContext), R(1), // | |
5162 B(Ldar), R(helper.kLastParamIndex), // | |
5163 B(StaContextSlot), R(context), U8(first_context_slot), // | |
5164 B(StackCheck), // | |
5165 B(CreateClosure), U8(0), U8(0), // | |
5166 B(Star), R(0), // | |
5167 B(LdaContextSlot), R(context), U8(first_context_slot), // | |
5168 B(Return), // | |
5169 }, | |
5170 1, | |
5171 {InstanceType::SHARED_FUNCTION_INFO_TYPE}}, | |
5172 {"function f(a1, a2, a3, a4) { return function() { a1 = a3; }; }", | |
5173 1 * kPointerSize, | |
5174 5, | |
5175 22, | |
5176 { | |
5177 B(CallRuntime), U16(Runtime::kNewFunctionContext), // | |
5178 /* */ R(closure), U8(1), // | |
5179 B(PushContext), R(0), // | |
5180 B(Ldar), R(helper.kLastParamIndex - 3), // | |
5181 B(StaContextSlot), R(context), U8(first_context_slot + 1), // | |
5182 B(Ldar), R(helper.kLastParamIndex -1), // | |
5183 B(StaContextSlot), R(context), U8(first_context_slot), // | |
5184 B(StackCheck), // | |
5185 B(CreateClosure), U8(0), U8(0), // | |
5186 B(Return), // | |
5187 }, | |
5188 1, | |
5189 {InstanceType::SHARED_FUNCTION_INFO_TYPE}}, | |
5190 {"function f() { var self = this; return function() { self = 2; }; }", | |
5191 1 * kPointerSize, | |
5192 1, | |
5193 17, | |
5194 { | |
5195 B(CallRuntime), U16(Runtime::kNewFunctionContext), // | |
5196 /* */ R(closure), U8(1), // | |
5197 B(PushContext), R(0), // | |
5198 B(StackCheck), // | |
5199 B(Ldar), R(helper.kLastParamIndex), // | |
5200 B(StaContextSlot), R(context), U8(first_context_slot), // | |
5201 B(CreateClosure), U8(0), U8(0), // | |
5202 B(Return), // | |
5203 }, | |
5204 1, | |
5205 {InstanceType::SHARED_FUNCTION_INFO_TYPE}}, | |
5206 }; | |
5207 // clang-format on | |
5208 | |
5209 for (size_t i = 0; i < arraysize(snippets); i++) { | |
5210 Handle<BytecodeArray> bytecode_array = | |
5211 helper.MakeBytecodeForFunction(snippets[i].code_snippet); | |
5212 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
5213 } | |
5214 } | |
5215 | |
5216 | 1315 |
5217 TEST(OuterContextVariables) { | 1316 TEST(OuterContextVariables) { |
5218 InitializedHandleScope handle_scope; | 1317 InitializedIgnitionHandleScope scope; |
5219 BytecodeGeneratorHelper helper; | 1318 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
5220 | 1319 ConstantPoolType::kMixed); |
5221 int context = Register::current_context().index(); | 1320 printer.set_wrap(false); |
5222 int first_context_slot = Context::MIN_CONTEXT_SLOTS; | 1321 printer.set_test_function_name("f"); |
5223 | 1322 |
5224 // clang-format off | 1323 const char* snippets[] = { |
5225 ExpectedSnippet<InstanceType> snippets[] = { | 1324 "function Outer() {\n" |
5226 {"function Outer() {" | 1325 " var outerVar = 1;\n" |
5227 " var outerVar = 1;" | 1326 " function Inner(innerArg) {\n" |
5228 " function Inner(innerArg) {" | 1327 " this.innerFunc = function() { return outerVar * innerArg; }\n" |
5229 " this.innerFunc = function() { return outerVar * innerArg; }" | 1328 " }\n" |
5230 " }" | 1329 " this.getInnerFunc = function() { return new Inner(1).innerFunc; }\n" |
5231 " this.getInnerFunc = function() { return new Inner(1).innerFunc; }" | 1330 "}\n" |
5232 "}" | 1331 "var f = new Outer().getInnerFunc();", |
5233 "var f = new Outer().getInnerFunc();", | 1332 |
5234 2 * kPointerSize, | 1333 "function Outer() {\n" |
5235 1, | 1334 " var outerVar = 1;\n" |
5236 21, | 1335 " function Inner(innerArg) {\n" |
5237 { | 1336 " this.innerFunc = function() { outerVar = innerArg; }\n" |
5238 B(StackCheck), // | 1337 " }\n" |
5239 B(Ldar), R(context), // | 1338 " this.getInnerFunc = function() { return new Inner(1).innerFunc; }\n" |
5240 B(Star), R(0), // | 1339 "}\n" |
5241 B(LdaContextSlot), R(0), U8(Context::PREVIOUS_INDEX), // | 1340 "var f = new Outer().getInnerFunc();", |
5242 B(Star), R(0), // | 1341 }; |
5243 B(LdaContextSlot), R(0), U8(first_context_slot), // | 1342 |
5244 B(Star), R(1), // | 1343 CHECK_EQ(BuildActual(printer, snippets, "", "\nf();"), |
5245 B(LdaContextSlot), R(context), U8(first_context_slot), // | 1344 LoadGolden("OuterContextVariables.golden")); |
5246 B(Mul), R(1), // | 1345 } |
5247 B(Return), // | |
5248 }}, | |
5249 {"function Outer() {" | |
5250 " var outerVar = 1;" | |
5251 " function Inner(innerArg) {" | |
5252 " this.innerFunc = function() { outerVar = innerArg; }" | |
5253 " }" | |
5254 " this.getInnerFunc = function() { return new Inner(1).innerFunc; }" | |
5255 "}" | |
5256 "var f = new Outer().getInnerFunc();", | |
5257 2 * kPointerSize, | |
5258 1, | |
5259 22, | |
5260 { | |
5261 B(StackCheck), // | |
5262 B(LdaContextSlot), R(context), U8(first_context_slot), // | |
5263 B(Star), R(0), // | |
5264 B(Ldar), R(context), // | |
5265 B(Star), R(1), // | |
5266 B(LdaContextSlot), R(1), U8(Context::PREVIOUS_INDEX), // | |
5267 B(Star), R(1), // | |
5268 B(Ldar), R(0), // | |
5269 B(StaContextSlot), R(1), U8(first_context_slot), // | |
5270 B(LdaUndefined), // | |
5271 B(Return), // | |
5272 }}, | |
5273 }; | |
5274 // clang-format on | |
5275 | |
5276 for (size_t i = 0; i < arraysize(snippets); i++) { | |
5277 Handle<BytecodeArray> bytecode_array = | |
5278 helper.MakeBytecodeForFunctionNoFilter(snippets[i].code_snippet); | |
5279 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
5280 } | |
5281 } | |
5282 | |
5283 | 1346 |
5284 TEST(CountOperators) { | 1347 TEST(CountOperators) { |
5285 InitializedHandleScope handle_scope; | 1348 InitializedIgnitionHandleScope scope; |
5286 BytecodeGeneratorHelper helper; | 1349 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
5287 Zone zone; | 1350 ConstantPoolType::kMixed); |
5288 | 1351 const char* snippets[] = { |
5289 FeedbackVectorSpec feedback_spec(&zone); | 1352 "var a = 1; return ++a;", |
5290 FeedbackVectorSlot slot1 = feedback_spec.AddLoadICSlot(); | 1353 |
5291 FeedbackVectorSlot slot2 = feedback_spec.AddStoreICSlot(); | 1354 "var a = 1; return a++;", |
5292 Handle<i::TypeFeedbackVector> vector = | 1355 |
5293 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); | 1356 "var a = 1; return --a;", |
5294 | 1357 |
5295 FeedbackVectorSpec store_feedback_spec(&zone); | 1358 "var a = 1; return a--;", |
5296 FeedbackVectorSlot store_slot = store_feedback_spec.AddStoreICSlot(); | 1359 |
5297 Handle<i::TypeFeedbackVector> store_vector = | 1360 "var a = { val: 1 }; return a.val++;", |
5298 i::NewTypeFeedbackVector(helper.isolate(), &store_feedback_spec); | 1361 |
5299 | 1362 "var a = { val: 1 }; return --a.val;", |
5300 int closure = Register::function_closure().index(); | 1363 |
5301 int context = Register::current_context().index(); | 1364 "var name = 'var'; var a = { val: 1 }; return a[name]--;", |
5302 int first_context_slot = Context::MIN_CONTEXT_SLOTS; | 1365 |
5303 | 1366 "var name = 'var'; var a = { val: 1 }; return ++a[name];", |
5304 int object_literal_flags = | 1367 |
5305 ObjectLiteral::kFastElements | ObjectLiteral::kDisableMementos; | 1368 "var a = 1; var b = function() { return a }; return ++a;", |
5306 int array_literal_flags = | 1369 |
5307 ArrayLiteral::kDisableMementos | ArrayLiteral::kShallowElements; | 1370 "var a = 1; var b = function() { return a }; return a--;", |
5308 | 1371 |
5309 // clang-format off | 1372 "var idx = 1; var a = [1, 2]; return a[idx++] = 2;", |
5310 ExpectedSnippet<InstanceType> snippets[] = { | 1373 }; |
5311 {"var a = 1; return ++a;", | 1374 |
5312 1 * kPointerSize, | 1375 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("CountOperators.golden")); |
5313 1, | 1376 } |
5314 10, | |
5315 { | |
5316 B(StackCheck), // | |
5317 B(LdaSmi8), U8(1), // | |
5318 B(Star), R(0), // | |
5319 B(ToNumber), // | |
5320 B(Inc), // | |
5321 B(Star), R(0), // | |
5322 B(Return), // | |
5323 }}, | |
5324 {"var a = 1; return a++;", | |
5325 2 * kPointerSize, | |
5326 1, | |
5327 14, | |
5328 { | |
5329 B(StackCheck), // | |
5330 B(LdaSmi8), U8(1), // | |
5331 B(Star), R(0), // | |
5332 B(ToNumber), // | |
5333 B(Star), R(1), // | |
5334 B(Inc), // | |
5335 B(Star), R(0), // | |
5336 B(Ldar), R(1), // | |
5337 B(Return), // | |
5338 }}, | |
5339 {"var a = 1; return --a;", | |
5340 1 * kPointerSize, | |
5341 1, | |
5342 10, | |
5343 { | |
5344 B(StackCheck), // | |
5345 B(LdaSmi8), U8(1), // | |
5346 B(Star), R(0), // | |
5347 B(ToNumber), // | |
5348 B(Dec), // | |
5349 B(Star), R(0), // | |
5350 B(Return), // | |
5351 }}, | |
5352 {"var a = 1; return a--;", | |
5353 2 * kPointerSize, | |
5354 1, | |
5355 14, | |
5356 { | |
5357 B(StackCheck), // | |
5358 B(LdaSmi8), U8(1), // | |
5359 B(Star), R(0), // | |
5360 B(ToNumber), // | |
5361 B(Star), R(1), // | |
5362 B(Dec), // | |
5363 B(Star), R(0), // | |
5364 B(Ldar), R(1), // | |
5365 B(Return), // | |
5366 }}, | |
5367 {"var a = { val: 1 }; return a.val++;", | |
5368 3 * kPointerSize, | |
5369 1, | |
5370 26, | |
5371 { | |
5372 B(StackCheck), // | |
5373 B(CreateObjectLiteral), U8(0), U8(0), U8(object_literal_flags), // | |
5374 B(Star), R(1), // | |
5375 B(Star), R(0), // | |
5376 B(Star), R(1), // | |
5377 B(LoadIC), R(1), U8(1), U8(vector->GetIndex(slot1)), // | |
5378 B(ToNumber), // | |
5379 B(Star), R(2), // | |
5380 B(Inc), // | |
5381 B(StoreICSloppy), R(1), U8(1), U8(vector->GetIndex(slot2)), // | |
5382 B(Ldar), R(2), // | |
5383 B(Return), // | |
5384 }, | |
5385 2, | |
5386 {InstanceType::FIXED_ARRAY_TYPE, | |
5387 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
5388 {"var a = { val: 1 }; return --a.val;", | |
5389 2 * kPointerSize, | |
5390 1, | |
5391 22, | |
5392 { | |
5393 B(StackCheck), // | |
5394 B(CreateObjectLiteral), U8(0), U8(0), U8(object_literal_flags), // | |
5395 B(Star), R(1), // | |
5396 B(Star), R(0), // | |
5397 B(Star), R(1), // | |
5398 B(LoadIC), R(1), U8(1), U8(vector->GetIndex(slot1)), // | |
5399 B(ToNumber), // | |
5400 B(Dec), // | |
5401 B(StoreICSloppy), R(1), U8(1), U8(vector->GetIndex(slot2)), // | |
5402 B(Return), // | |
5403 }, | |
5404 2, | |
5405 {InstanceType::FIXED_ARRAY_TYPE, | |
5406 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
5407 {"var name = 'var'; var a = { val: 1 }; return a[name]--;", | |
5408 5 * kPointerSize, | |
5409 1, | |
5410 33, | |
5411 { | |
5412 B(StackCheck), // | |
5413 B(LdaConstant), U8(0), // | |
5414 B(Star), R(0), // | |
5415 B(CreateObjectLiteral), U8(1), U8(0), U8(object_literal_flags), // | |
5416 B(Star), R(2), // | |
5417 B(Star), R(1), // | |
5418 B(Star), R(2), // | |
5419 B(Ldar), R(0), // | |
5420 B(Star), R(3), // | |
5421 B(KeyedLoadIC), R(2), U8(vector->GetIndex(slot1)), // | |
5422 B(ToNumber), // | |
5423 B(Star), R(4), // | |
5424 B(Dec), // | |
5425 B(KeyedStoreICSloppy), R(2), R(3), U8(vector->GetIndex(slot2)), // | |
5426 B(Ldar), R(4), // | |
5427 B(Return), // | |
5428 }, | |
5429 2, | |
5430 {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
5431 InstanceType::FIXED_ARRAY_TYPE}}, | |
5432 {"var name = 'var'; var a = { val: 1 }; return ++a[name];", | |
5433 4 * kPointerSize, | |
5434 1, | |
5435 29, | |
5436 { | |
5437 B(StackCheck), // | |
5438 B(LdaConstant), U8(0), // | |
5439 B(Star), R(0), // | |
5440 B(CreateObjectLiteral), U8(1), U8(0), U8(object_literal_flags), // | |
5441 B(Star), R(2), // | |
5442 B(Star), R(1), // | |
5443 B(Star), R(2), // | |
5444 B(Ldar), R(0), // | |
5445 B(Star), R(3), // | |
5446 B(KeyedLoadIC), R(2), U8(vector->GetIndex(slot1)), // | |
5447 B(ToNumber), // | |
5448 B(Inc), // | |
5449 B(KeyedStoreICSloppy), R(2), R(3), U8(vector->GetIndex(slot2)), // | |
5450 B(Return), // | |
5451 }, | |
5452 2, | |
5453 {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
5454 InstanceType::FIXED_ARRAY_TYPE}}, | |
5455 {"var a = 1; var b = function() { return a }; return ++a;", | |
5456 2 * kPointerSize, | |
5457 1, | |
5458 27, | |
5459 { | |
5460 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // | |
5461 /* */ U8(1), // | |
5462 B(PushContext), R(1), // | |
5463 B(StackCheck), // | |
5464 B(LdaSmi8), U8(1), // | |
5465 B(StaContextSlot), R(context), U8(first_context_slot), // | |
5466 B(CreateClosure), U8(0), U8(0), // | |
5467 B(Star), R(0), // | |
5468 B(LdaContextSlot), R(context), U8(first_context_slot), // | |
5469 B(ToNumber), // | |
5470 B(Inc), // | |
5471 B(StaContextSlot), R(context), U8(first_context_slot), // | |
5472 B(Return), // | |
5473 }, | |
5474 1, | |
5475 {InstanceType::SHARED_FUNCTION_INFO_TYPE}}, | |
5476 {"var a = 1; var b = function() { return a }; return a--;", | |
5477 3 * kPointerSize, | |
5478 1, | |
5479 31, | |
5480 { | |
5481 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // | |
5482 /* */ U8(1), // | |
5483 B(PushContext), R(1), // | |
5484 B(StackCheck), // | |
5485 B(LdaSmi8), U8(1), // | |
5486 B(StaContextSlot), R(context), U8(first_context_slot), // | |
5487 B(CreateClosure), U8(0), U8(0), // | |
5488 B(Star), R(0), // | |
5489 B(LdaContextSlot), R(context), U8(first_context_slot), // | |
5490 B(ToNumber), // | |
5491 B(Star), R(2), // | |
5492 B(Dec), // | |
5493 B(StaContextSlot), R(context), U8(first_context_slot), // | |
5494 B(Ldar), R(2), // | |
5495 B(Return), // | |
5496 }, | |
5497 1, | |
5498 {InstanceType::SHARED_FUNCTION_INFO_TYPE}}, | |
5499 {"var idx = 1; var a = [1, 2]; return a[idx++] = 2;", | |
5500 4 * kPointerSize, | |
5501 1, | |
5502 28, | |
5503 { | |
5504 B(StackCheck), // | |
5505 B(LdaSmi8), U8(1), // | |
5506 B(Star), R(0), // | |
5507 B(CreateArrayLiteral), U8(0), U8(0), U8(array_literal_flags), // | |
5508 B(Star), R(1), // | |
5509 B(Star), R(2), // | |
5510 B(Ldar), R(0), // | |
5511 B(ToNumber), // | |
5512 B(Star), R(3), // | |
5513 B(Inc), // | |
5514 B(Star), R(0), // | |
5515 B(LdaSmi8), U8(2), // | |
5516 B(KeyedStoreICSloppy), R(2), R(3), // | |
5517 /* */ U8(store_vector->GetIndex(store_slot)), // | |
5518 B(Return), // | |
5519 }, | |
5520 1, | |
5521 {InstanceType::FIXED_ARRAY_TYPE}}, | |
5522 }; | |
5523 // clang-format on | |
5524 | |
5525 for (size_t i = 0; i < arraysize(snippets); i++) { | |
5526 Handle<BytecodeArray> bytecode_array = | |
5527 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
5528 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
5529 } | |
5530 } | |
5531 | |
5532 | 1377 |
5533 TEST(GlobalCountOperators) { | 1378 TEST(GlobalCountOperators) { |
5534 InitializedHandleScope handle_scope; | 1379 InitializedIgnitionHandleScope scope; |
5535 BytecodeGeneratorHelper helper; | 1380 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
5536 Zone zone; | 1381 ConstantPoolType::kString); |
5537 | 1382 printer.set_wrap(false); |
5538 FeedbackVectorSpec feedback_spec(&zone); | 1383 printer.set_test_function_name("f"); |
5539 FeedbackVectorSlot slot1 = feedback_spec.AddLoadICSlot(); | 1384 |
5540 FeedbackVectorSlot slot2 = feedback_spec.AddStoreICSlot(); | 1385 const char* snippets[] = { |
5541 | 1386 "var global = 1;\n" |
5542 Handle<i::TypeFeedbackVector> vector = | 1387 "function f() { return ++global; }\n" |
5543 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); | 1388 "f();", |
5544 | 1389 |
5545 // clang-format off | 1390 "var global = 1;\n" |
5546 ExpectedSnippet<const char*> snippets[] = { | 1391 "function f() { return global--; }\n" |
5547 {"var global = 1;\nfunction f() { return ++global; }\nf()", | 1392 "f();", |
5548 0, | 1393 |
5549 1, | 1394 "unallocated = 1;\n" |
5550 10, | 1395 "function f() { 'use strict'; return --unallocated; }\n" |
5551 { | 1396 "f();", |
5552 B(StackCheck), // | 1397 |
5553 B(LdaGlobal), U8(0), U8(vector->GetIndex(slot1)), // | 1398 "unallocated = 1;\n" |
5554 B(ToNumber), // | 1399 "function f() { return unallocated++; }\n" |
5555 B(Inc), // | 1400 "f();", |
5556 B(StaGlobalSloppy), U8(0), U8(vector->GetIndex(slot2)), // | 1401 }; |
5557 B(Return), // | 1402 |
5558 }, | 1403 CHECK_EQ(BuildActual(printer, snippets), |
5559 1, | 1404 LoadGolden("GlobalCountOperators.golden")); |
5560 {"global"}}, | 1405 } |
5561 {"var global = 1;\nfunction f() { return global--; }\nf()", | |
5562 1 * kPointerSize, | |
5563 1, | |
5564 14, | |
5565 { | |
5566 B(StackCheck), // | |
5567 B(LdaGlobal), U8(0), U8(vector->GetIndex(slot1)), // | |
5568 B(ToNumber), // | |
5569 B(Star), R(0), // | |
5570 B(Dec), // | |
5571 B(StaGlobalSloppy), U8(0), U8(vector->GetIndex(slot2)), // | |
5572 B(Ldar), R(0), // | |
5573 B(Return), | |
5574 }, | |
5575 1, | |
5576 {"global"}}, | |
5577 {"unallocated = 1;\nfunction f() { 'use strict'; return --unallocated; }" | |
5578 "f()", | |
5579 0, | |
5580 1, | |
5581 10, | |
5582 { | |
5583 B(StackCheck), // | |
5584 B(LdaGlobal), U8(0), U8(vector->GetIndex(slot1)), // | |
5585 B(ToNumber), // | |
5586 B(Dec), // | |
5587 B(StaGlobalStrict), U8(0), U8(vector->GetIndex(slot2)), // | |
5588 B(Return), // | |
5589 }, | |
5590 1, | |
5591 {"unallocated"}}, | |
5592 {"unallocated = 1;\nfunction f() { return unallocated++; }\nf()", | |
5593 1 * kPointerSize, | |
5594 1, | |
5595 14, | |
5596 { | |
5597 B(StackCheck), // | |
5598 B(LdaGlobal), U8(0), U8(vector->GetIndex(slot1)), // | |
5599 B(ToNumber), // | |
5600 B(Star), R(0), // | |
5601 B(Inc), // | |
5602 B(StaGlobalSloppy), U8(0), U8(vector->GetIndex(slot2)), // | |
5603 B(Ldar), R(0), // | |
5604 B(Return), | |
5605 }, | |
5606 1, | |
5607 {"unallocated"}}, | |
5608 }; | |
5609 // clang-format on | |
5610 | |
5611 for (size_t i = 0; i < arraysize(snippets); i++) { | |
5612 Handle<BytecodeArray> bytecode_array = | |
5613 helper.MakeBytecode(snippets[i].code_snippet, "f"); | |
5614 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
5615 } | |
5616 } | |
5617 | |
5618 | 1406 |
5619 TEST(CompoundExpressions) { | 1407 TEST(CompoundExpressions) { |
5620 InitializedHandleScope handle_scope; | 1408 InitializedIgnitionHandleScope scope; |
5621 BytecodeGeneratorHelper helper; | 1409 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
5622 Zone zone; | 1410 ConstantPoolType::kMixed); |
5623 | 1411 const char* snippets[] = { |
5624 int closure = Register::function_closure().index(); | 1412 "var a = 1; a += 2;", |
5625 int context = Register::current_context().index(); | 1413 |
5626 int first_context_slot = Context::MIN_CONTEXT_SLOTS; | 1414 "var a = 1; a /= 2;", |
5627 | 1415 |
5628 FeedbackVectorSpec feedback_spec(&zone); | 1416 "var a = { val: 2 }; a.name *= 2;", |
5629 FeedbackVectorSlot slot1 = feedback_spec.AddLoadICSlot(); | 1417 |
5630 FeedbackVectorSlot slot2 = feedback_spec.AddStoreICSlot(); | 1418 "var a = { 1: 2 }; a[1] ^= 2;", |
5631 | 1419 |
5632 Handle<i::TypeFeedbackVector> vector = | 1420 "var a = 1; (function f() { return a; }); a |= 24;", |
5633 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); | 1421 }; |
5634 | 1422 |
5635 int object_literal_flags = | 1423 CHECK_EQ(BuildActual(printer, snippets), |
5636 ObjectLiteral::kFastElements | ObjectLiteral::kDisableMementos; | 1424 LoadGolden("CompoundExpressions.golden")); |
5637 | 1425 } |
5638 // clang-format off | |
5639 ExpectedSnippet<InstanceType> snippets[] = { | |
5640 {"var a = 1; a += 2;", | |
5641 2 * kPointerSize, | |
5642 1, | |
5643 15, | |
5644 { | |
5645 B(StackCheck), // | |
5646 B(LdaSmi8), U8(1), // | |
5647 B(Star), R(0), // | |
5648 B(Star), R(1), // | |
5649 B(LdaSmi8), U8(2), // | |
5650 B(Add), R(1), // | |
5651 B(Star), R(0), // | |
5652 B(LdaUndefined), // | |
5653 B(Return), // | |
5654 }}, | |
5655 {"var a = 1; a /= 2;", | |
5656 2 * kPointerSize, | |
5657 1, | |
5658 15, | |
5659 { | |
5660 B(StackCheck), // | |
5661 B(LdaSmi8), U8(1), // | |
5662 B(Star), R(0), // | |
5663 B(Star), R(1), // | |
5664 B(LdaSmi8), U8(2), // | |
5665 B(Div), R(1), // | |
5666 B(Star), R(0), // | |
5667 B(LdaUndefined), // | |
5668 B(Return), // | |
5669 }}, | |
5670 {"var a = { val: 2 }; a.name *= 2;", | |
5671 3 * kPointerSize, | |
5672 1, | |
5673 27, | |
5674 { | |
5675 B(StackCheck), // | |
5676 B(CreateObjectLiteral), U8(0), U8(0), U8(object_literal_flags), // | |
5677 B(Star), R(1), // | |
5678 B(Star), R(0), // | |
5679 B(Star), R(1), // | |
5680 B(LoadIC), R(1), U8(1), U8(vector->GetIndex(slot1)), // | |
5681 B(Star), R(2), // | |
5682 B(LdaSmi8), U8(2), // | |
5683 B(Mul), R(2), // | |
5684 B(StoreICSloppy), R(1), U8(1), U8(vector->GetIndex(slot2)), // | |
5685 B(LdaUndefined), // | |
5686 B(Return), // | |
5687 }, | |
5688 2, | |
5689 {InstanceType::FIXED_ARRAY_TYPE, | |
5690 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
5691 {"var a = { 1: 2 }; a[1] ^= 2;", | |
5692 4 * kPointerSize, | |
5693 1, | |
5694 30, | |
5695 { | |
5696 B(StackCheck), // | |
5697 B(CreateObjectLiteral), U8(0), U8(0), U8(object_literal_flags), // | |
5698 B(Star), R(1), // | |
5699 B(Star), R(0), // | |
5700 B(Star), R(1), // | |
5701 B(LdaSmi8), U8(1), // | |
5702 B(Star), R(2), // | |
5703 B(KeyedLoadIC), R(1), U8(vector->GetIndex(slot1)), // | |
5704 B(Star), R(3), // | |
5705 B(LdaSmi8), U8(2), // | |
5706 B(BitwiseXor), R(3), // | |
5707 B(KeyedStoreICSloppy), R(1), R(2), U8(vector->GetIndex(slot2)), // | |
5708 B(LdaUndefined), // | |
5709 B(Return), // | |
5710 }, | |
5711 1, | |
5712 {InstanceType::FIXED_ARRAY_TYPE}}, | |
5713 {"var a = 1; (function f() { return a; }); a |= 24;", | |
5714 2 * kPointerSize, | |
5715 1, | |
5716 30, | |
5717 { | |
5718 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // | |
5719 /* */ U8(1), // | |
5720 B(PushContext), R(0), // | |
5721 B(StackCheck), // | |
5722 B(LdaSmi8), U8(1), // | |
5723 B(StaContextSlot), R(context), U8(first_context_slot), // | |
5724 B(CreateClosure), U8(0), U8(0), // | |
5725 B(LdaContextSlot), R(context), U8(first_context_slot), // | |
5726 B(Star), R(1), // | |
5727 B(LdaSmi8), U8(24), // | |
5728 B(BitwiseOr), R(1), // | |
5729 B(StaContextSlot), R(context), U8(first_context_slot), // | |
5730 B(LdaUndefined), // | |
5731 B(Return), // | |
5732 }, | |
5733 1, | |
5734 {InstanceType::SHARED_FUNCTION_INFO_TYPE}}, | |
5735 }; | |
5736 // clang-format on | |
5737 | |
5738 for (size_t i = 0; i < arraysize(snippets); i++) { | |
5739 Handle<BytecodeArray> bytecode_array = | |
5740 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
5741 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
5742 } | |
5743 } | |
5744 | |
5745 | 1426 |
5746 TEST(GlobalCompoundExpressions) { | 1427 TEST(GlobalCompoundExpressions) { |
5747 InitializedHandleScope handle_scope; | 1428 InitializedIgnitionHandleScope scope; |
5748 BytecodeGeneratorHelper helper; | 1429 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
5749 Zone zone; | 1430 ConstantPoolType::kString); |
5750 | 1431 printer.set_wrap(false); |
5751 FeedbackVectorSpec feedback_spec(&zone); | 1432 printer.set_test_function_name("f"); |
5752 FeedbackVectorSlot slot1 = feedback_spec.AddLoadICSlot(); | 1433 |
5753 FeedbackVectorSlot slot2 = feedback_spec.AddStoreICSlot(); | 1434 const char* snippets[] = { |
5754 | 1435 "var global = 1;\n" |
5755 Handle<i::TypeFeedbackVector> vector = | 1436 "function f() { return global &= 1; }\n" |
5756 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); | 1437 "f();", |
5757 | 1438 |
5758 // clang-format off | 1439 "unallocated = 1;\n" |
5759 ExpectedSnippet<const char*> snippets[] = { | 1440 "function f() { return unallocated += 1; }\n" |
5760 {"var global = 1;\nfunction f() { return global &= 1; }\nf()", | 1441 "f();", |
5761 1 * kPointerSize, | 1442 }; |
5762 1, | 1443 |
5763 14, | 1444 CHECK_EQ(BuildActual(printer, snippets), |
5764 { | 1445 LoadGolden("GlobalCompoundExpressions.golden")); |
5765 B(StackCheck), // | 1446 } |
5766 B(LdaGlobal), U8(0), U8(vector->GetIndex(slot1)), // | |
5767 B(Star), R(0), // | |
5768 B(LdaSmi8), U8(1), // | |
5769 B(BitwiseAnd), R(0), // | |
5770 B(StaGlobalSloppy), U8(0), U8(vector->GetIndex(slot2)), // | |
5771 B(Return), // | |
5772 }, | |
5773 1, | |
5774 {"global"}}, | |
5775 {"unallocated = 1;\nfunction f() { return unallocated += 1; }\nf()", | |
5776 1 * kPointerSize, | |
5777 1, | |
5778 14, | |
5779 { | |
5780 B(StackCheck), // | |
5781 B(LdaGlobal), U8(0), U8(vector->GetIndex(slot1)), // | |
5782 B(Star), R(0), // | |
5783 B(LdaSmi8), U8(1), // | |
5784 B(Add), R(0), // | |
5785 B(StaGlobalSloppy), U8(0), U8(vector->GetIndex(slot2)), // | |
5786 B(Return), // | |
5787 }, | |
5788 1, | |
5789 {"unallocated"}}, | |
5790 }; | |
5791 // clang-format on | |
5792 | |
5793 for (size_t i = 0; i < arraysize(snippets); i++) { | |
5794 Handle<BytecodeArray> bytecode_array = | |
5795 helper.MakeBytecode(snippets[i].code_snippet, "f"); | |
5796 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
5797 } | |
5798 } | |
5799 | |
5800 | 1447 |
5801 TEST(CreateArguments) { | 1448 TEST(CreateArguments) { |
5802 InitializedHandleScope handle_scope; | 1449 InitializedIgnitionHandleScope scope; |
5803 BytecodeGeneratorHelper helper; | 1450 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
5804 Zone zone; | 1451 ConstantPoolType::kString); |
5805 | 1452 printer.set_wrap(false); |
5806 int closure = Register::function_closure().index(); | 1453 printer.set_test_function_name("f"); |
5807 int context = Register::current_context().index(); | 1454 |
5808 int first_context_slot = Context::MIN_CONTEXT_SLOTS; | 1455 const char* snippets[] = { |
5809 | 1456 "function f() { return arguments; }", |
5810 FeedbackVectorSpec feedback_spec(&zone); | 1457 |
5811 FeedbackVectorSlot slot = feedback_spec.AddKeyedLoadICSlot(); | 1458 "function f() { return arguments[0]; }", |
5812 | 1459 |
5813 Handle<i::TypeFeedbackVector> vector = | 1460 "function f() { 'use strict'; return arguments; }", |
5814 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); | 1461 |
5815 | 1462 "function f(a) { return arguments[0]; }", |
5816 // clang-format off | 1463 |
5817 ExpectedSnippet<const char*> snippets[] = { | 1464 "function f(a, b, c) { return arguments; }", |
5818 {"function f() { return arguments; }", | 1465 |
5819 1 * kPointerSize, | 1466 "function f(a, b, c) { 'use strict'; return arguments; }", |
5820 1, | 1467 }; |
5821 7, | 1468 |
5822 { | 1469 CHECK_EQ(BuildActual(printer, snippets, "", "\nf();"), |
5823 B(CreateMappedArguments), // | 1470 LoadGolden("CreateArguments.golden")); |
5824 B(Star), R(0), // | |
5825 B(StackCheck), // | |
5826 B(Ldar), R(0), // | |
5827 B(Return), // | |
5828 }}, | |
5829 {"function f() { return arguments[0]; }", | |
5830 2 * kPointerSize, | |
5831 1, | |
5832 13, | |
5833 { | |
5834 B(CreateMappedArguments), // | |
5835 B(Star), R(0), // | |
5836 B(StackCheck), // | |
5837 B(Ldar), R(0), // | |
5838 B(Star), R(1), // | |
5839 B(LdaZero), // | |
5840 B(KeyedLoadIC), R(1), U8(vector->GetIndex(slot)), // | |
5841 B(Return), // | |
5842 }}, | |
5843 {"function f() { 'use strict'; return arguments; }", | |
5844 1 * kPointerSize, | |
5845 1, | |
5846 7, | |
5847 { | |
5848 B(CreateUnmappedArguments), // | |
5849 B(Star), R(0), // | |
5850 B(StackCheck), // | |
5851 B(Ldar), R(0), // | |
5852 B(Return), // | |
5853 }}, | |
5854 {"function f(a) { return arguments[0]; }", | |
5855 3 * kPointerSize, | |
5856 2, | |
5857 25, | |
5858 { | |
5859 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // | |
5860 /* */ U8(1), // | |
5861 B(PushContext), R(1), // | |
5862 B(Ldar), R(BytecodeGeneratorHelper::kLastParamIndex), // | |
5863 B(StaContextSlot), R(context), U8(first_context_slot), // | |
5864 B(CreateMappedArguments), // | |
5865 B(Star), R(0), // | |
5866 B(StackCheck), // | |
5867 B(Ldar), R(0), // | |
5868 B(Star), R(2), // | |
5869 B(LdaZero), // | |
5870 B(KeyedLoadIC), R(2), U8(vector->GetIndex(slot)), // | |
5871 B(Return), // | |
5872 }}, | |
5873 {"function f(a, b, c) { return arguments; }", | |
5874 2 * kPointerSize, | |
5875 4, | |
5876 29, | |
5877 { | |
5878 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // | |
5879 /* */ U8(1), // | |
5880 B(PushContext), R(1), // | |
5881 B(Ldar), R(BytecodeGeneratorHelper::kLastParamIndex - 2), // | |
5882 B(StaContextSlot), R(context), U8(first_context_slot + 2), // | |
5883 B(Ldar), R(BytecodeGeneratorHelper::kLastParamIndex - 1), // | |
5884 B(StaContextSlot), R(context), U8(first_context_slot + 1), // | |
5885 B(Ldar), R(BytecodeGeneratorHelper::kLastParamIndex), // | |
5886 B(StaContextSlot), R(context), U8(first_context_slot), // | |
5887 B(CreateMappedArguments), // | |
5888 B(Star), R(0), // | |
5889 B(StackCheck), // | |
5890 B(Ldar), R(0), // | |
5891 B(Return), // | |
5892 }}, | |
5893 {"function f(a, b, c) { 'use strict'; return arguments; }", | |
5894 1 * kPointerSize, | |
5895 4, | |
5896 7, | |
5897 { | |
5898 B(CreateUnmappedArguments), // | |
5899 B(Star), R(0), // | |
5900 B(StackCheck), // | |
5901 B(Ldar), R(0), // | |
5902 B(Return), // | |
5903 }}, | |
5904 }; | |
5905 // clang-format on | |
5906 | |
5907 for (size_t i = 0; i < arraysize(snippets); i++) { | |
5908 Handle<BytecodeArray> bytecode_array = | |
5909 helper.MakeBytecodeForFunction(snippets[i].code_snippet); | |
5910 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
5911 } | |
5912 } | 1471 } |
5913 | 1472 |
5914 TEST(CreateRestParameter) { | 1473 TEST(CreateRestParameter) { |
5915 InitializedHandleScope handle_scope; | 1474 InitializedIgnitionHandleScope scope; |
5916 BytecodeGeneratorHelper helper; | 1475 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
5917 Zone zone; | 1476 ConstantPoolType::kNumber); |
5918 | 1477 printer.set_wrap(false); |
5919 FeedbackVectorSpec feedback_spec(&zone); | 1478 printer.set_test_function_name("f"); |
5920 FeedbackVectorSlot slot = feedback_spec.AddKeyedLoadICSlot(); | 1479 |
5921 FeedbackVectorSlot slot1 = feedback_spec.AddKeyedLoadICSlot(); | 1480 const char* snippets[] = { |
5922 | 1481 "function f(...restArgs) { return restArgs; }", |
5923 Handle<i::TypeFeedbackVector> vector = | 1482 |
5924 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); | 1483 "function f(a, ...restArgs) { return restArgs; }", |
5925 | 1484 |
5926 // clang-format off | 1485 "function f(a, ...restArgs) { return restArgs[0]; }", |
5927 ExpectedSnippet<int> snippets[] = { | 1486 |
5928 {"function f(...restArgs) { return restArgs; }", | 1487 "function f(a, ...restArgs) { return restArgs[0] + arguments[0]; }", |
5929 1 * kPointerSize, | 1488 }; |
5930 1, | 1489 |
5931 7, | 1490 CHECK_EQ(BuildActual(printer, snippets, "", "\nf();"), |
5932 { | 1491 LoadGolden("CreateRestParameter.golden")); |
5933 B(CreateRestParameter), // | |
5934 B(Star), R(0), // | |
5935 B(StackCheck), // | |
5936 B(Ldar), R(0), // | |
5937 B(Return), // | |
5938 }, | |
5939 0, | |
5940 {}}, | |
5941 {"function f(a, ...restArgs) { return restArgs; }", | |
5942 2 * kPointerSize, | |
5943 2, | |
5944 14, | |
5945 { | |
5946 B(CreateRestParameter), // | |
5947 B(Star), R(0), // | |
5948 B(LdaTheHole), // | |
5949 B(Star), R(1), // | |
5950 B(StackCheck), // | |
5951 B(Ldar), A(1, 2), // | |
5952 B(Star), R(1), // | |
5953 B(Ldar), R(0), // | |
5954 B(Return), // | |
5955 }, | |
5956 0, | |
5957 {}}, | |
5958 {"function f(a, ...restArgs) { return restArgs[0]; }", | |
5959 3 * kPointerSize, | |
5960 2, | |
5961 20, | |
5962 { | |
5963 B(CreateRestParameter), // | |
5964 B(Star), R(0), // | |
5965 B(LdaTheHole), // | |
5966 B(Star), R(1), // | |
5967 B(StackCheck), // | |
5968 B(Ldar), A(1, 2), // | |
5969 B(Star), R(1), // | |
5970 B(Ldar), R(0), // | |
5971 B(Star), R(2), // | |
5972 B(LdaZero), // | |
5973 B(KeyedLoadIC), R(2), U8(vector->GetIndex(slot)), // | |
5974 B(Return), // | |
5975 }, | |
5976 0, | |
5977 {}}, | |
5978 {"function f(a, ...restArgs) { return restArgs[0] + arguments[0]; }", | |
5979 5 * kPointerSize, | |
5980 2, | |
5981 35, | |
5982 { | |
5983 B(CreateUnmappedArguments), // | |
5984 B(Star), R(0), // | |
5985 B(CreateRestParameter), // | |
5986 B(Star), R(1), // | |
5987 B(LdaTheHole), // | |
5988 B(Star), R(2), // | |
5989 B(StackCheck), // | |
5990 B(Ldar), A(1, 2), // | |
5991 B(Star), R(2), // | |
5992 B(Ldar), R(1), // | |
5993 B(Star), R(3), // | |
5994 B(LdaZero), // | |
5995 B(KeyedLoadIC), R(3), U8(vector->GetIndex(slot)), // | |
5996 B(Star), R(4), // | |
5997 B(Ldar), R(0), // | |
5998 B(Star), R(3), // | |
5999 B(LdaZero), // | |
6000 B(KeyedLoadIC), R(3), U8(vector->GetIndex(slot1)), // | |
6001 B(Add), R(4), // | |
6002 B(Return), // | |
6003 }, | |
6004 0, | |
6005 {}}, | |
6006 }; | |
6007 // clang-format on | |
6008 | |
6009 for (size_t i = 0; i < arraysize(snippets); i++) { | |
6010 Handle<BytecodeArray> bytecode_array = | |
6011 helper.MakeBytecodeForFunction(snippets[i].code_snippet); | |
6012 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
6013 } | |
6014 } | 1492 } |
6015 | 1493 |
6016 TEST(IllegalRedeclaration) { | 1494 TEST(IllegalRedeclaration) { |
6017 bool old_legacy_const_flag = FLAG_legacy_const; | 1495 bool old_legacy_const_flag = FLAG_legacy_const; |
6018 FLAG_legacy_const = true; | 1496 FLAG_legacy_const = true; |
6019 | 1497 |
6020 InitializedHandleScope handle_scope; | |
6021 BytecodeGeneratorHelper helper; | |
6022 | |
6023 CHECK_GE(MessageTemplate::kVarRedeclaration, 128); | 1498 CHECK_GE(MessageTemplate::kVarRedeclaration, 128); |
6024 // Must adapt bytecode if this changes. | 1499 // Must adapt bytecode if this changes. |
6025 | 1500 |
6026 // clang-format off | 1501 InitializedIgnitionHandleScope scope; |
6027 ExpectedSnippet<Handle<Object>, 2> snippets[] = { | 1502 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
6028 {"const a = 1; { var a = 2; }", | 1503 ConstantPoolType::kMixed); |
6029 3 * kPointerSize, | 1504 const char* snippets[] = {"const a = 1; { var a = 2; }"}; |
6030 1, | 1505 |
6031 14, | 1506 CHECK_EQ(BuildActual(printer, snippets), |
6032 { | 1507 LoadGolden("IllegalRedeclaration.golden")); |
6033 B(LdaConstant), U8(0), // | |
6034 B(Star), R(1), // | |
6035 B(LdaConstant), U8(1), // | |
6036 B(Star), R(2), // | |
6037 B(CallRuntime), U16(Runtime::kNewSyntaxError), R(1), U8(2), // | |
6038 B(Throw), // | |
6039 }, | |
6040 2, | |
6041 {helper.factory()->NewNumberFromInt(MessageTemplate::kVarRedeclaration), | |
6042 helper.factory()->NewStringFromAsciiChecked("a")}}, | |
6043 }; | |
6044 // clang-format on | |
6045 | |
6046 for (size_t i = 0; i < arraysize(snippets); i++) { | |
6047 Handle<BytecodeArray> bytecode_array = | |
6048 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
6049 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
6050 } | |
6051 | 1508 |
6052 FLAG_legacy_const = old_legacy_const_flag; | 1509 FLAG_legacy_const = old_legacy_const_flag; |
6053 } | 1510 } |
6054 | 1511 |
6055 | |
6056 TEST(ForIn) { | 1512 TEST(ForIn) { |
6057 InitializedHandleScope handle_scope; | 1513 InitializedIgnitionHandleScope scope; |
6058 BytecodeGeneratorHelper helper; | 1514 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
6059 Zone zone; | 1515 ConstantPoolType::kMixed); |
6060 | 1516 const char* snippets[] = { |
6061 int simple_flags = | 1517 "for (var p in null) {}", |
6062 ArrayLiteral::kDisableMementos | ArrayLiteral::kShallowElements; | 1518 |
6063 int deep_elements_flags = | 1519 "for (var p in undefined) {}", |
6064 ObjectLiteral::kFastElements | ObjectLiteral::kDisableMementos; | 1520 |
6065 | 1521 "for (var p in undefined) {}", |
6066 FeedbackVectorSpec feedback_spec(&zone); | 1522 |
6067 feedback_spec.AddStoreICSlot(); | 1523 "var x = 'potatoes';\n" |
6068 FeedbackVectorSlot slot2 = feedback_spec.AddStoreICSlot(); | 1524 "for (var p in x) { return p; }", |
6069 FeedbackVectorSlot slot3 = feedback_spec.AddStoreICSlot(); | 1525 |
6070 FeedbackVectorSlot slot4 = feedback_spec.AddStoreICSlot(); | 1526 "var x = 0;\n" |
6071 Handle<i::TypeFeedbackVector> vector = | 1527 "for (var p in [1,2,3]) { x += p; }", |
6072 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); | 1528 |
6073 | 1529 "var x = { 'a': 1, 'b': 2 };\n" |
6074 // clang-format off | 1530 "for (x['a'] in [10, 20, 30]) {\n" |
6075 ExpectedSnippet<InstanceType> snippets[] = { | 1531 " if (x['a'] == 10) continue;\n" |
6076 {"for (var p in null) {}", | 1532 " if (x['a'] == 20) break;\n" |
6077 2 * kPointerSize, | 1533 "}", |
6078 1, | 1534 |
6079 3, | 1535 "var x = [ 10, 11, 12 ] ;\n" |
6080 { | 1536 "for (x[0] in [1,2,3]) { return x[3]; }", |
6081 B(StackCheck), // | 1537 }; |
6082 B(LdaUndefined), // | 1538 |
6083 B(Return) // | 1539 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("ForIn.golden")); |
6084 }, | 1540 } |
6085 0}, | 1541 |
6086 {"for (var p in undefined) {}", | 1542 TEST(ForOf) { |
6087 2 * kPointerSize, | 1543 InitializedIgnitionHandleScope scope; |
6088 1, | 1544 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
6089 3, | 1545 ConstantPoolType::kMixed); |
6090 { | 1546 const char* snippets[] = { |
6091 B(StackCheck), // | 1547 "for (var p of [0, 1, 2]) {}", |
6092 B(LdaUndefined), // | 1548 |
6093 B(Return) // | 1549 "var x = 'potatoes';\n" |
6094 }, | 1550 "for (var p of x) { return p; }", |
6095 0}, | 1551 |
6096 {"for (var p in undefined) {}", | 1552 "for (var x of [10, 20, 30]) {\n" |
6097 2 * kPointerSize, | 1553 " if (x == 10) continue;\n" |
6098 1, | 1554 " if (x == 20) break;\n" |
6099 3, | 1555 "}", |
6100 { | 1556 |
6101 B(StackCheck), // | 1557 "var x = { 'a': 1, 'b': 2 };\n" |
6102 B(LdaUndefined), // | 1558 "for (x['a'] of [1,2,3]) { return x['a']; }", |
6103 B(Return) // | 1559 }; |
6104 }, | 1560 |
6105 0}, | 1561 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("ForOf.golden")); |
6106 {"var x = 'potatoes';\n" | 1562 } |
6107 "for (var p in x) { return p; }", | |
6108 8 * kPointerSize, | |
6109 1, | |
6110 46, | |
6111 { | |
6112 B(StackCheck), // | |
6113 B(LdaConstant), U8(0), // | |
6114 B(Star), R(1), // | |
6115 B(JumpIfUndefined), U8(39), // | |
6116 B(JumpIfNull), U8(37), // | |
6117 B(ToObject), // | |
6118 B(JumpIfNull), U8(34), // | |
6119 B(Star), R(3), // | |
6120 B(ForInPrepare), R(4), // | |
6121 B(LdaZero), // | |
6122 B(Star), R(7), // | |
6123 B(ForInDone), R(7), R(6), // | |
6124 B(JumpIfTrue), U8(22), // | |
6125 B(ForInNext), R(3), R(7), R(4), // | |
6126 B(JumpIfUndefined), U8(10), // | |
6127 B(Star), R(0), // | |
6128 B(StackCheck), // | |
6129 B(Ldar), R(0), // | |
6130 B(Star), R(2), // | |
6131 B(Return), // | |
6132 B(ForInStep), R(7), // | |
6133 B(Star), R(7), // | |
6134 B(Jump), U8(-23), // | |
6135 B(LdaUndefined), // | |
6136 B(Return), // | |
6137 }, | |
6138 1, | |
6139 {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
6140 {"var x = 0;\n" | |
6141 "for (var p in [1,2,3]) { x += p; }", | |
6142 9 * kPointerSize, | |
6143 1, | |
6144 58, | |
6145 { | |
6146 B(StackCheck), // | |
6147 B(LdaZero), // | |
6148 B(Star), R(1), // | |
6149 B(CreateArrayLiteral), U8(0), U8(0), U8(3), // | |
6150 B(JumpIfUndefined), U8(48), // | |
6151 B(JumpIfNull), U8(46), // | |
6152 B(ToObject), // | |
6153 B(JumpIfNull), U8(43), // | |
6154 B(Star), R(3), // | |
6155 B(ForInPrepare), R(4), // | |
6156 B(LdaZero), // | |
6157 B(Star), R(7), // | |
6158 B(ForInDone), R(7), R(6), // | |
6159 B(JumpIfTrue), U8(31), // | |
6160 B(ForInNext), R(3), R(7), R(4), // | |
6161 B(JumpIfUndefined), U8(19), // | |
6162 B(Star), R(0), // | |
6163 B(StackCheck), // | |
6164 B(Ldar), R(0), // | |
6165 B(Star), R(2), // | |
6166 B(Ldar), R(1), // | |
6167 B(Star), R(8), // | |
6168 B(Ldar), R(2), // | |
6169 B(Add), R(8), // | |
6170 B(Star), R(1), // | |
6171 B(ForInStep), R(7), // | |
6172 B(Star), R(7), // | |
6173 B(Jump), U8(-32), // | |
6174 B(LdaUndefined), // | |
6175 B(Return), // | |
6176 }, | |
6177 1, | |
6178 {InstanceType::FIXED_ARRAY_TYPE}}, | |
6179 {"var x = { 'a': 1, 'b': 2 };\n" | |
6180 "for (x['a'] in [10, 20, 30]) {\n" | |
6181 " if (x['a'] == 10) continue;\n" | |
6182 " if (x['a'] == 20) break;\n" | |
6183 "}", | |
6184 8 * kPointerSize, | |
6185 1, | |
6186 95, | |
6187 { | |
6188 B(StackCheck), // | |
6189 B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags), // | |
6190 B(Star), R(1), // | |
6191 B(Star), R(0), // | |
6192 B(CreateArrayLiteral), U8(1), U8(1), U8(simple_flags), // | |
6193 B(JumpIfUndefined), U8(80), // | |
6194 B(JumpIfNull), U8(78), // | |
6195 B(ToObject), // | |
6196 B(JumpIfNull), U8(75), // | |
6197 B(Star), R(1), // | |
6198 B(ForInPrepare), R(2), // | |
6199 B(LdaZero), // | |
6200 B(Star), R(5), // | |
6201 B(ForInDone), R(5), R(4), // | |
6202 B(JumpIfTrue), U8(63), // | |
6203 B(ForInNext), R(1), R(5), R(2), // | |
6204 B(JumpIfUndefined), U8(51), // | |
6205 B(Star), R(6), // | |
6206 B(Ldar), R(0), // | |
6207 B(Star), R(7), // | |
6208 B(Ldar), R(6), // | |
6209 B(StoreICSloppy), R(7), U8(2), U8(vector->GetIndex(slot4)), // | |
6210 B(StackCheck), // | |
6211 B(Ldar), R(0), // | |
6212 B(Star), R(6), // | |
6213 B(LoadIC), R(6), U8(2), U8(vector->GetIndex(slot2)), // | |
6214 B(Star), R(7), // | |
6215 B(LdaSmi8), U8(10), // | |
6216 B(TestEqual), R(7), // | |
6217 B(JumpIfFalse), U8(4), // | |
6218 B(Jump), U8(20), // | |
6219 B(Ldar), R(0), // | |
6220 B(Star), R(6), // | |
6221 B(LoadIC), R(6), U8(2), U8(vector->GetIndex(slot3)), // | |
6222 B(Star), R(7), // | |
6223 B(LdaSmi8), U8(20), // | |
6224 B(TestEqual), R(7), // | |
6225 B(JumpIfFalse), U8(4), // | |
6226 B(Jump), U8(8), // | |
6227 B(ForInStep), R(5), // | |
6228 B(Star), R(5), // | |
6229 B(Jump), U8(-64), // | |
6230 B(LdaUndefined), // | |
6231 B(Return), // | |
6232 }, | |
6233 3, | |
6234 {InstanceType::FIXED_ARRAY_TYPE, InstanceType::FIXED_ARRAY_TYPE, | |
6235 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
6236 {"var x = [ 10, 11, 12 ] ;\n" | |
6237 "for (x[0] in [1,2,3]) { return x[3]; }", | |
6238 9 * kPointerSize, | |
6239 1, | |
6240 70, | |
6241 { | |
6242 B(StackCheck), // | |
6243 B(CreateArrayLiteral), U8(0), U8(0), U8(simple_flags), // | |
6244 B(Star), R(0), // | |
6245 B(CreateArrayLiteral), U8(1), U8(1), U8(simple_flags), // | |
6246 B(JumpIfUndefined), U8(57), // | |
6247 B(JumpIfNull), U8(55), // | |
6248 B(ToObject), // | |
6249 B(JumpIfNull), U8(52), // | |
6250 B(Star), R(1), // | |
6251 B(ForInPrepare), R(2), // | |
6252 B(LdaZero), // | |
6253 B(Star), R(5), // | |
6254 B(ForInDone), R(5), R(4), // | |
6255 B(JumpIfTrue), U8(40), // | |
6256 B(ForInNext), R(1), R(5), R(2), // | |
6257 B(JumpIfUndefined), U8(28), // | |
6258 B(Star), R(6), // | |
6259 B(Ldar), R(0), // | |
6260 B(Star), R(7), // | |
6261 B(LdaZero), // | |
6262 B(Star), R(8), // | |
6263 B(Ldar), R(6), // | |
6264 B(KeyedStoreICSloppy), R(7), R(8), U8(vector->GetIndex(slot3)), // | |
6265 B(StackCheck), // | |
6266 B(Ldar), R(0), // | |
6267 B(Star), R(6), // | |
6268 B(LdaSmi8), U8(3), // | |
6269 B(KeyedLoadIC), R(6), U8(vector->GetIndex(slot2)), // | |
6270 B(Return), // | |
6271 B(ForInStep), R(5), // | |
6272 B(Star), R(5), // | |
6273 B(Jump), U8(-41), // | |
6274 B(LdaUndefined), // | |
6275 B(Return), // | |
6276 }, | |
6277 2, | |
6278 {InstanceType::FIXED_ARRAY_TYPE, InstanceType::FIXED_ARRAY_TYPE}}, | |
6279 }; | |
6280 // clang-format on | |
6281 | |
6282 for (size_t i = 0; i < arraysize(snippets); i++) { | |
6283 Handle<BytecodeArray> bytecode_array = | |
6284 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
6285 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
6286 } | |
6287 } | |
6288 | |
6289 | |
6290 // TODO(rmcilroy): Do something about this; new bytecode is too large | |
6291 // (150+ instructions) to adapt manually. | |
6292 DISABLED_TEST(ForOf) { | |
6293 InitializedHandleScope handle_scope; | |
6294 BytecodeGeneratorHelper helper; | |
6295 Zone zone; | |
6296 | |
6297 int array_literal_flags = | |
6298 ArrayLiteral::kDisableMementos | ArrayLiteral::kShallowElements; | |
6299 int object_literal_flags = | |
6300 ObjectLiteral::kFastElements | ObjectLiteral::kDisableMementos; | |
6301 | |
6302 FeedbackVectorSpec feedback_spec(&zone); | |
6303 FeedbackVectorSlot slot1 = feedback_spec.AddCallICSlot(); | |
6304 FeedbackVectorSlot slot2 = feedback_spec.AddKeyedLoadICSlot(); | |
6305 FeedbackVectorSlot slot3 = feedback_spec.AddCallICSlot(); | |
6306 FeedbackVectorSlot slot4 = feedback_spec.AddLoadICSlot(); | |
6307 FeedbackVectorSlot slot5 = feedback_spec.AddLoadICSlot(); | |
6308 FeedbackVectorSlot slot6 = feedback_spec.AddLoadICSlot(); | |
6309 FeedbackVectorSlot slot7 = feedback_spec.AddStoreICSlot(); | |
6310 FeedbackVectorSlot slot8 = feedback_spec.AddLoadICSlot(); | |
6311 Handle<i::TypeFeedbackVector> vector = | |
6312 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); | |
6313 | |
6314 // clang-format off | |
6315 ExpectedSnippet<InstanceType, 8> snippets[] = { | |
6316 {"for (var p of [0, 1, 2]) {}", | |
6317 7 * kPointerSize, | |
6318 1, | |
6319 86, | |
6320 { | |
6321 B(StackCheck), // | |
6322 B(CreateArrayLiteral), U8(0), U8(0), U8(array_literal_flags), // | |
6323 B(Star), R(5), // | |
6324 B(LdaConstant), U8(1), // | |
6325 B(KeyedLoadIC), R(5), U8(vector->GetIndex(slot2)), // | |
6326 B(Star), R(4), // | |
6327 B(Call), R(4), R(5), U8(1), U8(vector->GetIndex(slot1)), // | |
6328 B(Star), R(1), // | |
6329 B(Ldar), R(1), // | |
6330 B(Star), R(6), // | |
6331 B(LoadIC), R(6), U8(2), U8(vector->GetIndex(slot4)), // | |
6332 B(Star), R(5), // | |
6333 B(Call), R(5), R(6), U8(1), U8(vector->GetIndex(slot3)), // | |
6334 B(Star), R(2), // | |
6335 B(Star), R(4), // | |
6336 B(CallRuntime), U16(Runtime::kInlineIsJSReceiver), R(4), U8(1), // | |
6337 B(LogicalNot), // | |
6338 B(JumpIfFalse), U8(11), // | |
6339 B(Ldar), R(2), // | |
6340 B(Star), R(4), // | |
6341 B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), // | |
6342 /* */ R(4), U8(1), // | |
6343 B(Ldar), R(2), // | |
6344 B(Star), R(4), // | |
6345 B(LoadIC), R(4), U8(3), U8(vector->GetIndex(slot5)), // | |
6346 B(JumpIfToBooleanTrue), U8(19), // | |
6347 B(Ldar), R(2), // | |
6348 B(Star), R(4), // | |
6349 B(LoadIC), R(4), U8(4), U8(vector->GetIndex(slot6)), // | |
6350 B(Star), R(0), // | |
6351 B(StackCheck), // | |
6352 B(Ldar), R(0), // | |
6353 B(Star), R(3), // | |
6354 B(Jump), U8(-61), // | |
6355 B(LdaUndefined), // | |
6356 B(Return), // | |
6357 }, | |
6358 5, | |
6359 {InstanceType::FIXED_ARRAY_TYPE, InstanceType::SYMBOL_TYPE, | |
6360 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
6361 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
6362 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
6363 {"var x = 'potatoes';\n" | |
6364 "for (var p of x) { return p; }", | |
6365 8 * kPointerSize, | |
6366 1, | |
6367 85, | |
6368 { | |
6369 B(StackCheck), // | |
6370 B(LdaConstant), U8(0), // | |
6371 B(Star), R(3), // | |
6372 B(Star), R(6), // | |
6373 B(LdaConstant), U8(1), // | |
6374 B(KeyedLoadIC), R(6), U8(vector->GetIndex(slot2)), // | |
6375 B(Star), R(5), // | |
6376 B(Call), R(5), R(6), U8(1), U8(vector->GetIndex(slot1)), // | |
6377 B(Star), R(1), // | |
6378 B(Ldar), R(1), // | |
6379 B(Star), R(7), // | |
6380 B(LoadIC), R(7), U8(2), U8(vector->GetIndex(slot4)), // | |
6381 B(Star), R(6), // | |
6382 B(Call), R(6), R(7), U8(1), U8(vector->GetIndex(slot3)), // | |
6383 B(Star), R(2), // | |
6384 B(Star), R(5), // | |
6385 B(CallRuntime), U16(Runtime::kInlineIsJSReceiver), R(5), U8(1), // | |
6386 B(LogicalNot), // | |
6387 B(JumpIfFalse), U8(11), // | |
6388 B(Ldar), R(2), // | |
6389 B(Star), R(5), // | |
6390 B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), // | |
6391 /* */ R(5), U8(1), // | |
6392 B(Ldar), R(2), // | |
6393 B(Star), R(5), // | |
6394 B(LoadIC), R(5), U8(3), U8(vector->GetIndex(slot5)), // | |
6395 B(JumpIfToBooleanTrue), U8(18), // | |
6396 B(Ldar), R(2), // | |
6397 B(Star), R(5), // | |
6398 B(LoadIC), R(5), U8(4), U8(vector->GetIndex(slot6)), // | |
6399 B(Star), R(0), // | |
6400 B(StackCheck), // | |
6401 B(Ldar), R(0), // | |
6402 B(Star), R(4), // | |
6403 B(Return), // | |
6404 B(LdaUndefined), // | |
6405 B(Return), // | |
6406 }, | |
6407 5, | |
6408 {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
6409 InstanceType::SYMBOL_TYPE, | |
6410 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
6411 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
6412 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
6413 {"for (var x of [10, 20, 30]) {\n" | |
6414 " if (x == 10) continue;\n" | |
6415 " if (x == 20) break;\n" | |
6416 "}", | |
6417 7 * kPointerSize, | |
6418 1, | |
6419 108, | |
6420 { | |
6421 B(StackCheck), // | |
6422 B(CreateArrayLiteral), U8(0), U8(0), U8(array_literal_flags), // | |
6423 B(Star), R(5), // | |
6424 B(LdaConstant), U8(1), // | |
6425 B(KeyedLoadIC), R(5), U8(vector->GetIndex(slot2)), // | |
6426 B(Star), R(4), // | |
6427 B(Call), R(4), R(5), U8(1), U8(vector->GetIndex(slot1)), // | |
6428 B(Star), R(1), // | |
6429 B(Ldar), R(1), // | |
6430 B(Star), R(6), // | |
6431 B(LoadIC), R(6), U8(2), U8(vector->GetIndex(slot4)), // | |
6432 B(Star), R(5), // | |
6433 B(Call), R(5), R(6), U8(1), U8(vector->GetIndex(slot3)), // | |
6434 B(Star), R(2), // | |
6435 B(Star), R(4), // | |
6436 B(CallRuntime), U16(Runtime::kInlineIsJSReceiver), R(4), U8(1), // | |
6437 B(LogicalNot), // | |
6438 B(JumpIfFalse), U8(11), // | |
6439 B(Ldar), R(2), // | |
6440 B(Star), R(4), // | |
6441 B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), // | |
6442 /* */ R(4), U8(1), // | |
6443 B(Ldar), R(2), // | |
6444 B(Star), R(4), // | |
6445 B(LoadIC), R(4), U8(3), U8(vector->GetIndex(slot5)), // | |
6446 B(JumpIfToBooleanTrue), U8(41), // | |
6447 B(Ldar), R(2), // | |
6448 B(Star), R(4), // | |
6449 B(LoadIC), R(4), U8(4), U8(vector->GetIndex(slot6)), // | |
6450 B(Star), R(0), // | |
6451 B(StackCheck), // | |
6452 B(Ldar), R(0), // | |
6453 B(Star), R(3), // | |
6454 B(Star), R(4), // | |
6455 B(LdaSmi8), U8(10), // | |
6456 B(TestEqual), R(4), // | |
6457 B(JumpIfFalse), U8(4), // | |
6458 B(Jump), U8(-69), // | |
6459 B(Ldar), R(3), // | |
6460 B(Star), R(4), // | |
6461 B(LdaSmi8), U8(20), // | |
6462 B(TestEqual), R(4), // | |
6463 B(JumpIfFalse), U8(4), // | |
6464 B(Jump), U8(4), // | |
6465 B(Jump), U8(-83), // | |
6466 B(LdaUndefined), // | |
6467 B(Return), // | |
6468 }, | |
6469 5, | |
6470 {InstanceType::FIXED_ARRAY_TYPE, InstanceType::SYMBOL_TYPE, | |
6471 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
6472 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
6473 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
6474 {"var x = { 'a': 1, 'b': 2 };\n" | |
6475 "for (x['a'] of [1,2,3]) { return x['a']; }", | |
6476 6 * kPointerSize, | |
6477 1, | |
6478 103, | |
6479 { | |
6480 B(StackCheck), // | |
6481 B(CreateObjectLiteral), U8(0), U8(0), U8(object_literal_flags), // | |
6482 B(Star), R(3), // | |
6483 B(Star), R(2), // | |
6484 B(CreateArrayLiteral), U8(1), U8(1), U8(array_literal_flags), // | |
6485 B(Star), R(4), // | |
6486 B(LdaConstant), U8(2), // | |
6487 B(KeyedLoadIC), R(4), U8(vector->GetIndex(slot2)), // | |
6488 B(Star), R(3), // | |
6489 B(Call), R(3), R(4), U8(1), U8(vector->GetIndex(slot1)), // | |
6490 B(Star), R(0), // | |
6491 B(Ldar), R(0), // | |
6492 B(Star), R(5), // | |
6493 B(LoadIC), R(5), U8(3), U8(vector->GetIndex(slot4)), // | |
6494 B(Star), R(4), // | |
6495 B(Call), R(4), R(5), U8(1), U8(vector->GetIndex(slot3)), // | |
6496 B(Star), R(1), // | |
6497 B(Star), R(3), // | |
6498 B(CallRuntime), U16(Runtime::kInlineIsJSReceiver), R(3), U8(1), // | |
6499 B(LogicalNot), // | |
6500 B(JumpIfFalse), U8(11), // | |
6501 B(Ldar), R(1), // | |
6502 B(Star), R(3), // | |
6503 B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), // | |
6504 /* */ R(3), U8(1), // | |
6505 B(Ldar), R(1), // | |
6506 B(Star), R(3), // | |
6507 B(LoadIC), R(3), U8(4), U8(vector->GetIndex(slot5)), // | |
6508 B(JumpIfToBooleanTrue), U8(28), // | |
6509 B(Ldar), R(2), // | |
6510 B(Star), R(3), // | |
6511 B(Ldar), R(1), // | |
6512 B(Star), R(4), // | |
6513 B(LoadIC), R(4), U8(5), U8(vector->GetIndex(slot6)), // | |
6514 B(StoreICSloppy), R(3), U8(6), U8(vector->GetIndex(slot7)), // | |
6515 B(StackCheck), // | |
6516 B(Ldar), R(2), // | |
6517 B(Star), R(3), // | |
6518 B(LoadIC), R(3), U8(6), U8(vector->GetIndex(slot8)), // | |
6519 B(Return), // | |
6520 B(LdaUndefined), // | |
6521 B(Return), // | |
6522 }, | |
6523 7, | |
6524 {InstanceType::FIXED_ARRAY_TYPE, | |
6525 InstanceType::FIXED_ARRAY_TYPE, | |
6526 InstanceType::SYMBOL_TYPE, | |
6527 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
6528 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
6529 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
6530 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
6531 }; | |
6532 // clang-format on | |
6533 | |
6534 for (size_t i = 0; i < arraysize(snippets); i++) { | |
6535 Handle<BytecodeArray> bytecode_array = | |
6536 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
6537 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
6538 } | |
6539 } | |
6540 | |
6541 | 1563 |
6542 TEST(Conditional) { | 1564 TEST(Conditional) { |
6543 InitializedHandleScope handle_scope; | 1565 InitializedIgnitionHandleScope scope; |
6544 BytecodeGeneratorHelper helper; | 1566 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
6545 | 1567 ConstantPoolType::kNumber); |
6546 // clang-format off | 1568 const char* snippets[] = { |
6547 ExpectedSnippet<int> snippets[] = { | 1569 "return 1 ? 2 : 3;", |
6548 {"return 1 ? 2 : 3;", | 1570 |
6549 0, | 1571 "return 1 ? 2 ? 3 : 4 : 5;", |
6550 1, | 1572 }; |
6551 12, | 1573 |
6552 { | 1574 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("Conditional.golden")); |
6553 B(StackCheck), // | 1575 } |
6554 B(LdaSmi8), U8(1), // | |
6555 B(JumpIfToBooleanFalse), U8(6), // | |
6556 B(LdaSmi8), U8(2), // | |
6557 B(Jump), U8(4), // | |
6558 B(LdaSmi8), U8(3), // | |
6559 B(Return), // | |
6560 }}, | |
6561 {"return 1 ? 2 ? 3 : 4 : 5;", | |
6562 0, | |
6563 1, | |
6564 20, | |
6565 { | |
6566 B(StackCheck), // | |
6567 B(LdaSmi8), U8(1), // | |
6568 B(JumpIfToBooleanFalse), U8(14), // | |
6569 B(LdaSmi8), U8(2), // | |
6570 B(JumpIfToBooleanFalse), U8(6), // | |
6571 B(LdaSmi8), U8(3), // | |
6572 B(Jump), U8(4), // | |
6573 B(LdaSmi8), U8(4), // | |
6574 B(Jump), U8(4), // | |
6575 B(LdaSmi8), U8(5), // | |
6576 B(Return), // | |
6577 }}, | |
6578 }; | |
6579 // clang-format on | |
6580 | |
6581 for (size_t i = 0; i < arraysize(snippets); i++) { | |
6582 Handle<BytecodeArray> bytecode_array = | |
6583 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
6584 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
6585 } | |
6586 } | |
6587 | |
6588 | 1576 |
6589 TEST(Switch) { | 1577 TEST(Switch) { |
6590 InitializedHandleScope handle_scope; | 1578 InitializedIgnitionHandleScope scope; |
6591 BytecodeGeneratorHelper helper; | 1579 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
6592 | 1580 ConstantPoolType::kNumber); |
6593 // clang-format off | 1581 const char* snippets[] = { |
6594 ExpectedSnippet<int> snippets[] = { | 1582 "var a = 1;\n" |
6595 {"var a = 1;\n" | 1583 "switch(a) {\n" |
6596 "switch(a) {\n" | 1584 " case 1: return 2;\n" |
6597 " case 1: return 2;\n" | 1585 " case 2: return 3;\n" |
6598 " case 2: return 3;\n" | 1586 "}", |
6599 "}\n", | 1587 |
6600 3 * kPointerSize, | 1588 "var a = 1;\n" |
6601 1, | 1589 "switch(a) {\n" |
6602 31, | 1590 " case 1: a = 2; break;\n" |
6603 { | 1591 " case 2: a = 3; break;\n" |
6604 B(StackCheck), // | 1592 "}", |
6605 B(LdaSmi8), U8(1), // | 1593 |
6606 B(Star), R(1), // The tag variable is allocated as a | 1594 "var a = 1;\n" |
6607 B(Star), R(0), // local by the parser, hence the store | 1595 "switch(a) {\n" |
6608 B(Star), R(2), // to another local register. | 1596 " case 1: a = 2; // fall-through\n" |
6609 B(LdaSmi8), U8(1), // | 1597 " case 2: a = 3; break;\n" |
6610 B(TestEqualStrict), R(2), // | 1598 "}", |
6611 B(JumpIfTrue), U8(10), // | 1599 |
6612 B(LdaSmi8), U8(2), // | 1600 "var a = 1;\n" |
6613 B(TestEqualStrict), R(2), // | 1601 "switch(a) {\n" |
6614 B(JumpIfTrue), U8(7), // | 1602 " case 2: break;\n" |
6615 B(Jump), U8(8), // | 1603 " case 3: break;\n" |
6616 B(LdaSmi8), U8(2), // | 1604 " default: a = 1; break;\n" |
6617 B(Return), // | 1605 "}", |
6618 B(LdaSmi8), U8(3), // | 1606 |
6619 B(Return), // | 1607 "var a = 1;\n" |
6620 B(LdaUndefined), // | 1608 "switch(typeof(a)) {\n" |
6621 B(Return), // | 1609 " case 2: a = 1; break;\n" |
6622 }}, | 1610 " case 3: a = 2; break;\n" |
6623 {"var a = 1;\n" | 1611 " default: a = 3; break;\n" |
6624 "switch(a) {\n" | 1612 "}", |
6625 " case 1: a = 2; break;\n" | 1613 |
6626 " case 2: a = 3; break;\n" | 1614 "var a = 1;\n" |
6627 "}\n", | 1615 "switch(a) {\n" |
6628 3 * kPointerSize, | 1616 " case typeof(a): a = 1; break;\n" |
6629 1, | 1617 " default: a = 2; break;\n" |
6630 37, | 1618 "}", |
6631 { | 1619 |
6632 B(StackCheck), // | 1620 "var a = 1;\n" |
6633 B(LdaSmi8), U8(1), // | 1621 "switch(a) {\n" |
6634 B(Star), R(1), // | 1622 " case 1:\n" |
6635 B(Star), R(0), // | 1623 REPEAT_64(" a = 2;\n") |
6636 B(Star), R(2), // | 1624 " break;\n" |
6637 B(LdaSmi8), U8(1), // | 1625 " case 2:\n" |
6638 B(TestEqualStrict), R(2), // | 1626 " a = 3;\n" |
6639 B(JumpIfTrue), U8(10), // | 1627 " break;\n" |
6640 B(LdaSmi8), U8(2), // | 1628 "}", |
6641 B(TestEqualStrict), R(2), // | 1629 |
6642 B(JumpIfTrue), U8(10), // | 1630 "var a = 1;\n" |
6643 B(Jump), U8(14), // | 1631 "switch(a) {\n" |
6644 B(LdaSmi8), U8(2), // | 1632 " case 1: \n" |
6645 B(Star), R(1), // | 1633 " switch(a + 1) {\n" |
6646 B(Jump), U8(8), // | 1634 " case 2 : a = 1; break;\n" |
6647 B(LdaSmi8), U8(3), // | 1635 " default : a = 2; break;\n" |
6648 B(Star), R(1), // | 1636 " } // fall-through\n" |
6649 B(Jump), U8(2), // | 1637 " case 2: a = 3;\n" |
6650 B(LdaUndefined), // | 1638 "}", |
6651 B(Return), // | 1639 }; |
6652 }}, | 1640 |
6653 {"var a = 1;\n" | 1641 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("Switch.golden")); |
6654 "switch(a) {\n" | 1642 } |
6655 " case 1: a = 2; // fall-through\n" | |
6656 " case 2: a = 3; break;\n" | |
6657 "}\n", | |
6658 3 * kPointerSize, | |
6659 1, | |
6660 35, | |
6661 { | |
6662 B(StackCheck), // | |
6663 B(LdaSmi8), U8(1), // | |
6664 B(Star), R(1), // | |
6665 B(Star), R(0), // | |
6666 B(Star), R(2), // | |
6667 B(LdaSmi8), U8(1), // | |
6668 B(TestEqualStrict), R(2), // | |
6669 B(JumpIfTrue), U8(10), // | |
6670 B(LdaSmi8), U8(2), // | |
6671 B(TestEqualStrict), R(2), // | |
6672 B(JumpIfTrue), U8(8), // | |
6673 B(Jump), U8(12), // | |
6674 B(LdaSmi8), U8(2), // | |
6675 B(Star), R(1), // | |
6676 B(LdaSmi8), U8(3), // | |
6677 B(Star), R(1), // | |
6678 B(Jump), U8(2), // | |
6679 B(LdaUndefined), // | |
6680 B(Return), // | |
6681 }}, | |
6682 {"var a = 1;\n" | |
6683 "switch(a) {\n" | |
6684 " case 2: break;\n" | |
6685 " case 3: break;\n" | |
6686 " default: a = 1; break;\n" | |
6687 "}\n", | |
6688 3 * kPointerSize, | |
6689 1, | |
6690 35, | |
6691 { | |
6692 B(StackCheck), // | |
6693 B(LdaSmi8), U8(1), // | |
6694 B(Star), R(1), // | |
6695 B(Star), R(0), // | |
6696 B(Star), R(2), // | |
6697 B(LdaSmi8), U8(2), // | |
6698 B(TestEqualStrict), R(2), // | |
6699 B(JumpIfTrue), U8(10), // | |
6700 B(LdaSmi8), U8(3), // | |
6701 B(TestEqualStrict), R(2), // | |
6702 B(JumpIfTrue), U8(6), // | |
6703 B(Jump), U8(6), // | |
6704 B(Jump), U8(10), // | |
6705 B(Jump), U8(8), // | |
6706 B(LdaSmi8), U8(1), // | |
6707 B(Star), R(1), // | |
6708 B(Jump), U8(2), // | |
6709 B(LdaUndefined), // | |
6710 B(Return), // | |
6711 }}, | |
6712 {"var a = 1;\n" | |
6713 "switch(typeof(a)) {\n" | |
6714 " case 2: a = 1; break;\n" | |
6715 " case 3: a = 2; break;\n" | |
6716 " default: a = 3; break;\n" | |
6717 "}\n", | |
6718 3 * kPointerSize, | |
6719 1, | |
6720 44, | |
6721 { | |
6722 B(StackCheck), // | |
6723 B(LdaSmi8), U8(1), // | |
6724 B(Star), R(1), // | |
6725 B(TypeOf), // | |
6726 B(Star), R(0), // | |
6727 B(Star), R(2), // | |
6728 B(LdaSmi8), U8(2), // | |
6729 B(TestEqualStrict), R(2), // | |
6730 B(JumpIfTrue), U8(10), // | |
6731 B(LdaSmi8), U8(3), // | |
6732 B(TestEqualStrict), R(2), // | |
6733 B(JumpIfTrue), U8(10), // | |
6734 B(Jump), U8(14), // | |
6735 B(LdaSmi8), U8(1), // | |
6736 B(Star), R(1), // | |
6737 B(Jump), U8(14), // | |
6738 B(LdaSmi8), U8(2), // | |
6739 B(Star), R(1), // | |
6740 B(Jump), U8(8), // | |
6741 B(LdaSmi8), U8(3), // | |
6742 B(Star), R(1), // | |
6743 B(Jump), U8(2), // | |
6744 B(LdaUndefined), // | |
6745 B(Return), // | |
6746 }}, | |
6747 {"var a = 1;\n" | |
6748 "switch(a) {\n" | |
6749 " case typeof(a): a = 1; break;\n" | |
6750 " default: a = 2; break;\n" | |
6751 "}\n", | |
6752 3 * kPointerSize, | |
6753 1, | |
6754 32, | |
6755 { | |
6756 B(StackCheck), // | |
6757 B(LdaSmi8), U8(1), // | |
6758 B(Star), R(1), // | |
6759 B(Star), R(0), // | |
6760 B(Star), R(2), // | |
6761 B(Ldar), R(1), // | |
6762 B(TypeOf), // | |
6763 B(TestEqualStrict), R(2), // | |
6764 B(JumpIfTrue), U8(4), // | |
6765 B(Jump), U8(8), // | |
6766 B(LdaSmi8), U8(1), // | |
6767 B(Star), R(1), // | |
6768 B(Jump), U8(8), // | |
6769 B(LdaSmi8), U8(2), // | |
6770 B(Star), R(1), // | |
6771 B(Jump), U8(2), // | |
6772 B(LdaUndefined), // | |
6773 B(Return), // | |
6774 }}, | |
6775 {"var a = 1;\n" | |
6776 "switch(a) {\n" | |
6777 " case 1:\n" REPEAT_64(SPACE, " a = 2;") | |
6778 "break;\n" | |
6779 " case 2: a = 3; break;" | |
6780 "}\n", | |
6781 3 * kPointerSize, | |
6782 1, | |
6783 289, | |
6784 { | |
6785 B(StackCheck), // | |
6786 B(LdaSmi8), U8(1), // | |
6787 B(Star), R(1), // | |
6788 B(Star), R(0), // | |
6789 B(Star), R(2), // | |
6790 B(LdaSmi8), U8(1), // | |
6791 B(TestEqualStrict), R(2), // | |
6792 B(JumpIfTrue), U8(10), // | |
6793 B(LdaSmi8), U8(2), // | |
6794 B(TestEqualStrict), R(2), // | |
6795 B(JumpIfTrueConstant), U8(0), // | |
6796 B(JumpConstant), U8(1), // | |
6797 REPEAT_64(COMMA, // | |
6798 B(LdaSmi8), U8(2), // | |
6799 B(Star), R(1)), // | |
6800 B(Jump), U8(8), // | |
6801 B(LdaSmi8), U8(3), // | |
6802 B(Star), R(1), // | |
6803 B(Jump), U8(2), // | |
6804 B(LdaUndefined), // | |
6805 B(Return), // | |
6806 }, | |
6807 2, | |
6808 {262, 266}}, | |
6809 {"var a = 1;\n" | |
6810 "switch(a) {\n" | |
6811 " case 1: \n" | |
6812 " switch(a + 1) {\n" | |
6813 " case 2 : a = 1; break;\n" | |
6814 " default : a = 2; break;\n" | |
6815 " } // fall-through\n" | |
6816 " case 2: a = 3;\n" | |
6817 "}\n", | |
6818 5 * kPointerSize, | |
6819 1, | |
6820 61, | |
6821 { | |
6822 B(StackCheck), // | |
6823 B(LdaSmi8), U8(1), // | |
6824 B(Star), R(2), // | |
6825 B(Star), R(0), // | |
6826 B(Star), R(3), // | |
6827 B(LdaSmi8), U8(1), // | |
6828 B(TestEqualStrict), R(3), // | |
6829 B(JumpIfTrue), U8(10), // | |
6830 B(LdaSmi8), U8(2), // | |
6831 B(TestEqualStrict), R(3), // | |
6832 B(JumpIfTrue), U8(36), // | |
6833 B(Jump), U8(38), // | |
6834 B(Ldar), R(2), // | |
6835 B(Star), R(4), // | |
6836 B(LdaSmi8), U8(1), // | |
6837 B(Add), R(4), // | |
6838 B(Star), R(1), // | |
6839 B(Star), R(4), // | |
6840 B(LdaSmi8), U8(2), // | |
6841 B(TestEqualStrict), R(4), // | |
6842 B(JumpIfTrue), U8(4), // | |
6843 B(Jump), U8(8), // | |
6844 B(LdaSmi8), U8(1), // | |
6845 B(Star), R(2), // | |
6846 B(Jump), U8(8), // | |
6847 B(LdaSmi8), U8(2), // | |
6848 B(Star), R(2), // | |
6849 B(Jump), U8(2), // | |
6850 B(LdaSmi8), U8(3), // | |
6851 B(Star), R(2), // | |
6852 B(LdaUndefined), // | |
6853 B(Return), // | |
6854 }}, | |
6855 }; | |
6856 // clang-format on | |
6857 | |
6858 for (size_t i = 0; i < arraysize(snippets); i++) { | |
6859 Handle<BytecodeArray> bytecode_array = | |
6860 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
6861 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
6862 } | |
6863 } | |
6864 | |
6865 | 1643 |
6866 TEST(BasicBlockToBoolean) { | 1644 TEST(BasicBlockToBoolean) { |
6867 InitializedHandleScope handle_scope; | 1645 InitializedIgnitionHandleScope scope; |
6868 BytecodeGeneratorHelper helper; | 1646 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
6869 | 1647 ConstantPoolType::kNumber); |
6870 // Check that we generate JumpIfToBoolean if they are at the start of basic | 1648 const char* snippets[] = { |
6871 // blocks. | 1649 "var a = 1; if (a || a < 0) { return 1; }", |
6872 // clang-format off | 1650 |
6873 ExpectedSnippet<int> snippets[] = { | 1651 "var a = 1; if (a && a < 0) { return 1; }", |
6874 {"var a = 1; if (a || a < 0) { return 1; }", | 1652 |
6875 2 * kPointerSize, | 1653 "var a = 1; a = (a || a < 0) ? 2 : 3;", |
6876 1, | 1654 }; |
6877 21, | 1655 |
6878 { | 1656 CHECK_EQ(BuildActual(printer, snippets), |
6879 B(StackCheck), // | 1657 LoadGolden("BasicBlockToBoolean.golden")); |
6880 B(LdaSmi8), U8(1), // | 1658 } |
6881 B(Star), R(0), // | |
6882 B(JumpIfToBooleanTrue), U8(9), // | |
6883 B(Ldar), R(0), // | |
6884 B(Star), R(1), // | |
6885 B(LdaZero), // | |
6886 B(TestLessThan), R(1), // | |
6887 B(JumpIfToBooleanFalse), U8(5), // | |
6888 B(LdaSmi8), U8(1), // | |
6889 B(Return), // | |
6890 B(LdaUndefined), // | |
6891 B(Return), // | |
6892 }}, | |
6893 {"var a = 1; if (a && a < 0) { return 1; }", | |
6894 2 * kPointerSize, | |
6895 1, | |
6896 21, | |
6897 { | |
6898 B(StackCheck), // | |
6899 B(LdaSmi8), U8(1), // | |
6900 B(Star), R(0), // | |
6901 B(JumpIfToBooleanFalse), U8(9), // | |
6902 B(Ldar), R(0), // | |
6903 B(Star), R(1), // | |
6904 B(LdaZero), // | |
6905 B(TestLessThan), R(1), // | |
6906 B(JumpIfToBooleanFalse), U8(5), // | |
6907 B(LdaSmi8), U8(1), // | |
6908 B(Return), // | |
6909 B(LdaUndefined), // | |
6910 B(Return), // | |
6911 }}, | |
6912 {"var a = 1; a = (a || a < 0) ? 2 : 3;", | |
6913 2 * kPointerSize, | |
6914 1, | |
6915 26, | |
6916 { | |
6917 B(StackCheck), // | |
6918 B(LdaSmi8), U8(1), // | |
6919 B(Star), R(0), // | |
6920 B(JumpIfToBooleanTrue), U8(9), // | |
6921 B(Ldar), R(0), // | |
6922 B(Star), R(1), // | |
6923 B(LdaZero), // | |
6924 B(TestLessThan), R(1), // | |
6925 B(JumpIfToBooleanFalse), U8(6), // | |
6926 B(LdaSmi8), U8(2), // | |
6927 B(Jump), U8(4), // | |
6928 B(LdaSmi8), U8(3), // | |
6929 B(Star), R(0), // | |
6930 B(LdaUndefined), // | |
6931 B(Return), // | |
6932 }}, | |
6933 }; | |
6934 // clang-format on | |
6935 | |
6936 for (size_t i = 0; i < arraysize(snippets); i++) { | |
6937 Handle<BytecodeArray> bytecode_array = | |
6938 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
6939 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
6940 } | |
6941 } | |
6942 | |
6943 | 1659 |
6944 TEST(DeadCodeRemoval) { | 1660 TEST(DeadCodeRemoval) { |
6945 InitializedHandleScope handle_scope; | 1661 InitializedIgnitionHandleScope scope; |
6946 BytecodeGeneratorHelper helper; | 1662 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
6947 | 1663 ConstantPoolType::kNumber); |
6948 // clang-format off | 1664 const char* snippets[] = { |
6949 ExpectedSnippet<int> snippets[] = { | 1665 "return; var a = 1; a();", |
6950 {"return; var a = 1; a();", | 1666 |
6951 1 * kPointerSize, | 1667 "if (false) { return; }; var a = 1;", |
6952 1, | 1668 |
6953 3, | 1669 "if (true) { return 1; } else { return 2; };", |
6954 { | 1670 |
6955 B(StackCheck), // | 1671 "var a = 1; if (a) { return 1; }; return 2;", |
6956 B(LdaUndefined), // | 1672 }; |
6957 B(Return), // | 1673 |
6958 }}, | 1674 CHECK_EQ(BuildActual(printer, snippets), |
6959 {"if (false) { return; }; var a = 1;", | 1675 LoadGolden("DeadCodeRemoval.golden")); |
6960 1 * kPointerSize, | 1676 } |
6961 1, | |
6962 7, | |
6963 { | |
6964 B(StackCheck), // | |
6965 B(LdaSmi8), U8(1), // | |
6966 B(Star), R(0), // | |
6967 B(LdaUndefined), // | |
6968 B(Return), // | |
6969 }}, | |
6970 {"if (true) { return 1; } else { return 2; };", | |
6971 0, | |
6972 1, | |
6973 4, | |
6974 { | |
6975 B(StackCheck), // | |
6976 B(LdaSmi8), U8(1), // | |
6977 B(Return), // | |
6978 }}, | |
6979 {"var a = 1; if (a) { return 1; }; return 2;", | |
6980 1 * kPointerSize, | |
6981 1, | |
6982 13, | |
6983 { | |
6984 B(StackCheck), // | |
6985 B(LdaSmi8), U8(1), // | |
6986 B(Star), R(0), // | |
6987 B(JumpIfToBooleanFalse), U8(5), // | |
6988 B(LdaSmi8), U8(1), // | |
6989 B(Return), // | |
6990 B(LdaSmi8), U8(2), // | |
6991 B(Return), // | |
6992 }}, | |
6993 }; | |
6994 // clang-format on | |
6995 | |
6996 for (size_t i = 0; i < arraysize(snippets); i++) { | |
6997 Handle<BytecodeArray> bytecode_array = | |
6998 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
6999 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
7000 } | |
7001 } | |
7002 | |
7003 | 1677 |
7004 TEST(ThisFunction) { | 1678 TEST(ThisFunction) { |
7005 InitializedHandleScope handle_scope; | 1679 InitializedIgnitionHandleScope scope; |
7006 BytecodeGeneratorHelper helper; | 1680 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
7007 | 1681 ConstantPoolType::kNumber); |
7008 int closure = Register::function_closure().index(); | 1682 printer.set_wrap(false); |
7009 | 1683 printer.set_test_function_name("f"); |
7010 // clang-format off | 1684 |
7011 ExpectedSnippet<int> snippets[] = { | 1685 const char* snippets[] = { |
7012 {"var f;\n f = function f() { }", | 1686 "var f;\n" |
7013 2 * kPointerSize, | 1687 "f = function f() {};", |
7014 1, | 1688 |
7015 19, | 1689 "var f;\n" |
7016 { | 1690 "f = function f() { return f; };", |
7017 B(LdaTheHole), // | 1691 }; |
7018 B(Star), R(0), // | 1692 |
7019 B(StackCheck), // | 1693 CHECK_EQ(BuildActual(printer, snippets, "", "\nf();"), |
7020 B(Ldar), R(closure), // | 1694 LoadGolden("ThisFunction.golden")); |
7021 B(Star), R(1), // | 1695 } |
7022 B(Ldar), R(0), // | |
7023 B(JumpIfNotHole), U8(5), // | |
7024 B(Mov), R(1), R(0), // | |
7025 B(Ldar), R(1), // | |
7026 B(LdaUndefined), // | |
7027 B(Return), // | |
7028 }}, | |
7029 {"var f;\n f = function f() { return f; }", | |
7030 2 * kPointerSize, | |
7031 1, | |
7032 23, | |
7033 { | |
7034 B(LdaTheHole), // | |
7035 B(Star), R(0), // | |
7036 B(StackCheck), // | |
7037 B(Ldar), R(closure), // | |
7038 B(Star), R(1), // | |
7039 B(Ldar), R(0), // | |
7040 B(JumpIfNotHole), U8(5), // | |
7041 B(Mov), R(1), R(0), // | |
7042 B(Ldar), R(1), // | |
7043 B(Ldar), R(0), // | |
7044 B(JumpIfNotHole), U8(3), // | |
7045 B(LdaUndefined), // | |
7046 B(Return), // | |
7047 }}, | |
7048 }; | |
7049 // clang-format on | |
7050 | |
7051 for (size_t i = 0; i < arraysize(snippets); i++) { | |
7052 Handle<BytecodeArray> bytecode_array = | |
7053 helper.MakeBytecodeForFunction(snippets[i].code_snippet); | |
7054 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
7055 } | |
7056 } | |
7057 | |
7058 | 1696 |
7059 TEST(NewTarget) { | 1697 TEST(NewTarget) { |
7060 InitializedHandleScope handle_scope; | 1698 InitializedIgnitionHandleScope scope; |
7061 BytecodeGeneratorHelper helper; | 1699 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
7062 | 1700 ConstantPoolType::kMixed); |
7063 int new_target = Register::new_target().index(); | 1701 |
7064 | 1702 const char* snippets[] = { |
7065 // clang-format off | 1703 "return new.target;", |
7066 ExpectedSnippet<InstanceType> snippets[] = { | 1704 |
7067 {"return new.target;", | 1705 "new.target;", |
7068 2 * kPointerSize, | 1706 }; |
7069 1, | 1707 |
7070 19, | 1708 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("NewTarget.golden")); |
7071 { | 1709 } |
7072 B(Ldar), R(new_target), // | |
7073 B(Star), R(0), // | |
7074 B(StackCheck), // | |
7075 B(Ldar), R(0), // | |
7076 B(JumpIfNotHole), U8(11), // | |
7077 B(LdaConstant), U8(0), // | |
7078 B(Star), R(1), // | |
7079 B(CallRuntime), U16(Runtime::kThrowReferenceError), R(1), U8(1), // | |
7080 B(Return), // | |
7081 }, | |
7082 1, | |
7083 {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
7084 {"new.target;", | |
7085 2 * kPointerSize, | |
7086 1, | |
7087 20, | |
7088 { | |
7089 B(Ldar), R(new_target), // | |
7090 B(Star), R(0), // | |
7091 B(StackCheck), // | |
7092 B(Ldar), R(0), // | |
7093 B(JumpIfNotHole), U8(11), // | |
7094 B(LdaConstant), U8(0), // | |
7095 B(Star), R(1), // | |
7096 B(CallRuntime), U16(Runtime::kThrowReferenceError), R(1), U8(1), // | |
7097 B(LdaUndefined), // | |
7098 B(Return), // | |
7099 }, | |
7100 1, | |
7101 {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}}; | |
7102 // clang-format on | |
7103 | |
7104 for (size_t i = 0; i < arraysize(snippets); i++) { | |
7105 Handle<BytecodeArray> bytecode_array = | |
7106 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
7107 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
7108 } | |
7109 } | |
7110 | |
7111 | 1710 |
7112 TEST(RemoveRedundantLdar) { | 1711 TEST(RemoveRedundantLdar) { |
7113 InitializedHandleScope handle_scope; | 1712 InitializedIgnitionHandleScope scope; |
7114 BytecodeGeneratorHelper helper; | 1713 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
7115 | 1714 ConstantPoolType::kNumber); |
7116 // clang-format off | 1715 const char* snippets[] = { |
7117 ExpectedSnippet<int> snippets[] = { | 1716 "var ld_a = 1;\n" // This test is to check Ldar does not |
7118 {"var ld_a = 1;\n" // This test is to check Ldar does not | 1717 "while(true) {\n" // get removed if the preceding Star is |
7119 "while(true) {\n" // get removed if the preceding Star is | 1718 " ld_a = ld_a + ld_a;\n" // in a different basicblock. |
7120 " ld_a = ld_a + ld_a;\n" // in a different basicblock. | 1719 " if (ld_a > 10) break;\n" |
7121 " if (ld_a > 10) break;\n" | 1720 "}\n" |
7122 "}\n" | 1721 "return ld_a;", |
7123 "return ld_a;", | 1722 |
7124 2 * kPointerSize, | 1723 "var ld_a = 1;\n" |
7125 1, | 1724 "do {\n" |
7126 31, | 1725 " ld_a = ld_a + ld_a;\n" |
7127 {B(StackCheck), // | 1726 " if (ld_a > 10) continue;\n" |
7128 B(LdaSmi8), U8(1), // | 1727 "} while(false);\n" |
7129 B(Star), R(0), // | 1728 "return ld_a;", |
7130 B(StackCheck), // | 1729 |
7131 B(Ldar), R(0), // This load should not be removed as it | 1730 "var ld_a = 1;\n" |
7132 B(Star), R(1), // is the target of the branch. | 1731 " ld_a = ld_a + ld_a;\n" |
7133 B(Ldar), R(0), // | 1732 " return ld_a;", |
7134 B(Add), R(1), // | 1733 }; |
7135 B(Star), R(0), // | 1734 |
7136 B(Star), R(1), // | 1735 CHECK_EQ(BuildActual(printer, snippets), |
7137 B(LdaSmi8), U8(10), // | 1736 LoadGolden("RemoveRedundantLdar.golden")); |
7138 B(TestGreaterThan), R(1), // | 1737 } |
7139 B(JumpIfFalse), U8(4), // | |
7140 B(Jump), U8(4), // | |
7141 B(Jump), U8(-21), // | |
7142 B(Ldar), R(0), // | |
7143 B(Return)}}, | |
7144 {"var ld_a = 1;\n" | |
7145 "do {\n" | |
7146 " ld_a = ld_a + ld_a;\n" | |
7147 " if (ld_a > 10) continue;\n" | |
7148 "} while(false);\n" | |
7149 "return ld_a;", | |
7150 2 * kPointerSize, | |
7151 1, | |
7152 29, | |
7153 {B(StackCheck), // | |
7154 B(LdaSmi8), U8(1), // | |
7155 B(Star), R(0), // | |
7156 B(StackCheck), // | |
7157 B(Ldar), R(0), // | |
7158 B(Star), R(1), // | |
7159 B(Ldar), R(0), // | |
7160 B(Add), R(1), // | |
7161 B(Star), R(0), // | |
7162 B(Star), R(1), // | |
7163 B(LdaSmi8), U8(10), // | |
7164 B(TestGreaterThan), R(1), // | |
7165 B(JumpIfFalse), U8(4), // | |
7166 B(Jump), U8(2), // | |
7167 B(Ldar), R(0), // | |
7168 B(Return)}}, | |
7169 {"var ld_a = 1;\n" | |
7170 " ld_a = ld_a + ld_a;\n" | |
7171 " return ld_a;", | |
7172 2 * kPointerSize, | |
7173 1, | |
7174 14, | |
7175 { | |
7176 B(StackCheck), // | |
7177 B(LdaSmi8), U8(1), // | |
7178 B(Star), R(0), // | |
7179 B(Star), R(1), // | |
7180 B(Ldar), R(0), // | |
7181 B(Add), R(1), // | |
7182 B(Star), R(0), // | |
7183 B(Return) // | |
7184 }}, | |
7185 }; | |
7186 // clang-format on | |
7187 | |
7188 for (size_t i = 0; i < arraysize(snippets); i++) { | |
7189 Handle<BytecodeArray> bytecode_array = | |
7190 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
7191 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
7192 } | |
7193 } | |
7194 | |
7195 | 1738 |
7196 TEST(AssignmentsInBinaryExpression) { | 1739 TEST(AssignmentsInBinaryExpression) { |
7197 InitializedHandleScope handle_scope; | 1740 InitializedIgnitionHandleScope scope; |
7198 BytecodeGeneratorHelper helper; | 1741 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
7199 | 1742 ConstantPoolType::kString); |
7200 // clang-format off | 1743 const char* snippets[] = { |
7201 ExpectedSnippet<const char*> snippets[] = { | 1744 "var x = 0, y = 1;\n" |
7202 {"var x = 0, y = 1;\n" | 1745 "return (x = 2, y = 3, x = 4, y = 5);", |
7203 "return (x = 2, y = 3, x = 4, y = 5)", | 1746 |
7204 2 * kPointerSize, | 1747 "var x = 55;\n" |
7205 1, | 1748 "var y = (x = 100);\n" |
7206 25, | 1749 "return y;", |
7207 { | 1750 |
7208 B(StackCheck), // | 1751 "var x = 55;\n" |
7209 B(LdaZero), B(Star), R(0), // | 1752 "x = x + (x = 100) + (x = 101);\n" |
7210 B(LdaSmi8), U8(1), // | 1753 "return x;", |
7211 B(Star), R(1), // | 1754 |
7212 B(LdaSmi8), U8(2), // | 1755 "var x = 55;\n" |
7213 B(Star), R(0), // | 1756 "x = (x = 56) - x + (x = 57);\n" |
7214 B(LdaSmi8), U8(3), // | 1757 "x++;\n" |
7215 B(Star), R(1), // | 1758 "return x;", |
7216 B(LdaSmi8), U8(4), // | 1759 |
7217 B(Star), R(0), // | 1760 "var x = 55;\n" |
7218 B(LdaSmi8), U8(5), // | 1761 "var y = x + (x = 1) + (x = 2) + (x = 3);\n" |
7219 B(Star), R(1), // | 1762 "return y;", |
7220 B(Return), // | 1763 |
7221 }, | 1764 "var x = 55;\n" |
7222 0}, | 1765 "var x = x + (x = 1) + (x = 2) + (x = 3);\n" |
7223 {"var x = 55;\n" | 1766 "return x;", |
7224 "var y = (x = 100);\n" | 1767 |
7225 "return y", | 1768 "var x = 10, y = 20;\n" |
7226 2 * kPointerSize, | 1769 "return x + (x = 1) + (x + 1) * (y = 2) + (y = 3) + (x = 4) + (y = 5) + " |
7227 1, | 1770 "y;\n", |
7228 12, | 1771 |
7229 { | 1772 "var x = 17;\n" |
7230 B(StackCheck), // | 1773 "return 1 + x + (x++) + (++x);\n", |
7231 B(LdaSmi8), U8(55), // | 1774 }; |
7232 B(Star), R(0), // | 1775 |
7233 B(LdaSmi8), U8(100), // | 1776 CHECK_EQ(BuildActual(printer, snippets), |
7234 B(Star), R(0), // | 1777 LoadGolden("AssignmentsInBinaryExpression.golden")); |
7235 B(Star), R(1), // | 1778 } |
7236 B(Return), // | |
7237 }, | |
7238 0}, | |
7239 {"var x = 55;\n" | |
7240 "x = x + (x = 100) + (x = 101);\n" | |
7241 "return x;", | |
7242 3 * kPointerSize, | |
7243 1, | |
7244 24, | |
7245 { | |
7246 B(StackCheck), // | |
7247 B(LdaSmi8), U8(55), // | |
7248 B(Star), R(0), // | |
7249 B(Star), R(1), // | |
7250 B(LdaSmi8), U8(100), // | |
7251 B(Star), R(0), // | |
7252 B(Add), R(1), // | |
7253 B(Star), R(2), // | |
7254 B(LdaSmi8), U8(101), // | |
7255 B(Star), R(0), // | |
7256 B(Add), R(2), // | |
7257 B(Star), R(0), // | |
7258 B(Return), // | |
7259 }, | |
7260 0}, | |
7261 {"var x = 55;\n" | |
7262 "x = (x = 56) - x + (x = 57);\n" | |
7263 "x++;\n" | |
7264 "return x;", | |
7265 3 * kPointerSize, | |
7266 1, | |
7267 32, | |
7268 { | |
7269 B(StackCheck), // | |
7270 B(LdaSmi8), U8(55), // | |
7271 B(Star), R(0), // | |
7272 B(LdaSmi8), U8(56), // | |
7273 B(Star), R(0), // | |
7274 B(Star), R(1), // | |
7275 B(Ldar), R(0), // | |
7276 B(Sub), R(1), // | |
7277 B(Star), R(2), // | |
7278 B(LdaSmi8), U8(57), // | |
7279 B(Star), R(0), // | |
7280 B(Add), R(2), // | |
7281 B(Star), R(0), // | |
7282 B(ToNumber), // | |
7283 B(Star), R(1), // | |
7284 B(Inc), // | |
7285 B(Star), R(0), // | |
7286 B(Return), // | |
7287 }, | |
7288 0}, | |
7289 {"var x = 55;\n" | |
7290 "var y = x + (x = 1) + (x = 2) + (x = 3);\n" | |
7291 "return y;", | |
7292 4 * kPointerSize, | |
7293 1, | |
7294 32, | |
7295 { | |
7296 B(StackCheck), // | |
7297 B(LdaSmi8), U8(55), // | |
7298 B(Star), R(0), // | |
7299 B(Star), R(2), // | |
7300 B(LdaSmi8), U8(1), // | |
7301 B(Star), R(0), // | |
7302 B(Add), R(2), // | |
7303 B(Star), R(3), // | |
7304 B(LdaSmi8), U8(2), // | |
7305 B(Star), R(0), // | |
7306 B(Add), R(3), // | |
7307 B(Star), R(2), // | |
7308 B(LdaSmi8), U8(3), // | |
7309 B(Star), R(0), // | |
7310 B(Add), R(2), // | |
7311 B(Star), R(1), // | |
7312 B(Return), // | |
7313 }, | |
7314 0}, | |
7315 {"var x = 55;\n" | |
7316 "var x = x + (x = 1) + (x = 2) + (x = 3);\n" | |
7317 "return x;", | |
7318 3 * kPointerSize, | |
7319 1, | |
7320 32, | |
7321 { | |
7322 B(StackCheck), // | |
7323 B(LdaSmi8), U8(55), // | |
7324 B(Star), R(0), // | |
7325 B(Star), R(1), // | |
7326 B(LdaSmi8), U8(1), // | |
7327 B(Star), R(0), // | |
7328 B(Add), R(1), // | |
7329 B(Star), R(2), // | |
7330 B(LdaSmi8), U8(2), // | |
7331 B(Star), R(0), // | |
7332 B(Add), R(2), // | |
7333 B(Star), R(1), // | |
7334 B(LdaSmi8), U8(3), // | |
7335 B(Star), R(0), // | |
7336 B(Add), R(1), // | |
7337 B(Star), R(0), // | |
7338 B(Return), // | |
7339 }, | |
7340 0}, | |
7341 {"var x = 10, y = 20;\n" | |
7342 "return x + (x = 1) + (x + 1) * (y = 2) + (y = 3) + (x = 4) + (y = 5) + " | |
7343 "y;\n", | |
7344 5 * kPointerSize, | |
7345 1, | |
7346 70, | |
7347 { | |
7348 B(StackCheck), // | |
7349 B(LdaSmi8), U8(10), // | |
7350 B(Star), R(0), // | |
7351 B(LdaSmi8), U8(20), // | |
7352 B(Star), R(1), // | |
7353 B(Ldar), R(0), // | |
7354 B(Star), R(2), // | |
7355 B(LdaSmi8), U8(1), // | |
7356 B(Star), R(0), // | |
7357 B(Add), R(2), // | |
7358 B(Star), R(3), // | |
7359 B(Ldar), R(0), // | |
7360 B(Star), R(2), // | |
7361 B(LdaSmi8), U8(1), // | |
7362 B(Add), R(2), // | |
7363 B(Star), R(4), // | |
7364 B(LdaSmi8), U8(2), // | |
7365 B(Star), R(1), // | |
7366 B(Mul), R(4), // | |
7367 B(Add), R(3), // | |
7368 B(Star), R(2), // | |
7369 B(LdaSmi8), U8(3), // | |
7370 B(Star), R(1), // | |
7371 B(Add), R(2), // | |
7372 B(Star), R(3), // | |
7373 B(LdaSmi8), U8(4), // | |
7374 B(Star), R(0), // | |
7375 B(Add), R(3), // | |
7376 B(Star), R(2), // | |
7377 B(LdaSmi8), U8(5), // | |
7378 B(Star), R(1), // | |
7379 B(Add), R(2), // | |
7380 B(Star), R(3), // | |
7381 B(Ldar), R(1), // | |
7382 B(Add), R(3), // | |
7383 B(Return), // | |
7384 }, | |
7385 0}, | |
7386 {"var x = 17;\n" | |
7387 "return 1 + x + (x++) + (++x);\n", | |
7388 4 * kPointerSize, | |
7389 1, | |
7390 38, | |
7391 { | |
7392 B(StackCheck), // | |
7393 B(LdaSmi8), U8(17), // | |
7394 B(Star), R(0), // | |
7395 B(LdaSmi8), U8(1), // | |
7396 B(Star), R(1), // | |
7397 B(Ldar), R(0), // | |
7398 B(Add), R(1), // | |
7399 B(Star), R(2), // | |
7400 B(Ldar), R(0), // | |
7401 B(ToNumber), // | |
7402 B(Star), R(1), // | |
7403 B(Inc), // | |
7404 B(Star), R(0), // | |
7405 B(Ldar), R(1), // | |
7406 B(Add), R(2), // | |
7407 B(Star), R(3), // | |
7408 B(Ldar), R(0), // | |
7409 B(ToNumber), // | |
7410 B(Inc), // | |
7411 B(Star), R(0), // | |
7412 B(Add), R(3), // | |
7413 B(Return), // | |
7414 }, | |
7415 0} | |
7416 }; | |
7417 // clang-format on | |
7418 | |
7419 for (size_t i = 0; i < arraysize(snippets); i++) { | |
7420 Handle<BytecodeArray> bytecode_array = | |
7421 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
7422 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
7423 } | |
7424 } | |
7425 | |
7426 | 1779 |
7427 TEST(Eval) { | 1780 TEST(Eval) { |
7428 InitializedHandleScope handle_scope; | 1781 InitializedIgnitionHandleScope scope; |
7429 BytecodeGeneratorHelper helper; | 1782 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
7430 Zone zone; | 1783 ConstantPoolType::kString); |
7431 | 1784 const char* snippets[] = { |
7432 int closure = Register::function_closure().index(); | 1785 "return eval('1;');", |
7433 int context = Register::current_context().index(); | 1786 }; |
7434 int new_target = Register::new_target().index(); | 1787 |
7435 | 1788 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("Eval.golden")); |
7436 int first_context_slot = Context::MIN_CONTEXT_SLOTS; | 1789 } |
7437 | |
7438 // clang-format off | |
7439 ExpectedSnippet<const char*> snippets[] = { | |
7440 {"return eval('1;');", | |
7441 9 * kPointerSize, | |
7442 1, | |
7443 65, | |
7444 { | |
7445 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // | |
7446 /* */ U8(1), // | |
7447 B(PushContext), R(0), // | |
7448 B(Ldar), THIS(1), // | |
7449 B(StaContextSlot), R(context), U8(first_context_slot), // | |
7450 B(CreateMappedArguments), // | |
7451 B(StaContextSlot), R(context), U8(first_context_slot + 1), // | |
7452 B(Ldar), R(new_target), // | |
7453 B(StaContextSlot), R(context), U8(first_context_slot + 2), // | |
7454 B(StackCheck), // | |
7455 B(LdaConstant), U8(0), // | |
7456 B(Star), R(3), // | |
7457 B(CallRuntimeForPair), U16(Runtime::kLoadLookupSlotForCall), // | |
7458 /* */ R(3), U8(1), R(1), // | |
7459 B(LdaConstant), U8(1), // | |
7460 B(Star), R(3), // | |
7461 B(Mov), R(1), R(4), // | |
7462 B(Mov), R(3), R(5), // | |
7463 B(Mov), R(closure), R(6), // | |
7464 B(LdaZero), // | |
7465 B(Star), R(7), // | |
7466 B(LdaSmi8), U8(10), // | |
7467 B(Star), R(8), // | |
7468 B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), // | |
7469 /* */ U8(5), // | |
7470 B(Star), R(1), // | |
7471 B(Call), R(1), R(2), U8(2), U8(0), // | |
7472 B(Return), // | |
7473 }, | |
7474 2, | |
7475 {"eval", "1;"}}, | |
7476 }; | |
7477 // clang-format on | |
7478 | |
7479 for (size_t i = 0; i < arraysize(snippets); i++) { | |
7480 Handle<BytecodeArray> bytecode_array = | |
7481 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
7482 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
7483 } | |
7484 } | |
7485 | |
7486 | 1790 |
7487 TEST(LookupSlot) { | 1791 TEST(LookupSlot) { |
7488 InitializedHandleScope handle_scope; | 1792 InitializedIgnitionHandleScope scope; |
7489 BytecodeGeneratorHelper helper; | 1793 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
7490 | 1794 ConstantPoolType::kString); |
7491 int closure = Register::function_closure().index(); | 1795 |
7492 int context = Register::current_context().index(); | 1796 const char* snippets[] = { |
7493 int first_context_slot = Context::MIN_CONTEXT_SLOTS; | 1797 "eval('var x = 10;'); return x;", |
7494 int new_target = Register::new_target().index(); | 1798 |
7495 | 1799 "eval('var x = 10;'); return typeof x;", |
7496 // clang-format off | 1800 |
7497 ExpectedSnippet<const char*> snippets[] = { | 1801 "x = 20; return eval('');", |
7498 {"eval('var x = 10;'); return x;", | 1802 }; |
7499 9 * kPointerSize, | 1803 |
7500 1, | 1804 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("LookupSlot.golden")); |
7501 67, | 1805 } |
7502 { | |
7503 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // | |
7504 /* */ U8(1), // | |
7505 B(PushContext), R(0), // | |
7506 B(Ldar), THIS(1), // | |
7507 B(StaContextSlot), R(context), U8(first_context_slot), // | |
7508 B(CreateMappedArguments), // | |
7509 B(StaContextSlot), R(context), U8(first_context_slot + 1), // | |
7510 B(Ldar), R(new_target), // | |
7511 B(StaContextSlot), R(context), U8(first_context_slot + 2), // | |
7512 B(StackCheck), // | |
7513 B(LdaConstant), U8(0), // | |
7514 B(Star), R(3), // | |
7515 B(CallRuntimeForPair), U16(Runtime::kLoadLookupSlotForCall), // | |
7516 R(3), U8(1), R(1), // | |
7517 B(LdaConstant), U8(1), // | |
7518 B(Star), R(3), // | |
7519 B(Mov), R(1), R(4), // | |
7520 B(Mov), R(3), R(5), // | |
7521 B(Mov), R(closure), R(6), // | |
7522 B(LdaZero), // | |
7523 B(Star), R(7), // | |
7524 B(LdaSmi8), U8(10), // | |
7525 B(Star), R(8), // | |
7526 B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), // | |
7527 U8(5), // | |
7528 B(Star), R(1), // | |
7529 B(Call), R(1), R(2), U8(2), U8(0), // | |
7530 B(LdaLookupSlot), U8(2), // | |
7531 B(Return), // | |
7532 }, | |
7533 3, | |
7534 {"eval", "var x = 10;", "x"}}, | |
7535 {"eval('var x = 10;'); return typeof x;", | |
7536 9 * kPointerSize, | |
7537 1, | |
7538 68, | |
7539 { | |
7540 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // | |
7541 /* */ U8(1), // | |
7542 B(PushContext), R(0), // | |
7543 B(Ldar), THIS(1), // | |
7544 B(StaContextSlot), R(context), U8(first_context_slot), // | |
7545 B(CreateMappedArguments), // | |
7546 B(StaContextSlot), R(context), U8(first_context_slot + 1), // | |
7547 B(Ldar), R(new_target), // | |
7548 B(StaContextSlot), R(context), U8(first_context_slot + 2), // | |
7549 B(StackCheck), // | |
7550 B(LdaConstant), U8(0), // | |
7551 B(Star), R(3), // | |
7552 B(CallRuntimeForPair), U16(Runtime::kLoadLookupSlotForCall), // | |
7553 /* */ R(3), U8(1), R(1), // | |
7554 B(LdaConstant), U8(1), // | |
7555 B(Star), R(3), // | |
7556 B(Mov), R(1), R(4), // | |
7557 B(Mov), R(3), R(5), // | |
7558 B(Mov), R(closure), R(6), // | |
7559 B(LdaZero), // | |
7560 B(Star), R(7), // | |
7561 B(LdaSmi8), U8(10), // | |
7562 B(Star), R(8), // | |
7563 B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), // | |
7564 /* */ U8(5), // | |
7565 B(Star), R(1), // | |
7566 B(Call), R(1), R(2), U8(2), U8(0), // | |
7567 B(LdaLookupSlotInsideTypeof), U8(2), // | |
7568 B(TypeOf), // | |
7569 B(Return), // | |
7570 }, | |
7571 3, | |
7572 {"eval", "var x = 10;", "x"}}, | |
7573 {"x = 20; return eval('');", | |
7574 9 * kPointerSize, | |
7575 1, | |
7576 69, | |
7577 { | |
7578 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // | |
7579 U8(1), // | |
7580 B(PushContext), R(0), // | |
7581 B(Ldar), THIS(1), // | |
7582 B(StaContextSlot), R(context), U8(first_context_slot), // | |
7583 B(CreateMappedArguments), // | |
7584 B(StaContextSlot), R(context), U8(first_context_slot + 1), // | |
7585 B(Ldar), R(new_target), // | |
7586 B(StaContextSlot), R(context), U8(first_context_slot + 2), // | |
7587 B(StackCheck), // | |
7588 B(LdaSmi8), U8(20), // | |
7589 B(StaLookupSlotSloppy), U8(0), // | |
7590 B(LdaConstant), U8(1), // | |
7591 B(Star), R(3), // | |
7592 B(CallRuntimeForPair), U16(Runtime::kLoadLookupSlotForCall), // | |
7593 /* */ R(3), U8(1), R(1), // | |
7594 B(LdaConstant), U8(2), // | |
7595 B(Star), R(3), // | |
7596 B(Mov), R(1), R(4), // | |
7597 B(Mov), R(3), R(5), // | |
7598 B(Mov), R(closure), R(6), // | |
7599 B(LdaZero), // | |
7600 B(Star), R(7), // | |
7601 B(LdaSmi8), U8(10), // | |
7602 B(Star), R(8), // | |
7603 B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), // | |
7604 /* */ U8(5), // | |
7605 B(Star), R(1), // | |
7606 B(Call), R(1), R(2), U8(2), U8(0), // | |
7607 B(Return), // | |
7608 }, | |
7609 3, | |
7610 {"x", "eval", ""}}, | |
7611 }; | |
7612 // clang-format on | |
7613 | |
7614 for (size_t i = 0; i < arraysize(snippets); i++) { | |
7615 Handle<BytecodeArray> bytecode_array = | |
7616 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
7617 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
7618 } | |
7619 } | |
7620 | |
7621 | 1806 |
7622 TEST(CallLookupSlot) { | 1807 TEST(CallLookupSlot) { |
7623 InitializedHandleScope handle_scope; | 1808 InitializedIgnitionHandleScope scope; |
7624 BytecodeGeneratorHelper helper; | 1809 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
7625 Zone zone; | 1810 ConstantPoolType::kMixed); |
7626 | 1811 const char* snippets[] = { |
7627 FeedbackVectorSpec feedback_spec(&zone); | 1812 "g = function(){}; eval(''); return g();", |
7628 FeedbackVectorSlot slot1 = feedback_spec.AddLoadICSlot(); | 1813 }; |
7629 FeedbackVectorSlot slot2 = feedback_spec.AddCallICSlot(); | 1814 |
7630 USE(slot1); | 1815 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("CallLookupSlot.golden")); |
7631 | 1816 } |
7632 Handle<i::TypeFeedbackVector> vector = | |
7633 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); | |
7634 | |
7635 int closure = Register::function_closure().index(); | |
7636 int context = Register::current_context().index(); | |
7637 int new_target = Register::new_target().index(); | |
7638 | |
7639 // clang-format off | |
7640 ExpectedSnippet<InstanceType> snippets[] = { | |
7641 {"g = function(){}; eval(''); return g();", | |
7642 9 * kPointerSize, | |
7643 1, | |
7644 85, | |
7645 { | |
7646 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // | |
7647 /* */ U8(1), // | |
7648 B(PushContext), R(0), // | |
7649 B(Ldar), THIS(1), // | |
7650 B(StaContextSlot), R(context), U8(4), // | |
7651 B(CreateMappedArguments), // | |
7652 B(StaContextSlot), R(context), U8(5), // | |
7653 B(Ldar), R(new_target), // | |
7654 B(StaContextSlot), R(context), U8(6), // | |
7655 B(StackCheck), // | |
7656 B(CreateClosure), U8(0), U8(0), // | |
7657 B(StaLookupSlotSloppy), U8(1), // | |
7658 B(LdaConstant), U8(2), // | |
7659 B(Star), R(3), // | |
7660 B(CallRuntimeForPair), U16(Runtime::kLoadLookupSlotForCall), // | |
7661 R(3), U8(1), R(1), // | |
7662 B(LdaConstant), U8(3), // | |
7663 B(Star), R(3), // | |
7664 B(Mov), R(1), R(4), // | |
7665 B(Mov), R(3), R(5), // | |
7666 B(Mov), R(closure), R(6), // | |
7667 B(LdaZero), // | |
7668 B(Star), R(7), // | |
7669 B(LdaSmi8), U8(10), // | |
7670 B(Star), R(8), // | |
7671 B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), // | |
7672 U8(5), // | |
7673 B(Star), R(1), // | |
7674 B(Call), R(1), R(2), U8(2), U8(0), // | |
7675 B(LdaConstant), U8(1), // | |
7676 B(Star), R(3), // | |
7677 B(CallRuntimeForPair), U16(Runtime::kLoadLookupSlotForCall), // | |
7678 R(3), U8(1), R(1), // | |
7679 B(Call), R(1), R(2), U8(1), U8(vector->GetIndex(slot2)), // | |
7680 B(Return), // | |
7681 }, | |
7682 4, | |
7683 {InstanceType::SHARED_FUNCTION_INFO_TYPE, | |
7684 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
7685 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
7686 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
7687 }; | |
7688 // clang-format on | |
7689 | |
7690 for (size_t i = 0; i < arraysize(snippets); i++) { | |
7691 Handle<BytecodeArray> bytecode_array = | |
7692 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
7693 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
7694 } | |
7695 } | |
7696 | |
7697 | 1817 |
7698 // TODO(mythria): tests for variable/function declaration in lookup slots. | 1818 // TODO(mythria): tests for variable/function declaration in lookup slots. |
7699 | 1819 |
7700 TEST(LookupSlotInEval) { | 1820 TEST(LookupSlotInEval) { |
7701 InitializedHandleScope handle_scope; | 1821 InitializedIgnitionHandleScope scope; |
7702 BytecodeGeneratorHelper helper; | 1822 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
7703 | 1823 ConstantPoolType::kString); |
7704 const char* function_prologue = "var f;" | 1824 printer.set_wrap(false); |
7705 "var x = 1;" | 1825 printer.set_test_function_name("f"); |
7706 "function f1() {" | 1826 |
7707 " eval(\"function t() {"; | 1827 const char* snippets[] = { |
7708 const char* function_epilogue = " }; f = t; f();\");" | 1828 "return x;", |
7709 "}" | 1829 |
7710 "f1();"; | 1830 "x = 10;", |
7711 | 1831 |
7712 // clang-format off | 1832 "'use strict'; x = 10;", |
7713 ExpectedSnippet<const char*> snippets[] = { | 1833 |
7714 {"return x;", | 1834 "return typeof x;", |
7715 0 * kPointerSize, | 1835 }; |
7716 1, | 1836 |
7717 4, | 1837 std::string actual = BuildActual(printer, snippets, |
7718 { | 1838 "var f;\n" |
7719 B(StackCheck), // | 1839 "var x = 1;\n" |
7720 B(LdaLookupSlot), U8(0), // | 1840 "function f1() {\n" |
7721 B(Return) // | 1841 " eval(\"function t() { ", |
7722 }, | 1842 |
7723 1, | 1843 " }; f = t; f();\");\n" |
7724 {"x"}}, | 1844 "}\n" |
7725 {"x = 10;", | 1845 "f1();"); |
7726 0 * kPointerSize, | 1846 |
7727 1, | 1847 CHECK_EQ(actual, LoadGolden("LookupSlotInEval.golden")); |
7728 7, | 1848 } |
7729 { | |
7730 B(StackCheck), // | |
7731 B(LdaSmi8), U8(10), // | |
7732 B(StaLookupSlotSloppy), U8(0), // | |
7733 B(LdaUndefined), // | |
7734 B(Return), // | |
7735 }, | |
7736 1, | |
7737 {"x"}}, | |
7738 {"'use strict'; x = 10;", | |
7739 0 * kPointerSize, | |
7740 1, | |
7741 7, | |
7742 { | |
7743 B(StackCheck), // | |
7744 B(LdaSmi8), U8(10), // | |
7745 B(StaLookupSlotStrict), U8(0), // | |
7746 B(LdaUndefined), // | |
7747 B(Return), // | |
7748 }, | |
7749 1, | |
7750 {"x"}}, | |
7751 {"return typeof x;", | |
7752 0 * kPointerSize, | |
7753 1, | |
7754 5, | |
7755 { | |
7756 B(StackCheck), // | |
7757 B(LdaLookupSlotInsideTypeof), U8(0), // | |
7758 B(TypeOf), // | |
7759 B(Return), // | |
7760 }, | |
7761 1, | |
7762 {"x"}}, | |
7763 }; | |
7764 // clang-format on | |
7765 | |
7766 for (size_t i = 0; i < arraysize(snippets); i++) { | |
7767 std::string script = std::string(function_prologue) + | |
7768 std::string(snippets[i].code_snippet) + | |
7769 std::string(function_epilogue); | |
7770 Handle<BytecodeArray> bytecode_array = | |
7771 helper.MakeBytecode(script.c_str(), "*", "f"); | |
7772 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
7773 } | |
7774 } | |
7775 | |
7776 | 1849 |
7777 TEST(LookupSlotWideInEval) { | 1850 TEST(LookupSlotWideInEval) { |
7778 InitializedHandleScope handle_scope; | 1851 InitializedIgnitionHandleScope scope; |
7779 BytecodeGeneratorHelper helper; | 1852 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
7780 | 1853 ConstantPoolType::kMixed); |
7781 const char* function_prologue = | 1854 printer.set_wrap(false); |
7782 "var f;" | 1855 printer.set_test_function_name("f"); |
7783 "var x = 1;" | 1856 |
7784 "function f1() {" | 1857 const char* snippets[] = { |
7785 " eval(\"function t() {"; | 1858 REPEAT_256(" \"var y = 2.3;\" +\n") // |
7786 const char* function_epilogue = | 1859 " \"return x;\" +\n", |
7787 " }; f = t; f();\");" | 1860 |
7788 "}" | 1861 REPEAT_256(" \"var y = 2.3;\" +\n") // |
7789 "f1();"; | 1862 " \"return typeof x;\" +\n", |
7790 | 1863 |
7791 int const_count[] = {0, 0, 0, 0}; | 1864 REPEAT_256(" \"var y = 2.3;\" +\n") // |
7792 // clang-format off | 1865 " \"x = 10;\" +\n", |
7793 ExpectedSnippet<InstanceType, 257> snippets[] = { | 1866 |
7794 {REPEAT_256(SPACE, "var y = 2.3;") | 1867 " \"'use strict';\" +\n" // |
7795 "return x;", | 1868 REPEAT_256(" \"var y = 2.3;\" +\n") // |
7796 1 * kPointerSize, | 1869 " \"x = 10;\" +\n", |
7797 1, | 1870 }; |
7798 1029, | 1871 |
7799 { | 1872 std::string actual = BuildActual(printer, snippets, |
7800 B(StackCheck), // | 1873 "var f;\n" |
7801 REPEAT_256(SPACE, // | 1874 "var x = 1;\n" |
7802 B(LdaConstant), U8(const_count[0]++), // | 1875 "function f1() {\n" |
7803 B(Star), R(0), ) // | 1876 " eval(\"function t() {\" +\n", |
7804 B(LdaLookupSlotWide), U16(256), // | 1877 |
7805 B(Return) // | 1878 " \"};\" +\n" |
7806 }, | 1879 " \"f = t; f();\"\n);\n" |
7807 257, | 1880 "}\n" |
7808 {REPEAT_256(COMMA, InstanceType::HEAP_NUMBER_TYPE), | 1881 "f1();"); |
7809 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | 1882 |
7810 {REPEAT_256(SPACE, "var y = 2.3;") | 1883 CHECK_EQ(actual, LoadGolden("LookupSlotWideInEval.golden")); |
7811 "return typeof x;", | 1884 } |
7812 1 * kPointerSize, | |
7813 1, | |
7814 1030, | |
7815 { | |
7816 B(StackCheck), // | |
7817 REPEAT_256(SPACE, // | |
7818 B(LdaConstant), U8(const_count[1]++), // | |
7819 B(Star), R(0), ) // | |
7820 B(LdaLookupSlotInsideTypeofWide), U16(256), // | |
7821 B(TypeOf), // | |
7822 B(Return) // | |
7823 }, | |
7824 257, | |
7825 {REPEAT_256(COMMA, InstanceType::HEAP_NUMBER_TYPE), | |
7826 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
7827 {REPEAT_256(SPACE, "var y = 2.3;") | |
7828 "x = 10;", | |
7829 1 * kPointerSize, | |
7830 1, | |
7831 1032, | |
7832 { | |
7833 B(StackCheck), // | |
7834 REPEAT_256(SPACE, // | |
7835 B(LdaConstant), U8(const_count[2]++), // | |
7836 B(Star), R(0), ) // | |
7837 B(LdaSmi8), U8(10), // | |
7838 B(StaLookupSlotSloppyWide), U16(256), // | |
7839 B(LdaUndefined), // | |
7840 B(Return) // | |
7841 }, | |
7842 257, | |
7843 {REPEAT_256(COMMA, InstanceType::HEAP_NUMBER_TYPE), | |
7844 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
7845 {"'use strict';" | |
7846 REPEAT_256(SPACE, "var y = 2.3;") | |
7847 "x = 10;", | |
7848 1 * kPointerSize, | |
7849 1, | |
7850 1032, | |
7851 { | |
7852 B(StackCheck), // | |
7853 REPEAT_256(SPACE, // | |
7854 B(LdaConstant), U8(const_count[3]++), // | |
7855 B(Star), R(0), ) // | |
7856 B(LdaSmi8), U8(10), // | |
7857 B(StaLookupSlotStrictWide), U16(256), // | |
7858 B(LdaUndefined), // | |
7859 B(Return) // | |
7860 }, | |
7861 257, | |
7862 {REPEAT_256(COMMA, InstanceType::HEAP_NUMBER_TYPE), | |
7863 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
7864 }; | |
7865 // clang-format on | |
7866 | |
7867 for (size_t i = 0; i < arraysize(snippets); i++) { | |
7868 std::string script = std::string(function_prologue) + | |
7869 std::string(snippets[i].code_snippet) + | |
7870 std::string(function_epilogue); | |
7871 Handle<BytecodeArray> bytecode_array = | |
7872 helper.MakeBytecode(script.c_str(), "*", "f"); | |
7873 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
7874 } | |
7875 } | |
7876 | |
7877 | 1885 |
7878 TEST(DeleteLookupSlotInEval) { | 1886 TEST(DeleteLookupSlotInEval) { |
7879 InitializedHandleScope handle_scope; | 1887 InitializedIgnitionHandleScope scope; |
7880 BytecodeGeneratorHelper helper; | 1888 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
7881 | 1889 ConstantPoolType::kString); |
7882 const char* function_prologue = "var f;" | 1890 printer.set_wrap(false); |
7883 "var x = 1;" | 1891 printer.set_test_function_name("f"); |
7884 "z = 10;" | 1892 |
7885 "function f1() {" | 1893 const char* snippets[] = { |
7886 " var y;" | 1894 "delete x;", |
7887 " eval(\"function t() {"; | 1895 |
7888 const char* function_epilogue = " }; f = t; f();\");" | 1896 "return delete y;", |
7889 "}" | 1897 |
7890 "f1();"; | 1898 "return delete z;", |
7891 | 1899 }; |
7892 // clang-format off | 1900 |
7893 ExpectedSnippet<const char*> snippets[] = { | 1901 std::string actual = BuildActual(printer, snippets, |
7894 {"delete x;", | 1902 "var f;\n" |
7895 1 * kPointerSize, | 1903 "var x = 1;\n" |
7896 1, | 1904 "z = 10;\n" |
7897 12, | 1905 "function f1() {\n" |
7898 { | 1906 " var y;\n" |
7899 B(StackCheck), // | 1907 " eval(\"function t() { ", |
7900 B(LdaConstant), U8(0), // | 1908 |
7901 B(Star), R(0), // | 1909 " }; f = t; f();\");\n" |
7902 B(CallRuntime), U16(Runtime::kDeleteLookupSlot), R(0), U8(1), // | 1910 "}\n" |
7903 B(LdaUndefined), // | 1911 "f1();"); |
7904 B(Return) // | 1912 |
7905 }, | 1913 CHECK_EQ(actual, LoadGolden("DeleteLookupSlotInEval.golden")); |
7906 1, | |
7907 {"x"}}, | |
7908 {"return delete y;", | |
7909 0 * kPointerSize, | |
7910 1, | |
7911 3, | |
7912 { | |
7913 B(StackCheck), // | |
7914 B(LdaFalse), // | |
7915 B(Return) // | |
7916 }, | |
7917 0}, | |
7918 {"return delete z;", | |
7919 1 * kPointerSize, | |
7920 1, | |
7921 11, | |
7922 { | |
7923 B(StackCheck), // | |
7924 B(LdaConstant), U8(0), // | |
7925 B(Star), R(0), // | |
7926 B(CallRuntime), U16(Runtime::kDeleteLookupSlot), R(0), U8(1), // | |
7927 B(Return) // | |
7928 }, | |
7929 1, | |
7930 {"z"}}, | |
7931 }; | |
7932 // clang-format on | |
7933 | |
7934 for (size_t i = 0; i < arraysize(snippets); i++) { | |
7935 std::string script = std::string(function_prologue) + | |
7936 std::string(snippets[i].code_snippet) + | |
7937 std::string(function_epilogue); | |
7938 Handle<BytecodeArray> bytecode_array = | |
7939 helper.MakeBytecode(script.c_str(), "*", "f"); | |
7940 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
7941 } | |
7942 } | 1914 } |
7943 | 1915 |
7944 TEST(WideRegisters) { | 1916 TEST(WideRegisters) { |
7945 // Prepare prologue that creates frame for lots of registers. | 1917 // Prepare prologue that creates frame for lots of registers. |
7946 std::ostringstream os; | 1918 std::ostringstream os; |
7947 for (size_t i = 0; i < 157; ++i) { | 1919 for (size_t i = 0; i < 157; ++i) { |
7948 os << "var x" << i << ";\n"; | 1920 os << "var x" << i << ";\n"; |
7949 } | 1921 } |
7950 std::string prologue(os.str()); | 1922 std::string prologue(os.str()); |
7951 | 1923 |
7952 // clang-format off | 1924 InitializedIgnitionHandleScope scope; |
7953 ExpectedSnippet<int> snippets[] = { | 1925 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
7954 {"x0 = x127;\n" | 1926 ConstantPoolType::kNumber); |
7955 "return x0;\n", | 1927 const char* snippets[] = { |
7956 161 * kPointerSize, | 1928 "x0 = x127;\n" |
7957 1, | 1929 "return x0;", |
7958 11, | 1930 |
7959 { | 1931 "x127 = x126;\n" |
7960 B(StackCheck), // | 1932 "return x127;", |
7961 B(MovWide), R16(131), R16(125), // | 1933 |
7962 B(Ldar), R(125), // | 1934 "if (x2 > 3) { return x129; }\n" |
7963 B(Star), R(0), // | 1935 "return x128;", |
7964 B(Return), // | 1936 |
7965 }}, | 1937 "var x0 = 0;\n" |
7966 {"x127 = x126;\n" | 1938 "if (x129 == 3) { var x129 = x0; }\n" |
7967 "return x127;\n", | 1939 "if (x2 > 3) { return x0; }\n" |
7968 161 * kPointerSize, | 1940 "return x129;", |
7969 1, | 1941 |
7970 23, | 1942 "var x0 = 0;\n" |
7971 { | 1943 "var x1 = 0;\n" |
7972 B(StackCheck), // | 1944 "for (x128 = 0; x128 < 64; x128++) {" |
7973 B(MovWide), R16(130), R16(125), // | 1945 " x1 += x128;" |
7974 B(Ldar), R(125), // | 1946 "}" |
7975 B(Star), R(125), // | 1947 "return x128;", |
7976 B(MovWide), R16(125), R16(131), // | 1948 |
7977 B(MovWide), R16(131), R16(125), // | 1949 "var x0 = 1234;\n" |
7978 B(Ldar), R(125), // | 1950 "var x1 = 0;\n" |
7979 B(Return), // | 1951 "for (x128 in x0) {" |
7980 }}, | 1952 " x1 += x128;" |
7981 {"if (x2 > 3) { return x129; }\n" | 1953 "}" |
7982 "return x128;\n", | 1954 "return x1;", |
7983 162 * kPointerSize, | 1955 |
7984 1, | 1956 "x0 = %Add(x64, x63);\n" |
7985 37, | 1957 "x1 = %Add(x27, x143);\n" |
7986 { | 1958 "%TheHole();\n" |
7987 B(StackCheck), // | 1959 "return x1;", |
7988 B(Ldar), R(2), // | 1960 }; |
7989 B(Star), R(125), // | 1961 |
7990 B(MovWide), R16(125), R16(161), // | 1962 CHECK_EQ(BuildActual(printer, snippets, prologue.c_str()), |
7991 B(LdaSmi8), U8(3), // | 1963 LoadGolden("WideRegisters.golden")); |
7992 B(MovWide), R16(161), R16(125), // | |
7993 B(TestGreaterThan), R(125), // | |
7994 B(JumpIfFalse), U8(10), // | |
7995 B(MovWide), R16(133), R16(125), // | |
7996 B(Ldar), R(125), // | |
7997 B(Return), // | |
7998 B(MovWide), R16(132), R16(125), // | |
7999 B(Ldar), R(125), // | |
8000 B(Return), // | |
8001 }}, | |
8002 {"var x0 = 0;\n" | |
8003 "if (x129 == 3) { var x129 = x0; }\n" | |
8004 "if (x2 > 3) { return x0; }\n" | |
8005 "return x129;\n", | |
8006 162 * kPointerSize, | |
8007 1, | |
8008 69, | |
8009 { | |
8010 B(StackCheck), // | |
8011 B(LdaZero), // | |
8012 B(Star), R(0), // | |
8013 B(MovWide), R16(133), R16(125), // | |
8014 B(Ldar), R(125), // | |
8015 B(Star), R(125), // | |
8016 B(MovWide), R16(125), R16(161), // | |
8017 B(LdaSmi8), U8(3), // | |
8018 B(MovWide), R16(161), R16(125), // | |
8019 B(TestEqual), R(125), // | |
8020 B(JumpIfFalse), U8(11), // | |
8021 B(Ldar), R(0), // | |
8022 B(Star), R(125), // | |
8023 B(MovWide), R16(125), R16(133), // | |
8024 B(Ldar), R(2), // | |
8025 B(Star), R(125), // | |
8026 B(MovWide), R16(125), R16(161), // | |
8027 B(LdaSmi8), U8(3), // | |
8028 B(MovWide), R16(161), R16(125), // | |
8029 B(TestGreaterThan), R(125), // | |
8030 B(JumpIfFalse), U8(5), // | |
8031 B(Ldar), R(0), // | |
8032 B(Return), // | |
8033 B(MovWide), R16(133), R16(125), // | |
8034 B(Ldar), R(125), // | |
8035 B(Return), // | |
8036 }}, | |
8037 {"var x0 = 0;\n" | |
8038 "var x1 = 0;\n" | |
8039 "for (x128 = 0; x128 < 64; x128++) {" | |
8040 " x1 += x128;" | |
8041 "}" | |
8042 "return x128;\n", | |
8043 162 * kPointerSize, | |
8044 1, | |
8045 99, | |
8046 { | |
8047 B(StackCheck), // | |
8048 B(LdaZero), // | |
8049 B(Star), R(0), // | |
8050 B(LdaZero), // | |
8051 B(Star), R(1), // | |
8052 B(LdaZero), // | |
8053 B(Star), R(125), // | |
8054 B(MovWide), R16(125), R16(132), // | |
8055 B(MovWide), R16(132), R16(125), // | |
8056 B(Ldar), R(125), // | |
8057 B(Star), R(125), // | |
8058 B(MovWide), R16(125), R16(161), // | |
8059 B(LdaSmi8), U8(64), // | |
8060 B(MovWide), R16(161), R16(125), // | |
8061 B(TestLessThan), R(125), // | |
8062 B(JumpIfFalse), U8(53), // | |
8063 B(StackCheck), // | |
8064 B(Ldar), R(1), // | |
8065 B(Star), R(125), // | |
8066 B(MovWide), R16(125), R16(161), // | |
8067 B(MovWide), R16(132), R16(125), // | |
8068 B(Ldar), R(125), // | |
8069 B(MovWide), R16(161), R16(125), // | |
8070 B(Add), R(125), // | |
8071 B(Star), R(1), // | |
8072 B(MovWide), R16(132), R16(125), // | |
8073 B(Ldar), R(125), // | |
8074 B(ToNumber), // | |
8075 B(Star), R(125), // | |
8076 B(MovWide), R16(125), R16(161), // | |
8077 B(Inc), // | |
8078 B(Star), R(125), // | |
8079 B(MovWide), R16(125), R16(132), // | |
8080 B(Jump), U8(-74), // | |
8081 B(MovWide), R16(132), R16(125), // | |
8082 B(Ldar), R(125), // | |
8083 B(Return), // | |
8084 }}, | |
8085 {"var x0 = 1234;\n" | |
8086 "var x1 = 0;\n" | |
8087 "for (x128 in x0) {" | |
8088 " x1 += x128;" | |
8089 "}" | |
8090 "return x1;\n", | |
8091 167 * kPointerSize, | |
8092 1, | |
8093 111, | |
8094 { | |
8095 B(StackCheck), // | |
8096 B(LdaConstant), U8(0), // | |
8097 B(Star), R(0), // | |
8098 B(LdaZero), // | |
8099 B(Star), R(1), // | |
8100 B(Ldar), R(0), // | |
8101 B(JumpIfUndefined), U8(98), // | |
8102 B(JumpIfNull), U8(96), // | |
8103 B(ToObject), // | |
8104 B(JumpIfNull), U8(93), // | |
8105 B(Star), R(125), // | |
8106 B(MovWide), R16(125), R16(161), // | |
8107 B(ForInPrepareWide), R16(162), // | |
8108 B(LdaZero), // | |
8109 B(Star), R(125), // | |
8110 B(MovWide), R16(125), R16(165), // | |
8111 B(MovWide), R16(165), R16(125), // | |
8112 B(MovWide), R16(164), R16(126), // | |
8113 B(ForInDone), R(125), R(126), // | |
8114 B(JumpIfTrue), U8(60), // | |
8115 B(ForInNextWide), R16(161), R16(165), R16(162), // | |
8116 B(JumpIfUndefined), U8(35), // | |
8117 B(Star), R(125), // | |
8118 B(MovWide), R16(125), R16(132), // | |
8119 B(StackCheck), // | |
8120 B(Ldar), R(1), // | |
8121 B(Star), R(125), // | |
8122 B(MovWide), R16(125), R16(166), // | |
8123 B(MovWide), R16(132), R16(125), // | |
8124 B(Ldar), R(125), // | |
8125 B(MovWide), R16(166), R16(125), // | |
8126 B(Add), R(125), // | |
8127 B(Star), R(1), // | |
8128 B(MovWide), R16(165), R16(125), // | |
8129 B(ForInStep), R(125), // | |
8130 B(Star), R(125), // | |
8131 B(MovWide), R16(125), R16(165), // | |
8132 B(Jump), U8(-71), // | |
8133 B(Ldar), R(1), // | |
8134 B(Return), // | |
8135 }, | |
8136 1, | |
8137 {1234}}, | |
8138 {"x0 = %Add(x64, x63);\n" | |
8139 "x1 = %Add(x27, x143);\n" | |
8140 "%TheHole();\n" | |
8141 "return x1;\n", | |
8142 163 * kPointerSize, | |
8143 1, | |
8144 66, | |
8145 { | |
8146 B(StackCheck), // | |
8147 B(Ldar), R(64), // | |
8148 B(Star), R(125), // | |
8149 B(MovWide), R16(125), R16(161), // | |
8150 B(Ldar), R(63), // | |
8151 B(Star), R(125), // | |
8152 B(MovWide), R16(125), R16(162), // | |
8153 B(CallRuntimeWide), U16(Runtime::kAdd), R16(161), U8(2), // | |
8154 B(Star), R(0), // | |
8155 B(Ldar), R(27), // | |
8156 B(Star), R(125), // | |
8157 B(MovWide), R16(125), R16(161), // | |
8158 B(MovWide), R16(147), R16(125), // | |
8159 B(Ldar), R(125), // | |
8160 B(Star), R(125), // | |
8161 B(MovWide), R16(125), R16(162), // | |
8162 B(CallRuntimeWide), U16(Runtime::kAdd), R16(161), U8(2), // | |
8163 B(Star), R(1), // | |
8164 B(CallRuntime), U16(Runtime::kTheHole), R(0), U8(0), // | |
8165 B(Ldar), R(1), // | |
8166 B(Return), // | |
8167 }} | |
8168 }; | |
8169 // clang-format on | |
8170 | |
8171 InitializedHandleScope handle_scope; | |
8172 BytecodeGeneratorHelper helper; | |
8173 | |
8174 for (size_t i = 0; i < arraysize(snippets); ++i) { | |
8175 std::string body = prologue + snippets[i].code_snippet; | |
8176 Handle<BytecodeArray> bytecode_array = | |
8177 helper.MakeBytecodeForFunctionBody(body.c_str()); | |
8178 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
8179 } | |
8180 } | 1964 } |
8181 | 1965 |
8182 TEST(ConstVariable) { | 1966 TEST(ConstVariable) { |
8183 InitializedHandleScope handle_scope; | 1967 InitializedIgnitionHandleScope scope; |
8184 BytecodeGeneratorHelper helper; | 1968 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
8185 // clang-format off | 1969 ConstantPoolType::kString); |
8186 ExpectedSnippet<const char*> snippets[] = { | 1970 const char* snippets[] = { |
8187 {"const x = 10;", | 1971 "const x = 10;", |
8188 1 * kPointerSize, | 1972 |
8189 1, | 1973 "const x = 10; return x;", |
8190 10, | 1974 |
8191 { | 1975 "const x = ( x = 20);", |
8192 B(LdaTheHole), // | 1976 |
8193 B(Star), R(0), // | 1977 "const x = 10; x = 20;", |
8194 B(StackCheck), // | 1978 }; |
8195 B(LdaSmi8), U8(10), // | 1979 |
8196 B(Star), R(0), // | 1980 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("ConstVariable.golden")); |
8197 B(LdaUndefined), // | |
8198 B(Return) // | |
8199 }, | |
8200 0}, | |
8201 {"const x = 10; return x;", | |
8202 2 * kPointerSize, | |
8203 1, | |
8204 20, | |
8205 { | |
8206 B(LdaTheHole), // | |
8207 B(Star), R(0), // | |
8208 B(StackCheck), // | |
8209 B(LdaSmi8), U8(10), // | |
8210 B(Star), R(0), // | |
8211 B(JumpIfNotHole), U8(11), // | |
8212 B(LdaConstant), U8(0), // | |
8213 B(Star), R(1), // | |
8214 B(CallRuntime), U16(Runtime::kThrowReferenceError), R(1), U8(1), // | |
8215 B(Return) // | |
8216 }, | |
8217 1, | |
8218 {"x"}}, | |
8219 {"const x = ( x = 20);", | |
8220 3 * kPointerSize, | |
8221 1, | |
8222 32, | |
8223 { | |
8224 B(LdaTheHole), // | |
8225 B(Star), R(0), // | |
8226 B(StackCheck), // | |
8227 B(LdaSmi8), U8(20), // | |
8228 B(Star), R(1), // | |
8229 B(Ldar), R(0), // | |
8230 B(JumpIfNotHole), U8(11), // | |
8231 B(LdaConstant), U8(0), // | |
8232 B(Star), R(2), // | |
8233 B(CallRuntime), U16(Runtime::kThrowReferenceError), R(2), U8(1), // | |
8234 B(CallRuntime), U16(Runtime::kThrowConstAssignError), R(0), // | |
8235 /* */ U8(0), // | |
8236 B(Ldar), R(1), // | |
8237 B(Star), R(0), // | |
8238 B(LdaUndefined), // | |
8239 B(Return) // | |
8240 }, | |
8241 1, | |
8242 {"x"}}, | |
8243 {"const x = 10; x = 20;", | |
8244 3 * kPointerSize, | |
8245 1, | |
8246 36, | |
8247 { | |
8248 B(LdaTheHole), // | |
8249 B(Star), R(0), // | |
8250 B(StackCheck), // | |
8251 B(LdaSmi8), U8(10), // | |
8252 B(Star), R(0), // | |
8253 B(LdaSmi8), U8(20), // | |
8254 B(Star), R(1), // | |
8255 B(Ldar), R(0), // | |
8256 B(JumpIfNotHole), U8(11), // | |
8257 B(LdaConstant), U8(0), // | |
8258 B(Star), R(2), // | |
8259 B(CallRuntime), U16(Runtime::kThrowReferenceError), R(2), U8(1), // | |
8260 B(CallRuntime), U16(Runtime::kThrowConstAssignError), R(0), // | |
8261 /* */ U8(0), // | |
8262 B(Ldar), R(1), // | |
8263 B(Star), R(0), // | |
8264 B(LdaUndefined), // | |
8265 B(Return) // | |
8266 }, | |
8267 1, | |
8268 {"x"}}, | |
8269 }; | |
8270 // clang-format on | |
8271 | |
8272 for (size_t i = 0; i < arraysize(snippets); i++) { | |
8273 Handle<BytecodeArray> bytecode_array = | |
8274 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
8275 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
8276 } | |
8277 } | 1981 } |
8278 | 1982 |
8279 TEST(LetVariable) { | 1983 TEST(LetVariable) { |
8280 InitializedHandleScope handle_scope; | 1984 InitializedIgnitionHandleScope scope; |
8281 BytecodeGeneratorHelper helper; | 1985 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
8282 | 1986 ConstantPoolType::kString); |
8283 // clang-format off | 1987 const char* snippets[] = { |
8284 ExpectedSnippet<const char*> snippets[] = { | 1988 "let x = 10;", |
8285 {"let x = 10;", | 1989 |
8286 1 * kPointerSize, | 1990 "let x = 10; return x;", |
8287 1, | 1991 |
8288 10, | 1992 "let x = (x = 20);", |
8289 { | 1993 |
8290 B(LdaTheHole), // | 1994 "let x = 10; x = 20;", |
8291 B(Star), R(0), // | 1995 }; |
8292 B(StackCheck), // | 1996 |
8293 B(LdaSmi8), U8(10), // | 1997 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("LetVariable.golden")); |
8294 B(Star), R(0), // | |
8295 B(LdaUndefined), // | |
8296 B(Return) // | |
8297 }, | |
8298 0}, | |
8299 {"let x = 10; return x;", | |
8300 2 * kPointerSize, | |
8301 1, | |
8302 20, | |
8303 { | |
8304 B(LdaTheHole), // | |
8305 B(Star), R(0), // | |
8306 B(StackCheck), // | |
8307 B(LdaSmi8), U8(10), // | |
8308 B(Star), R(0), // | |
8309 B(JumpIfNotHole), U8(11), // | |
8310 B(LdaConstant), U8(0), // | |
8311 B(Star), R(1), // | |
8312 B(CallRuntime), U16(Runtime::kThrowReferenceError), R(1), U8(1), // | |
8313 B(Return) // | |
8314 }, | |
8315 1, | |
8316 {"x"}}, | |
8317 {"let x = (x = 20);", | |
8318 3 * kPointerSize, | |
8319 1, | |
8320 27, | |
8321 { | |
8322 B(LdaTheHole), // | |
8323 B(Star), R(0), // | |
8324 B(StackCheck), // | |
8325 B(LdaSmi8), U8(20), // | |
8326 B(Star), R(1), // | |
8327 B(Ldar), R(0), // | |
8328 B(JumpIfNotHole), U8(11), // | |
8329 B(LdaConstant), U8(0), // | |
8330 B(Star), R(2), // | |
8331 B(CallRuntime), U16(Runtime::kThrowReferenceError), R(2), U8(1), // | |
8332 B(Ldar), R(1), // | |
8333 B(Star), R(0), // | |
8334 B(LdaUndefined), // | |
8335 B(Return) // | |
8336 }, | |
8337 1, | |
8338 {"x"}}, | |
8339 {"let x = 10; x = 20;", | |
8340 3 * kPointerSize, | |
8341 1, | |
8342 31, | |
8343 { | |
8344 B(LdaTheHole), // | |
8345 B(Star), R(0), // | |
8346 B(StackCheck), // | |
8347 B(LdaSmi8), U8(10), // | |
8348 B(Star), R(0), // | |
8349 B(LdaSmi8), U8(20), // | |
8350 B(Star), R(1), // | |
8351 B(Ldar), R(0), // | |
8352 B(JumpIfNotHole), U8(11), // | |
8353 B(LdaConstant), U8(0), // | |
8354 B(Star), R(2), // | |
8355 B(CallRuntime), U16(Runtime::kThrowReferenceError), R(2), U8(1), // | |
8356 B(Ldar), R(1), // | |
8357 B(Star), R(0), // | |
8358 B(LdaUndefined), // | |
8359 B(Return) // | |
8360 }, | |
8361 1, | |
8362 {"x"}}, | |
8363 }; | |
8364 // clang-format on | |
8365 | |
8366 for (size_t i = 0; i < arraysize(snippets); i++) { | |
8367 Handle<BytecodeArray> bytecode_array = | |
8368 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
8369 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
8370 } | |
8371 } | 1998 } |
8372 | 1999 |
8373 TEST(LegacyConstVariable) { | 2000 TEST(LegacyConstVariable) { |
8374 bool old_legacy_const_flag = FLAG_legacy_const; | 2001 bool old_legacy_const_flag = FLAG_legacy_const; |
8375 FLAG_legacy_const = true; | 2002 FLAG_legacy_const = true; |
8376 | 2003 |
8377 InitializedHandleScope handle_scope; | 2004 InitializedIgnitionHandleScope scope; |
8378 BytecodeGeneratorHelper helper; | 2005 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
8379 | 2006 ConstantPoolType::kString); |
8380 // clang-format off | 2007 const char* snippets[] = { |
8381 ExpectedSnippet<const char*> snippets[] = { | 2008 "const x = 10;", |
8382 {"const x = 10;", | 2009 |
8383 2 * kPointerSize, | 2010 "const x = 10; return x;", |
8384 1, | 2011 |
8385 19, | 2012 "const x = ( x = 20);", |
8386 { | 2013 |
8387 B(LdaTheHole), // | 2014 "const x = 10; x = 20;", |
8388 B(Star), R(0), // | 2015 }; |
8389 B(StackCheck), // | 2016 |
8390 B(LdaSmi8), U8(10), // | 2017 CHECK_EQ(BuildActual(printer, snippets), |
8391 B(Star), R(1), // | 2018 LoadGolden("LegacyConstVariable.golden")); |
8392 B(Ldar), R(0), // | |
8393 B(JumpIfNotHole), U8(5), // | |
8394 B(Mov), R(1), R(0), // | |
8395 B(Ldar), R(1), // | |
8396 B(LdaUndefined), // | |
8397 B(Return) // | |
8398 }, | |
8399 0}, | |
8400 {"const x = 10; return x;", | |
8401 2 * kPointerSize, | |
8402 1, | |
8403 23, | |
8404 { | |
8405 B(LdaTheHole), // | |
8406 B(Star), R(0), // | |
8407 B(StackCheck), // | |
8408 B(LdaSmi8), U8(10), // | |
8409 B(Star), R(1), // | |
8410 B(Ldar), R(0), // | |
8411 B(JumpIfNotHole), U8(5), // | |
8412 B(Mov), R(1), R(0), // | |
8413 B(Ldar), R(1), // | |
8414 B(Ldar), R(0), // | |
8415 B(JumpIfNotHole), U8(3), // | |
8416 B(LdaUndefined), // | |
8417 B(Return) // | |
8418 }, | |
8419 0}, | |
8420 {"const x = ( x = 20);", | |
8421 2 * kPointerSize, | |
8422 1, | |
8423 23, | |
8424 { | |
8425 B(LdaTheHole), // | |
8426 B(Star), R(0), // | |
8427 B(StackCheck), // | |
8428 B(LdaSmi8), U8(20), // | |
8429 B(Star), R(1), // | |
8430 B(Ldar), R(0), // | |
8431 B(Ldar), R(1), // | |
8432 B(Ldar), R(0), // | |
8433 B(JumpIfNotHole), U8(5), // | |
8434 B(Mov), R(1), R(0), // | |
8435 B(Ldar), R(1), // | |
8436 B(LdaUndefined), // | |
8437 B(Return) // | |
8438 }, | |
8439 0}, | |
8440 {"const x = 10; x = 20;", | |
8441 2 * kPointerSize, | |
8442 1, | |
8443 27, | |
8444 { | |
8445 B(LdaTheHole), // | |
8446 B(Star), R(0), // | |
8447 B(StackCheck), // | |
8448 B(LdaSmi8), U8(10), // | |
8449 B(Star), R(1), // | |
8450 B(Ldar), R(0), // | |
8451 B(JumpIfNotHole), U8(5), // | |
8452 B(Mov), R(1), R(0), // | |
8453 B(Ldar), R(1), // | |
8454 B(LdaSmi8), U8(20), // | |
8455 B(Star), R(1), // | |
8456 B(Ldar), R(0), // | |
8457 B(Ldar), R(1), // | |
8458 B(LdaUndefined), // | |
8459 B(Return) // | |
8460 }, | |
8461 0}, | |
8462 }; | |
8463 // clang-format on | |
8464 | |
8465 for (size_t i = 0; i < arraysize(snippets); i++) { | |
8466 Handle<BytecodeArray> bytecode_array = | |
8467 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
8468 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
8469 } | |
8470 | 2019 |
8471 FLAG_legacy_const = old_legacy_const_flag; | 2020 FLAG_legacy_const = old_legacy_const_flag; |
8472 } | 2021 } |
8473 | 2022 |
8474 TEST(ConstVariableContextSlot) { | 2023 TEST(ConstVariableContextSlot) { |
8475 InitializedHandleScope handle_scope; | |
8476 BytecodeGeneratorHelper helper; | |
8477 | |
8478 int closure = Register::function_closure().index(); | |
8479 int context = Register::current_context().index(); | |
8480 | |
8481 // TODO(mythria): Add tests for initialization of this via super calls. | 2024 // TODO(mythria): Add tests for initialization of this via super calls. |
8482 // TODO(mythria): Add tests that walk the context chain. | 2025 // TODO(mythria): Add tests that walk the context chain. |
8483 // clang-format off | 2026 InitializedIgnitionHandleScope scope; |
8484 ExpectedSnippet<InstanceType> snippets[] = { | 2027 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
8485 {"const x = 10; function f1() {return x;}", | 2028 ConstantPoolType::kMixed); |
8486 2 * kPointerSize, | 2029 const char* snippets[] = { |
8487 1, | 2030 "const x = 10; function f1() {return x;}", |
8488 24, | 2031 |
8489 { | 2032 "const x = 10; function f1() {return x;} return x;", |
8490 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // | 2033 |
8491 U8(1), // | 2034 "const x = (x = 20); function f1() {return x;}", |
8492 B(PushContext), R(1), // | 2035 |
8493 B(LdaTheHole), // | 2036 "const x = 10; x = 20; function f1() {return x;}", |
8494 B(StaContextSlot), R(context), U8(4), // | 2037 }; |
8495 B(CreateClosure), U8(0), U8(0), // | 2038 |
8496 B(Star), R(0), // | 2039 CHECK_EQ(BuildActual(printer, snippets), |
8497 B(StackCheck), // | 2040 LoadGolden("ConstVariableContextSlot.golden")); |
8498 B(LdaSmi8), U8(10), // | |
8499 B(StaContextSlot), R(context), U8(4), // | |
8500 B(LdaUndefined), // | |
8501 B(Return) // | |
8502 }, | |
8503 1, | |
8504 {InstanceType::SHARED_FUNCTION_INFO_TYPE}}, | |
8505 {"const x = 10; function f1() {return x;} return x;", | |
8506 3 * kPointerSize, | |
8507 1, | |
8508 37, | |
8509 { | |
8510 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // | |
8511 U8(1), // | |
8512 B(PushContext), R(1), // | |
8513 B(LdaTheHole), // | |
8514 B(StaContextSlot), R(context), U8(4), // | |
8515 B(CreateClosure), U8(0), U8(0), // | |
8516 B(Star), R(0), // | |
8517 B(StackCheck), // | |
8518 B(LdaSmi8), U8(10), // | |
8519 B(StaContextSlot), R(context), U8(4), // | |
8520 B(LdaContextSlot), R(context), U8(4), // | |
8521 B(JumpIfNotHole), U8(11), // | |
8522 B(LdaConstant), U8(1), // | |
8523 B(Star), R(2), // | |
8524 B(CallRuntime), U16(Runtime::kThrowReferenceError), R(2), U8(1), // | |
8525 B(Return) // | |
8526 }, | |
8527 2, | |
8528 {InstanceType::SHARED_FUNCTION_INFO_TYPE, | |
8529 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
8530 {"const x = (x = 20); function f1() {return x;}", | |
8531 4 * kPointerSize, | |
8532 1, | |
8533 50, | |
8534 { | |
8535 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // | |
8536 /* */ U8(1), // | |
8537 B(PushContext), R(1), // | |
8538 B(LdaTheHole), // | |
8539 B(StaContextSlot), R(context), U8(4), // | |
8540 B(CreateClosure), U8(0), U8(0), // | |
8541 B(Star), R(0), // | |
8542 B(StackCheck), // | |
8543 B(LdaSmi8), U8(20), // | |
8544 B(Star), R(2), // | |
8545 B(LdaContextSlot), R(context), U8(4), // | |
8546 B(JumpIfNotHole), U8(11), // | |
8547 B(LdaConstant), U8(1), // | |
8548 B(Star), R(3), // | |
8549 B(CallRuntime), U16(Runtime::kThrowReferenceError), R(3), U8(1), // | |
8550 B(CallRuntime), U16(Runtime::kThrowConstAssignError), R(0), // | |
8551 U8(0), // | |
8552 B(Ldar), R(2), // | |
8553 B(StaContextSlot), R(context), U8(4), // | |
8554 B(StaContextSlot), R(context), U8(4), // | |
8555 B(LdaUndefined), // | |
8556 B(Return) // | |
8557 }, | |
8558 2, | |
8559 {InstanceType::SHARED_FUNCTION_INFO_TYPE, | |
8560 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
8561 {"const x = 10; x = 20; function f1() {return x;}", | |
8562 4 * kPointerSize, | |
8563 1, | |
8564 52, | |
8565 { | |
8566 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // | |
8567 /* */ U8(1), // | |
8568 B(PushContext), R(1), // | |
8569 B(LdaTheHole), // | |
8570 B(StaContextSlot), R(context), U8(4), // | |
8571 B(CreateClosure), U8(0), U8(0), // | |
8572 B(Star), R(0), // | |
8573 B(StackCheck), // | |
8574 B(LdaSmi8), U8(10), // | |
8575 B(StaContextSlot), R(context), U8(4), // | |
8576 B(LdaSmi8), U8(20), // | |
8577 B(Star), R(2), // | |
8578 B(LdaContextSlot), R(context), U8(4), // | |
8579 B(JumpIfNotHole), U8(11), // | |
8580 B(LdaConstant), U8(1), // | |
8581 B(Star), R(3), // | |
8582 B(CallRuntime), U16(Runtime::kThrowReferenceError), R(3), U8(1), // | |
8583 B(CallRuntime), U16(Runtime::kThrowConstAssignError), R(0), // | |
8584 U8(0), // | |
8585 B(Ldar), R(2), // | |
8586 B(StaContextSlot), R(context), U8(4), // | |
8587 B(LdaUndefined), // | |
8588 B(Return) // | |
8589 }, | |
8590 2, | |
8591 {InstanceType::SHARED_FUNCTION_INFO_TYPE, | |
8592 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
8593 }; | |
8594 // clang-format on | |
8595 | |
8596 for (size_t i = 0; i < arraysize(snippets); i++) { | |
8597 Handle<BytecodeArray> bytecode_array = | |
8598 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
8599 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
8600 } | |
8601 } | 2041 } |
8602 | 2042 |
8603 TEST(LetVariableContextSlot) { | 2043 TEST(LetVariableContextSlot) { |
8604 InitializedHandleScope handle_scope; | 2044 InitializedIgnitionHandleScope scope; |
8605 BytecodeGeneratorHelper helper; | 2045 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
8606 | 2046 ConstantPoolType::kMixed); |
8607 int closure = Register::function_closure().index(); | 2047 const char* snippets[] = { |
8608 int context = Register::current_context().index(); | 2048 "let x = 10; function f1() {return x;}", |
8609 | 2049 |
8610 // clang-format off | 2050 "let x = 10; function f1() {return x;} return x;", |
8611 ExpectedSnippet<InstanceType> snippets[] = { | 2051 |
8612 {"let x = 10; function f1() {return x;}", | 2052 "let x = (x = 20); function f1() {return x;}", |
8613 2 * kPointerSize, | 2053 |
8614 1, | 2054 "let x = 10; x = 20; function f1() {return x;}", |
8615 24, | 2055 }; |
8616 { | 2056 |
8617 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // | 2057 CHECK_EQ(BuildActual(printer, snippets), |
8618 /* */ U8(1), // | 2058 LoadGolden("LetVariableContextSlot.golden")); |
8619 B(PushContext), R(1), // | |
8620 B(LdaTheHole), // | |
8621 B(StaContextSlot), R(context), U8(4), // | |
8622 B(CreateClosure), U8(0), U8(0), // | |
8623 B(Star), R(0), // | |
8624 B(StackCheck), // | |
8625 B(LdaSmi8), U8(10), // | |
8626 B(StaContextSlot), R(context), U8(4), // | |
8627 B(LdaUndefined), // | |
8628 B(Return) // | |
8629 }, | |
8630 1, | |
8631 {InstanceType::SHARED_FUNCTION_INFO_TYPE}}, | |
8632 {"let x = 10; function f1() {return x;} return x;", | |
8633 3 * kPointerSize, | |
8634 1, | |
8635 37, | |
8636 { | |
8637 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // | |
8638 /* */ U8(1), // | |
8639 B(PushContext), R(1), // | |
8640 B(LdaTheHole), // | |
8641 B(StaContextSlot), R(context), U8(4), // | |
8642 B(CreateClosure), U8(0), U8(0), // | |
8643 B(Star), R(0), // | |
8644 B(StackCheck), // | |
8645 B(LdaSmi8), U8(10), // | |
8646 B(StaContextSlot), R(context), U8(4), // | |
8647 B(LdaContextSlot), R(context), U8(4), // | |
8648 B(JumpIfNotHole), U8(11), // | |
8649 B(LdaConstant), U8(1), // | |
8650 B(Star), R(2), // | |
8651 B(CallRuntime), U16(Runtime::kThrowReferenceError), R(2), U8(1), // | |
8652 B(Return) // | |
8653 }, | |
8654 2, | |
8655 {InstanceType::SHARED_FUNCTION_INFO_TYPE, | |
8656 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
8657 {"let x = (x = 20); function f1() {return x;}", | |
8658 4 * kPointerSize, | |
8659 1, | |
8660 45, | |
8661 { | |
8662 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // | |
8663 /* */ U8(1), // | |
8664 B(PushContext), R(1), // | |
8665 B(LdaTheHole), // | |
8666 B(StaContextSlot), R(context), U8(4), // | |
8667 B(CreateClosure), U8(0), U8(0), // | |
8668 B(Star), R(0), // | |
8669 B(StackCheck), // | |
8670 B(LdaSmi8), U8(20), // | |
8671 B(Star), R(2), // | |
8672 B(LdaContextSlot), R(context), U8(4), // | |
8673 B(JumpIfNotHole), U8(11), // | |
8674 B(LdaConstant), U8(1), // | |
8675 B(Star), R(3), // | |
8676 B(CallRuntime), U16(Runtime::kThrowReferenceError), R(3), U8(1), // | |
8677 B(Ldar), R(2), // | |
8678 B(StaContextSlot), R(context), U8(4), // | |
8679 B(StaContextSlot), R(context), U8(4), // | |
8680 B(LdaUndefined), // | |
8681 B(Return) // | |
8682 }, | |
8683 2, | |
8684 {InstanceType::SHARED_FUNCTION_INFO_TYPE, | |
8685 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
8686 {"let x = 10; x = 20; function f1() {return x;}", | |
8687 4 * kPointerSize, | |
8688 1, | |
8689 47, | |
8690 { | |
8691 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // | |
8692 /* */ U8(1), // | |
8693 B(PushContext), R(1), // | |
8694 B(LdaTheHole), // | |
8695 B(StaContextSlot), R(context), U8(4), // | |
8696 B(CreateClosure), U8(0), U8(0), // | |
8697 B(Star), R(0), // | |
8698 B(StackCheck), // | |
8699 B(LdaSmi8), U8(10), // | |
8700 B(StaContextSlot), R(context), U8(4), // | |
8701 B(LdaSmi8), U8(20), // | |
8702 B(Star), R(2), // | |
8703 B(LdaContextSlot), R(context), U8(4), // | |
8704 B(JumpIfNotHole), U8(11), // | |
8705 B(LdaConstant), U8(1), // | |
8706 B(Star), R(3), // | |
8707 B(CallRuntime), U16(Runtime::kThrowReferenceError), R(3), U8(1), // | |
8708 B(Ldar), R(2), // | |
8709 B(StaContextSlot), R(context), U8(4), // | |
8710 B(LdaUndefined), // | |
8711 B(Return) // | |
8712 }, | |
8713 2, | |
8714 {InstanceType::SHARED_FUNCTION_INFO_TYPE, | |
8715 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
8716 }; | |
8717 // clang-format on | |
8718 | |
8719 for (size_t i = 0; i < arraysize(snippets); i++) { | |
8720 Handle<BytecodeArray> bytecode_array = | |
8721 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
8722 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
8723 } | |
8724 } | 2059 } |
8725 | 2060 |
8726 TEST(DoExpression) { | 2061 TEST(DoExpression) { |
8727 bool old_flag = FLAG_harmony_do_expressions; | 2062 bool old_flag = FLAG_harmony_do_expressions; |
8728 FLAG_harmony_do_expressions = true; | 2063 FLAG_harmony_do_expressions = true; |
8729 | 2064 |
8730 InitializedHandleScope handle_scope; | 2065 InitializedIgnitionHandleScope scope; |
8731 BytecodeGeneratorHelper helper; | 2066 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
8732 | 2067 ConstantPoolType::kString); |
8733 // clang-format off | 2068 const char* snippets[] = { |
8734 ExpectedSnippet<const char*> snippets[] = { | 2069 "var a = do { }; return a;", |
8735 {"var a = do { }; return a;", | 2070 |
8736 2 * kPointerSize, | 2071 "var a = do { var x = 100; }; return a;", |
8737 1, | 2072 |
8738 6, | 2073 "while(true) { var a = 10; a = do { ++a; break; }; a = 20; }", |
8739 { | 2074 }; |
8740 B(StackCheck), // | 2075 |
8741 B(Ldar), R(0), // | 2076 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("DoExpression.golden")); |
8742 B(Star), R(1), // | 2077 |
8743 B(Return) // | |
8744 }, | |
8745 0}, | |
8746 {"var a = do { var x = 100; }; return a;", | |
8747 3 * kPointerSize, | |
8748 1, | |
8749 11, | |
8750 { | |
8751 B(StackCheck), // | |
8752 B(LdaSmi8), U8(100), // | |
8753 B(Star), R(1), // | |
8754 B(LdaUndefined), // | |
8755 B(Star), R(0), // | |
8756 B(Star), R(2), // | |
8757 B(Return) // | |
8758 }, | |
8759 0}, | |
8760 {"while(true) { var a = 10; a = do { ++a; break; }; a = 20; }", | |
8761 2 * kPointerSize, | |
8762 1, | |
8763 26, | |
8764 { | |
8765 B(StackCheck), // | |
8766 B(StackCheck), // | |
8767 B(LdaSmi8), U8(10), // | |
8768 B(Star), R(1), // | |
8769 B(ToNumber), // | |
8770 B(Inc), // | |
8771 B(Star), R(1), // | |
8772 B(Star), R(0), // | |
8773 B(Jump), U8(12), // | |
8774 B(Ldar), R(0), // | |
8775 B(Star), R(1), // | |
8776 B(LdaSmi8), U8(20), // | |
8777 B(Star), R(1), // | |
8778 B(Jump), U8(-21), // | |
8779 B(LdaUndefined), // | |
8780 B(Return), // | |
8781 }, | |
8782 0}, | |
8783 }; | |
8784 // clang-format on | |
8785 | |
8786 for (size_t i = 0; i < arraysize(snippets); i++) { | |
8787 Handle<BytecodeArray> bytecode_array = | |
8788 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
8789 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
8790 } | |
8791 FLAG_harmony_do_expressions = old_flag; | 2078 FLAG_harmony_do_expressions = old_flag; |
8792 } | 2079 } |
8793 | 2080 |
8794 TEST(WithStatement) { | 2081 TEST(WithStatement) { |
8795 InitializedHandleScope handle_scope; | 2082 InitializedIgnitionHandleScope scope; |
8796 BytecodeGeneratorHelper helper; | 2083 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
8797 | 2084 ConstantPoolType::kMixed); |
8798 int deep_elements_flags = | 2085 const char* snippets[] = { |
8799 ObjectLiteral::kFastElements | ObjectLiteral::kDisableMementos; | 2086 "with ({x:42}) { return x; }", |
8800 int context = Register::current_context().index(); | 2087 }; |
8801 int closure = Register::function_closure().index(); | 2088 |
8802 int new_target = Register::new_target().index(); | 2089 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("WithStatement.golden")); |
8803 | |
8804 // clang-format off | |
8805 ExpectedSnippet<InstanceType> snippets[] = { | |
8806 {"with ({x:42}) { return x; }", | |
8807 5 * kPointerSize, | |
8808 1, | |
8809 47, | |
8810 { | |
8811 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // | |
8812 /* */ U8(1), // | |
8813 B(PushContext), R(0), // | |
8814 B(Ldar), THIS(1), // | |
8815 B(StaContextSlot), R(context), U8(4), // | |
8816 B(CreateMappedArguments), // | |
8817 B(StaContextSlot), R(context), U8(5), // | |
8818 B(Ldar), R(new_target), // | |
8819 B(StaContextSlot), R(context), U8(6), // | |
8820 B(StackCheck), // | |
8821 B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags), // | |
8822 B(Star), R(2), // | |
8823 B(ToObject), // | |
8824 B(Star), R(3), // | |
8825 B(Ldar), R(closure), // | |
8826 B(Star), R(4), // | |
8827 B(CallRuntime), U16(Runtime::kPushWithContext), R(3), U8(2), // | |
8828 B(PushContext), R(1), // | |
8829 B(LdaLookupSlot), U8(1), // | |
8830 B(PopContext), R(0), // | |
8831 B(Return), // | |
8832 }, | |
8833 2, | |
8834 {InstanceType::FIXED_ARRAY_TYPE, | |
8835 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
8836 }; | |
8837 // clang-format on | |
8838 | |
8839 for (size_t i = 0; i < arraysize(snippets); i++) { | |
8840 Handle<BytecodeArray> bytecode_array = | |
8841 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
8842 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
8843 } | |
8844 } | 2090 } |
8845 | 2091 |
8846 TEST(DoDebugger) { | 2092 TEST(DoDebugger) { |
8847 InitializedHandleScope handle_scope; | 2093 InitializedIgnitionHandleScope scope; |
8848 BytecodeGeneratorHelper helper; | 2094 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
8849 | 2095 ConstantPoolType::kString); |
8850 // clang-format off | 2096 const char* snippets[] = { |
8851 ExpectedSnippet<const char*> snippet = { | |
8852 "debugger;", | 2097 "debugger;", |
8853 0, | 2098 }; |
8854 1, | 2099 |
8855 4, | 2100 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("DoDebugger.golden")); |
8856 { | |
8857 B(StackCheck), // | |
8858 B(Debugger), // | |
8859 B(LdaUndefined), // | |
8860 B(Return) // | |
8861 }, | |
8862 0 | |
8863 }; | |
8864 // clang-format on | |
8865 | |
8866 Handle<BytecodeArray> bytecode_array = | |
8867 helper.MakeBytecodeForFunctionBody(snippet.code_snippet); | |
8868 CheckBytecodeArrayEqual(snippet, bytecode_array); | |
8869 } | 2101 } |
8870 | 2102 |
8871 // TODO(rmcilroy): Update expectations after switch to | 2103 // TODO(rmcilroy): Update expectations after switch to |
8872 // Runtime::kDefineDataPropertyInLiteral. | 2104 // Runtime::kDefineDataPropertyInLiteral. |
8873 TEST(ClassDeclarations) { | 2105 TEST(ClassDeclarations) { |
8874 InitializedHandleScope handle_scope; | 2106 InitializedIgnitionHandleScope scope; |
8875 BytecodeGeneratorHelper helper; | 2107 BytecodeExpectationsPrinter printer(CcTest::isolate(), |
8876 | 2108 ConstantPoolType::kMixed); |
8877 int closure = Register::function_closure().index(); | 2109 const char* snippets[] = { |
8878 int context = Register::current_context().index(); | 2110 "class Person {\n" |
8879 | 2111 " constructor(name) { this.name = name; }\n" |
8880 // clang-format off | 2112 " speak() { console.log(this.name + ' is speaking.'); }\n" |
8881 ExpectedSnippet<InstanceType, 12> snippets[] = { | 2113 "}", |
8882 {"class Person {\n" | 2114 |
8883 " constructor(name) { this.name = name; }\n" | 2115 "class person {\n" |
8884 " speak() { console.log(this.name + ' is speaking.'); }\n" | 2116 " constructor(name) { this.name = name; }\n" |
8885 "}\n", | 2117 " speak() { console.log(this.name + ' is speaking.'); }\n" |
8886 9 * kPointerSize, | 2118 "}", |
8887 1, | 2119 |
8888 71, | 2120 "var n0 = 'a';\n" |
8889 { | 2121 "var n1 = 'b';\n" |
8890 B(LdaTheHole), // | 2122 "class N {\n" |
8891 B(Star), R(1), // | 2123 " [n0]() { return n0; }\n" |
8892 B(StackCheck), // | 2124 " static [n1]() { return n1; }\n" |
8893 B(LdaTheHole), // | 2125 "}", |
8894 B(Star), R(0), // | 2126 |
8895 B(LdaTheHole), // | 2127 "var count = 0;\n" |
8896 B(Star), R(2), // | 2128 "class C { constructor() { count++; }}\n" |
8897 B(CreateClosure), U8(0), U8(0), // | 2129 "return new C();\n", |
8898 B(Star), R(3), // | 2130 }; |
8899 B(LdaSmi8), U8(15), // | 2131 |
8900 B(Star), R(4), // | 2132 CHECK_EQ(BuildActual(printer, snippets), |
8901 B(LdaConstant), U8(1), // | 2133 LoadGolden("ClassDeclarations.golden")); |
8902 B(Star), R(5), // | |
8903 B(CallRuntime), U16(Runtime::kDefineClass), R(2), U8(4), // | |
8904 B(Star), R(2), // | |
8905 B(LoadIC), R(2), U8(2), U8(1), // | |
8906 B(Star), R(3), // | |
8907 B(Mov), R(3), R(4), // | |
8908 B(LdaConstant), U8(3), // | |
8909 B(Star), R(5), // | |
8910 B(CreateClosure), U8(4), U8(0), // | |
8911 B(Star), R(6), // | |
8912 B(LdaSmi8), U8(2), // | |
8913 B(Star), R(7), // | |
8914 B(LdaZero), // | |
8915 B(Star), R(8), // | |
8916 B(CallRuntime), U16(Runtime::kDefineDataPropertyInLiteral), R(4), U8(5), | |
8917 B(CallRuntime), U16(Runtime::kFinalizeClassDefinition), R(2), U8(2), // | |
8918 B(Star), R(0), // | |
8919 B(Star), R(1), // | |
8920 B(LdaUndefined), // | |
8921 B(Return) // | |
8922 }, | |
8923 5, | |
8924 { InstanceType::SHARED_FUNCTION_INFO_TYPE, kInstanceTypeDontCare, | |
8925 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
8926 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
8927 InstanceType::SHARED_FUNCTION_INFO_TYPE}}, | |
8928 {"class person {\n" | |
8929 " constructor(name) { this.name = name; }\n" | |
8930 " speak() { console.log(this.name + ' is speaking.'); }\n" | |
8931 "}\n", | |
8932 9 * kPointerSize, | |
8933 1, | |
8934 71, | |
8935 { | |
8936 B(LdaTheHole), // | |
8937 B(Star), R(1), // | |
8938 B(StackCheck), // | |
8939 B(LdaTheHole), // | |
8940 B(Star), R(0), // | |
8941 B(LdaTheHole), // | |
8942 B(Star), R(2), // | |
8943 B(CreateClosure), U8(0), U8(0), // | |
8944 B(Star), R(3), // | |
8945 B(LdaSmi8), U8(15), // | |
8946 B(Star), R(4), // | |
8947 B(LdaConstant), U8(1), // | |
8948 B(Star), R(5), // | |
8949 B(CallRuntime), U16(Runtime::kDefineClass), R(2), U8(4), // | |
8950 B(Star), R(2), // | |
8951 B(LoadIC), R(2), U8(2), U8(1), // | |
8952 B(Star), R(3), // | |
8953 B(Mov), R(3), R(4), // | |
8954 B(LdaConstant), U8(3), // | |
8955 B(Star), R(5), // | |
8956 B(CreateClosure), U8(4), U8(0), // | |
8957 B(Star), R(6), // | |
8958 B(LdaSmi8), U8(2), // | |
8959 B(Star), R(7), // | |
8960 B(LdaZero), // | |
8961 B(Star), R(8), // | |
8962 B(CallRuntime), U16(Runtime::kDefineDataPropertyInLiteral), R(4), U8(5), | |
8963 B(CallRuntime), U16(Runtime::kFinalizeClassDefinition), R(2), U8(2), // | |
8964 B(Star), R(0), // | |
8965 B(Star), R(1), // | |
8966 B(LdaUndefined), // | |
8967 B(Return) // | |
8968 }, | |
8969 5, | |
8970 { InstanceType::SHARED_FUNCTION_INFO_TYPE, kInstanceTypeDontCare, | |
8971 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
8972 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
8973 InstanceType::SHARED_FUNCTION_INFO_TYPE}}, | |
8974 {"var n0 = 'a';" | |
8975 "var n1 = 'b';" | |
8976 "class N {\n" | |
8977 " [n0]() { return n0; }\n" | |
8978 " static [n1]() { return n1; }\n" | |
8979 "}\n", | |
8980 10 * kPointerSize, | |
8981 1, | |
8982 125, | |
8983 { | |
8984 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // | |
8985 /* */ U8(1), // | |
8986 B(PushContext), R(2), // | |
8987 B(LdaTheHole), // | |
8988 B(Star), R(1), // | |
8989 B(StackCheck), // | |
8990 B(LdaConstant), U8(0), // | |
8991 B(StaContextSlot), R(context), U8(4), // | |
8992 B(LdaConstant), U8(1), // | |
8993 B(StaContextSlot), R(context), U8(5), // | |
8994 B(LdaTheHole), // | |
8995 B(Star), R(0), // | |
8996 B(LdaTheHole), // | |
8997 B(Star), R(3), // | |
8998 B(CreateClosure), U8(2), U8(0), // | |
8999 B(Star), R(4), // | |
9000 B(LdaSmi8), U8(41), // | |
9001 B(Star), R(5), // | |
9002 B(LdaSmi8), U8(107), // | |
9003 B(Star), R(6), // | |
9004 B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(4), // | |
9005 B(Star), R(3), // | |
9006 B(LoadIC), R(3), U8(3), U8(1), // | |
9007 B(Star), R(4), // | |
9008 B(Mov), R(4), R(5), // | |
9009 B(LdaContextSlot), R(context), U8(4), // | |
9010 B(ToName), // | |
9011 B(Star), R(6), // | |
9012 B(CreateClosure), U8(4), U8(0), // | |
9013 B(Star), R(7), // | |
9014 B(LdaSmi8), U8(2), // | |
9015 B(Star), R(8), // | |
9016 B(LdaSmi8), U8(1), // | |
9017 B(Star), R(9), // | |
9018 B(CallRuntime), U16(Runtime::kDefineDataPropertyInLiteral), R(5), U8(5), | |
9019 B(Mov), R(3), R(5), // | |
9020 B(LdaContextSlot), R(context), U8(5), // | |
9021 B(ToName), // | |
9022 B(Star), R(6), // | |
9023 B(LdaConstant), U8(3), // | |
9024 B(TestEqualStrict), R(6), // | |
9025 B(JumpIfFalse), U8(7), // | |
9026 B(CallRuntime), U16(Runtime::kThrowStaticPrototypeError), // | |
9027 /* */ R(0), U8(0), // | |
9028 B(CreateClosure), U8(5), U8(0), // | |
9029 B(Star), R(7), // | |
9030 B(LdaSmi8), U8(1), // | |
9031 B(Star), R(9), // | |
9032 B(CallRuntime), U16(Runtime::kDefineDataPropertyInLiteral), R(5), U8(5), | |
9033 B(CallRuntime), U16(Runtime::kFinalizeClassDefinition), R(3), U8(2), // | |
9034 B(Star), R(0), // | |
9035 B(Star), R(1), // | |
9036 B(LdaUndefined), // | |
9037 B(Return), // | |
9038 }, | |
9039 6, | |
9040 { InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
9041 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
9042 InstanceType::SHARED_FUNCTION_INFO_TYPE, | |
9043 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
9044 InstanceType::SHARED_FUNCTION_INFO_TYPE, | |
9045 InstanceType::SHARED_FUNCTION_INFO_TYPE}}, | |
9046 {"var count = 0;\n" | |
9047 "class C { constructor() { count++; }}\n" | |
9048 "return new C();\n", | |
9049 10 * kPointerSize, | |
9050 1, | |
9051 74, | |
9052 { | |
9053 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1), // | |
9054 B(PushContext), R(2), // | |
9055 B(LdaTheHole), // | |
9056 B(Star), R(1), // | |
9057 B(StackCheck), // | |
9058 B(LdaZero), // | |
9059 B(StaContextSlot), R(context), U8(4), // | |
9060 B(LdaTheHole), // | |
9061 B(Star), R(0), // | |
9062 B(LdaTheHole), // | |
9063 B(Star), R(3), // | |
9064 B(CreateClosure), U8(0), U8(0), // | |
9065 B(Star), R(4), // | |
9066 B(LdaSmi8), U8(30), // | |
9067 B(Star), R(5), // | |
9068 B(LdaSmi8), U8(67), // | |
9069 B(Star), R(6), // | |
9070 B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(4), // | |
9071 B(Star), R(3), // | |
9072 B(LoadIC), R(3), U8(1), U8(1), // | |
9073 B(Star), R(4), // | |
9074 B(CallRuntime), U16(Runtime::kFinalizeClassDefinition), R(3), U8(2), // | |
9075 B(Star), R(0), // | |
9076 B(Star), R(1), // | |
9077 B(JumpIfNotHole), U8(11), // | |
9078 B(LdaConstant), U8(2), // | |
9079 B(Star), R(4), // | |
9080 B(CallRuntime), U16(Runtime::kThrowReferenceError), R(4), U8(1), // | |
9081 B(Star), R(3), // | |
9082 B(New), R(3), R(0), U8(0), // | |
9083 B(Return), // | |
9084 }, | |
9085 3, | |
9086 { InstanceType::SHARED_FUNCTION_INFO_TYPE, | |
9087 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
9088 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, | |
9089 }; | |
9090 // clang-format on | |
9091 | |
9092 for (size_t i = 0; i < arraysize(snippets); i++) { | |
9093 Handle<BytecodeArray> bytecode_array = | |
9094 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
9095 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
9096 } | |
9097 } | 2134 } |
9098 | 2135 |
9099 // TODO(oth): Add tests for super keyword. | 2136 // TODO(oth): Add tests for super keyword. |
9100 | 2137 |
9101 } // namespace interpreter | 2138 } // namespace interpreter |
9102 } // namespace internal | 2139 } // namespace internal |
9103 } // namespace v8 | 2140 } // namespace v8 |
OLD | NEW |