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

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

Powered by Google App Engine
This is Rietveld 408576698