Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(962)

Side by Side Diff: test/cctest/interpreter/test-bytecode-generator.cc

Issue 1717293002: [Interpreter] Refactor bytecode generator test suite. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Reflow REPEAT_249 macro. Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « test/cctest/interpreter/generate-bytecode-expectations.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
OLDNEW
« no previous file with comments | « test/cctest/interpreter/generate-bytecode-expectations.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698