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

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: Fix semicolons. Created 4 years, 10 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__) REPEAT_4(__VA_ARGS__) REPEAT_2(__VA_ARGS__) __VA_ARGS__
oth 2016/02/25 10:42:00 Retentively, I'd put each REPEAT_X on it's own lin
Stefano Sanfilippo 2016/02/25 11:38:20 Done.
40
41 #define REPEAT_249(...) \
42 REPEAT_127(__VA_ARGS__) \
43 REPEAT_64(__VA_ARGS__) \
oth 2016/02/25 10:42:00 Same comment here about scanning for the reader.
Stefano Sanfilippo 2016/02/25 11:38:20 Done.
44 REPEAT_32(__VA_ARGS__) \
45 REPEAT_16(__VA_ARGS__) REPEAT_8(__VA_ARGS__) REPEAT_2(__VA_ARGS__)
46
47 #define REPEAT_2_UNIQUE_VARS() UNIQUE_VAR() UNIQUE_VAR()
48 #define REPEAT_4_UNIQUE_VARS() REPEAT_2_UNIQUE_VARS() REPEAT_2_UNIQUE_VARS()
49 #define REPEAT_8_UNIQUE_VARS() REPEAT_4_UNIQUE_VARS() REPEAT_4_UNIQUE_VARS()
50 #define REPEAT_16_UNIQUE_VARS() REPEAT_8_UNIQUE_VARS() REPEAT_8_UNIQUE_VARS()
51 #define REPEAT_32_UNIQUE_VARS() REPEAT_16_UNIQUE_VARS() REPEAT_16_UNIQUE_VARS()
52 #define REPEAT_64_UNIQUE_VARS() REPEAT_32_UNIQUE_VARS() REPEAT_32_UNIQUE_VARS()
53 #define REPEAT_128_UNIQUE_VARS() REPEAT_64_UNIQUE_VARS() REPEAT_64_UNIQUE_VARS()
54
55 #define REPEAT_249_UNIQUE_VARS() \
56 REPEAT_128_UNIQUE_VARS() \
57 REPEAT_64_UNIQUE_VARS() \
58 REPEAT_32_UNIQUE_VARS() \
59 REPEAT_16_UNIQUE_VARS() \
60 REPEAT_8_UNIQUE_VARS() \
61 UNIQUE_VAR()
62
63 static const char* kGoldenFileDirectory =
64 "test/cctest/interpreter/bytecode_expectations/";
65
66 class InitializedIgnitionHandleScope : public InitializedHandleScope {
21 public: 67 public:
22 const char* kFunctionName = "f"; 68 InitializedIgnitionHandleScope() {
23
24 static const int kLastParamIndex =
25 -InterpreterFrameConstants::kLastParamFromRegisterPointer / kPointerSize;
26
27 BytecodeGeneratorHelper() {
28 i::FLAG_ignition = true; 69 i::FLAG_ignition = true;
29 i::FLAG_ignition_filter = StrDup(kFunctionName);
30 i::FLAG_always_opt = false; 70 i::FLAG_always_opt = false;
31 i::FLAG_allow_natives_syntax = true; 71 i::FLAG_allow_natives_syntax = true;
32 CcTest::i_isolate()->interpreter()->Initialize(); 72 CcTest::i_isolate()->interpreter()->Initialize();
33 } 73 }
34 74 };
35 Isolate* isolate() { return CcTest::i_isolate(); } 75
36 Factory* factory() { return CcTest::i_isolate()->factory(); } 76 void SkipGoldenFileHeader(std::istream& stream) { // NOLINT
37 77 std::string line;
38 Handle<BytecodeArray> MakeTopLevelBytecode(const char* source) { 78 int separators_seen = 0;
39 const char* old_ignition_filter = i::FLAG_ignition_filter; 79 while (std::getline(stream, line)) {
40 i::FLAG_ignition_filter = "*"; 80 if (line == "---") separators_seen += 1;
41 Local<v8::Script> script = v8_compile(source); 81 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 } 82 }
46 83 }
47 Handle<BytecodeArray> MakeBytecode(const char* script, 84
48 const char* function_name) { 85 std::string LoadGolden(const std::string& golden_filename) {
49 CompileRun(script); 86 std::ifstream expected_file((kGoldenFileDirectory + golden_filename).c_str());
50 v8::Local<v8::Context> context = 87 CHECK(expected_file.is_open());
51 v8::Isolate::GetCurrent()->GetCurrentContext(); 88 SkipGoldenFileHeader(expected_file);
52 Local<Function> function = Local<Function>::Cast( 89 std::ostringstream expected_stream;
53 CcTest::global()->Get(context, v8_str(function_name)).ToLocalChecked()); 90 // Restore the first separator, which was consumed by SkipGoldenFileHeader
54 i::Handle<i::JSFunction> js_function = 91 expected_stream << "---\n" << expected_file.rdbuf();
55 i::Handle<i::JSFunction>::cast(v8::Utils::OpenHandle(*function)); 92 return expected_stream.str();
56 return handle(js_function->shared()->bytecode_array(), CcTest::i_isolate()); 93 }
94
95 template <size_t N>
96 std::string BuildActual(const BytecodeExpectationsPrinter& printer,
97 const char* (&snippet_list)[N],
98 const char* prologue = nullptr,
99 const char* epilogue = nullptr) {
100 std::ostringstream actual_stream;
101 for (const char* snippet : snippet_list) {
102 std::string source_code;
103 if (prologue) source_code += prologue;
104 source_code += snippet;
105 if (epilogue) source_code += epilogue;
106 printer.PrintExpectation(actual_stream, source_code);
57 } 107 }
58 108 return actual_stream.str();
59 Handle<BytecodeArray> MakeBytecode(const char* script, const char* filter, 109 }
60 const char* function_name) { 110
61 const char* old_ignition_filter = i::FLAG_ignition_filter; 111 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 112
276 TEST(PrimitiveReturnStatements) { 113 TEST(PrimitiveReturnStatements) {
277 InitializedHandleScope handle_scope; 114 InitializedIgnitionHandleScope scope;
278 BytecodeGeneratorHelper helper; 115 BytecodeExpectationsPrinter printer(CcTest::isolate(),
279 116 ConstantPoolType::kNumber);
280 // clang-format off 117 const char* snippets[] = {
281 ExpectedSnippet<int> snippets[] = { 118 "",
282 {"", 119
283 0, 120 "return;",
284 1, 121
285 3, 122 "return null;",
286 { 123
287 B(StackCheck), // 124 "return true;",
288 B(LdaUndefined), // 125
289 B(Return) // 126 "return false;",
290 }, 127
291 0}, 128 "return 0;",
292 {"return;", 129
293 0, 130 "return +1;",
294 1, 131
295 3, 132 "return -1;",
296 { 133
297 B(StackCheck), // 134 "return +127;",
298 B(LdaUndefined), // 135
299 B(Return) // 136 "return -128;",
300 }, 137 };
301 0}, 138
302 {"return null;", 139 CHECK_EQ(BuildActual(printer, snippets),
303 0, 140 LoadGolden("PrimitiveReturnStatements.golden"));
304 1, 141 }
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 142
393 TEST(PrimitiveExpressions) { 143 TEST(PrimitiveExpressions) {
394 InitializedHandleScope handle_scope; 144 InitializedIgnitionHandleScope scope;
395 BytecodeGeneratorHelper helper; 145 BytecodeExpectationsPrinter printer(CcTest::isolate(),
396 146 ConstantPoolType::kNumber);
397 // clang-format off 147 const char* snippets[] = {
398 ExpectedSnippet<int> snippets[] = { 148 "var x = 0; return x;",
399 {"var x = 0; return x;", 149
400 kPointerSize, 150 "var x = 0; return x + 3;",
401 1, 151
402 5, 152 "var x = 0; return x - 3;",
403 {B(StackCheck), // 153
404 B(LdaZero), // 154 "var x = 4; return x * 3;",
405 B(Star), R(0), // 155
406 B(Return)}, 156 "var x = 4; return x / 3;",
407 0}, 157
408 {"var x = 0; return x + 3;", 158 "var x = 4; return x % 3;",
409 2 * kPointerSize, 159
410 1, 160 "var x = 1; return x | 2;",
411 11, 161
412 {B(StackCheck), // 162 "var x = 1; return x ^ 2;",
413 B(LdaZero), // 163
414 B(Star), R(0), // 164 "var x = 1; return x & 2;",
415 B(Star), R(1), // 165
416 B(LdaSmi8), U8(3), // 166 "var x = 10; return x << 3;",
417 B(Add), R(1), // 167
418 B(Return)}, 168 "var x = 10; return x >> 3;",
419 0}, 169
420 {"var x = 0; return x - 3;", 170 "var x = 10; return x >>> 3;",
421 2 * kPointerSize, 171
422 1, 172 "var x = 0; return (x, 3);",
423 11, 173 };
424 {B(StackCheck), // 174
425 B(LdaZero), // 175 CHECK_EQ(BuildActual(printer, snippets),
426 B(Star), R(0), // 176 LoadGolden("PrimitiveExpressions.golden"));
427 B(Star), R(1), // 177 }
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 178
561 TEST(LogicalExpressions) { 179 TEST(LogicalExpressions) {
562 InitializedHandleScope handle_scope; 180 InitializedIgnitionHandleScope scope;
563 BytecodeGeneratorHelper helper; 181 BytecodeExpectationsPrinter printer(CcTest::isolate(),
564 182 ConstantPoolType::kNumber);
565 // clang-format off 183 const char* snippets[] = {
566 ExpectedSnippet<int> snippets[] = { 184 "var x = 0; return x || 3;",
567 {"var x = 0; return x || 3;", 185
568 1 * kPointerSize, 186 "var x = 0; return (x == 1) || 3;",
569 1, 187
570 9, 188 "var x = 0; return x && 3;",
571 {B(StackCheck), // 189
572 B(LdaZero), // 190 "var x = 0; return (x == 0) && 3;",
573 B(Star), R(0), // 191
574 B(JumpIfToBooleanTrue), U8(4), // 192 "var x = 0; return x || (1, 2, 3);",
575 B(LdaSmi8), U8(3), // 193
576 B(Return)}, 194 "var a = 2, b = 3, c = 4; return a || (a, b, a, b, c = 5, 3);",
577 0}, 195
578 {"var x = 0; return (x == 1) || 3;", 196 "var x = 1; var a = 2, b = 3; return x || (" //
579 2 * kPointerSize, 197 REPEAT_32("\n a = 1, b = 2, ") //
580 1, 198 "3);",
581 15, 199
582 {B(StackCheck), // 200 "var x = 0; var a = 2, b = 3; return x && (" //
583 B(LdaZero), // 201 REPEAT_32("\n a = 1, b = 2, ") //
584 B(Star), R(0), // 202 "3);",
585 B(Star), R(1), // 203
586 B(LdaSmi8), U8(1), // 204 "var x = 1; var a = 2, b = 3; return (x > 3) || (" //
587 B(TestEqual), R(1), // 205 REPEAT_32("\n a = 1, b = 2, ") //
588 B(JumpIfTrue), U8(4), // 206 "3);",
589 B(LdaSmi8), U8(3), // 207
590 B(Return)}, 208 "var x = 0; var a = 2, b = 3; return (x < 5) && (" //
591 0}, 209 REPEAT_32("\n a = 1, b = 2, ") //
592 {"var x = 0; return x && 3;", 210 "3);",
593 1 * kPointerSize, 211
594 1, 212 "return 0 && 3;",
595 9, 213
596 {B(StackCheck), // 214 "return 1 || 3;",
597 B(LdaZero), // 215
598 B(Star), R(0), // 216 "var x = 1; return x && 3 || 0, 1;",
599 B(JumpIfToBooleanFalse), U8(4), // 217 };
600 B(LdaSmi8), U8(3), // 218
601 B(Return)}, 219 CHECK_EQ(BuildActual(printer, snippets),
602 0}, 220 LoadGolden("LogicalExpressions.golden"));
603 {"var x = 0; return (x == 0) && 3;", 221 }
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 222
793 TEST(Parameters) { 223 TEST(Parameters) {
794 InitializedHandleScope handle_scope; 224 InitializedIgnitionHandleScope scope;
795 BytecodeGeneratorHelper helper; 225 BytecodeExpectationsPrinter printer(CcTest::isolate(),
796 226 ConstantPoolType::kNumber);
797 // clang-format off 227 printer.set_wrap(false);
798 ExpectedSnippet<int> snippets[] = { 228 printer.set_test_function_name("f");
799 {"function f() { return this; }", 229
800 0, 230 const char* snippets[] = {
801 1, 231 "function f() { return this; }",
802 4, 232
803 {B(StackCheck), // 233 "function f(arg1) { return arg1; }",
804 B(Ldar), THIS(1), // 234
805 B(Return)}, 235 "function f(arg1) { return this; }",
806 0}, 236
807 {"function f(arg1) { return arg1; }", 237 "function f(arg1, arg2, arg3, arg4, arg5, arg6, arg7) { return arg4; }",
808 0, 238
809 2, 239 "function f(arg1, arg2, arg3, arg4, arg5, arg6, arg7) { return this; }",
810 4, 240
811 {B(StackCheck), // 241 "function f(arg1) { arg1 = 1; }",
812 B(Ldar), A(1, 2), // 242
813 B(Return)}, 243 "function f(arg1, arg2, arg3, arg4) { arg2 = 1; }",
814 0}, 244 };
815 {"function f(arg1) { return this; }", 245
816 0, 246 CHECK_EQ(BuildActual(printer, snippets, "", "\nf();"),
817 2, 247 LoadGolden("Parameters.golden"));
818 4, 248 }
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 249
870 TEST(IntegerConstants) { 250 TEST(IntegerConstants) {
871 InitializedHandleScope handle_scope; 251 InitializedIgnitionHandleScope scope;
872 BytecodeGeneratorHelper helper; 252 BytecodeExpectationsPrinter printer(CcTest::isolate(),
873 253 ConstantPoolType::kNumber);
874 // clang-format off 254 const char* snippets[] = {
875 ExpectedSnippet<int> snippets[] = { 255 "return 12345678;",
876 {"return 12345678;", 256
877 0, 257 "var a = 1234; return 5678;",
878 1, 258
879 4, 259 "var a = 1234; return 1234;",
880 { 260 };
881 B(StackCheck), // 261
882 B(LdaConstant), U8(0), // 262 CHECK_EQ(BuildActual(printer, snippets),
883 B(Return) // 263 LoadGolden("IntegerConstants.golden"));
884 }, 264 }
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 265
924 TEST(HeapNumberConstants) { 266 TEST(HeapNumberConstants) {
925 InitializedHandleScope handle_scope; 267 InitializedIgnitionHandleScope scope;
926 BytecodeGeneratorHelper helper; 268 BytecodeExpectationsPrinter printer(CcTest::isolate(),
927 269 ConstantPoolType::kNumber);
928 int wide_idx = 0; 270 const char* snippets[] = {
929 271 "return 1.2;",
930 // clang-format off 272
931 ExpectedSnippet<double, 257> snippets[] = { 273 "var a = 1.2; return 2.6;",
932 {"return 1.2;", 274
933 0, 275 "var a = 3.14; return 3.14;",
934 1, 276
935 4, 277 "var a;" //
936 { 278 REPEAT_256("\na = 1.414;") //
937 B(StackCheck), // 279 " a = 3.14;",
938 B(LdaConstant), U8(0), // 280 };
939 B(Return) // 281
940 }, 282 CHECK_EQ(BuildActual(printer, snippets),
941 1, 283 LoadGolden("HeapNumberConstants.golden"));
942 {1.2}}, 284 }
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 285
999 TEST(StringConstants) { 286 TEST(StringConstants) {
1000 InitializedHandleScope handle_scope; 287 InitializedIgnitionHandleScope scope;
1001 BytecodeGeneratorHelper helper; 288 BytecodeExpectationsPrinter printer(CcTest::isolate(),
1002 289 ConstantPoolType::kString);
1003 // clang-format off 290 const char* snippets[] = {
1004 ExpectedSnippet<const char*> snippets[] = { 291 "return \"This is a string\";",
1005 {"return \"This is a string\";", 292
1006 0, 293 "var a = \"First string\"; return \"Second string\";",
1007 1, 294
1008 4, 295 "var a = \"Same string\"; return \"Same string\";",
1009 { 296 };
1010 B(StackCheck), // 297
1011 B(LdaConstant), U8(0), // 298 CHECK_EQ(BuildActual(printer, snippets),
1012 B(Return) // 299 LoadGolden("StringConstants.golden"));
1013 }, 300 }
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 301
1053 TEST(PropertyLoads) { 302 TEST(PropertyLoads) {
1054 InitializedHandleScope handle_scope; 303 InitializedIgnitionHandleScope scope;
1055 BytecodeGeneratorHelper helper; 304 BytecodeExpectationsPrinter printer(CcTest::isolate(),
1056 Zone zone; 305 ConstantPoolType::kString);
1057 306 printer.set_wrap(false);
1058 FeedbackVectorSpec feedback_spec(&zone); 307 printer.set_test_function_name("f");
1059 FeedbackVectorSlot slot1 = feedback_spec.AddLoadICSlot(); 308
1060 FeedbackVectorSlot slot2 = feedback_spec.AddLoadICSlot(); 309 const char* snippets[] = {
1061 310 "function f(a) { return a.name; }\n"
1062 Handle<i::TypeFeedbackVector> vector = 311 "f({name : \"test\"});",
1063 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); 312
1064 313 "function f(a) { return a[\"key\"]; }\n"
1065 // These are a hack used by the LoadICXXXWide tests below. 314 "f({key : \"test\"});",
1066 int wide_idx_1 = vector->GetIndex(slot1) - 2; 315
1067 int wide_idx_2 = vector->GetIndex(slot1) - 2; 316 "function f(a) { return a[100]; }\n"
1068 317 "f({100 : \"test\"});",
1069 // clang-format off 318
1070 ExpectedSnippet<const char*> snippets[] = { 319 "function f(a, b) { return a[b]; }\n"
1071 {"function f(a) { return a.name; }\nf({name : \"test\"})", 320 "f({arg : \"test\"}, \"arg\");",
1072 1 * kPointerSize, 321
1073 2, 322 "function f(a) { var b = a.name; return a[-124]; }\n"
1074 10, 323 "f({\"-124\" : \"test\", name : 123 })",
1075 { 324
1076 B(StackCheck), // 325 "function f(a) {\n"
1077 B(Ldar), A(1, 2), // 326 " var b;\n"
1078 B(Star), R(0), // 327 " b = a.name;\n"
1079 B(LoadIC), R(0), U8(0), U8(vector->GetIndex(slot1)), // 328 REPEAT_127(" b = a.name;\n")
1080 B(Return), // 329 " return a.name;\n"
1081 }, 330 "}\n"
1082 1, 331 "f({name : \"test\"})\n",
1083 {"name"}}, 332
1084 {"function f(a) { return a[\"key\"]; }\nf({key : \"test\"})", 333 "function f(a, b) {\n"
1085 1 * kPointerSize, 334 " var c;\n"
1086 2, 335 " c = a[b];\n"
1087 10, 336 REPEAT_127(" c = a[b];\n")
1088 { 337 " return a[b];\n"
1089 B(StackCheck), // 338 "}\n"
1090 B(Ldar), A(1, 2), // 339 "f({name : \"test\"}, \"name\")\n",
1091 B(Star), R(0), // 340 };
1092 B(LoadIC), R(0), U8(0), U8(vector->GetIndex(slot1)), // 341
1093 B(Return) // 342 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("PropertyLoads.golden"));
1094 }, 343 }
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 344
1209 TEST(PropertyStores) { 345 TEST(PropertyStores) {
1210 InitializedHandleScope handle_scope; 346 InitializedIgnitionHandleScope scope;
1211 BytecodeGeneratorHelper helper; 347 BytecodeExpectationsPrinter printer(CcTest::isolate(),
1212 Zone zone; 348 ConstantPoolType::kString);
1213 349 printer.set_wrap(false);
1214 FeedbackVectorSpec feedback_spec(&zone); 350 printer.set_test_function_name("f");
1215 FeedbackVectorSlot slot1 = feedback_spec.AddStoreICSlot(); 351
1216 FeedbackVectorSlot slot2 = feedback_spec.AddStoreICSlot(); 352 const char* snippets[] = {
1217 353 "function f(a) { a.name = \"val\"; }\n"
1218 Handle<i::TypeFeedbackVector> vector = 354 "f({name : \"test\"})",
1219 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); 355
1220 356 "function f(a) { a[\"key\"] = \"val\"; }\n"
1221 // These are a hack used by the StoreICXXXWide tests below. 357 "f({key : \"test\"})",
1222 int wide_idx_1 = vector->GetIndex(slot1) - 2; 358
1223 int wide_idx_2 = vector->GetIndex(slot1) - 2; 359 "function f(a) { a[100] = \"val\"; }\n"
1224 int wide_idx_3 = vector->GetIndex(slot1) - 2; 360 "f({100 : \"test\"})",
1225 int wide_idx_4 = vector->GetIndex(slot1) - 2; 361
1226 362 "function f(a, b) { a[b] = \"val\"; }\n"
1227 // clang-format off 363 "f({arg : \"test\"}, \"arg\")",
1228 ExpectedSnippet<const char*> snippets[] = { 364
1229 {"function f(a) { a.name = \"val\"; }\nf({name : \"test\"})", 365 "function f(a) { a.name = a[-124]; }\n"
1230 kPointerSize, 366 "f({\"-124\" : \"test\", name : 123 })",
1231 2, 367
1232 13, 368 "function f(a) { \"use strict\"; a.name = \"val\"; }\n"
1233 { 369 "f({name : \"test\"})",
1234 B(StackCheck), // 370
1235 B(Ldar), A(1, 2), // 371 "function f(a, b) { \"use strict\"; a[b] = \"val\"; }\n"
1236 B(Star), R(0), // 372 "f({arg : \"test\"}, \"arg\")",
1237 B(LdaConstant), U8(0), // 373
1238 B(StoreICSloppy), R(0), U8(1), U8(vector->GetIndex(slot1)), // 374 "function f(a) {\n"
1239 B(LdaUndefined), // 375 " a.name = 1;\n"
1240 B(Return), // 376 REPEAT_127(" a.name = 1;\n")
1241 }, 377 " a.name = 2;\n"
1242 2, 378 "}\n"
1243 {"val", "name"}}, 379 "f({name : \"test\"})\n",
1244 {"function f(a) { a[\"key\"] = \"val\"; }\nf({key : \"test\"})", 380
1245 kPointerSize, 381 "function f(a) {\n"
1246 2, 382 " 'use strict';\n"
1247 13, 383 " a.name = 1;\n"
1248 { 384 REPEAT_127(" a.name = 1;\n")
1249 B(StackCheck), // 385 " a.name = 2;\n"
1250 B(Ldar), A(1, 2), // 386 "}\n"
1251 B(Star), R(0), // 387 "f({name : \"test\"})\n",
1252 B(LdaConstant), U8(0), // 388
1253 B(StoreICSloppy), R(0), U8(1), U8(vector->GetIndex(slot1)), // 389 "function f(a, b) {\n"
1254 B(LdaUndefined), // 390 " a[b] = 1;\n"
1255 B(Return), // 391 REPEAT_127(" a[b] = 1;\n")
1256 }, 392 " a[b] = 2;\n"
1257 2, 393 "}\n"
1258 {"val", "key"}}, 394 "f({name : \"test\"})\n",
1259 {"function f(a) { a[100] = \"val\"; }\nf({100 : \"test\"})", 395
1260 2 * kPointerSize, 396 "function f(a, b) {\n"
1261 2, 397 " 'use strict';\n"
1262 17, 398 " a[b] = 1;\n"
1263 { 399 REPEAT_127(" a[b] = 1;\n")
1264 B(StackCheck), // 400 " a[b] = 2;\n"
1265 B(Ldar), A(1, 2), // 401 "}\n"
1266 B(Star), R(0), // 402 "f({name : \"test\"})\n",
1267 B(LdaSmi8), U8(100), // 403 };
1268 B(Star), R(1), // 404
1269 B(LdaConstant), U8(0), // 405 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("PropertyStores.golden"));
1270 B(KeyedStoreICSloppy), R(0), R(1), // 406 }
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 407
1485 #define FUNC_ARG "new (function Obj() { this.func = function() { return; }})()" 408 #define FUNC_ARG "new (function Obj() { this.func = function() { return; }})()"
1486 409
1487
1488 TEST(PropertyCall) { 410 TEST(PropertyCall) {
1489 InitializedHandleScope handle_scope; 411 InitializedIgnitionHandleScope scope;
1490 BytecodeGeneratorHelper helper; 412 BytecodeExpectationsPrinter printer(CcTest::isolate(),
1491 Zone zone; 413 ConstantPoolType::kString);
1492 414 printer.set_wrap(false);
1493 FeedbackVectorSpec feedback_spec(&zone); 415 printer.set_test_function_name("f");
1494 FeedbackVectorSlot slot1 = feedback_spec.AddCallICSlot(); 416
1495 FeedbackVectorSlot slot2 = feedback_spec.AddLoadICSlot(); 417 const char* snippets[] = {
1496 418 "function f(a) { return a.func(); }\n"
1497 Handle<i::TypeFeedbackVector> vector = 419 "f(" FUNC_ARG ")",
1498 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); 420
1499 421 "function f(a, b, c) { return a.func(b, c); }\n"
1500 // These are a hack used by the CallWide test below. 422 "f(" FUNC_ARG ", 1, 2)",
1501 int wide_idx = vector->GetIndex(slot1) - 2; 423
1502 424 "function f(a, b) { return a.func(b + b, b); }\n"
1503 // clang-format off 425 "f(" FUNC_ARG ", 1)",
1504 ExpectedSnippet<const char*> snippets[] = { 426
1505 {"function f(a) { return a.func(); }\nf(" FUNC_ARG ")", 427 "function f(a) {\n"
1506 2 * kPointerSize, 428 " a.func;\n" //
1507 2, 429 REPEAT_127(" a.func;\n") //
1508 17, 430 " return a.func(); }\n"
1509 { 431 "f(" FUNC_ARG ")",
1510 B(StackCheck), // 432 };
1511 B(Ldar), A(1, 2), // 433
1512 B(Star), R(1), // 434 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("PropertyCall.golden"));
1513 B(LoadIC), R(1), U8(0), U8(vector->GetIndex(slot2)), // 435 }
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 436
1596 TEST(LoadGlobal) { 437 TEST(LoadGlobal) {
1597 InitializedHandleScope handle_scope; 438 InitializedIgnitionHandleScope scope;
1598 BytecodeGeneratorHelper helper; 439 BytecodeExpectationsPrinter printer(CcTest::isolate(),
1599 Zone zone; 440 ConstantPoolType::kString);
1600 441 printer.set_wrap(false);
1601 FeedbackVectorSpec feedback_spec(&zone); 442 printer.set_test_function_name("f");
1602 FeedbackVectorSlot slot = feedback_spec.AddLoadICSlot(); 443
1603 444 const char* snippets[] = {
1604 Handle<i::TypeFeedbackVector> vector = 445 "var a = 1;\n"
1605 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); 446 "function f() { return a; }\n"
1606 447 "f()",
1607 // These are a hack used by the LdaGlobalXXXWide tests below. 448
1608 int wide_idx_1 = vector->GetIndex(slot) - 2; 449 "function t() { }\n"
1609 450 "function f() { return t; }\n"
1610 // clang-format off 451 "f()",
1611 ExpectedSnippet<const char*> snippets[] = { 452
1612 {"var a = 1;\nfunction f() { return a; }\nf()", 453 "a = 1;\n"
1613 0, 454 "function f() { return a; }\n"
1614 1, 455 "f()",
1615 5, 456
1616 { 457 "a = 1;\n"
1617 B(StackCheck), // 458 "function f(b) {\n"
1618 B(LdaGlobal), U8(0), U8(vector->GetIndex(slot)), // 459 " b.name;\n"
1619 B(Return) // 460 REPEAT_127(" b.name;\n")
1620 }, 461 " return a;\n"
1621 1, 462 "}\n"
1622 {"a"}}, 463 "f({name: 1});",
1623 {"function t() { }\nfunction f() { return t; }\nf()", 464 };
1624 0, 465
1625 1, 466 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("LoadGlobal.golden"));
1626 5, 467 }
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 468
1679 TEST(StoreGlobal) { 469 TEST(StoreGlobal) {
1680 InitializedHandleScope handle_scope; 470 InitializedIgnitionHandleScope scope;
1681 BytecodeGeneratorHelper helper; 471 BytecodeExpectationsPrinter printer(CcTest::isolate(),
1682 Zone zone; 472 ConstantPoolType::kString);
1683 473 printer.set_wrap(false);
1684 FeedbackVectorSpec feedback_spec(&zone); 474 printer.set_test_function_name("f");
1685 FeedbackVectorSlot slot = feedback_spec.AddStoreICSlot(); 475
1686 476 const char* snippets[] = {
1687 Handle<i::TypeFeedbackVector> vector = 477 "var a = 1;\n"
1688 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); 478 "function f() { a = 2; }\n"
1689 479 "f();",
1690 // These are a hack used by the StaGlobalXXXWide tests below. 480
1691 int wide_idx_1 = vector->GetIndex(slot) - 2; 481 "var a = \"test\"; function f(b) { a = b; }\n"
1692 int wide_idx_2 = vector->GetIndex(slot) - 2; 482 "f(\"global\");",
1693 483
1694 // clang-format off 484 "'use strict'; var a = 1;\n"
1695 ExpectedSnippet<const char*> snippets[] = { 485 "function f() { a = 2; }\n"
1696 {"var a = 1;\nfunction f() { a = 2; }\nf()", 486 "f();",
1697 0, 487
1698 1, 488 "a = 1;\n"
1699 8, 489 "function f() { a = 2; }\n"
1700 { 490 "f();",
1701 B(StackCheck), // 491
1702 B(LdaSmi8), U8(2), // 492 "a = 1;\n"
1703 B(StaGlobalSloppy), U8(0), U8(vector->GetIndex(slot)), // 493 "function f(b) {\n"
1704 B(LdaUndefined), // 494 " b.name;\n"
1705 B(Return) // 495 REPEAT_127(" b.name;\n")
1706 }, 496 " a = 2;\n"
1707 1, 497 "}\n"
1708 {"a"}}, 498 "f({name: 1});",
1709 {"var a = \"test\"; function f(b) { a = b; }\nf(\"global\")", 499
1710 0, 500 "a = 1;\n"
1711 2, 501 "function f(b) {\n"
1712 8, 502 " 'use strict';\n"
1713 { 503 " b.name;\n"
1714 B(StackCheck), // 504 REPEAT_127(" b.name;\n")
1715 B(Ldar), R(helper.kLastParamIndex), // 505 " a = 2;\n"
1716 B(StaGlobalSloppy), U8(0), U8(vector->GetIndex(slot)), // 506 "}\n"
1717 B(LdaUndefined), // 507 "f({name: 1});",
1718 B(Return) // 508 };
1719 }, 509
1720 1, 510 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("StoreGlobal.golden"));
1721 {"a"}}, 511 }
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 512
1810 TEST(CallGlobal) { 513 TEST(CallGlobal) {
1811 InitializedHandleScope handle_scope; 514 InitializedIgnitionHandleScope scope;
1812 BytecodeGeneratorHelper helper; 515 BytecodeExpectationsPrinter printer(CcTest::isolate(),
1813 Zone zone; 516 ConstantPoolType::kString);
1814 517 printer.set_wrap(false);
1815 FeedbackVectorSpec feedback_spec(&zone); 518 printer.set_test_function_name("f");
1816 FeedbackVectorSlot slot1 = feedback_spec.AddCallICSlot(); 519
1817 FeedbackVectorSlot slot2 = feedback_spec.AddLoadICSlot(); 520 const char* snippets[] = {
1818 521 "function t() { }\n"
1819 Handle<i::TypeFeedbackVector> vector = 522 "function f() { return t(); }\n"
1820 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); 523 "f();",
1821 524
1822 // clang-format off 525 "function t(a, b, c) { }\n"
1823 ExpectedSnippet<const char*> snippets[] = { 526 "function f() { return t(1, 2, 3); }\n"
1824 {"function t() { }\nfunction f() { return t(); }\nf()", 527 "f();",
1825 2 * kPointerSize, 528 };
1826 1, 529
1827 15, 530 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("CallGlobal.golden"));
1828 { 531 }
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 532
1872 TEST(CallRuntime) { 533 TEST(CallRuntime) {
1873 InitializedHandleScope handle_scope; 534 InitializedIgnitionHandleScope scope;
1874 BytecodeGeneratorHelper helper; 535 BytecodeExpectationsPrinter printer(CcTest::isolate(),
1875 536 ConstantPoolType::kMixed);
1876 // clang-format off 537 printer.set_wrap(false);
1877 ExpectedSnippet<InstanceType> snippets[] = { 538 printer.set_test_function_name("f");
1878 { 539
1879 "function f() { %TheHole() }\nf()", 540 const char* snippets[] = {
1880 0, 541 "function f() { %TheHole() }\n"
1881 1, 542 "f();",
1882 8, 543
1883 { 544 "function f(a) { return %IsArray(a) }\n"
1884 B(StackCheck), // 545 "f(undefined);",
1885 B(CallRuntime), U16(Runtime::kTheHole), R(0), U8(0), // 546
1886 B(LdaUndefined), // 547 "function f() { return %Add(1, 2) }\n"
1887 B(Return) // 548 "f();",
1888 }, 549
1889 }, 550 "function f() { return %spread_iterable([1]) }\n"
1890 { 551 "f();",
1891 "function f(a) { return %IsArray(a) }\nf(undefined)", 552 };
1892 1 * kPointerSize, 553
1893 2, 554 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("CallRuntime.golden"));
1894 11, 555 }
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 556
1947 TEST(IfConditions) { 557 TEST(IfConditions) {
1948 InitializedHandleScope handle_scope; 558 InitializedIgnitionHandleScope scope;
1949 BytecodeGeneratorHelper helper; 559 BytecodeExpectationsPrinter printer(CcTest::isolate(),
1950 560 ConstantPoolType::kNumber);
1951 Handle<Object> unused = helper.factory()->undefined_value(); 561 printer.set_wrap(false);
1952 562 printer.set_test_function_name("f");
1953 // clang-format off 563
1954 ExpectedSnippet<Handle<Object>> snippets[] = { 564 const char* snippets[] = {
1955 {"function f() { if (0) { return 1; } else { return -1; } } f()", 565 "function f() {\n"
1956 0, 566 " if (0) {\n"
1957 1, 567 " return 1;\n"
1958 4, 568 " } else {\n"
1959 { 569 " return -1;\n"
1960 B(StackCheck), // 570 " }\n"
1961 B(LdaSmi8), U8(-1), // 571 "};\n"
1962 B(Return), // 572 "f();",
1963 }, 573
1964 0, 574 "function f() {\n"
1965 {unused, unused, unused, unused, unused, unused}}, 575 " if ('lucky') {\n"
1966 {"function f() { if ('lucky') { return 1; } else { return -1; } } f();", 576 " return 1;\n"
1967 0, 577 " } else {\n"
1968 1, 578 " return -1;\n"
1969 4, 579 " }\n"
1970 { 580 "};\n"
1971 B(StackCheck), // 581 "f();",
1972 B(LdaSmi8), U8(1), // 582
1973 B(Return), // 583 "function f() {\n"
1974 }, 584 " if (false) {\n"
1975 0, 585 " return 1;\n"
1976 {unused, unused, unused, unused, unused, unused}}, 586 " } else {\n"
1977 {"function f() { if (false) { return 1; } else { return -1; } } f();", 587 " return -1;\n"
1978 0, 588 " }\n"
1979 1, 589 "};\n"
1980 4, 590 "f();",
1981 { 591
1982 B(StackCheck), // 592 "function f() {\n"
1983 B(LdaSmi8), U8(-1), // 593 " if (false) {\n"
1984 B(Return), // 594 " return 1;\n"
1985 }, 595 " }\n"
1986 0, 596 "};\n"
1987 {unused, unused, unused, unused, unused, unused}}, 597 "f();",
1988 {"function f() { if (false) { return 1; } } f();", 598
1989 0, 599 "function f() {\n"
1990 1, 600 " var a = 1;\n"
1991 3, 601 " if (a) {\n"
1992 { 602 " a += 1;\n"
1993 B(StackCheck), // 603 " } else {\n"
1994 B(LdaUndefined), // 604 " return 2;\n"
1995 B(Return), // 605 " }\n"
1996 }, 606 "};\n"
1997 0, 607 "f();",
1998 {unused, unused, unused, unused, unused, unused}}, 608
1999 {"function f() { var a = 1; if (a) { a += 1; } else { return 2; } } f();", 609 "function f(a) {\n"
2000 2 * kPointerSize, 610 " if (a <= 0) {\n"
2001 1, 611 " return 200;\n"
2002 24, 612 " } else {\n"
2003 { 613 " return -200;\n"
2004 B(StackCheck), // 614 " }\n"
2005 B(LdaSmi8), U8(1), // 615 "};\n"
2006 B(Star), R(0), // 616 "f(99);",
2007 B(JumpIfToBooleanFalse), U8(14), // 617
2008 B(Ldar), R(0), // 618 "function f(a, b) { if (a in b) { return 200; } }"
2009 B(Star), R(1), // 619 "f('prop', { prop: 'yes'});",
2010 B(LdaSmi8), U8(1), // 620
2011 B(Add), R(1), // 621 "function f(z) { var a = 0; var b = 0; if (a === 0.01) {\n"
2012 B(Star), R(0), // 622 REPEAT_64(" b = a; a = b;\n")
2013 B(Jump), U8(5), // 623 " return 200; } else { return -200; } } f(0.001);",
2014 B(LdaSmi8), U8(2), // 624
2015 B(Return), // 625 "function f() {\n"
2016 B(LdaUndefined), // 626 " var a = 0; var b = 0;\n"
2017 B(Return), // 627 " if (a) {\n"
2018 }, 628 REPEAT_64(" b = a; a = b;\n")
2019 0, 629 " return 200; } else { return -200; }\n"
2020 {unused, unused, unused, unused, unused, unused}}, 630 "};\n"
2021 {"function f(a) { if (a <= 0) { return 200; } else { return -200; } }" 631 "f();",
2022 "f(99);", 632
2023 kPointerSize, 633 "function f(a, b) {\n"
2024 2, 634 " if (a == b) { return 1; }\n"
2025 18, 635 " if (a === b) { return 1; }\n"
2026 { 636 " if (a < b) { return 1; }\n"
2027 B(StackCheck), // 637 " if (a > b) { return 1; }\n"
2028 B(Ldar), A(1, 2), // 638 " if (a <= b) { return 1; }\n"
2029 B(Star), R(0), // 639 " if (a >= b) { return 1; }\n"
2030 B(LdaZero), // 640 " if (a in b) { return 1; }\n"
2031 B(TestLessThanOrEqual), R(0), // 641 " if (a instanceof b) { return 1; }\n"
2032 B(JumpIfFalse), U8(5), // 642 " return 0;\n"
2033 B(LdaConstant), U8(0), // 643 "}\n"
2034 B(Return), // 644 "f(1, 1);",
2035 B(LdaConstant), U8(1), // 645
2036 B(Return), // 646 "function f() {\n"
2037 B(LdaUndefined), // 647 " var a = 0;\n"
2038 B(Return), // 648 " if (a) {\n"
2039 }, 649 " return 20;\n"
2040 2, 650 " } else {\n"
2041 {helper.factory()->NewNumberFromInt(200), 651 " return -20;\n"
2042 helper.factory()->NewNumberFromInt(-200), unused, unused, unused, 652 " }\n"
2043 unused}}, 653 "};\n"
2044 {"function f(a, b) { if (a in b) { return 200; } }" 654 "f();",
2045 "f('prop', { prop: 'yes'});", 655 };
2046 kPointerSize, 656
2047 3, 657 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("IfConditions.golden"));
2048 16, 658 }
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 659
2198 TEST(DeclareGlobals) { 660 TEST(DeclareGlobals) {
2199 InitializedHandleScope handle_scope; 661 InitializedIgnitionHandleScope scope;
2200 BytecodeGeneratorHelper helper; 662 BytecodeExpectationsPrinter printer(CcTest::isolate(),
2201 Zone zone; 663 ConstantPoolType::kMixed);
2202 664 printer.set_wrap(false);
2203 // Create different feedback vector specs to be precise on slot numbering. 665 printer.set_test_function_name("f");
2204 FeedbackVectorSpec feedback_spec_stores(&zone); 666 printer.set_execute(false);
2205 FeedbackVectorSlot store_slot_1 = feedback_spec_stores.AddStoreICSlot(); 667 printer.set_top_level(true);
2206 FeedbackVectorSlot store_slot_2 = feedback_spec_stores.AddStoreICSlot(); 668
2207 USE(store_slot_1); 669 const char* snippets[] = {
2208 670 "var a = 1;",
2209 Handle<i::TypeFeedbackVector> store_vector = 671
2210 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec_stores); 672 "function f() {}",
2211 673
2212 FeedbackVectorSpec feedback_spec_loads(&zone); 674 "var a = 1;\n"
2213 FeedbackVectorSlot load_slot_1 = feedback_spec_loads.AddLoadICSlot(); 675 "a=2;",
2214 FeedbackVectorSlot call_slot_1 = feedback_spec_loads.AddCallICSlot(); 676
2215 677 "function f() {}\n"
2216 Handle<i::TypeFeedbackVector> load_vector = 678 "f();",
2217 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec_loads); 679 };
2218 680
2219 // clang-format off 681 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("DeclareGlobals.golden"));
2220 ExpectedSnippet<InstanceType> snippets[] = { 682 }
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 683
2322 TEST(BreakableBlocks) { 684 TEST(BreakableBlocks) {
2323 InitializedHandleScope handle_scope; 685 InitializedIgnitionHandleScope scope;
2324 BytecodeGeneratorHelper helper; 686 BytecodeExpectationsPrinter printer(CcTest::isolate(),
2325 687 ConstantPoolType::kMixed);
2326 int closure = Register::function_closure().index(); 688
2327 int context = Register::current_context().index(); 689 const char* snippets[] = {
2328 690 "var x = 0;\n"
2329 // clang-format off 691 "label: {\n"
2330 ExpectedSnippet<InstanceType> snippets[] = { 692 " x = x + 1;\n"
2331 {"var x = 0;\n" 693 " break label;\n"
2332 "label: {\n" 694 " x = x + 1;\n"
2333 " x = x + 1;\n" 695 "}\n"
2334 " break label;\n" 696 "return x;",
2335 " x = x + 1;\n" 697
2336 "}\n" 698 "var sum = 0;\n"
2337 "return x;", 699 "outer: {\n"
2338 2 * kPointerSize, 700 " for (var x = 0; x < 10; ++x) {\n"
2339 1, 701 " for (var y = 0; y < 3; ++y) {\n"
2340 17, 702 " ++sum;\n"
2341 { 703 " if (x + y == 12) { break outer; }\n"
2342 B(StackCheck), // 704 " }\n"
2343 B(LdaZero), // 705 " }\n"
2344 B(Star), R(0), // 706 "}\n"
2345 B(Star), R(1), // 707 "return sum;",
2346 B(LdaSmi8), U8(1), // 708
2347 B(Add), R(1), // 709 "outer: {\n"
2348 B(Star), R(0), // 710 " let y = 10;\n"
2349 B(Jump), U8(2), // 711 " function f() { return y; }\n"
2350 B(Ldar), R(0), // 712 " break outer;\n"
2351 B(Return) // 713 "}\n",
2352 }}, 714
2353 {"var sum = 0;\n" 715 "let x = 1;\n"
2354 "outer: {\n" 716 "outer: {\n"
2355 " for (var x = 0; x < 10; ++x) {\n" 717 " inner: {\n"
2356 " for (var y = 0; y < 3; ++y) {\n" 718 " let y = 2;\n"
2357 " ++sum;\n" 719 " function f() { return x + y; }\n"
2358 " if (x + y == 12) { break outer; }\n" 720 " if (y) break outer;\n"
2359 " }\n" 721 " y = 3;\n"
2360 " }\n" 722 " }\n"
2361 "}\n" 723 "}\n"
2362 "return sum;", 724 "x = 4;",
2363 5 * kPointerSize, 725 };
2364 1, 726
2365 75, 727 CHECK_EQ(BuildActual(printer, snippets),
2366 { 728 LoadGolden("BreakableBlocks.golden"));
2367 B(StackCheck), // 729 }
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 730
2534 TEST(BasicLoops) { 731 TEST(BasicLoops) {
2535 InitializedHandleScope handle_scope; 732 InitializedIgnitionHandleScope scope;
2536 BytecodeGeneratorHelper helper; 733 BytecodeExpectationsPrinter printer(CcTest::isolate(),
2537 734 ConstantPoolType::kMixed);
2538 int closure = Register::function_closure().index(); 735 const char* snippets[] = {
2539 int context = Register::current_context().index(); 736 "var x = 0;\n"
2540 737 "while (false) { x = 99; break; continue; }\n"
2541 // clang-format off 738 "return x;",
2542 ExpectedSnippet<InstanceType> snippets[] = { 739
2543 {"var x = 0;\n" 740 "var x = 0;\n"
2544 "while (false) { x = 99; break; continue; }\n" 741 "while (false) {\n"
2545 "return x;", 742 " x = x + 1;\n"
2546 1 * kPointerSize, 743 "};\n"
2547 1, 744 "return x;",
2548 5, 745
2549 { 746 "var x = 0;\n"
2550 B(StackCheck), // 747 "var y = 1;\n"
2551 B(LdaZero), // 748 "while (x < 10) {\n"
2552 B(Star), R(0), // 749 " y = y * 12;\n"
2553 B(Return) // 750 " x = x + 1;\n"
2554 }}, 751 " if (x == 3) continue;\n"
2555 {"var x = 0;" 752 " if (x == 4) break;\n"
2556 "while (false) {" 753 "}\n"
2557 " x = x + 1;" 754 "return y;",
2558 "};" 755
2559 "return x;", 756 "var i = 0;\n"
2560 1 * kPointerSize, 757 "while (true) {\n"
2561 1, 758 " if (i < 0) continue;\n"
2562 5, 759 " if (i == 3) break;\n"
2563 { 760 " if (i == 4) break;\n"
2564 B(StackCheck), // 761 " if (i == 10) continue;\n"
2565 B(LdaZero), // 762 " if (i == 5) break;\n"
2566 B(Star), R(0), // 763 " i = i + 1;\n"
2567 B(Return), // 764 "}\n"
2568 }, 765 "return i;",
2569 0}, 766
2570 {"var x = 0;" 767 "var i = 0;\n"
2571 "var y = 1;" 768 "while (true) {\n"
2572 "while (x < 10) {" 769 " while (i < 3) {\n"
2573 " y = y * 12;" 770 " if (i == 2) break;\n"
2574 " x = x + 1;" 771 " i = i + 1;\n"
2575 " if (x == 3) continue;" 772 " }\n"
2576 " if (x == 4) break;" 773 " i = i + 1;\n"
2577 "}" 774 " break;\n"
2578 "return y;", 775 "}\n"
2579 3 * kPointerSize, 776 "return i;",
2580 1, 777
2581 66, 778 "var x = 10;\n"
2582 { 779 "var y = 1;\n"
2583 B(StackCheck), // 780 "while (x) {\n"
2584 B(LdaZero), // 781 " y = y * 12;\n"
2585 B(Star), R(0), // 782 " x = x - 1;\n"
2586 B(LdaSmi8), U8(1), // 783 "}\n"
2587 B(Star), R(1), // 784 "return y;",
2588 B(Ldar), R(0), // 785
2589 B(Star), R(2), // 786 "var x = 0; var y = 1;\n"
2590 B(LdaSmi8), U8(10), // 787 "do {\n"
2591 B(TestLessThan), R(2), // 788 " y = y * 10;\n"
2592 B(JumpIfFalse), U8(47), // 789 " if (x == 5) break;\n"
2593 B(StackCheck), // 790 " if (x == 6) continue;\n"
2594 B(Ldar), R(1), // 791 " x = x + 1;\n"
2595 B(Star), R(2), // 792 "} while (x < 10);\n"
2596 B(LdaSmi8), U8(12), // 793 "return y;",
2597 B(Mul), R(2), // 794
2598 B(Star), R(1), // 795 "var x = 10;\n"
2599 B(Ldar), R(0), // 796 "var y = 1;\n"
2600 B(Star), R(2), // 797 "do {\n"
2601 B(LdaSmi8), U8(1), // 798 " y = y * 12;\n"
2602 B(Add), R(2), // 799 " x = x - 1;\n"
2603 B(Star), R(0), // 800 "} while (x);\n"
2604 B(Star), R(2), // 801 "return y;",
2605 B(LdaSmi8), U8(3), // 802
2606 B(TestEqual), R(2), // 803 "var x = 0; var y = 1;\n"
2607 B(JumpIfFalse), U8(4), // 804 "do {\n"
2608 B(Jump), U8(-39), // 805 " y = y * 10;\n"
2609 B(Ldar), R(0), // 806 " if (x == 5) break;\n"
2610 B(Star), R(2), // 807 " x = x + 1;\n"
2611 B(LdaSmi8), U8(4), // 808 " if (x == 6) continue;\n"
2612 B(TestEqual), R(2), // 809 "} while (false);\n"
2613 B(JumpIfFalse), U8(4), // 810 "return y;",
2614 B(Jump), U8(4), // 811
2615 B(Jump), U8(-53), // 812 "var x = 0; var y = 1;\n"
2616 B(Ldar), R(1), // 813 "do {\n"
2617 B(Return), // 814 " y = y * 10;\n"
2618 }, 815 " if (x == 5) break;\n"
2619 0}, 816 " x = x + 1;\n"
2620 {"var i = 0;" 817 " if (x == 6) continue;\n"
2621 "while (true) {" 818 "} while (true);\n"
2622 " if (i < 0) continue;" 819 "return y;",
2623 " if (i == 3) break;" 820
2624 " if (i == 4) break;" 821 "var x = 0;\n"
2625 " if (i == 10) continue;" 822 "for (;;) {\n"
2626 " if (i == 5) break;" 823 " if (x == 1) break;\n"
2627 " i = i + 1;" 824 " if (x == 2) continue;\n"
2628 "}" 825 " x = x + 1;\n"
2629 "return i;", 826 "}",
2630 2 * kPointerSize, 827
2631 1, 828 "for (var x = 0;;) {\n"
2632 79, 829 " if (x == 1) break;\n"
2633 { 830 " if (x == 2) continue;\n"
2634 B(StackCheck), // 831 " x = x + 1;\n"
2635 B(LdaZero), // 832 "}",
2636 B(Star), R(0), // 833
2637 B(StackCheck), // 834 "var x = 0;\n"
2638 B(Ldar), R(0), // 835 "for (;; x = x + 1) {\n"
2639 B(Star), R(1), // 836 " if (x == 1) break;\n"
2640 B(LdaZero), // 837 " if (x == 2) continue;\n"
2641 B(TestLessThan), R(1), // 838 "}",
2642 B(JumpIfFalse), U8(4), // 839
2643 B(Jump), U8(-10), // 840 "for (var x = 0;; x = x + 1) {\n"
2644 B(Ldar), R(0), // 841 " if (x == 1) break;\n"
2645 B(Star), R(1), // 842 " if (x == 2) continue;\n"
2646 B(LdaSmi8), U8(3), // 843 "}",
2647 B(TestEqual), R(1), // 844
2648 B(JumpIfFalse), U8(4), // 845 "var u = 0;\n"
2649 B(Jump), U8(50), // 846 "for (var i = 0; i < 100; i = i + 1) {\n"
2650 B(Ldar), R(0), // 847 " u = u + 1;\n"
2651 B(Star), R(1), // 848 " continue;\n"
2652 B(LdaSmi8), U8(4), // 849 "}",
2653 B(TestEqual), R(1), // 850
2654 B(JumpIfFalse), U8(4), // 851 "var y = 1;\n"
2655 B(Jump), U8(38), // 852 "for (var x = 10; x; --x) {\n"
2656 B(Ldar), R(0), // 853 " y = y * 12;\n"
2657 B(Star), R(1), // 854 "}\n"
2658 B(LdaSmi8), U8(10), // 855 "return y;",
2659 B(TestEqual), R(1), // 856
2660 B(JumpIfFalse), U8(4), // 857 "var x = 0;\n"
2661 B(Jump), U8(-46), // 858 "for (var i = 0; false; i++) {\n"
2662 B(Ldar), R(0), // 859 " x = x + 1;\n"
2663 B(Star), R(1), // 860 "};\n"
2664 B(LdaSmi8), U8(5), // 861 "return x;",
2665 B(TestEqual), R(1), // 862
2666 B(JumpIfFalse), U8(4), // 863 "var x = 0;\n"
2667 B(Jump), U8(14), // 864 "for (var i = 0; true; ++i) {\n"
2668 B(Ldar), R(0), // 865 " x = x + 1;\n"
2669 B(Star), R(1), // 866 " if (x == 20) break;\n"
2670 B(LdaSmi8), U8(1), // 867 "};\n"
2671 B(Add), R(1), // 868 "return x;",
2672 B(Star), R(0), // 869
2673 B(Jump), U8(-70), // 870 "var a = 0;\n"
2674 B(Ldar), R(0), // 871 "while (a) {\n"
2675 B(Return), // 872 " { \n"
2676 }, 873 " let z = 1;\n"
2677 0}, 874 " function f() { z = 2; }\n"
2678 {"var i = 0;" 875 " if (z) continue;\n"
2679 "while (true) {" 876 " z++;\n"
2680 " while (i < 3) {" 877 " }\n"
2681 " if (i == 2) break;" 878 "}",
2682 " i = i + 1;" 879 };
2683 " }" 880
2684 " i = i + 1;" 881 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("BasicLoops.golden"));
2685 " break;" 882 }
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 883
3269 TEST(JumpsRequiringConstantWideOperands) { 884 TEST(JumpsRequiringConstantWideOperands) {
3270 InitializedHandleScope handle_scope; 885 InitializedIgnitionHandleScope scope;
3271 BytecodeGeneratorHelper helper; 886 BytecodeExpectationsPrinter printer(CcTest::isolate(),
3272 887 ConstantPoolType::kNumber);
3273 int constant_count = 0; 888 const char* snippets[] = {
3274 // clang-format off 889 REPEAT_256("var x = 0.1;\n")
3275 ExpectedSnippet<Handle<Object>, 316> snippets[] = { 890 REPEAT_32("var x = 0.2;\n")
3276 { 891 REPEAT_16("var x = 0.3;\n")
3277 REPEAT_256(SPACE, "var x = 0.1;") 892 REPEAT_8("var x = 0.4;\n")
3278 REPEAT_32(SPACE, "var x = 0.2;") 893 "for (var i = 0; i < 3; i++) {\n"
3279 REPEAT_16(SPACE, "var x = 0.3;") 894 " if (i == 1) continue;\n"
3280 REPEAT_8(SPACE, "var x = 0.4;") 895 " if (i == 2) break;\n"
3281 "for (var i = 0; i < 3; i++) {\n" 896 "}\n"
3282 " if (i == 1) continue;\n" 897 "return 3;",
3283 " if (i == 2) break;\n" 898 };
3284 "}\n" 899
3285 "return 3;", 900 CHECK_EQ(BuildActual(printer, snippets),
3286 kPointerSize * 3, 901 LoadGolden("JumpsRequiringConstantWideOperands.golden"));
3287 1, 902 }
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 903
3351 TEST(UnaryOperators) { 904 TEST(UnaryOperators) {
3352 InitializedHandleScope handle_scope; 905 InitializedIgnitionHandleScope scope;
3353 BytecodeGeneratorHelper helper; 906 BytecodeExpectationsPrinter printer(CcTest::isolate(),
3354 907 ConstantPoolType::kNumber);
3355 // clang-format off 908 const char* snippets[] = {
3356 ExpectedSnippet<int> snippets[] = { 909 "var x = 0;\n"
3357 {"var x = 0;" 910 "while (x != 10) {\n"
3358 "while (x != 10) {" 911 " x = x + 10;\n"
3359 " x = x + 10;" 912 "}\n"
3360 "}" 913 "return x;",
3361 "return x;", 914
3362 2 * kPointerSize, 915 "var x = false;\n"
3363 1, 916 "do {\n"
3364 31, 917 " x = !x;\n"
3365 { 918 "} while(x == false);\n"
3366 B(StackCheck), // 919 "return x;",
3367 B(LdaZero), // 920
3368 B(Star), R(0), // 921 "var x = 101;\n"
3369 B(Ldar), R(0), // 922 "return void(x * 3);",
3370 B(Star), R(1), // 923
3371 B(LdaSmi8), U8(10), // 924 "var x = 1234;\n"
3372 B(TestEqual), R(1), // 925 "var y = void (x * x - 1);\n"
3373 B(LogicalNot), // 926 "return y;",
3374 B(JumpIfFalse), U8(15), // 927
3375 B(StackCheck), // 928 "var x = 13;\n"
3376 B(Ldar), R(0), // 929 "return ~x;",
3377 B(Star), R(1), // 930
3378 B(LdaSmi8), U8(10), // 931 "var x = 13;\n"
3379 B(Add), R(1), // 932 "return +x;",
3380 B(Star), R(0), // 933
3381 B(Jump), U8(-22), // 934 "var x = 13;\n"
3382 B(Ldar), R(0), // 935 "return -x;",
3383 B(Return), // 936 };
3384 }, 937
3385 0}, 938 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("UnaryOperators.golden"));
3386 {"var x = false;" 939 }
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 940
3505 TEST(Typeof) { 941 TEST(Typeof) {
3506 InitializedHandleScope handle_scope; 942 InitializedIgnitionHandleScope scope;
3507 BytecodeGeneratorHelper helper; 943 BytecodeExpectationsPrinter printer(CcTest::isolate(),
3508 Zone zone; 944 ConstantPoolType::kString);
3509 945 printer.set_wrap(false);
3510 FeedbackVectorSpec feedback_spec(&zone); 946 printer.set_test_function_name("f");
3511 FeedbackVectorSlot slot = feedback_spec.AddLoadICSlot(); 947
3512 948 const char* snippets[] = {
3513 Handle<i::TypeFeedbackVector> vector = 949 "function f() {\n"
3514 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); 950 " var x = 13;\n"
3515 951 " return typeof(x);\n"
3516 // clang-format off 952 "};",
3517 ExpectedSnippet<const char*> snippets[] = { 953
3518 {"function f() {\n" 954 "var x = 13;\n"
3519 " var x = 13;\n" 955 "function f() {\n"
3520 " return typeof(x);\n" 956 " return typeof(x);\n"
3521 "}; f();", 957 "};",
3522 kPointerSize, 958 };
3523 1, 959
3524 7, 960 CHECK_EQ(BuildActual(printer, snippets, "", "\nf();"),
3525 { 961 LoadGolden("Typeof.golden"));
3526 B(StackCheck), // 962 }
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 963
3558 TEST(Delete) { 964 TEST(Delete) {
3559 InitializedHandleScope handle_scope; 965 InitializedIgnitionHandleScope scope;
3560 BytecodeGeneratorHelper helper; 966 BytecodeExpectationsPrinter printer(CcTest::isolate(),
3561 967 ConstantPoolType::kMixed);
3562 int deep_elements_flags = 968
3563 ObjectLiteral::kFastElements | ObjectLiteral::kDisableMementos; 969 const char* snippets[] = {
3564 int closure = Register::function_closure().index(); 970 "var a = {x:13, y:14}; return delete a.x;",
3565 int context = Register::current_context().index(); 971
3566 int first_context_slot = Context::MIN_CONTEXT_SLOTS; 972 "'use strict'; var a = {x:13, y:14}; return delete a.x;",
3567 973
3568 // clang-format off 974 "var a = {1:13, 2:14}; return delete a[2];",
3569 ExpectedSnippet<InstanceType> snippets[] = { 975
3570 {"var a = {x:13, y:14}; return delete a.x;", 976 "var a = 10; return delete a;",
3571 2 * kPointerSize, 977
3572 1, 978 "'use strict';\n"
3573 16, 979 "var a = {1:10};\n"
3574 { 980 "(function f1() {return a;});\n"
3575 B(StackCheck), // 981 "return delete a[1];",
3576 B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags), // 982
3577 B(Star), R(1), // 983 "return delete 'test';",
3578 B(Star), R(0), // 984 };
3579 B(Star), R(1), // 985
3580 B(LdaConstant), U8(1), // 986 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("Delete.golden"));
3581 B(DeletePropertySloppy), R(1), // 987 }
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 988
3667 TEST(GlobalDelete) { 989 TEST(GlobalDelete) {
3668 InitializedHandleScope handle_scope; 990 InitializedIgnitionHandleScope scope;
3669 BytecodeGeneratorHelper helper; 991 BytecodeExpectationsPrinter printer(CcTest::isolate(),
3670 Zone zone; 992 ConstantPoolType::kMixed);
3671 993 printer.set_wrap(false);
3672 int context = Register::current_context().index(); 994 printer.set_test_function_name("f");
3673 int native_context_index = Context::NATIVE_CONTEXT_INDEX; 995
3674 int global_context_index = Context::EXTENSION_INDEX; 996 const char* snippets[] = {
3675 FeedbackVectorSpec feedback_spec(&zone); 997 "var a = {x:13, y:14};\n"
3676 FeedbackVectorSlot slot = feedback_spec.AddLoadICSlot(); 998 "function f() {\n"
3677 999 " return delete a.x;\n"
3678 Handle<i::TypeFeedbackVector> vector = 1000 "};\n"
3679 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); 1001 "f();",
3680 1002
3681 // clang-format off 1003 "a = {1:13, 2:14};\n"
3682 ExpectedSnippet<InstanceType> snippets[] = { 1004 "function f() {\n"
3683 {"var a = {x:13, y:14};\n function f() { return delete a.x; };\n f();", 1005 " 'use strict';\n"
3684 1 * kPointerSize, 1006 " return delete a[1];\n"
3685 1, 1007 "};\n"
3686 11, 1008 "f();",
3687 {B(StackCheck), // 1009
3688 B(LdaGlobal), U8(0), U8(vector->GetIndex(slot)), // 1010 "var a = {x:13, y:14};\n"
3689 B(Star), R(0), // 1011 "function f() {\n"
3690 B(LdaConstant), U8(1), // 1012 " return delete a;\n"
3691 B(DeletePropertySloppy), R(0), // 1013 "};\n"
3692 B(Return)}, 1014 "f();",
3693 2, 1015
3694 {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, 1016 "b = 30;\n"
3695 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, 1017 "function f() {\n"
3696 {"a = {1:13, 2:14};\n" 1018 " return delete b;\n"
3697 "function f() {'use strict'; return delete a[1];};\n f();", 1019 "};\n"
3698 1 * kPointerSize, 1020 "f();",
3699 1, 1021 };
3700 11, 1022
3701 {B(StackCheck), // 1023 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("GlobalDelete.golden"));
3702 B(LdaGlobal), U8(0), U8(vector->GetIndex(slot)), // 1024 }
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 1025
3748 TEST(FunctionLiterals) { 1026 TEST(FunctionLiterals) {
3749 InitializedHandleScope handle_scope; 1027 InitializedIgnitionHandleScope scope;
3750 BytecodeGeneratorHelper helper; 1028 BytecodeExpectationsPrinter printer(CcTest::isolate(),
3751 Zone zone; 1029 ConstantPoolType::kMixed);
3752 1030
3753 FeedbackVectorSpec feedback_spec(&zone); 1031 const char* snippets[] = {
3754 FeedbackVectorSlot slot = feedback_spec.AddCallICSlot(); 1032 "return function(){ }",
3755 1033
3756 Handle<i::TypeFeedbackVector> vector = 1034 "return (function(){ })()",
3757 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); 1035
3758 1036 "return (function(x){ return x; })(1)",
3759 // clang-format off 1037 };
3760 ExpectedSnippet<InstanceType> snippets[] = { 1038
3761 {"return function(){ }", 1039 CHECK_EQ(BuildActual(printer, snippets),
3762 0, 1040 LoadGolden("FunctionLiterals.golden"));
3763 1, 1041 }
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 1042
3815 TEST(RegExpLiterals) { 1043 TEST(RegExpLiterals) {
3816 InitializedHandleScope handle_scope; 1044 InitializedIgnitionHandleScope scope;
3817 BytecodeGeneratorHelper helper; 1045 BytecodeExpectationsPrinter printer(CcTest::isolate(),
3818 Zone zone; 1046 ConstantPoolType::kString);
3819 1047
3820 FeedbackVectorSpec feedback_spec(&zone); 1048 const char* snippets[] = {
3821 FeedbackVectorSlot slot1 = feedback_spec.AddCallICSlot(); 1049 "return /ab+d/;",
3822 FeedbackVectorSlot slot2 = feedback_spec.AddLoadICSlot(); 1050
3823 uint8_t i_flags = JSRegExp::kIgnoreCase; 1051 "return /(\\w+)\\s(\\w+)/i;",
3824 1052
3825 Handle<i::TypeFeedbackVector> vector = 1053 "return /ab+d/.exec('abdd');",
3826 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); 1054 };
3827 1055
3828 // clang-format off 1056 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("RegExpLiterals.golden"));
3829 ExpectedSnippet<const char*> snippets[] = { 1057 }
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 1058
3880 TEST(RegExpLiteralsWide) { 1059 TEST(RegExpLiteralsWide) {
3881 InitializedHandleScope handle_scope; 1060 InitializedIgnitionHandleScope scope;
3882 BytecodeGeneratorHelper helper; 1061 BytecodeExpectationsPrinter printer(CcTest::isolate(),
3883 Zone zone; 1062 ConstantPoolType::kMixed);
3884 1063
3885 int wide_idx = 0; 1064 const char* snippets[] = {
3886 1065 "var a;" //
3887 // clang-format off 1066 REPEAT_256("\na = 1.23;") //
3888 ExpectedSnippet<InstanceType, 257> snippets[] = { 1067 "\nreturn /ab+d/;",
3889 {"var a;" REPEAT_256(SPACE, "a = 1.23;") "return /ab+d/;", 1068 };
3890 1 * kPointerSize, 1069
3891 1, 1070 CHECK_EQ(BuildActual(printer, snippets),
3892 1032, 1071 LoadGolden("RegExpLiteralsWide.golden"));
3893 { 1072 }
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 1073
3915 TEST(ArrayLiterals) { 1074 TEST(ArrayLiterals) {
3916 InitializedHandleScope handle_scope; 1075 InitializedIgnitionHandleScope scope;
3917 BytecodeGeneratorHelper helper; 1076 BytecodeExpectationsPrinter printer(CcTest::isolate(),
3918 Zone zone; 1077 ConstantPoolType::kMixed);
3919 1078
3920 FeedbackVectorSpec feedback_spec(&zone); 1079 const char* snippets[] = {
3921 FeedbackVectorSlot slot1 = feedback_spec.AddKeyedStoreICSlot(); 1080 "return [ 1, 2 ];",
3922 FeedbackVectorSlot slot2 = feedback_spec.AddKeyedStoreICSlot(); 1081
3923 FeedbackVectorSlot slot3 = feedback_spec.AddKeyedStoreICSlot(); 1082 "var a = 1; return [ a, a + 1 ];",
3924 1083
3925 Handle<i::TypeFeedbackVector> vector = 1084 "return [ [ 1, 2 ], [ 3 ] ];",
3926 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); 1085
3927 1086 "var a = 1; return [ [ a, 2 ], [ a + 2 ] ];",
3928 int simple_flags = 1087 };
3929 ArrayLiteral::kDisableMementos | ArrayLiteral::kShallowElements; 1088
3930 int deep_elements_flags = ArrayLiteral::kDisableMementos; 1089 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("ArrayLiterals.golden"));
3931 // clang-format off 1090 }
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 1091
4031 TEST(ArrayLiteralsWide) { 1092 TEST(ArrayLiteralsWide) {
4032 InitializedHandleScope handle_scope; 1093 InitializedIgnitionHandleScope scope;
4033 BytecodeGeneratorHelper helper; 1094 BytecodeExpectationsPrinter printer(CcTest::isolate(),
4034 Zone zone; 1095 ConstantPoolType::kMixed);
4035 1096
4036 int wide_idx = 0; 1097 const char* snippets[] = {
4037 int simple_flags = 1098 "var a;" //
4038 ArrayLiteral::kDisableMementos | ArrayLiteral::kShallowElements; 1099 REPEAT_256("\na = 1.23;") //
4039 1100 "\nreturn [ 1 , 2 ];",
4040 // clang-format off 1101 };
4041 ExpectedSnippet<InstanceType, 257> snippets[] = { 1102
4042 {"var a;" REPEAT_256(SPACE, "a = 1.23;") "return [ 1 , 2 ];", 1103 CHECK_EQ(BuildActual(printer, snippets),
4043 1 * kPointerSize, 1104 LoadGolden("ArrayLiteralsWide.golden"));
4044 1, 1105 }
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 1106
4068 TEST(ObjectLiterals) { 1107 TEST(ObjectLiterals) {
4069 InitializedHandleScope handle_scope; 1108 InitializedIgnitionHandleScope scope;
4070 BytecodeGeneratorHelper helper; 1109 BytecodeExpectationsPrinter printer(CcTest::isolate(),
4071 Zone zone; 1110 ConstantPoolType::kMixed);
4072 1111
4073 FeedbackVectorSpec feedback_spec(&zone); 1112 const char* snippets[] = {
4074 FeedbackVectorSlot slot1 = feedback_spec.AddStoreICSlot(); 1113 "return { };",
4075 1114
4076 Handle<i::TypeFeedbackVector> vector = 1115 "return { name: 'string', val: 9.2 };",
4077 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); 1116
4078 1117 "var a = 1; return { name: 'string', val: a };",
4079 int simple_flags = ObjectLiteral::kFastElements | 1118
4080 ObjectLiteral::kShallowProperties | 1119 "var a = 1; return { val: a, val: a + 1 };",
4081 ObjectLiteral::kDisableMementos; 1120
4082 int deep_elements_flags = 1121 "return { func: function() { } };",
4083 ObjectLiteral::kFastElements | ObjectLiteral::kDisableMementos; 1122
4084 1123 "return { func(a) { return a; } };",
4085 // clang-format off 1124
4086 ExpectedSnippet<InstanceType> snippets[] = { 1125 "return { get a() { return 2; } };",
4087 {"return { };", 1126
4088 kPointerSize, 1127 "return { get a() { return this.x; }, set a(val) { this.x = val } };",
4089 1, 1128
4090 8, 1129 "return { set b(val) { this.y = val } };",
4091 { 1130
4092 B(StackCheck), // 1131 "var a = 1; return { 1: a };",
4093 B(CreateObjectLiteral), U8(0), U8(0), U8(simple_flags), // 1132
4094 B(Star), R(0), // 1133 "return { __proto__: null };",
4095 B(Return) // 1134
4096 }, 1135 "var a = 'test'; return { [a]: 1 };",
4097 1, 1136
4098 {InstanceType::FIXED_ARRAY_TYPE}}, 1137 "var a = 'test'; return { val: a, [a]: 1 };",
4099 {"return { name: 'string', val: 9.2 };", 1138
4100 kPointerSize, 1139 "var a = 'test'; return { [a]: 1, __proto__: {} };",
4101 1, 1140
4102 8, 1141 "var n = 'name'; return { [n]: 'val', get a() { }, set a(b) {} };",
4103 { 1142 };
4104 B(StackCheck), // 1143
4105 B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags), // 1144 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("ObjectLiterals.golden"));
4106 B(Star), R(0), // 1145 }
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 1146
4453 TEST(ObjectLiteralsWide) { 1147 TEST(ObjectLiteralsWide) {
4454 InitializedHandleScope handle_scope; 1148 InitializedIgnitionHandleScope scope;
4455 BytecodeGeneratorHelper helper; 1149 BytecodeExpectationsPrinter printer(CcTest::isolate(),
4456 Zone zone; 1150 ConstantPoolType::kMixed);
4457 1151 const char* snippets[] = {
4458 int deep_elements_flags = 1152 "var a;" //
4459 ObjectLiteral::kFastElements | ObjectLiteral::kDisableMementos; 1153 REPEAT_256("\na = 1.23;") //
4460 int wide_idx = 0; 1154 "\nreturn { name: 'string', val: 9.2 };",
4461 1155 };
4462 // clang-format off 1156
4463 ExpectedSnippet<InstanceType, 257> snippets[] = { 1157 CHECK_EQ(BuildActual(printer, snippets),
4464 {"var a;" REPEAT_256(SPACE, 1158 LoadGolden("ObjectLiteralsWide.golden"));
4465 "a = 1.23;") "return { name: 'string', val: 9.2 };", 1159 }
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 1160
4493 TEST(TopLevelObjectLiterals) { 1161 TEST(TopLevelObjectLiterals) {
4494 InitializedHandleScope handle_scope; 1162 InitializedIgnitionHandleScope scope;
4495 BytecodeGeneratorHelper helper; 1163 BytecodeExpectationsPrinter printer(CcTest::isolate(),
4496 1164 ConstantPoolType::kMixed);
4497 int has_function_flags = ObjectLiteral::kFastElements | 1165 printer.set_wrap(false);
4498 ObjectLiteral::kHasFunction | 1166 printer.set_test_function_name("f");
4499 ObjectLiteral::kDisableMementos; 1167 printer.set_execute(false);
4500 // clang-format off 1168 printer.set_top_level(true);
4501 ExpectedSnippet<InstanceType> snippets[] = { 1169
4502 {"var a = { func: function() { } };", 1170 const char* snippets[] = {
4503 5 * kPointerSize, 1171 "var a = { func: function() { } };",
4504 1, 1172 };
4505 49, 1173
4506 { 1174 CHECK_EQ(BuildActual(printer, snippets),
4507 B(LdaConstant), U8(0), // 1175 LoadGolden("TopLevelObjectLiterals.golden"));
4508 B(Star), R(1), // 1176 }
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 1177
4545 TEST(TryCatch) { 1178 TEST(TryCatch) {
4546 InitializedHandleScope handle_scope; 1179 InitializedIgnitionHandleScope scope;
4547 BytecodeGeneratorHelper helper; 1180 BytecodeExpectationsPrinter printer(CcTest::isolate(),
4548 1181 ConstantPoolType::kString);
4549 int closure = Register::function_closure().index(); 1182
4550 int context = Register::current_context().index(); 1183 const char* snippets[] = {
4551 1184 "try { return 1; } catch(e) { return 2; }",
4552 // clang-format off 1185
4553 ExpectedSnippet<const char*> snippets[] = { 1186 "var a;\n"
4554 {"try { return 1; } catch(e) { return 2; }", 1187 "try { a = 1 } catch(e1) {};\n"
4555 5 * kPointerSize, 1188 "try { a = 2 } catch(e2) { a = 3 }",
4556 1, 1189 };
4557 40, 1190
4558 { 1191 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("TryCatch.golden"));
4559 B(StackCheck), // 1192 }
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 1193
4643 TEST(TryFinally) { 1194 TEST(TryFinally) {
4644 InitializedHandleScope handle_scope; 1195 InitializedIgnitionHandleScope scope;
4645 BytecodeGeneratorHelper helper; 1196 BytecodeExpectationsPrinter printer(CcTest::isolate(),
4646 1197 ConstantPoolType::kString);
4647 int closure = Register::function_closure().index(); 1198 const char* snippets[] = {
4648 int context = Register::current_context().index(); 1199 "var a = 1;\n"
4649 1200 "try { a = 2; } finally { a = 3; }",
4650 // clang-format off 1201
4651 ExpectedSnippet<const char*> snippets[] = { 1202 "var a = 1;\n"
4652 {"var a = 1; try { a = 2; } finally { a = 3; }", 1203 "try { a = 2; } catch(e) { a = 20 } finally { a = 3; }",
4653 4 * kPointerSize, 1204
4654 1, 1205 "var a; try {\n"
4655 51, 1206 " try { a = 1 } catch(e) { a = 2 }\n"
4656 { 1207 "} catch(e) { a = 20 } finally { a = 3; }",
4657 B(StackCheck), // 1208 };
4658 B(LdaSmi8), U8(1), // 1209
4659 B(Star), R(0), // 1210 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("TryFinally.golden"));
4660 B(Mov), R(context), R(3), // 1211 }
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 1212
4822 TEST(Throw) { 1213 TEST(Throw) {
4823 InitializedHandleScope handle_scope; 1214 InitializedIgnitionHandleScope scope;
4824 BytecodeGeneratorHelper helper; 1215 BytecodeExpectationsPrinter printer(CcTest::isolate(),
4825 1216 ConstantPoolType::kString);
4826 // clang-format off 1217 const char* snippets[] = {
4827 ExpectedSnippet<const char*> snippets[] = { 1218 "throw 1;",
4828 {"throw 1;", 1219
4829 0, 1220 "throw 'Error';",
4830 1, 1221
4831 4, 1222 "var a = 1; if (a) { throw 'Error'; };",
4832 { 1223 };
4833 B(StackCheck), // 1224
4834 B(LdaSmi8), U8(1), // 1225 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("Throw.golden"));
4835 B(Throw), // 1226 }
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 1227
4876 TEST(CallNew) { 1228 TEST(CallNew) {
4877 InitializedHandleScope handle_scope; 1229 InitializedIgnitionHandleScope scope;
4878 BytecodeGeneratorHelper helper; 1230 BytecodeExpectationsPrinter printer(CcTest::isolate(),
4879 Zone zone; 1231 ConstantPoolType::kMixed);
4880 1232 printer.set_wrap(false);
4881 FeedbackVectorSpec feedback_spec(&zone); 1233 printer.set_test_function_name("f");
4882 FeedbackVectorSlot slot1 = feedback_spec.AddGeneralSlot(); 1234
4883 FeedbackVectorSlot slot2 = feedback_spec.AddLoadICSlot(); 1235 const char* snippets[] = {
4884 USE(slot1); 1236 "function bar() { this.value = 0; }\n"
4885 1237 "function f() { return new bar(); }\n"
4886 Handle<i::TypeFeedbackVector> vector = 1238 "f();",
4887 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); 1239
4888 1240 "function bar(x) { this.value = 18; this.x = x;}\n"
4889 // clang-format off 1241 "function f() { return new bar(3); }\n"
4890 ExpectedSnippet<InstanceType> snippets[] = { 1242 "f();",
4891 {"function bar() { this.value = 0; }\n" 1243
4892 "function f() { return new bar(); }\n" 1244 "function bar(w, x, y, z) {\n"
4893 "f()", 1245 " this.value = 18;\n"
4894 1 * kPointerSize, 1246 " this.x = x;\n"
4895 1, 1247 " this.y = y;\n"
4896 11, 1248 " this.z = z;\n"
4897 { 1249 "}\n"
4898 B(StackCheck), // 1250 "function f() { return new bar(3, 4, 5); }\n"
4899 B(LdaGlobal), U8(0), U8(vector->GetIndex(slot2)), // 1251 "f();",
4900 B(Star), R(0), // 1252 };
4901 B(New), R(0), R(0), U8(0), // 1253
4902 B(Return), // 1254 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("CallNew.golden"));
4903 }, 1255 }
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 1256
4962 TEST(ContextVariables) { 1257 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 1258 // 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 1259 // ever changes, the REPEAT_XXX should be changed to output the correct number
4980 // of unique variables to trigger the wide slot load / store. 1260 // of unique variables to trigger the wide slot load / store.
4981 STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS + 3 + 249 == 256); 1261 STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS + 3 + 249 == 256);
4982 int wide_slot = first_context_slot + 3; 1262
4983 1263 InitializedIgnitionHandleScope scope;
4984 // clang-format off 1264 BytecodeExpectationsPrinter printer(CcTest::isolate(),
4985 ExpectedSnippet<InstanceType> snippets[] = { 1265 ConstantPoolType::kMixed);
4986 {"var a; return function() { a = 1; };", 1266 const char* snippets[] = {
4987 1 * kPointerSize, 1267 "var a; return function() { a = 1; };",
4988 1, 1268
4989 12, 1269 "var a = 1; return function() { a = 2; };",
4990 { 1270
4991 B(CallRuntime), U16(Runtime::kNewFunctionContext), // 1271 "var a = 1; var b = 2; return function() { a = 2; b = 3 };",
4992 /* */ R(closure), U8(1), // 1272
4993 B(PushContext), R(0), // 1273 "var a; (function() { a = 2; })(); return a;",
4994 B(StackCheck), // 1274
4995 B(CreateClosure), U8(0), U8(0), // 1275 "'use strict';\n"
4996 B(Return), // 1276 "let a = 1;\n"
4997 }, 1277 "{ let b = 2; return function() { a + b; }; }",
4998 1, 1278
4999 {InstanceType::SHARED_FUNCTION_INFO_TYPE}}, 1279 "'use strict';\n"
5000 {"var a = 1; return function() { a = 2; };", 1280 REPEAT_249_UNIQUE_VARS()
5001 1 * kPointerSize, 1281 "eval();\n"
5002 1, 1282 "var b = 100;\n"
5003 17, 1283 "return b",
5004 { 1284 };
5005 B(CallRuntime), U16(Runtime::kNewFunctionContext), // 1285
5006 /* */ R(closure), U8(1), // 1286 CHECK_EQ(BuildActual(printer, snippets),
5007 B(PushContext), R(0), // 1287 LoadGolden("ContextVariables.golden"));
5008 B(StackCheck), // 1288 }
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 1289
5128 TEST(ContextParameters) { 1290 TEST(ContextParameters) {
5129 InitializedHandleScope handle_scope; 1291 InitializedIgnitionHandleScope scope;
5130 BytecodeGeneratorHelper helper; 1292 BytecodeExpectationsPrinter printer(CcTest::isolate(),
5131 1293 ConstantPoolType::kMixed);
5132 int closure = Register::function_closure().index(); 1294 printer.set_wrap(false);
5133 int context = Register::current_context().index(); 1295 printer.set_test_function_name("f");
5134 int first_context_slot = Context::MIN_CONTEXT_SLOTS; 1296
5135 1297 const char* snippets[] = {
5136 // clang-format off 1298 "function f(arg1) { return function() { arg1 = 2; }; }",
5137 ExpectedSnippet<InstanceType> snippets[] = { 1299
5138 {"function f(arg1) { return function() { arg1 = 2; }; }", 1300 "function f(arg1) { var a = function() { arg1 = 2; }; return arg1; }",
5139 1 * kPointerSize, 1301
5140 2, 1302 "function f(a1, a2, a3, a4) { return function() { a1 = a3; }; }",
5141 17, 1303
5142 { 1304 "function f() { var self = this; return function() { self = 2; }; }",
5143 B(CallRuntime), U16(Runtime::kNewFunctionContext), // 1305 };
5144 /* */ R(closure), U8(1), // 1306
5145 B(PushContext), R(0), // 1307 CHECK_EQ(BuildActual(printer, snippets, "", "\nf();"),
5146 B(Ldar), R(helper.kLastParamIndex), // 1308 LoadGolden("ContextParameters.golden"));
5147 B(StaContextSlot), R(context), U8(first_context_slot), // 1309 }
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 1310
5217 TEST(OuterContextVariables) { 1311 TEST(OuterContextVariables) {
5218 InitializedHandleScope handle_scope; 1312 InitializedIgnitionHandleScope scope;
5219 BytecodeGeneratorHelper helper; 1313 BytecodeExpectationsPrinter printer(CcTest::isolate(),
5220 1314 ConstantPoolType::kMixed);
5221 int context = Register::current_context().index(); 1315 printer.set_wrap(false);
5222 int first_context_slot = Context::MIN_CONTEXT_SLOTS; 1316 printer.set_test_function_name("f");
5223 1317
5224 // clang-format off 1318 const char* snippets[] = {
5225 ExpectedSnippet<InstanceType> snippets[] = { 1319 "function Outer() {\n"
5226 {"function Outer() {" 1320 " var outerVar = 1;\n"
5227 " var outerVar = 1;" 1321 " function Inner(innerArg) {\n"
5228 " function Inner(innerArg) {" 1322 " this.innerFunc = function() { return outerVar * innerArg; }\n"
5229 " this.innerFunc = function() { return outerVar * innerArg; }" 1323 " }\n"
5230 " }" 1324 " this.getInnerFunc = function() { return new Inner(1).innerFunc; }\n"
5231 " this.getInnerFunc = function() { return new Inner(1).innerFunc; }" 1325 "}\n"
5232 "}" 1326 "var f = new Outer().getInnerFunc();",
5233 "var f = new Outer().getInnerFunc();", 1327
5234 2 * kPointerSize, 1328 "function Outer() {\n"
5235 1, 1329 " var outerVar = 1;\n"
5236 21, 1330 " function Inner(innerArg) {\n"
5237 { 1331 " this.innerFunc = function() { outerVar = innerArg; }\n"
5238 B(StackCheck), // 1332 " }\n"
5239 B(Ldar), R(context), // 1333 " this.getInnerFunc = function() { return new Inner(1).innerFunc; }\n"
5240 B(Star), R(0), // 1334 "}\n"
5241 B(LdaContextSlot), R(0), U8(Context::PREVIOUS_INDEX), // 1335 "var f = new Outer().getInnerFunc();",
5242 B(Star), R(0), // 1336 };
5243 B(LdaContextSlot), R(0), U8(first_context_slot), // 1337
5244 B(Star), R(1), // 1338 CHECK_EQ(BuildActual(printer, snippets, "", "\nf();"),
5245 B(LdaContextSlot), R(context), U8(first_context_slot), // 1339 LoadGolden("OuterContextVariables.golden"));
5246 B(Mul), R(1), // 1340 }
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 1341
5284 TEST(CountOperators) { 1342 TEST(CountOperators) {
5285 InitializedHandleScope handle_scope; 1343 InitializedIgnitionHandleScope scope;
5286 BytecodeGeneratorHelper helper; 1344 BytecodeExpectationsPrinter printer(CcTest::isolate(),
5287 Zone zone; 1345 ConstantPoolType::kMixed);
5288 1346 const char* snippets[] = {
5289 FeedbackVectorSpec feedback_spec(&zone); 1347 "var a = 1; return ++a;",
5290 FeedbackVectorSlot slot1 = feedback_spec.AddLoadICSlot(); 1348
5291 FeedbackVectorSlot slot2 = feedback_spec.AddStoreICSlot(); 1349 "var a = 1; return a++;",
5292 Handle<i::TypeFeedbackVector> vector = 1350
5293 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); 1351 "var a = 1; return --a;",
5294 1352
5295 FeedbackVectorSpec store_feedback_spec(&zone); 1353 "var a = 1; return a--;",
5296 FeedbackVectorSlot store_slot = store_feedback_spec.AddStoreICSlot(); 1354
5297 Handle<i::TypeFeedbackVector> store_vector = 1355 "var a = { val: 1 }; return a.val++;",
5298 i::NewTypeFeedbackVector(helper.isolate(), &store_feedback_spec); 1356
5299 1357 "var a = { val: 1 }; return --a.val;",
5300 int closure = Register::function_closure().index(); 1358
5301 int context = Register::current_context().index(); 1359 "var name = 'var'; var a = { val: 1 }; return a[name]--;",
5302 int first_context_slot = Context::MIN_CONTEXT_SLOTS; 1360
5303 1361 "var name = 'var'; var a = { val: 1 }; return ++a[name];",
5304 int object_literal_flags = 1362
5305 ObjectLiteral::kFastElements | ObjectLiteral::kDisableMementos; 1363 "var a = 1; var b = function() { return a }; return ++a;",
5306 int array_literal_flags = 1364
5307 ArrayLiteral::kDisableMementos | ArrayLiteral::kShallowElements; 1365 "var a = 1; var b = function() { return a }; return a--;",
5308 1366
5309 // clang-format off 1367 "var idx = 1; var a = [1, 2]; return a[idx++] = 2;",
5310 ExpectedSnippet<InstanceType> snippets[] = { 1368 };
5311 {"var a = 1; return ++a;", 1369
5312 1 * kPointerSize, 1370 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("CountOperators.golden"));
5313 1, 1371 }
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 1372
5533 TEST(GlobalCountOperators) { 1373 TEST(GlobalCountOperators) {
5534 InitializedHandleScope handle_scope; 1374 InitializedIgnitionHandleScope scope;
5535 BytecodeGeneratorHelper helper; 1375 BytecodeExpectationsPrinter printer(CcTest::isolate(),
5536 Zone zone; 1376 ConstantPoolType::kString);
5537 1377 printer.set_wrap(false);
5538 FeedbackVectorSpec feedback_spec(&zone); 1378 printer.set_test_function_name("f");
5539 FeedbackVectorSlot slot1 = feedback_spec.AddLoadICSlot(); 1379
5540 FeedbackVectorSlot slot2 = feedback_spec.AddStoreICSlot(); 1380 const char* snippets[] = {
5541 1381 "var global = 1;\n"
5542 Handle<i::TypeFeedbackVector> vector = 1382 "function f() { return ++global; }\n"
5543 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); 1383 "f();",
5544 1384
5545 // clang-format off 1385 "var global = 1;\n"
5546 ExpectedSnippet<const char*> snippets[] = { 1386 "function f() { return global--; }\n"
5547 {"var global = 1;\nfunction f() { return ++global; }\nf()", 1387 "f();",
5548 0, 1388
5549 1, 1389 "unallocated = 1;\n"
5550 10, 1390 "function f() { 'use strict'; return --unallocated; }\n"
5551 { 1391 "f();",
5552 B(StackCheck), // 1392
5553 B(LdaGlobal), U8(0), U8(vector->GetIndex(slot1)), // 1393 "unallocated = 1;\n"
5554 B(ToNumber), // 1394 "function f() { return unallocated++; }\n"
5555 B(Inc), // 1395 "f();",
5556 B(StaGlobalSloppy), U8(0), U8(vector->GetIndex(slot2)), // 1396 };
5557 B(Return), // 1397
5558 }, 1398 CHECK_EQ(BuildActual(printer, snippets),
5559 1, 1399 LoadGolden("GlobalCountOperators.golden"));
5560 {"global"}}, 1400 }
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 1401
5619 TEST(CompoundExpressions) { 1402 TEST(CompoundExpressions) {
5620 InitializedHandleScope handle_scope; 1403 InitializedIgnitionHandleScope scope;
5621 BytecodeGeneratorHelper helper; 1404 BytecodeExpectationsPrinter printer(CcTest::isolate(),
5622 Zone zone; 1405 ConstantPoolType::kMixed);
5623 1406 const char* snippets[] = {
5624 int closure = Register::function_closure().index(); 1407 "var a = 1; a += 2;",
5625 int context = Register::current_context().index(); 1408
5626 int first_context_slot = Context::MIN_CONTEXT_SLOTS; 1409 "var a = 1; a /= 2;",
5627 1410
5628 FeedbackVectorSpec feedback_spec(&zone); 1411 "var a = { val: 2 }; a.name *= 2;",
5629 FeedbackVectorSlot slot1 = feedback_spec.AddLoadICSlot(); 1412
5630 FeedbackVectorSlot slot2 = feedback_spec.AddStoreICSlot(); 1413 "var a = { 1: 2 }; a[1] ^= 2;",
5631 1414
5632 Handle<i::TypeFeedbackVector> vector = 1415 "var a = 1; (function f() { return a; }); a |= 24;",
5633 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); 1416 };
5634 1417
5635 int object_literal_flags = 1418 CHECK_EQ(BuildActual(printer, snippets),
5636 ObjectLiteral::kFastElements | ObjectLiteral::kDisableMementos; 1419 LoadGolden("CompoundExpressions.golden"));
5637 1420 }
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 1421
5746 TEST(GlobalCompoundExpressions) { 1422 TEST(GlobalCompoundExpressions) {
5747 InitializedHandleScope handle_scope; 1423 InitializedIgnitionHandleScope scope;
5748 BytecodeGeneratorHelper helper; 1424 BytecodeExpectationsPrinter printer(CcTest::isolate(),
5749 Zone zone; 1425 ConstantPoolType::kString);
5750 1426 printer.set_wrap(false);
5751 FeedbackVectorSpec feedback_spec(&zone); 1427 printer.set_test_function_name("f");
5752 FeedbackVectorSlot slot1 = feedback_spec.AddLoadICSlot(); 1428
5753 FeedbackVectorSlot slot2 = feedback_spec.AddStoreICSlot(); 1429 const char* snippets[] = {
5754 1430 "var global = 1;\n"
5755 Handle<i::TypeFeedbackVector> vector = 1431 "function f() { return global &= 1; }\n"
5756 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); 1432 "f();",
5757 1433
5758 // clang-format off 1434 "unallocated = 1;\n"
5759 ExpectedSnippet<const char*> snippets[] = { 1435 "function f() { return unallocated += 1; }\n"
5760 {"var global = 1;\nfunction f() { return global &= 1; }\nf()", 1436 "f();",
5761 1 * kPointerSize, 1437 };
5762 1, 1438
5763 14, 1439 CHECK_EQ(BuildActual(printer, snippets),
5764 { 1440 LoadGolden("GlobalCompoundExpressions.golden"));
5765 B(StackCheck), // 1441 }
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 1442
5801 TEST(CreateArguments) { 1443 TEST(CreateArguments) {
5802 InitializedHandleScope handle_scope; 1444 InitializedIgnitionHandleScope scope;
5803 BytecodeGeneratorHelper helper; 1445 BytecodeExpectationsPrinter printer(CcTest::isolate(),
5804 Zone zone; 1446 ConstantPoolType::kString);
5805 1447 printer.set_wrap(false);
5806 int closure = Register::function_closure().index(); 1448 printer.set_test_function_name("f");
5807 int context = Register::current_context().index(); 1449
5808 int first_context_slot = Context::MIN_CONTEXT_SLOTS; 1450 const char* snippets[] = {
5809 1451 "function f() { return arguments; }",
5810 FeedbackVectorSpec feedback_spec(&zone); 1452
5811 FeedbackVectorSlot slot = feedback_spec.AddKeyedLoadICSlot(); 1453 "function f() { return arguments[0]; }",
5812 1454
5813 Handle<i::TypeFeedbackVector> vector = 1455 "function f() { 'use strict'; return arguments; }",
5814 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); 1456
5815 1457 "function f(a) { return arguments[0]; }",
5816 // clang-format off 1458
5817 ExpectedSnippet<const char*> snippets[] = { 1459 "function f(a, b, c) { return arguments; }",
5818 {"function f() { return arguments; }", 1460
5819 1 * kPointerSize, 1461 "function f(a, b, c) { 'use strict'; return arguments; }",
5820 1, 1462 };
5821 7, 1463
5822 { 1464 CHECK_EQ(BuildActual(printer, snippets, "", "\nf();"),
5823 B(CreateMappedArguments), // 1465 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 } 1466 }
5913 1467
5914 TEST(CreateRestParameter) { 1468 TEST(CreateRestParameter) {
5915 InitializedHandleScope handle_scope; 1469 InitializedIgnitionHandleScope scope;
5916 BytecodeGeneratorHelper helper; 1470 BytecodeExpectationsPrinter printer(CcTest::isolate(),
5917 Zone zone; 1471 ConstantPoolType::kNumber);
5918 1472 printer.set_wrap(false);
5919 FeedbackVectorSpec feedback_spec(&zone); 1473 printer.set_test_function_name("f");
5920 FeedbackVectorSlot slot = feedback_spec.AddKeyedLoadICSlot(); 1474
5921 FeedbackVectorSlot slot1 = feedback_spec.AddKeyedLoadICSlot(); 1475 const char* snippets[] = {
5922 1476 "function f(...restArgs) { return restArgs; }",
5923 Handle<i::TypeFeedbackVector> vector = 1477
5924 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); 1478 "function f(a, ...restArgs) { return restArgs; }",
5925 1479
5926 // clang-format off 1480 "function f(a, ...restArgs) { return restArgs[0]; }",
5927 ExpectedSnippet<int> snippets[] = { 1481
5928 {"function f(...restArgs) { return restArgs; }", 1482 "function f(a, ...restArgs) { return restArgs[0] + arguments[0]; }",
5929 1 * kPointerSize, 1483 };
5930 1, 1484
5931 7, 1485 CHECK_EQ(BuildActual(printer, snippets, "", "\nf();"),
5932 { 1486 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 } 1487 }
6015 1488
6016 TEST(IllegalRedeclaration) { 1489 TEST(IllegalRedeclaration) {
6017 bool old_legacy_const_flag = FLAG_legacy_const; 1490 bool old_legacy_const_flag = FLAG_legacy_const;
6018 FLAG_legacy_const = true; 1491 FLAG_legacy_const = true;
6019 1492
6020 InitializedHandleScope handle_scope;
6021 BytecodeGeneratorHelper helper;
6022
6023 CHECK_GE(MessageTemplate::kVarRedeclaration, 128); 1493 CHECK_GE(MessageTemplate::kVarRedeclaration, 128);
6024 // Must adapt bytecode if this changes. 1494 // Must adapt bytecode if this changes.
6025 1495
6026 // clang-format off 1496 InitializedIgnitionHandleScope scope;
6027 ExpectedSnippet<Handle<Object>, 2> snippets[] = { 1497 BytecodeExpectationsPrinter printer(CcTest::isolate(),
6028 {"const a = 1; { var a = 2; }", 1498 ConstantPoolType::kMixed);
6029 3 * kPointerSize, 1499 const char* snippets[] = {"const a = 1; { var a = 2; }"};
6030 1, 1500
6031 14, 1501 CHECK_EQ(BuildActual(printer, snippets),
6032 { 1502 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 1503
6052 FLAG_legacy_const = old_legacy_const_flag; 1504 FLAG_legacy_const = old_legacy_const_flag;
6053 } 1505 }
6054 1506
6055
6056 TEST(ForIn) { 1507 TEST(ForIn) {
6057 InitializedHandleScope handle_scope; 1508 InitializedIgnitionHandleScope scope;
6058 BytecodeGeneratorHelper helper; 1509 BytecodeExpectationsPrinter printer(CcTest::isolate(),
6059 Zone zone; 1510 ConstantPoolType::kMixed);
6060 1511 const char* snippets[] = {
6061 int simple_flags = 1512 "for (var p in null) {}",
6062 ArrayLiteral::kDisableMementos | ArrayLiteral::kShallowElements; 1513
6063 int deep_elements_flags = 1514 "for (var p in undefined) {}",
6064 ObjectLiteral::kFastElements | ObjectLiteral::kDisableMementos; 1515
6065 1516 "for (var p in undefined) {}",
6066 FeedbackVectorSpec feedback_spec(&zone); 1517
6067 feedback_spec.AddStoreICSlot(); 1518 "var x = 'potatoes';\n"
6068 FeedbackVectorSlot slot2 = feedback_spec.AddStoreICSlot(); 1519 "for (var p in x) { return p; }",
6069 FeedbackVectorSlot slot3 = feedback_spec.AddStoreICSlot(); 1520
6070 FeedbackVectorSlot slot4 = feedback_spec.AddStoreICSlot(); 1521 "var x = 0;\n"
6071 Handle<i::TypeFeedbackVector> vector = 1522 "for (var p in [1,2,3]) { x += p; }",
6072 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); 1523
6073 1524 "var x = { 'a': 1, 'b': 2 };\n"
6074 // clang-format off 1525 "for (x['a'] in [10, 20, 30]) {\n"
6075 ExpectedSnippet<InstanceType> snippets[] = { 1526 " if (x['a'] == 10) continue;\n"
6076 {"for (var p in null) {}", 1527 " if (x['a'] == 20) break;\n"
6077 2 * kPointerSize, 1528 "}",
6078 1, 1529
6079 3, 1530 "var x = [ 10, 11, 12 ] ;\n"
6080 { 1531 "for (x[0] in [1,2,3]) { return x[3]; }",
6081 B(StackCheck), // 1532 };
6082 B(LdaUndefined), // 1533
6083 B(Return) // 1534 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("ForIn.golden"));
6084 }, 1535 }
6085 0}, 1536
6086 {"for (var p in undefined) {}", 1537 TEST(ForOf) {
6087 2 * kPointerSize, 1538 InitializedIgnitionHandleScope scope;
6088 1, 1539 BytecodeExpectationsPrinter printer(CcTest::isolate(),
6089 3, 1540 ConstantPoolType::kMixed);
6090 { 1541 const char* snippets[] = {
6091 B(StackCheck), // 1542 "for (var p of [0, 1, 2]) {}",
6092 B(LdaUndefined), // 1543
6093 B(Return) // 1544 "var x = 'potatoes';\n"
6094 }, 1545 "for (var p of x) { return p; }",
6095 0}, 1546
6096 {"for (var p in undefined) {}", 1547 "for (var x of [10, 20, 30]) {\n"
6097 2 * kPointerSize, 1548 " if (x == 10) continue;\n"
6098 1, 1549 " if (x == 20) break;\n"
6099 3, 1550 "}",
6100 { 1551
6101 B(StackCheck), // 1552 "var x = { 'a': 1, 'b': 2 };\n"
6102 B(LdaUndefined), // 1553 "for (x['a'] of [1,2,3]) { return x['a']; }",
6103 B(Return) // 1554 };
6104 }, 1555
6105 0}, 1556 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("ForOf.golden"));
6106 {"var x = 'potatoes';\n" 1557 }
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 1558
6542 TEST(Conditional) { 1559 TEST(Conditional) {
6543 InitializedHandleScope handle_scope; 1560 InitializedIgnitionHandleScope scope;
6544 BytecodeGeneratorHelper helper; 1561 BytecodeExpectationsPrinter printer(CcTest::isolate(),
6545 1562 ConstantPoolType::kNumber);
6546 // clang-format off 1563 const char* snippets[] = {
6547 ExpectedSnippet<int> snippets[] = { 1564 "return 1 ? 2 : 3;",
6548 {"return 1 ? 2 : 3;", 1565
6549 0, 1566 "return 1 ? 2 ? 3 : 4 : 5;",
6550 1, 1567 };
6551 12, 1568
6552 { 1569 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("Conditional.golden"));
6553 B(StackCheck), // 1570 }
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 1571
6589 TEST(Switch) { 1572 TEST(Switch) {
6590 InitializedHandleScope handle_scope; 1573 InitializedIgnitionHandleScope scope;
6591 BytecodeGeneratorHelper helper; 1574 BytecodeExpectationsPrinter printer(CcTest::isolate(),
6592 1575 ConstantPoolType::kNumber);
6593 // clang-format off 1576 const char* snippets[] = {
6594 ExpectedSnippet<int> snippets[] = { 1577 "var a = 1;\n"
6595 {"var a = 1;\n" 1578 "switch(a) {\n"
6596 "switch(a) {\n" 1579 " case 1: return 2;\n"
6597 " case 1: return 2;\n" 1580 " case 2: return 3;\n"
6598 " case 2: return 3;\n" 1581 "}",
6599 "}\n", 1582
6600 3 * kPointerSize, 1583 "var a = 1;\n"
6601 1, 1584 "switch(a) {\n"
6602 31, 1585 " case 1: a = 2; break;\n"
6603 { 1586 " case 2: a = 3; break;\n"
6604 B(StackCheck), // 1587 "}",
6605 B(LdaSmi8), U8(1), // 1588
6606 B(Star), R(1), // The tag variable is allocated as a 1589 "var a = 1;\n"
6607 B(Star), R(0), // local by the parser, hence the store 1590 "switch(a) {\n"
6608 B(Star), R(2), // to another local register. 1591 " case 1: a = 2; // fall-through\n"
6609 B(LdaSmi8), U8(1), // 1592 " case 2: a = 3; break;\n"
6610 B(TestEqualStrict), R(2), // 1593 "}",
6611 B(JumpIfTrue), U8(10), // 1594
6612 B(LdaSmi8), U8(2), // 1595 "var a = 1;\n"
6613 B(TestEqualStrict), R(2), // 1596 "switch(a) {\n"
6614 B(JumpIfTrue), U8(7), // 1597 " case 2: break;\n"
6615 B(Jump), U8(8), // 1598 " case 3: break;\n"
6616 B(LdaSmi8), U8(2), // 1599 " default: a = 1; break;\n"
6617 B(Return), // 1600 "}",
6618 B(LdaSmi8), U8(3), // 1601
6619 B(Return), // 1602 "var a = 1;\n"
6620 B(LdaUndefined), // 1603 "switch(typeof(a)) {\n"
6621 B(Return), // 1604 " case 2: a = 1; break;\n"
6622 }}, 1605 " case 3: a = 2; break;\n"
6623 {"var a = 1;\n" 1606 " default: a = 3; break;\n"
6624 "switch(a) {\n" 1607 "}",
6625 " case 1: a = 2; break;\n" 1608
6626 " case 2: a = 3; break;\n" 1609 "var a = 1;\n"
6627 "}\n", 1610 "switch(a) {\n"
6628 3 * kPointerSize, 1611 " case typeof(a): a = 1; break;\n"
6629 1, 1612 " default: a = 2; break;\n"
6630 37, 1613 "}",
6631 { 1614
6632 B(StackCheck), // 1615 "var a = 1;\n"
6633 B(LdaSmi8), U8(1), // 1616 "switch(a) {\n"
6634 B(Star), R(1), // 1617 " case 1:\n"
6635 B(Star), R(0), // 1618 REPEAT_64(" a = 2;\n")
6636 B(Star), R(2), // 1619 " break;\n"
6637 B(LdaSmi8), U8(1), // 1620 " case 2:\n"
6638 B(TestEqualStrict), R(2), // 1621 " a = 3;\n"
6639 B(JumpIfTrue), U8(10), // 1622 " break;\n"
6640 B(LdaSmi8), U8(2), // 1623 "}",
6641 B(TestEqualStrict), R(2), // 1624
6642 B(JumpIfTrue), U8(10), // 1625 "var a = 1;\n"
6643 B(Jump), U8(14), // 1626 "switch(a) {\n"
6644 B(LdaSmi8), U8(2), // 1627 " case 1: \n"
6645 B(Star), R(1), // 1628 " switch(a + 1) {\n"
6646 B(Jump), U8(8), // 1629 " case 2 : a = 1; break;\n"
6647 B(LdaSmi8), U8(3), // 1630 " default : a = 2; break;\n"
6648 B(Star), R(1), // 1631 " } // fall-through\n"
6649 B(Jump), U8(2), // 1632 " case 2: a = 3;\n"
6650 B(LdaUndefined), // 1633 "}",
6651 B(Return), // 1634 };
6652 }}, 1635
6653 {"var a = 1;\n" 1636 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("Switch.golden"));
6654 "switch(a) {\n" 1637 }
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 1638
6866 TEST(BasicBlockToBoolean) { 1639 TEST(BasicBlockToBoolean) {
6867 InitializedHandleScope handle_scope; 1640 InitializedIgnitionHandleScope scope;
6868 BytecodeGeneratorHelper helper; 1641 BytecodeExpectationsPrinter printer(CcTest::isolate(),
6869 1642 ConstantPoolType::kNumber);
6870 // Check that we generate JumpIfToBoolean if they are at the start of basic 1643 const char* snippets[] = {
6871 // blocks. 1644 "var a = 1; if (a || a < 0) { return 1; }",
6872 // clang-format off 1645
6873 ExpectedSnippet<int> snippets[] = { 1646 "var a = 1; if (a && a < 0) { return 1; }",
6874 {"var a = 1; if (a || a < 0) { return 1; }", 1647
6875 2 * kPointerSize, 1648 "var a = 1; a = (a || a < 0) ? 2 : 3;",
6876 1, 1649 };
6877 21, 1650
6878 { 1651 CHECK_EQ(BuildActual(printer, snippets),
6879 B(StackCheck), // 1652 LoadGolden("BasicBlockToBoolean.golden"));
6880 B(LdaSmi8), U8(1), // 1653 }
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 1654
6944 TEST(DeadCodeRemoval) { 1655 TEST(DeadCodeRemoval) {
6945 InitializedHandleScope handle_scope; 1656 InitializedIgnitionHandleScope scope;
6946 BytecodeGeneratorHelper helper; 1657 BytecodeExpectationsPrinter printer(CcTest::isolate(),
6947 1658 ConstantPoolType::kNumber);
6948 // clang-format off 1659 const char* snippets[] = {
6949 ExpectedSnippet<int> snippets[] = { 1660 "return; var a = 1; a();",
6950 {"return; var a = 1; a();", 1661
6951 1 * kPointerSize, 1662 "if (false) { return; }; var a = 1;",
6952 1, 1663
6953 3, 1664 "if (true) { return 1; } else { return 2; };",
6954 { 1665
6955 B(StackCheck), // 1666 "var a = 1; if (a) { return 1; }; return 2;",
6956 B(LdaUndefined), // 1667 };
6957 B(Return), // 1668
6958 }}, 1669 CHECK_EQ(BuildActual(printer, snippets),
6959 {"if (false) { return; }; var a = 1;", 1670 LoadGolden("DeadCodeRemoval.golden"));
6960 1 * kPointerSize, 1671 }
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 1672
7004 TEST(ThisFunction) { 1673 TEST(ThisFunction) {
7005 InitializedHandleScope handle_scope; 1674 InitializedIgnitionHandleScope scope;
7006 BytecodeGeneratorHelper helper; 1675 BytecodeExpectationsPrinter printer(CcTest::isolate(),
7007 1676 ConstantPoolType::kNumber);
7008 int closure = Register::function_closure().index(); 1677 printer.set_wrap(false);
7009 1678 printer.set_test_function_name("f");
7010 // clang-format off 1679
7011 ExpectedSnippet<int> snippets[] = { 1680 const char* snippets[] = {
7012 {"var f;\n f = function f() { }", 1681 "var f;\n"
7013 2 * kPointerSize, 1682 "f = function f() {};",
7014 1, 1683
7015 19, 1684 "var f;\n"
7016 { 1685 "f = function f() { return f; };",
7017 B(LdaTheHole), // 1686 };
7018 B(Star), R(0), // 1687
7019 B(StackCheck), // 1688 CHECK_EQ(BuildActual(printer, snippets, "", "\nf();"),
7020 B(Ldar), R(closure), // 1689 LoadGolden("ThisFunction.golden"));
7021 B(Star), R(1), // 1690 }
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 1691
7059 TEST(NewTarget) { 1692 TEST(NewTarget) {
7060 InitializedHandleScope handle_scope; 1693 InitializedIgnitionHandleScope scope;
7061 BytecodeGeneratorHelper helper; 1694 BytecodeExpectationsPrinter printer(CcTest::isolate(),
7062 1695 ConstantPoolType::kMixed);
7063 int new_target = Register::new_target().index(); 1696
7064 1697 const char* snippets[] = {
7065 // clang-format off 1698 "return new.target;",
7066 ExpectedSnippet<InstanceType> snippets[] = { 1699
7067 {"return new.target;", 1700 "new.target;",
7068 2 * kPointerSize, 1701 };
7069 1, 1702
7070 19, 1703 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("NewTarget.golden"));
7071 { 1704 }
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 1705
7112 TEST(RemoveRedundantLdar) { 1706 TEST(RemoveRedundantLdar) {
7113 InitializedHandleScope handle_scope; 1707 InitializedIgnitionHandleScope scope;
7114 BytecodeGeneratorHelper helper; 1708 BytecodeExpectationsPrinter printer(CcTest::isolate(),
7115 1709 ConstantPoolType::kNumber);
7116 // clang-format off 1710 const char* snippets[] = {
7117 ExpectedSnippet<int> snippets[] = { 1711 "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 1712 "while(true) {\n" // get removed if the preceding Star is
7119 "while(true) {\n" // get removed if the preceding Star is 1713 " ld_a = ld_a + ld_a;\n" // in a different basicblock.
7120 " ld_a = ld_a + ld_a;\n" // in a different basicblock. 1714 " if (ld_a > 10) break;\n"
7121 " if (ld_a > 10) break;\n" 1715 "}\n"
7122 "}\n" 1716 "return ld_a;",
7123 "return ld_a;", 1717
7124 2 * kPointerSize, 1718 "var ld_a = 1;\n"
7125 1, 1719 "do {\n"
7126 31, 1720 " ld_a = ld_a + ld_a;\n"
7127 {B(StackCheck), // 1721 " if (ld_a > 10) continue;\n"
7128 B(LdaSmi8), U8(1), // 1722 "} while(false);\n"
7129 B(Star), R(0), // 1723 "return ld_a;",
7130 B(StackCheck), // 1724
7131 B(Ldar), R(0), // This load should not be removed as it 1725 "var ld_a = 1;\n"
7132 B(Star), R(1), // is the target of the branch. 1726 " ld_a = ld_a + ld_a;\n"
7133 B(Ldar), R(0), // 1727 " return ld_a;",
7134 B(Add), R(1), // 1728 };
7135 B(Star), R(0), // 1729
7136 B(Star), R(1), // 1730 CHECK_EQ(BuildActual(printer, snippets),
7137 B(LdaSmi8), U8(10), // 1731 LoadGolden("RemoveRedundantLdar.golden"));
7138 B(TestGreaterThan), R(1), // 1732 }
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 1733
7196 TEST(AssignmentsInBinaryExpression) { 1734 TEST(AssignmentsInBinaryExpression) {
7197 InitializedHandleScope handle_scope; 1735 InitializedIgnitionHandleScope scope;
7198 BytecodeGeneratorHelper helper; 1736 BytecodeExpectationsPrinter printer(CcTest::isolate(),
7199 1737 ConstantPoolType::kString);
7200 // clang-format off 1738 const char* snippets[] = {
7201 ExpectedSnippet<const char*> snippets[] = { 1739 "var x = 0, y = 1;\n"
7202 {"var x = 0, y = 1;\n" 1740 "return (x = 2, y = 3, x = 4, y = 5);",
7203 "return (x = 2, y = 3, x = 4, y = 5)", 1741
7204 2 * kPointerSize, 1742 "var x = 55;\n"
7205 1, 1743 "var y = (x = 100);\n"
7206 25, 1744 "return y;",
7207 { 1745
7208 B(StackCheck), // 1746 "var x = 55;\n"
7209 B(LdaZero), B(Star), R(0), // 1747 "x = x + (x = 100) + (x = 101);\n"
7210 B(LdaSmi8), U8(1), // 1748 "return x;",
7211 B(Star), R(1), // 1749
7212 B(LdaSmi8), U8(2), // 1750 "var x = 55;\n"
7213 B(Star), R(0), // 1751 "x = (x = 56) - x + (x = 57);\n"
7214 B(LdaSmi8), U8(3), // 1752 "x++;\n"
7215 B(Star), R(1), // 1753 "return x;",
7216 B(LdaSmi8), U8(4), // 1754
7217 B(Star), R(0), // 1755 "var x = 55;\n"
7218 B(LdaSmi8), U8(5), // 1756 "var y = x + (x = 1) + (x = 2) + (x = 3);\n"
7219 B(Star), R(1), // 1757 "return y;",
7220 B(Return), // 1758
7221 }, 1759 "var x = 55;\n"
7222 0}, 1760 "var x = x + (x = 1) + (x = 2) + (x = 3);\n"
7223 {"var x = 55;\n" 1761 "return x;",
7224 "var y = (x = 100);\n" 1762
7225 "return y", 1763 "var x = 10, y = 20;\n"
7226 2 * kPointerSize, 1764 "return x + (x = 1) + (x + 1) * (y = 2) + (y = 3) + (x = 4) + (y = 5) + "
7227 1, 1765 "y;\n",
7228 12, 1766
7229 { 1767 "var x = 17;\n"
7230 B(StackCheck), // 1768 "return 1 + x + (x++) + (++x);\n",
7231 B(LdaSmi8), U8(55), // 1769 };
7232 B(Star), R(0), // 1770
7233 B(LdaSmi8), U8(100), // 1771 CHECK_EQ(BuildActual(printer, snippets),
7234 B(Star), R(0), // 1772 LoadGolden("AssignmentsInBinaryExpression.golden"));
7235 B(Star), R(1), // 1773 }
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 1774
7427 TEST(Eval) { 1775 TEST(Eval) {
7428 InitializedHandleScope handle_scope; 1776 InitializedIgnitionHandleScope scope;
7429 BytecodeGeneratorHelper helper; 1777 BytecodeExpectationsPrinter printer(CcTest::isolate(),
7430 Zone zone; 1778 ConstantPoolType::kString);
7431 1779 const char* snippets[] = {
7432 int closure = Register::function_closure().index(); 1780 "return eval('1;');",
7433 int context = Register::current_context().index(); 1781 };
7434 int new_target = Register::new_target().index(); 1782
7435 1783 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("Eval.golden"));
7436 int first_context_slot = Context::MIN_CONTEXT_SLOTS; 1784 }
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 1785
7487 TEST(LookupSlot) { 1786 TEST(LookupSlot) {
7488 InitializedHandleScope handle_scope; 1787 InitializedIgnitionHandleScope scope;
7489 BytecodeGeneratorHelper helper; 1788 BytecodeExpectationsPrinter printer(CcTest::isolate(),
7490 1789 ConstantPoolType::kString);
7491 int closure = Register::function_closure().index(); 1790
7492 int context = Register::current_context().index(); 1791 const char* snippets[] = {
7493 int first_context_slot = Context::MIN_CONTEXT_SLOTS; 1792 "eval('var x = 10;'); return x;",
7494 int new_target = Register::new_target().index(); 1793
7495 1794 "eval('var x = 10;'); return typeof x;",
7496 // clang-format off 1795
7497 ExpectedSnippet<const char*> snippets[] = { 1796 "x = 20; return eval('');",
7498 {"eval('var x = 10;'); return x;", 1797 };
7499 9 * kPointerSize, 1798
7500 1, 1799 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("LookupSlot.golden"));
7501 67, 1800 }
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 1801
7622 TEST(CallLookupSlot) { 1802 TEST(CallLookupSlot) {
7623 InitializedHandleScope handle_scope; 1803 InitializedIgnitionHandleScope scope;
7624 BytecodeGeneratorHelper helper; 1804 BytecodeExpectationsPrinter printer(CcTest::isolate(),
7625 Zone zone; 1805 ConstantPoolType::kMixed);
7626 1806 const char* snippets[] = {
7627 FeedbackVectorSpec feedback_spec(&zone); 1807 "g = function(){}; eval(''); return g();",
7628 FeedbackVectorSlot slot1 = feedback_spec.AddLoadICSlot(); 1808 };
7629 FeedbackVectorSlot slot2 = feedback_spec.AddCallICSlot(); 1809
7630 USE(slot1); 1810 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("CallLookupSlot.golden"));
7631 1811 }
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 1812
7698 // TODO(mythria): tests for variable/function declaration in lookup slots. 1813 // TODO(mythria): tests for variable/function declaration in lookup slots.
7699 1814
7700 TEST(LookupSlotInEval) { 1815 TEST(LookupSlotInEval) {
7701 InitializedHandleScope handle_scope; 1816 InitializedIgnitionHandleScope scope;
7702 BytecodeGeneratorHelper helper; 1817 BytecodeExpectationsPrinter printer(CcTest::isolate(),
7703 1818 ConstantPoolType::kString);
7704 const char* function_prologue = "var f;" 1819 printer.set_wrap(false);
7705 "var x = 1;" 1820 printer.set_test_function_name("f");
7706 "function f1() {" 1821
7707 " eval(\"function t() {"; 1822 const char* snippets[] = {
7708 const char* function_epilogue = " }; f = t; f();\");" 1823 "return x;",
7709 "}" 1824
7710 "f1();"; 1825 "x = 10;",
7711 1826
7712 // clang-format off 1827 "'use strict'; x = 10;",
7713 ExpectedSnippet<const char*> snippets[] = { 1828
7714 {"return x;", 1829 "return typeof x;",
7715 0 * kPointerSize, 1830 };
7716 1, 1831
7717 4, 1832 std::string actual = BuildActual(printer, snippets,
7718 { 1833 "var f;\n"
7719 B(StackCheck), // 1834 "var x = 1;\n"
7720 B(LdaLookupSlot), U8(0), // 1835 "function f1() {\n"
7721 B(Return) // 1836 " eval(\"function t() { ",
7722 }, 1837
7723 1, 1838 " }; f = t; f();\");\n"
7724 {"x"}}, 1839 "}\n"
7725 {"x = 10;", 1840 "f1();");
7726 0 * kPointerSize, 1841
7727 1, 1842 CHECK_EQ(actual, LoadGolden("LookupSlotInEval.golden"));
7728 7, 1843 }
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 1844
7777 TEST(LookupSlotWideInEval) { 1845 TEST(LookupSlotWideInEval) {
7778 InitializedHandleScope handle_scope; 1846 InitializedIgnitionHandleScope scope;
7779 BytecodeGeneratorHelper helper; 1847 BytecodeExpectationsPrinter printer(CcTest::isolate(),
7780 1848 ConstantPoolType::kMixed);
7781 const char* function_prologue = 1849 printer.set_wrap(false);
7782 "var f;" 1850 printer.set_test_function_name("f");
7783 "var x = 1;" 1851
7784 "function f1() {" 1852 const char* snippets[] = {
7785 " eval(\"function t() {"; 1853 REPEAT_256(" \"var y = 2.3;\" +\n") //
7786 const char* function_epilogue = 1854 " \"return x;\" +\n",
7787 " }; f = t; f();\");" 1855
7788 "}" 1856 REPEAT_256(" \"var y = 2.3;\" +\n") //
7789 "f1();"; 1857 " \"return typeof x;\" +\n",
7790 1858
7791 int const_count[] = {0, 0, 0, 0}; 1859 REPEAT_256(" \"var y = 2.3;\" +\n") //
7792 // clang-format off 1860 " \"x = 10;\" +\n",
7793 ExpectedSnippet<InstanceType, 257> snippets[] = { 1861
7794 {REPEAT_256(SPACE, "var y = 2.3;") 1862 " \"'use strict';\" +\n" //
7795 "return x;", 1863 REPEAT_256(" \"var y = 2.3;\" +\n") //
7796 1 * kPointerSize, 1864 " \"x = 10;\" +\n",
7797 1, 1865 };
7798 1029, 1866
7799 { 1867 std::string actual = BuildActual(printer, snippets,
7800 B(StackCheck), // 1868 "var f;\n"
7801 REPEAT_256(SPACE, // 1869 "var x = 1;\n"
7802 B(LdaConstant), U8(const_count[0]++), // 1870 "function f1() {\n"
7803 B(Star), R(0), ) // 1871 " eval(\"function t() {\" +\n",
7804 B(LdaLookupSlotWide), U16(256), // 1872
7805 B(Return) // 1873 " \"};\" +\n"
7806 }, 1874 " \"f = t; f();\"\n);\n"
7807 257, 1875 "}\n"
7808 {REPEAT_256(COMMA, InstanceType::HEAP_NUMBER_TYPE), 1876 "f1();");
7809 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, 1877
7810 {REPEAT_256(SPACE, "var y = 2.3;") 1878 CHECK_EQ(actual, LoadGolden("LookupSlotWideInEval.golden"));
7811 "return typeof x;", 1879 }
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 1880
7878 TEST(DeleteLookupSlotInEval) { 1881 TEST(DeleteLookupSlotInEval) {
7879 InitializedHandleScope handle_scope; 1882 InitializedIgnitionHandleScope scope;
7880 BytecodeGeneratorHelper helper; 1883 BytecodeExpectationsPrinter printer(CcTest::isolate(),
7881 1884 ConstantPoolType::kString);
7882 const char* function_prologue = "var f;" 1885 printer.set_wrap(false);
7883 "var x = 1;" 1886 printer.set_test_function_name("f");
7884 "z = 10;" 1887
7885 "function f1() {" 1888 const char* snippets[] = {
7886 " var y;" 1889 "delete x;",
7887 " eval(\"function t() {"; 1890
7888 const char* function_epilogue = " }; f = t; f();\");" 1891 "return delete y;",
7889 "}" 1892
7890 "f1();"; 1893 "return delete z;",
7891 1894 };
7892 // clang-format off 1895
7893 ExpectedSnippet<const char*> snippets[] = { 1896 std::string actual = BuildActual(printer, snippets,
7894 {"delete x;", 1897 "var f;\n"
7895 1 * kPointerSize, 1898 "var x = 1;\n"
7896 1, 1899 "z = 10;\n"
7897 12, 1900 "function f1() {\n"
7898 { 1901 " var y;\n"
7899 B(StackCheck), // 1902 " eval(\"function t() { ",
7900 B(LdaConstant), U8(0), // 1903
7901 B(Star), R(0), // 1904 " }; f = t; f();\");\n"
7902 B(CallRuntime), U16(Runtime::kDeleteLookupSlot), R(0), U8(1), // 1905 "}\n"
7903 B(LdaUndefined), // 1906 "f1();");
7904 B(Return) // 1907
7905 }, 1908 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 } 1909 }
7943 1910
7944 TEST(WideRegisters) { 1911 TEST(WideRegisters) {
7945 // Prepare prologue that creates frame for lots of registers. 1912 // Prepare prologue that creates frame for lots of registers.
7946 std::ostringstream os; 1913 std::ostringstream os;
7947 for (size_t i = 0; i < 157; ++i) { 1914 for (size_t i = 0; i < 157; ++i) {
7948 os << "var x" << i << ";\n"; 1915 os << "var x" << i << ";\n";
7949 } 1916 }
7950 std::string prologue(os.str()); 1917 std::string prologue(os.str());
7951 1918
7952 // clang-format off 1919 InitializedIgnitionHandleScope scope;
7953 ExpectedSnippet<int> snippets[] = { 1920 BytecodeExpectationsPrinter printer(CcTest::isolate(),
7954 {"x0 = x127;\n" 1921 ConstantPoolType::kNumber);
7955 "return x0;\n", 1922 const char* snippets[] = {
7956 161 * kPointerSize, 1923 "x0 = x127;\n"
7957 1, 1924 "return x0;",
7958 11, 1925
7959 { 1926 "x127 = x126;\n"
7960 B(StackCheck), // 1927 "return x127;",
7961 B(MovWide), R16(131), R16(125), // 1928
7962 B(Ldar), R(125), // 1929 "if (x2 > 3) { return x129; }\n"
7963 B(Star), R(0), // 1930 "return x128;",
7964 B(Return), // 1931
7965 }}, 1932 "var x0 = 0;\n"
7966 {"x127 = x126;\n" 1933 "if (x129 == 3) { var x129 = x0; }\n"
7967 "return x127;\n", 1934 "if (x2 > 3) { return x0; }\n"
7968 161 * kPointerSize, 1935 "return x129;",
7969 1, 1936
7970 23, 1937 "var x0 = 0;\n"
7971 { 1938 "var x1 = 0;\n"
7972 B(StackCheck), // 1939 "for (x128 = 0; x128 < 64; x128++) {"
7973 B(MovWide), R16(130), R16(125), // 1940 " x1 += x128;"
7974 B(Ldar), R(125), // 1941 "}"
7975 B(Star), R(125), // 1942 "return x128;",
7976 B(MovWide), R16(125), R16(131), // 1943
7977 B(MovWide), R16(131), R16(125), // 1944 "var x0 = 1234;\n"
7978 B(Ldar), R(125), // 1945 "var x1 = 0;\n"
7979 B(Return), // 1946 "for (x128 in x0) {"
7980 }}, 1947 " x1 += x128;"
7981 {"if (x2 > 3) { return x129; }\n" 1948 "}"
7982 "return x128;\n", 1949 "return x1;",
7983 162 * kPointerSize, 1950
7984 1, 1951 "x0 = %Add(x64, x63);\n"
7985 37, 1952 "x1 = %Add(x27, x143);\n"
7986 { 1953 "%TheHole();\n"
7987 B(StackCheck), // 1954 "return x1;",
7988 B(Ldar), R(2), // 1955 };
7989 B(Star), R(125), // 1956
7990 B(MovWide), R16(125), R16(161), // 1957 CHECK_EQ(BuildActual(printer, snippets, prologue.c_str()),
7991 B(LdaSmi8), U8(3), // 1958 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 } 1959 }
8181 1960
8182 TEST(ConstVariable) { 1961 TEST(ConstVariable) {
8183 InitializedHandleScope handle_scope; 1962 InitializedIgnitionHandleScope scope;
8184 BytecodeGeneratorHelper helper; 1963 BytecodeExpectationsPrinter printer(CcTest::isolate(),
8185 // clang-format off 1964 ConstantPoolType::kString);
8186 ExpectedSnippet<const char*> snippets[] = { 1965 const char* snippets[] = {
8187 {"const x = 10;", 1966 "const x = 10;",
8188 1 * kPointerSize, 1967
8189 1, 1968 "const x = 10; return x;",
8190 10, 1969
8191 { 1970 "const x = ( x = 20);",
8192 B(LdaTheHole), // 1971
8193 B(Star), R(0), // 1972 "const x = 10; x = 20;",
8194 B(StackCheck), // 1973 };
8195 B(LdaSmi8), U8(10), // 1974
8196 B(Star), R(0), // 1975 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 } 1976 }
8278 1977
8279 TEST(LetVariable) { 1978 TEST(LetVariable) {
8280 InitializedHandleScope handle_scope; 1979 InitializedIgnitionHandleScope scope;
8281 BytecodeGeneratorHelper helper; 1980 BytecodeExpectationsPrinter printer(CcTest::isolate(),
8282 1981 ConstantPoolType::kString);
8283 // clang-format off 1982 const char* snippets[] = {
8284 ExpectedSnippet<const char*> snippets[] = { 1983 "let x = 10;",
8285 {"let x = 10;", 1984
8286 1 * kPointerSize, 1985 "let x = 10; return x;",
8287 1, 1986
8288 10, 1987 "let x = (x = 20);",
8289 { 1988
8290 B(LdaTheHole), // 1989 "let x = 10; x = 20;",
8291 B(Star), R(0), // 1990 };
8292 B(StackCheck), // 1991
8293 B(LdaSmi8), U8(10), // 1992 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 } 1993 }
8372 1994
8373 TEST(LegacyConstVariable) { 1995 TEST(LegacyConstVariable) {
8374 bool old_legacy_const_flag = FLAG_legacy_const; 1996 bool old_legacy_const_flag = FLAG_legacy_const;
8375 FLAG_legacy_const = true; 1997 FLAG_legacy_const = true;
8376 1998
8377 InitializedHandleScope handle_scope; 1999 InitializedIgnitionHandleScope scope;
8378 BytecodeGeneratorHelper helper; 2000 BytecodeExpectationsPrinter printer(CcTest::isolate(),
8379 2001 ConstantPoolType::kString);
8380 // clang-format off 2002 const char* snippets[] = {
8381 ExpectedSnippet<const char*> snippets[] = { 2003 "const x = 10;",
8382 {"const x = 10;", 2004
8383 2 * kPointerSize, 2005 "const x = 10; return x;",
8384 1, 2006
8385 19, 2007 "const x = ( x = 20);",
8386 { 2008
8387 B(LdaTheHole), // 2009 "const x = 10; x = 20;",
8388 B(Star), R(0), // 2010 };
8389 B(StackCheck), // 2011
8390 B(LdaSmi8), U8(10), // 2012 CHECK_EQ(BuildActual(printer, snippets),
8391 B(Star), R(1), // 2013 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 2014
8471 FLAG_legacy_const = old_legacy_const_flag; 2015 FLAG_legacy_const = old_legacy_const_flag;
8472 } 2016 }
8473 2017
8474 TEST(ConstVariableContextSlot) { 2018 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. 2019 // TODO(mythria): Add tests for initialization of this via super calls.
8482 // TODO(mythria): Add tests that walk the context chain. 2020 // TODO(mythria): Add tests that walk the context chain.
8483 // clang-format off 2021 InitializedIgnitionHandleScope scope;
8484 ExpectedSnippet<InstanceType> snippets[] = { 2022 BytecodeExpectationsPrinter printer(CcTest::isolate(),
8485 {"const x = 10; function f1() {return x;}", 2023 ConstantPoolType::kMixed);
8486 2 * kPointerSize, 2024 const char* snippets[] = {
8487 1, 2025 "const x = 10; function f1() {return x;}",
8488 24, 2026
8489 { 2027 "const x = 10; function f1() {return x;} return x;",
8490 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // 2028
8491 U8(1), // 2029 "const x = (x = 20); function f1() {return x;}",
8492 B(PushContext), R(1), // 2030
8493 B(LdaTheHole), // 2031 "const x = 10; x = 20; function f1() {return x;}",
8494 B(StaContextSlot), R(context), U8(4), // 2032 };
8495 B(CreateClosure), U8(0), U8(0), // 2033
8496 B(Star), R(0), // 2034 CHECK_EQ(BuildActual(printer, snippets),
8497 B(StackCheck), // 2035 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 } 2036 }
8602 2037
8603 TEST(LetVariableContextSlot) { 2038 TEST(LetVariableContextSlot) {
8604 InitializedHandleScope handle_scope; 2039 InitializedIgnitionHandleScope scope;
8605 BytecodeGeneratorHelper helper; 2040 BytecodeExpectationsPrinter printer(CcTest::isolate(),
8606 2041 ConstantPoolType::kMixed);
8607 int closure = Register::function_closure().index(); 2042 const char* snippets[] = {
8608 int context = Register::current_context().index(); 2043 "let x = 10; function f1() {return x;}",
8609 2044
8610 // clang-format off 2045 "let x = 10; function f1() {return x;} return x;",
8611 ExpectedSnippet<InstanceType> snippets[] = { 2046
8612 {"let x = 10; function f1() {return x;}", 2047 "let x = (x = 20); function f1() {return x;}",
8613 2 * kPointerSize, 2048
8614 1, 2049 "let x = 10; x = 20; function f1() {return x;}",
8615 24, 2050 };
8616 { 2051
8617 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // 2052 CHECK_EQ(BuildActual(printer, snippets),
8618 /* */ U8(1), // 2053 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 } 2054 }
8725 2055
8726 TEST(DoExpression) { 2056 TEST(DoExpression) {
8727 bool old_flag = FLAG_harmony_do_expressions; 2057 bool old_flag = FLAG_harmony_do_expressions;
8728 FLAG_harmony_do_expressions = true; 2058 FLAG_harmony_do_expressions = true;
8729 2059
8730 InitializedHandleScope handle_scope; 2060 InitializedIgnitionHandleScope scope;
8731 BytecodeGeneratorHelper helper; 2061 BytecodeExpectationsPrinter printer(CcTest::isolate(),
8732 2062 ConstantPoolType::kString);
8733 // clang-format off 2063 const char* snippets[] = {
8734 ExpectedSnippet<const char*> snippets[] = { 2064 "var a = do { }; return a;",
8735 {"var a = do { }; return a;", 2065
8736 2 * kPointerSize, 2066 "var a = do { var x = 100; }; return a;",
8737 1, 2067
8738 6, 2068 "while(true) { var a = 10; a = do { ++a; break; }; a = 20; }",
8739 { 2069 };
8740 B(StackCheck), // 2070
8741 B(Ldar), R(0), // 2071 CHECK_EQ(BuildActual(printer, snippets), LoadGolden("DoExpression.golden"));
8742 B(Star), R(1), // 2072
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; 2073 FLAG_harmony_do_expressions = old_flag;
8792 } 2074 }
8793 2075
8794 TEST(WithStatement) { 2076 TEST(WithStatement) {
8795 InitializedHandleScope handle_scope; 2077 InitializedIgnitionHandleScope scope;
8796 BytecodeGeneratorHelper helper; 2078 BytecodeExpectationsPrinter printer(CcTest::isolate(),
8797 2079 ConstantPoolType::kMixed);
8798 int deep_elements_flags = 2080 const char* snippets[] = {
8799 ObjectLiteral::kFastElements | ObjectLiteral::kDisableMementos; 2081 "with ({x:42}) { return x; }",
8800 int context = Register::current_context().index(); 2082 };
8801 int closure = Register::function_closure().index(); 2083
8802 int new_target = Register::new_target().index(); 2084 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 } 2085 }
8845 2086
8846 TEST(DoDebugger) { 2087 TEST(DoDebugger) {
8847 InitializedHandleScope handle_scope; 2088 InitializedIgnitionHandleScope scope;
8848 BytecodeGeneratorHelper helper; 2089 BytecodeExpectationsPrinter printer(CcTest::isolate(),
8849 2090 ConstantPoolType::kString);
8850 // clang-format off 2091 const char* snippets[] = {
8851 ExpectedSnippet<const char*> snippet = {
8852 "debugger;", 2092 "debugger;",
8853 0, 2093 };
8854 1, 2094
8855 4, 2095 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 } 2096 }
8870 2097
8871 // TODO(rmcilroy): Update expectations after switch to 2098 // TODO(rmcilroy): Update expectations after switch to
8872 // Runtime::kDefineDataPropertyInLiteral. 2099 // Runtime::kDefineDataPropertyInLiteral.
8873 TEST(ClassDeclarations) { 2100 TEST(ClassDeclarations) {
8874 InitializedHandleScope handle_scope; 2101 InitializedIgnitionHandleScope scope;
8875 BytecodeGeneratorHelper helper; 2102 BytecodeExpectationsPrinter printer(CcTest::isolate(),
8876 2103 ConstantPoolType::kMixed);
8877 int closure = Register::function_closure().index(); 2104 const char* snippets[] = {
8878 int context = Register::current_context().index(); 2105 "class Person {\n"
8879 2106 " constructor(name) { this.name = name; }\n"
8880 // clang-format off 2107 " speak() { console.log(this.name + ' is speaking.'); }\n"
8881 ExpectedSnippet<InstanceType, 12> snippets[] = { 2108 "}",
8882 {"class Person {\n" 2109
8883 " constructor(name) { this.name = name; }\n" 2110 "class person {\n"
8884 " speak() { console.log(this.name + ' is speaking.'); }\n" 2111 " constructor(name) { this.name = name; }\n"
8885 "}\n", 2112 " speak() { console.log(this.name + ' is speaking.'); }\n"
8886 9 * kPointerSize, 2113 "}",
8887 1, 2114
8888 71, 2115 "var n0 = 'a';\n"
8889 { 2116 "var n1 = 'b';\n"
8890 B(LdaTheHole), // 2117 "class N {\n"
8891 B(Star), R(1), // 2118 " [n0]() { return n0; }\n"
8892 B(StackCheck), // 2119 " static [n1]() { return n1; }\n"
8893 B(LdaTheHole), // 2120 "}",
8894 B(Star), R(0), // 2121
8895 B(LdaTheHole), // 2122 "var count = 0;\n"
8896 B(Star), R(2), // 2123 "class C { constructor() { count++; }}\n"
8897 B(CreateClosure), U8(0), U8(0), // 2124 "return new C();\n",
8898 B(Star), R(3), // 2125 };
8899 B(LdaSmi8), U8(15), // 2126
8900 B(Star), R(4), // 2127 CHECK_EQ(BuildActual(printer, snippets),
8901 B(LdaConstant), U8(1), // 2128 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 } 2129 }
9098 2130
9099 // TODO(oth): Add tests for super keyword. 2131 // TODO(oth): Add tests for super keyword.
9100 2132
9101 } // namespace interpreter 2133 } // namespace interpreter
9102 } // namespace internal 2134 } // namespace internal
9103 } // namespace v8 2135 } // 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