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

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

Issue 1343363002: [Interpreter] Basic flow control. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Switch test-bytecode-generator/IfConditions to use new style bytecode array check. Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/interpreter/interpreter.cc ('k') | test/cctest/interpreter/test-interpreter.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/compiler.h" 7 #include "src/compiler.h"
8 #include "src/interpreter/bytecode-array-iterator.h" 8 #include "src/interpreter/bytecode-array-iterator.h"
9 #include "src/interpreter/bytecode-generator.h" 9 #include "src/interpreter/bytecode-generator.h"
10 #include "src/interpreter/interpreter.h" 10 #include "src/interpreter/interpreter.h"
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 #define _ static_cast<uint8_t>(0x5a) 65 #define _ static_cast<uint8_t>(0x5a)
66 66
67 67
68 // Structure for containing expected bytecode snippets. 68 // Structure for containing expected bytecode snippets.
69 template<typename T> 69 template<typename T>
70 struct ExpectedSnippet { 70 struct ExpectedSnippet {
71 const char* code_snippet; 71 const char* code_snippet;
72 int frame_size; 72 int frame_size;
73 int parameter_count; 73 int parameter_count;
74 int bytecode_length; 74 int bytecode_length;
75 const uint8_t bytecode[32]; 75 const uint8_t bytecode[512];
76 int constant_count; 76 int constant_count;
77 T constants[16]; 77 T constants[4];
78 }; 78 };
79 79
80 80
81 static void CheckConstant(int expected, Object* actual) { 81 static void CheckConstant(int expected, Object* actual) {
82 CHECK_EQ(expected, Smi::cast(actual)->value()); 82 CHECK_EQ(expected, Smi::cast(actual)->value());
83 } 83 }
84 84
85 85
86 static void CheckConstant(double expected, Object* actual) { 86 static void CheckConstant(double expected, Object* actual) {
87 CHECK_EQ(expected, HeapNumber::cast(actual)->value()); 87 CHECK_EQ(expected, HeapNumber::cast(actual)->value());
88 } 88 }
89 89
90 90
91 static void CheckConstant(const char* expected, Object* actual) { 91 static void CheckConstant(const char* expected, Object* actual) {
92 Handle<String> expected_string = 92 Handle<String> expected_string =
93 CcTest::i_isolate()->factory()->NewStringFromAsciiChecked(expected); 93 CcTest::i_isolate()->factory()->NewStringFromAsciiChecked(expected);
94 CHECK(String::cast(actual)->Equals(*expected_string)); 94 CHECK(String::cast(actual)->Equals(*expected_string));
95 } 95 }
96 96
97 97
98 static void CheckConstant(Handle<Object> expected, Object* actual) {
99 CHECK(actual == *expected || expected->StrictEquals(actual));
100 }
101
102
98 template <typename T> 103 template <typename T>
99 static void CheckBytecodeArrayEqual(struct ExpectedSnippet<T> expected, 104 static void CheckBytecodeArrayEqual(struct ExpectedSnippet<T> expected,
100 Handle<BytecodeArray> actual, 105 Handle<BytecodeArray> actual,
101 bool has_unknown = false) { 106 bool has_unknown = false) {
102 CHECK_EQ(actual->frame_size(), expected.frame_size); 107 CHECK_EQ(actual->frame_size(), expected.frame_size);
103 CHECK_EQ(actual->parameter_count(), expected.parameter_count); 108 CHECK_EQ(actual->parameter_count(), expected.parameter_count);
104 CHECK_EQ(actual->length(), expected.bytecode_length); 109 CHECK_EQ(actual->length(), expected.bytecode_length);
105 if (expected.constant_count == 0) { 110 if (expected.constant_count == 0) {
106 CHECK_EQ(actual->constant_pool(), CcTest::heap()->empty_fixed_array()); 111 CHECK_EQ(actual->constant_pool(), CcTest::heap()->empty_fixed_array());
107 } else { 112 } else {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 {"return null;", 0, 1, 2, {B(LdaNull), B(Return)}, 0}, 164 {"return null;", 0, 1, 2, {B(LdaNull), B(Return)}, 0},
160 {"return true;", 0, 1, 2, {B(LdaTrue), B(Return)}, 0}, 165 {"return true;", 0, 1, 2, {B(LdaTrue), B(Return)}, 0},
161 {"return false;", 0, 1, 2, {B(LdaFalse), B(Return)}, 0}, 166 {"return false;", 0, 1, 2, {B(LdaFalse), B(Return)}, 0},
162 {"return 0;", 0, 1, 2, {B(LdaZero), B(Return)}, 0}, 167 {"return 0;", 0, 1, 2, {B(LdaZero), B(Return)}, 0},
163 {"return +1;", 0, 1, 3, {B(LdaSmi8), U8(1), B(Return)}, 0}, 168 {"return +1;", 0, 1, 3, {B(LdaSmi8), U8(1), B(Return)}, 0},
164 {"return -1;", 0, 1, 3, {B(LdaSmi8), U8(-1), B(Return)}, 0}, 169 {"return -1;", 0, 1, 3, {B(LdaSmi8), U8(-1), B(Return)}, 0},
165 {"return +127;", 0, 1, 3, {B(LdaSmi8), U8(127), B(Return)}, 0}, 170 {"return +127;", 0, 1, 3, {B(LdaSmi8), U8(127), B(Return)}, 0},
166 {"return -128;", 0, 1, 3, {B(LdaSmi8), U8(-128), B(Return)}, 0}, 171 {"return -128;", 0, 1, 3, {B(LdaSmi8), U8(-128), B(Return)}, 0},
167 }; 172 };
168 173
169 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); 174 for (size_t i = 0; i < arraysize(snippets); i++) {
170 for (size_t i = 0; i < num_snippets; i++) {
171 Handle<BytecodeArray> bytecode_array = 175 Handle<BytecodeArray> bytecode_array =
172 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); 176 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
173 CheckBytecodeArrayEqual(snippets[i], bytecode_array); 177 CheckBytecodeArrayEqual(snippets[i], bytecode_array);
174 } 178 }
175 } 179 }
176 180
177 181
178 TEST(PrimitiveExpressions) { 182 TEST(PrimitiveExpressions) {
179 InitializedHandleScope handle_scope; 183 InitializedHandleScope handle_scope;
180 BytecodeGeneratorHelper helper; 184 BytecodeGeneratorHelper helper;
(...skipping 20 matching lines...) Expand all
201 B(Star), R(0), // 205 B(Star), R(0), //
202 B(Ldar), R(0), // Easy to spot r1 not really needed here. 206 B(Ldar), R(0), // Easy to spot r1 not really needed here.
203 B(Star), R(1), // Dead store. 207 B(Star), R(1), // Dead store.
204 B(LdaSmi8), U8(3), // 208 B(LdaSmi8), U8(3), //
205 B(Add), R(1), // 209 B(Add), R(1), //
206 B(Return) // 210 B(Return) //
207 }, 211 },
208 0 212 0
209 }}; 213 }};
210 214
211 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); 215 for (size_t i = 0; i < arraysize(snippets); i++) {
212 for (size_t i = 0; i < num_snippets; i++) {
213 Handle<BytecodeArray> bytecode_array = 216 Handle<BytecodeArray> bytecode_array =
214 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); 217 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
215 CheckBytecodeArrayEqual(snippets[i], bytecode_array); 218 CheckBytecodeArrayEqual(snippets[i], bytecode_array);
216 } 219 }
217 } 220 }
218 221
219 222
220 TEST(Parameters) { 223 TEST(Parameters) {
221 InitializedHandleScope handle_scope; 224 InitializedHandleScope handle_scope;
222 BytecodeGeneratorHelper helper; 225 BytecodeGeneratorHelper helper;
223 226
224 ExpectedSnippet<int> snippets[] = { 227 ExpectedSnippet<int> snippets[] = {
225 {"function f() { return this; }", 228 {"function f() { return this; }",
226 0, 1, 3, {B(Ldar), R(helper.kLastParamIndex), B(Return)}, 0}, 229 0, 1, 3, {B(Ldar), R(helper.kLastParamIndex), B(Return)}, 0},
227 {"function f(arg1) { return arg1; }", 230 {"function f(arg1) { return arg1; }",
228 0, 2, 3, {B(Ldar), R(helper.kLastParamIndex), B(Return)}, 0}, 231 0, 2, 3, {B(Ldar), R(helper.kLastParamIndex), B(Return)}, 0},
229 {"function f(arg1) { return this; }", 232 {"function f(arg1) { return this; }",
230 0, 2, 3, {B(Ldar), R(helper.kLastParamIndex - 1), B(Return)}, 0}, 233 0, 2, 3, {B(Ldar), R(helper.kLastParamIndex - 1), B(Return)}, 0},
231 {"function f(arg1, arg2, arg3, arg4, arg5, arg6, arg7) { return arg4; }", 234 {"function f(arg1, arg2, arg3, arg4, arg5, arg6, arg7) { return arg4; }",
232 0, 8, 3, {B(Ldar), R(helper.kLastParamIndex - 3), B(Return)}, 0}, 235 0, 8, 3, {B(Ldar), R(helper.kLastParamIndex - 3), B(Return)}, 0},
233 {"function f(arg1, arg2, arg3, arg4, arg5, arg6, arg7) { return this; }", 236 {"function f(arg1, arg2, arg3, arg4, arg5, arg6, arg7) { return this; }",
234 0, 8, 3, {B(Ldar), R(helper.kLastParamIndex - 7), B(Return)}, 0} 237 0, 8, 3, {B(Ldar), R(helper.kLastParamIndex - 7), B(Return)}, 0}
235 }; 238 };
236 239
237 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); 240 for (size_t i = 0; i < arraysize(snippets); i++) {
238 for (size_t i = 0; i < num_snippets; i++) {
239 Handle<BytecodeArray> bytecode_array = 241 Handle<BytecodeArray> bytecode_array =
240 helper.MakeBytecodeForFunction(snippets[i].code_snippet); 242 helper.MakeBytecodeForFunction(snippets[i].code_snippet);
241 CheckBytecodeArrayEqual(snippets[i], bytecode_array); 243 CheckBytecodeArrayEqual(snippets[i], bytecode_array);
242 } 244 }
243 } 245 }
244 246
245 247
246 TEST(Constants) { 248 TEST(IntegerConstants) {
247 InitializedHandleScope handle_scope; 249 InitializedHandleScope handle_scope;
248 BytecodeGeneratorHelper helper; 250 BytecodeGeneratorHelper helper;
249 251
250 // Check large SMIs. 252 ExpectedSnippet<int> snippets[] = {
251 { 253 {"return 12345678;",
252 ExpectedSnippet<int> snippets[] = { 254 0,
253 {"return 12345678;", 0, 1, 3, 255 1,
254 { 256 3,
255 B(LdaConstant), U8(0), 257 {
256 B(Return) 258 B(LdaConstant), U8(0), //
257 }, 1, { 12345678 } 259 B(Return) //
258 }, 260 },
259 {"var a = 1234; return 5678;", 1 * kPointerSize, 1, 7, 261 1,
260 { 262 {12345678}},
261 B(LdaConstant), U8(0), 263 {"var a = 1234; return 5678;",
262 B(Star), R(0), 264 1 * kPointerSize,
263 B(LdaConstant), U8(1), 265 1,
264 B(Return) 266 7,
265 }, 2, { 1234, 5678 } 267 {
266 }, 268 B(LdaConstant), U8(0), //
267 {"var a = 1234; return 1234;", 269 B(Star), R(0), //
268 1 * kPointerSize, 1, 7, 270 B(LdaConstant), U8(1), //
269 { 271 B(Return) //
270 B(LdaConstant), U8(0), 272 },
271 B(Star), R(0), 273 2,
272 B(LdaConstant), U8(0), 274 {1234, 5678}},
273 B(Return) 275 {"var a = 1234; return 1234;",
274 }, 1, { 1234 } 276 1 * kPointerSize,
275 } 277 1,
276 }; 278 7,
279 {
280 B(LdaConstant), U8(0), //
281 B(Star), R(0), //
282 B(LdaConstant), U8(0), //
283 B(Return) //
284 },
285 1,
286 {1234}}};
277 287
278 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); 288 for (size_t i = 0; i < arraysize(snippets); i++) {
279 for (size_t i = 0; i < num_snippets; i++) { 289 Handle<BytecodeArray> bytecode_array =
280 Handle<BytecodeArray> bytecode_array = 290 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
281 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
282 CheckBytecodeArrayEqual(snippets[i], bytecode_array); 291 CheckBytecodeArrayEqual(snippets[i], bytecode_array);
283 }
284 }
285
286 // Check heap number double constants
287 {
288 ExpectedSnippet<double> snippets[] = {
289 {"return 1.2;",
290 0, 1, 3,
291 {
292 B(LdaConstant), U8(0),
293 B(Return)
294 }, 1, { 1.2 }
295 },
296 {"var a = 1.2; return 2.6;", 1 * kPointerSize, 1, 7,
297 {
298 B(LdaConstant), U8(0),
299 B(Star), R(0),
300 B(LdaConstant), U8(1),
301 B(Return)
302 }, 2, { 1.2, 2.6 }
303 },
304 {"var a = 3.14; return 3.14;", 1 * kPointerSize, 1, 7,
305 {
306 B(LdaConstant), U8(0),
307 B(Star), R(0),
308 B(LdaConstant), U8(1),
309 B(Return)
310 }, 2,
311 // TODO(rmcilroy): Currently multiple identical double literals end up
312 // being allocated as new HeapNumbers and so require multiple constant
313 // pool entries. De-dup identical values.
314 { 3.14, 3.14 }
315 }
316 };
317
318 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
319 for (size_t i = 0; i < num_snippets; i++) {
320 Handle<BytecodeArray> bytecode_array =
321 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
322 CheckBytecodeArrayEqual(snippets[i], bytecode_array);
323 }
324 }
325
326 // Check string literals
327 {
328 ExpectedSnippet<const char*> snippets[] = {
329 {"return \"This is a string\";", 0, 1, 3,
330 {
331 B(LdaConstant), U8(0),
332 B(Return)
333 }, 1,
334 { "This is a string" }
335 },
336 {"var a = \"First string\"; return \"Second string\";",
337 1 * kPointerSize, 1, 7,
338 {
339 B(LdaConstant), U8(0),
340 B(Star), R(0),
341 B(LdaConstant), U8(1),
342 B(Return)
343 }, 2, { "First string", "Second string"}
344 },
345 {"var a = \"Same string\"; return \"Same string\";",
346 1 * kPointerSize, 1, 7,
347 {
348 B(LdaConstant), U8(0),
349 B(Star), R(0),
350 B(LdaConstant), U8(0),
351 B(Return)
352 }, 1, { "Same string" }
353 }
354 };
355
356 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
357 for (size_t i = 0; i < num_snippets; i++) {
358 Handle<BytecodeArray> bytecode_array =
359 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
360 CheckBytecodeArrayEqual(snippets[i], bytecode_array);
361 }
362 } 292 }
363 } 293 }
364 294
295
296 TEST(HeapNumberConstants) {
297 InitializedHandleScope handle_scope;
298 BytecodeGeneratorHelper helper;
299
300 ExpectedSnippet<double> snippets[] = {
301 {"return 1.2;",
302 0,
303 1,
304 3,
305 {
306 B(LdaConstant), U8(0), //
307 B(Return) //
308 },
309 1,
310 {1.2}},
311 {"var a = 1.2; return 2.6;",
312 1 * kPointerSize,
313 1,
314 7,
315 {
316 B(LdaConstant), U8(0), //
317 B(Star), R(0), //
318 B(LdaConstant), U8(1), //
319 B(Return) //
320 },
321 2,
322 {1.2, 2.6}},
323 {"var a = 3.14; return 3.14;",
324 1 * kPointerSize,
325 1,
326 7,
327 {
328 B(LdaConstant), U8(0), //
329 B(Star), R(0), //
330 B(LdaConstant), U8(1), //
331 B(Return) //
332 },
333 2,
334 {3.14, 3.14}}};
335 for (size_t i = 0; i < arraysize(snippets); i++) {
336 Handle<BytecodeArray> bytecode_array =
337 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
338 CheckBytecodeArrayEqual(snippets[i], bytecode_array);
339 }
340 }
341
342
343 TEST(StringConstants) {
344 InitializedHandleScope handle_scope;
345 BytecodeGeneratorHelper helper;
346
347 ExpectedSnippet<const char*> snippets[] = {
348 {"return \"This is a string\";",
349 0,
350 1,
351 3,
352 {
353 B(LdaConstant), U8(0), //
354 B(Return) //
355 },
356 1,
357 {"This is a string"}},
358 {"var a = \"First string\"; return \"Second string\";",
359 1 * kPointerSize,
360 1,
361 7,
362 {
363 B(LdaConstant), U8(0), //
364 B(Star), R(0), //
365 B(LdaConstant), U8(1), //
366 B(Return) //
367 },
368 2,
369 {"First string", "Second string"}},
370 {"var a = \"Same string\"; return \"Same string\";",
371 1 * kPointerSize,
372 1,
373 7,
374 {
375 B(LdaConstant), U8(0), //
376 B(Star), R(0), //
377 B(LdaConstant), U8(0), //
378 B(Return) //
379 },
380 1,
381 {"Same string"}}};
382
383 for (size_t i = 0; i < arraysize(snippets); i++) {
384 Handle<BytecodeArray> bytecode_array =
385 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
386 CheckBytecodeArrayEqual(snippets[i], bytecode_array);
387 }
388 }
389
365 390
366 TEST(PropertyLoads) { 391 TEST(PropertyLoads) {
367 InitializedHandleScope handle_scope; 392 InitializedHandleScope handle_scope;
368 BytecodeGeneratorHelper helper; 393 BytecodeGeneratorHelper helper;
369 394
370 Code::Kind ic_kinds[] = { i::Code::LOAD_IC, i::Code::LOAD_IC }; 395 Code::Kind ic_kinds[] = { i::Code::LOAD_IC, i::Code::LOAD_IC };
371 FeedbackVectorSpec feedback_spec(0, 2, ic_kinds); 396 FeedbackVectorSpec feedback_spec(0, 2, ic_kinds);
372 Handle<i::TypeFeedbackVector> vector = 397 Handle<i::TypeFeedbackVector> vector =
373 helper.factory()->NewTypeFeedbackVector(&feedback_spec); 398 helper.factory()->NewTypeFeedbackVector(&feedback_spec);
374 399
375 ExpectedSnippet<const char*> snippets[] = { 400 ExpectedSnippet<const char*> snippets[] = {
376 {"function f(a) { return a.name; }\nf({name : \"test\"})", 401 {"function f(a) { return a.name; }\nf({name : \"test\"})",
377 1 * kPointerSize, 2, 10, 402 1 * kPointerSize,
403 2,
404 10,
378 { 405 {
379 B(Ldar), R(helper.kLastParamIndex), 406 B(Ldar), R(helper.kLastParamIndex), //
380 B(Star), R(0), 407 B(Star), R(0), //
381 B(LdaConstant), U8(0), 408 B(LdaConstant), U8(0), //
382 B(LoadIC), R(0), U8(vector->first_ic_slot_index()), 409 B(LoadIC), R(0), U8(vector->first_ic_slot_index()), //
383 B(Return) 410 B(Return) //
384 }, 411 },
385 1, { "name" } 412 1,
386 }, 413 {"name"}},
387 {"function f(a) { return a[\"key\"]; }\nf({key : \"test\"})", 414 {"function f(a) { return a[\"key\"]; }\nf({key : \"test\"})",
388 1 * kPointerSize, 2, 10, 415 1 * kPointerSize,
416 2,
417 10,
389 { 418 {
390 B(Ldar), R(helper.kLastParamIndex), 419 B(Ldar), R(helper.kLastParamIndex), //
391 B(Star), R(0), 420 B(Star), R(0), //
392 B(LdaConstant), U8(0), 421 B(LdaConstant), U8(0), //
393 B(LoadIC), R(0), U8(vector->first_ic_slot_index()), 422 B(LoadIC), R(0), U8(vector->first_ic_slot_index()), //
394 B(Return) 423 B(Return) //
395 }, 424 },
396 1, { "key" } 425 1,
397 }, 426 {"key"}},
398 {"function f(a) { return a[100]; }\nf({100 : \"test\"})", 427 {"function f(a) { return a[100]; }\nf({100 : \"test\"})",
399 1 * kPointerSize, 2, 10, 428 1 * kPointerSize,
429 2,
430 10,
400 { 431 {
401 B(Ldar), R(helper.kLastParamIndex), 432 B(Ldar), R(helper.kLastParamIndex), //
402 B(Star), R(0), 433 B(Star), R(0), //
403 B(LdaSmi8), U8(100), 434 B(LdaSmi8), U8(100), //
404 B(KeyedLoadIC), R(0), U8(vector->first_ic_slot_index()), 435 B(KeyedLoadIC), R(0), U8(vector->first_ic_slot_index()), //
405 B(Return) 436 B(Return) //
406 }, 0 437 },
407 }, 438 0},
408 {"function f(a, b) { return a[b]; }\nf({arg : \"test\"}, \"arg\")", 439 {"function f(a, b) { return a[b]; }\nf({arg : \"test\"}, \"arg\")",
409 1 * kPointerSize, 3, 10, 440 1 * kPointerSize,
441 3,
442 10,
410 { 443 {
411 B(Ldar), R(helper.kLastParamIndex - 1), 444 B(Ldar), R(helper.kLastParamIndex - 1), //
412 B(Star), R(0), 445 B(Star), R(0), //
413 B(Ldar), R(helper.kLastParamIndex), 446 B(Ldar), R(helper.kLastParamIndex), //
414 B(KeyedLoadIC), R(0), U8(vector->first_ic_slot_index()), 447 B(KeyedLoadIC), R(0), U8(vector->first_ic_slot_index()), //
415 B(Return) 448 B(Return) //
416 }, 0 449 },
417 }, 450 0},
418 {"function f(a) { var b = a.name; return a[-124]; }\n" 451 {"function f(a) { var b = a.name; return a[-124]; }\n"
419 "f({\"-124\" : \"test\", name : 123 })", 452 "f({\"-124\" : \"test\", name : 123 })",
420 2 * kPointerSize, 2, 21, 453 2 * kPointerSize,
454 2,
455 21,
421 { 456 {
422 B(Ldar), R(helper.kLastParamIndex), 457 B(Ldar), R(helper.kLastParamIndex), //
423 B(Star), R(1), 458 B(Star), R(1), //
424 B(LdaConstant), U8(0), 459 B(LdaConstant), U8(0), //
425 B(LoadIC), R(1), U8(vector->first_ic_slot_index()), 460 B(LoadIC), R(1), U8(vector->first_ic_slot_index()), //
426 B(Star), R(0), 461 B(Star), R(0), //
427 B(Ldar), R(helper.kLastParamIndex), 462 B(Ldar), R(helper.kLastParamIndex), //
428 B(Star), R(1), 463 B(Star), R(1), //
429 B(LdaSmi8), U8(-124), 464 B(LdaSmi8), U8(-124), //
430 B(KeyedLoadIC), R(1), U8(vector->first_ic_slot_index() + 2), 465 B(KeyedLoadIC), R(1), U8(vector->first_ic_slot_index() + 2), //
431 B(Return) 466 B(Return) //
432 }, 467 },
433 1, { "name" } 468 1,
434 } 469 {"name"}}};
435 }; 470 for (size_t i = 0; i < arraysize(snippets); i++) {
436 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
437 for (size_t i = 0; i < num_snippets; i++) {
438 Handle<BytecodeArray> bytecode_array = 471 Handle<BytecodeArray> bytecode_array =
439 helper.MakeBytecode(snippets[i].code_snippet, "f"); 472 helper.MakeBytecode(snippets[i].code_snippet, "f");
440 CheckBytecodeArrayEqual(snippets[i], bytecode_array); 473 CheckBytecodeArrayEqual(snippets[i], bytecode_array);
441 } 474 }
442 } 475 }
443 476
444 477
445 TEST(PropertyStores) { 478 TEST(PropertyStores) {
446 InitializedHandleScope handle_scope; 479 InitializedHandleScope handle_scope;
447 BytecodeGeneratorHelper helper; 480 BytecodeGeneratorHelper helper;
448 481
449 Code::Kind ic_kinds[] = { i::Code::STORE_IC, i::Code::STORE_IC }; 482 Code::Kind ic_kinds[] = { i::Code::STORE_IC, i::Code::STORE_IC };
450 FeedbackVectorSpec feedback_spec(0, 2, ic_kinds); 483 FeedbackVectorSpec feedback_spec(0, 2, ic_kinds);
451 Handle<i::TypeFeedbackVector> vector = 484 Handle<i::TypeFeedbackVector> vector =
452 helper.factory()->NewTypeFeedbackVector(&feedback_spec); 485 helper.factory()->NewTypeFeedbackVector(&feedback_spec);
453 486
454 ExpectedSnippet<const char*> snippets[] = { 487 ExpectedSnippet<const char*> snippets[] = {
455 {"function f(a) { a.name = \"val\"; }\nf({name : \"test\"})", 488 {"function f(a) { a.name = \"val\"; }\nf({name : \"test\"})",
456 2 * kPointerSize, 2, 16, 489 2 * kPointerSize,
490 2,
491 16,
457 { 492 {
458 B(Ldar), R(helper.kLastParamIndex), 493 B(Ldar), R(helper.kLastParamIndex), //
459 B(Star), R(0), 494 B(Star), R(0), //
460 B(LdaConstant), U8(0), 495 B(LdaConstant), U8(0), //
461 B(Star), R(1), 496 B(Star), R(1), //
462 B(LdaConstant), U8(1), 497 B(LdaConstant), U8(1), //
463 B(StoreIC), R(0), R(1), U8(vector->first_ic_slot_index()), 498 B(StoreIC), R(0), R(1), U8(vector->first_ic_slot_index()), //
464 B(LdaUndefined), 499 B(LdaUndefined), //
465 B(Return) 500 B(Return) //
466 }, 501 },
467 2, { "name", "val" } 502 2,
468 }, 503 {"name", "val"}},
469 {"function f(a) { a[\"key\"] = \"val\"; }\nf({key : \"test\"})", 504 {"function f(a) { a[\"key\"] = \"val\"; }\nf({key : \"test\"})",
470 2 * kPointerSize, 2, 16, 505 2 * kPointerSize,
506 2,
507 16,
471 { 508 {
472 B(Ldar), R(helper.kLastParamIndex), 509 B(Ldar), R(helper.kLastParamIndex), //
473 B(Star), R(0), 510 B(Star), R(0), //
474 B(LdaConstant), U8(0), 511 B(LdaConstant), U8(0), //
475 B(Star), R(1), 512 B(Star), R(1), //
476 B(LdaConstant), U8(1), 513 B(LdaConstant), U8(1), //
477 B(StoreIC), R(0), R(1), U8(vector->first_ic_slot_index()), 514 B(StoreIC), R(0), R(1), U8(vector->first_ic_slot_index()), //
478 B(LdaUndefined), 515 B(LdaUndefined), //
479 B(Return) 516 B(Return) //
480 }, 517 },
481 2, { "key", "val" } 518 2,
482 }, 519 {"key", "val"}},
483 {"function f(a) { a[100] = \"val\"; }\nf({100 : \"test\"})", 520 {"function f(a) { a[100] = \"val\"; }\nf({100 : \"test\"})",
484 2 * kPointerSize, 2, 16, 521 2 * kPointerSize,
522 2,
523 16,
485 { 524 {
486 B(Ldar), R(helper.kLastParamIndex), 525 B(Ldar), R(helper.kLastParamIndex), //
487 B(Star), R(0), 526 B(Star), R(0), //
488 B(LdaSmi8), U8(100), 527 B(LdaSmi8), U8(100), //
489 B(Star), R(1), 528 B(Star), R(1), //
490 B(LdaConstant), U8(0), 529 B(LdaConstant), U8(0), //
491 B(KeyedStoreIC), R(0), R(1), U8(vector->first_ic_slot_index()), 530 B(KeyedStoreIC), R(0), R(1), U8(vector->first_ic_slot_index()), //
492 B(LdaUndefined), 531 B(LdaUndefined), //
493 B(Return) 532 B(Return) //
494 }, 533 },
495 1, { "val" } 534 1,
496 }, 535 {"val"}},
497 {"function f(a, b) { a[b] = \"val\"; }\nf({arg : \"test\"}, \"arg\")", 536 {"function f(a, b) { a[b] = \"val\"; }\nf({arg : \"test\"}, \"arg\")",
498 2 * kPointerSize, 3, 16, 537 2 * kPointerSize,
538 3,
539 16,
499 { 540 {
500 B(Ldar), R(helper.kLastParamIndex - 1), 541 B(Ldar), R(helper.kLastParamIndex - 1), //
501 B(Star), R(0), 542 B(Star), R(0), //
502 B(Ldar), R(helper.kLastParamIndex), 543 B(Ldar), R(helper.kLastParamIndex), //
503 B(Star), R(1), 544 B(Star), R(1), //
504 B(LdaConstant), U8(0), 545 B(LdaConstant), U8(0), //
505 B(KeyedStoreIC), R(0), R(1), U8(vector->first_ic_slot_index()), 546 B(KeyedStoreIC), R(0), R(1), U8(vector->first_ic_slot_index()), //
506 B(LdaUndefined), 547 B(LdaUndefined), //
507 B(Return) 548 B(Return) //
508 }, 549 },
509 1, { "val" } 550 1,
510 }, 551 {"val"}},
511 {"function f(a) { a.name = a[-124]; }\n" 552 {"function f(a) { a.name = a[-124]; }\n"
512 "f({\"-124\" : \"test\", name : 123 })", 553 "f({\"-124\" : \"test\", name : 123 })",
513 3 * kPointerSize, 2, 23, 554 3 * kPointerSize,
555 2,
556 23,
514 { 557 {
515 B(Ldar), R(helper.kLastParamIndex), 558 B(Ldar), R(helper.kLastParamIndex), //
516 B(Star), R(0), 559 B(Star), R(0), //
517 B(LdaConstant), U8(0), 560 B(LdaConstant), U8(0), //
518 B(Star), R(1), 561 B(Star), R(1), //
519 B(Ldar), R(helper.kLastParamIndex), 562 B(Ldar), R(helper.kLastParamIndex), //
520 B(Star), R(2), 563 B(Star), R(2), //
521 B(LdaSmi8), U8(-124), 564 B(LdaSmi8), U8(-124), //
522 B(KeyedLoadIC), R(2), U8(vector->first_ic_slot_index()), 565 B(KeyedLoadIC), R(2), U8(vector->first_ic_slot_index()), //
523 B(StoreIC), R(0), R(1), U8(vector->first_ic_slot_index() + 2), 566 B(StoreIC), R(0), R(1), U8(vector->first_ic_slot_index() + 2), //
524 B(LdaUndefined), 567 B(LdaUndefined), //
525 B(Return) 568 B(Return) //
526 }, 569 },
527 1, { "name" } 570 1,
528 } 571 {"name"}}};
529 }; 572 for (size_t i = 0; i < arraysize(snippets); i++) {
530 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
531 for (size_t i = 0; i < num_snippets; i++) {
532 Handle<BytecodeArray> bytecode_array = 573 Handle<BytecodeArray> bytecode_array =
533 helper.MakeBytecode(snippets[i].code_snippet, "f"); 574 helper.MakeBytecode(snippets[i].code_snippet, "f");
534 CheckBytecodeArrayEqual(snippets[i], bytecode_array); 575 CheckBytecodeArrayEqual(snippets[i], bytecode_array);
535 } 576 }
536 } 577 }
537 578
538 579
539 #define FUNC_ARG "new (function Obj() { this.func = function() { return; }})()" 580 #define FUNC_ARG "new (function Obj() { this.func = function() { return; }})()"
540 581
541 582
542 TEST(PropertyCall) { 583 TEST(PropertyCall) {
543 InitializedHandleScope handle_scope; 584 InitializedHandleScope handle_scope;
544 BytecodeGeneratorHelper helper; 585 BytecodeGeneratorHelper helper; //
545 586
546 Code::Kind ic_kinds[] = { i::Code::LOAD_IC, i::Code::LOAD_IC }; 587 Code::Kind ic_kinds[] = { i::Code::LOAD_IC, i::Code::LOAD_IC };
547 FeedbackVectorSpec feedback_spec(0, 2, ic_kinds); 588 FeedbackVectorSpec feedback_spec(0, 2, ic_kinds);
548 Handle<i::TypeFeedbackVector> vector = 589 Handle<i::TypeFeedbackVector> vector =
549 helper.factory()->NewTypeFeedbackVector(&feedback_spec); 590 helper.factory()->NewTypeFeedbackVector(&feedback_spec);
550 591
551 ExpectedSnippet<const char*> snippets[] = { 592 ExpectedSnippet<const char*> snippets[] = {
552 {"function f(a) { return a.func(); }\nf(" FUNC_ARG ")", 593 {"function f(a) { return a.func(); }\nf(" FUNC_ARG ")",
553 2 * kPointerSize, 2, 16, 594 2 * kPointerSize,
595 2,
596 16,
554 { 597 {
555 B(Ldar), R(helper.kLastParamIndex), 598 B(Ldar), R(helper.kLastParamIndex), //
556 B(Star), R(1), 599 B(Star), R(1), //
557 B(LdaConstant), U8(0), 600 B(LdaConstant), U8(0), //
558 B(LoadIC), R(1), U8(vector->first_ic_slot_index() + 2), 601 B(LoadIC), R(1), U8(vector->first_ic_slot_index() + 2), //
559 B(Star), R(0), 602 B(Star), R(0), //
560 B(Call), R(0), R(1), U8(0), 603 B(Call), R(0), R(1), U8(0), //
561 B(Return) 604 B(Return) //
562 }, 605 },
563 1, { "func" } 606 1,
564 }, 607 {"func"}},
565 {"function f(a, b, c) { return a.func(b, c); }\nf(" FUNC_ARG ", 1, 2)", 608 {"function f(a, b, c) { return a.func(b, c); }\nf(" FUNC_ARG ", 1, 2)",
566 4 * kPointerSize, 4, 24, 609 4 * kPointerSize,
610 4,
611 24,
567 { 612 {
568 B(Ldar), R(helper.kLastParamIndex - 2), 613 B(Ldar), R(helper.kLastParamIndex - 2), //
569 B(Star), R(1), 614 B(Star), R(1), //
570 B(LdaConstant), U8(0), 615 B(LdaConstant), U8(0), //
571 B(LoadIC), R(1), U8(vector->first_ic_slot_index() + 2), 616 B(LoadIC), R(1), U8(vector->first_ic_slot_index() + 2), //
572 B(Star), R(0), 617 B(Star), R(0), //
573 B(Ldar), R(helper.kLastParamIndex - 1), 618 B(Ldar), R(helper.kLastParamIndex - 1), //
574 B(Star), R(2), 619 B(Star), R(2), //
575 B(Ldar), R(helper.kLastParamIndex), 620 B(Ldar), R(helper.kLastParamIndex), //
576 B(Star), R(3), 621 B(Star), R(3), //
577 B(Call), R(0), R(1), U8(2), 622 B(Call), R(0), R(1), U8(2), //
578 B(Return) 623 B(Return) //
579 }, 624 },
580 1, { "func" } 625 1,
581 }, 626 {"func"}},
582 {"function f(a, b) { return a.func(b + b, b); }\nf(" FUNC_ARG ", 1)", 627 {"function f(a, b) { return a.func(b + b, b); }\nf(" FUNC_ARG ", 1)",
583 4 * kPointerSize, 3, 30, 628 4 * kPointerSize,
584 { 629 3,
585 B(Ldar), R(helper.kLastParamIndex - 1), 630 30,
586 B(Star), R(1), 631 {
587 B(LdaConstant), U8(0), 632 B(Ldar), R(helper.kLastParamIndex - 1), //
588 B(LoadIC), R(1), U8(vector->first_ic_slot_index() + 2), 633 B(Star), R(1), //
589 B(Star), R(0), 634 B(LdaConstant), U8(0), //
590 B(Ldar), R(helper.kLastParamIndex), 635 B(LoadIC), R(1), U8(vector->first_ic_slot_index() + 2), //
591 B(Star), R(2), 636 B(Star), R(0), //
592 B(Ldar), R(helper.kLastParamIndex), 637 B(Ldar), R(helper.kLastParamIndex), //
593 B(Add), R(2), 638 B(Star), R(2), //
594 B(Star), R(2), 639 B(Ldar), R(helper.kLastParamIndex), //
595 B(Ldar), R(helper.kLastParamIndex), 640 B(Add), R(2), //
596 B(Star), R(3), 641 B(Star), R(2), //
597 B(Call), R(0), R(1), U8(2), 642 B(Ldar), R(helper.kLastParamIndex), //
598 B(Return) 643 B(Star), R(3), //
644 B(Call), R(0), R(1), U8(2), //
645 B(Return) //
599 }, 646 },
600 1, { "func" } 647 1,
601 } 648 {"func"}}};
602 }; 649 for (size_t i = 0; i < arraysize(snippets); i++) {
603 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
604 for (size_t i = 0; i < num_snippets; i++) {
605 Handle<BytecodeArray> bytecode_array = 650 Handle<BytecodeArray> bytecode_array =
606 helper.MakeBytecode(snippets[i].code_snippet, "f"); 651 helper.MakeBytecode(snippets[i].code_snippet, "f");
607 CheckBytecodeArrayEqual(snippets[i], bytecode_array); 652 CheckBytecodeArrayEqual(snippets[i], bytecode_array);
608 } 653 }
609 } 654 }
610 655
611 656
612 TEST(LoadGlobal) { 657 TEST(LoadGlobal) {
613 InitializedHandleScope handle_scope; 658 InitializedHandleScope handle_scope;
614 BytecodeGeneratorHelper helper; 659 BytecodeGeneratorHelper helper;
615 660
616 ExpectedSnippet<const char*> snippets[] = { 661 ExpectedSnippet<const char*> snippets[] = {
617 {"var a = 1;\nfunction f() { return a; }\nf()", 662 {"var a = 1;\nfunction f() { return a; }\nf()",
618 0, 1, 3, 663 0, 1, 3,
619 { 664 {
620 B(LdaGlobal), _, 665 B(LdaGlobal), _,
621 B(Return) 666 B(Return)
622 }, 667 },
623 }, 668 },
624 {"function t() { }\nfunction f() { return t; }\nf()", 669 {"function t() { }\nfunction f() { return t; }\nf()",
625 0, 1, 3, 670 0, 1, 3,
626 { 671 {
627 B(LdaGlobal), _, 672 B(LdaGlobal), _,
628 B(Return) 673 B(Return)
629 }, 674 },
630 }, 675 },
631 }; 676 };
632 677
633 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); 678 for (size_t i = 0; i < arraysize(snippets); i++) {
634 for (size_t i = 0; i < num_snippets; i++) {
635 Handle<BytecodeArray> bytecode_array = 679 Handle<BytecodeArray> bytecode_array =
636 helper.MakeBytecode(snippets[i].code_snippet, "f"); 680 helper.MakeBytecode(snippets[i].code_snippet, "f");
637 bytecode_array->Print(); 681 bytecode_array->Print();
638 CheckBytecodeArrayEqual(snippets[i], bytecode_array, true); 682 CheckBytecodeArrayEqual(snippets[i], bytecode_array, true);
639 } 683 }
640 } 684 }
641 685
642 686
643 TEST(CallGlobal) { 687 TEST(CallGlobal) {
644 InitializedHandleScope handle_scope; 688 InitializedHandleScope handle_scope;
(...skipping 23 matching lines...) Expand all
668 B(LdaSmi8), U8(2), 712 B(LdaSmi8), U8(2),
669 B(Star), R(3), 713 B(Star), R(3),
670 B(LdaSmi8), U8(3), 714 B(LdaSmi8), U8(3),
671 B(Star), R(4), 715 B(Star), R(4),
672 B(Call), R(0), R(1), U8(3), 716 B(Call), R(0), R(1), U8(3),
673 B(Return) 717 B(Return)
674 }, 718 },
675 }, 719 },
676 }; 720 };
677 721
678 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); 722 for (size_t i = 0; i < arraysize(snippets); i++) {
679 for (size_t i = 0; i < num_snippets; i++) {
680 Handle<BytecodeArray> bytecode_array = 723 Handle<BytecodeArray> bytecode_array =
681 helper.MakeBytecode(snippets[i].code_snippet, "f"); 724 helper.MakeBytecode(snippets[i].code_snippet, "f");
682 CheckBytecodeArrayEqual(snippets[i], bytecode_array, true); 725 CheckBytecodeArrayEqual(snippets[i], bytecode_array, true);
683 } 726 }
684 } 727 }
685 728
729
730 TEST(IfConditions) {
731 InitializedHandleScope handle_scope;
732 BytecodeGeneratorHelper helper;
733
734 Handle<Object> unused = helper.factory()->undefined_value();
735
736 ExpectedSnippet<Handle<Object>> snippets[] = {
737 {"function f() { if (0) { return 1; } else { return -1; } }",
738 0,
739 1,
740 14,
741 {B(LdaZero), //
742 B(ToBoolean), //
743 B(JumpIfFalse), U8(7), //
744 B(LdaSmi8), U8(1), //
745 B(Return), //
746 B(Jump), U8(5), // TODO(oth): Unreachable jump after return
747 B(LdaSmi8), U8(-1), //
748 B(Return), //
749 B(LdaUndefined), //
750 B(Return)}, //
751 0,
752 {unused, unused, unused, unused}},
753 {"function f() { if ('lucky') { return 1; } else { return -1; } }",
754 0,
755 1,
756 15,
757 {B(LdaConstant), U8(0), //
758 B(ToBoolean), //
759 B(JumpIfFalse), U8(7), //
760 B(LdaSmi8), U8(1), //
761 B(Return), //
762 B(Jump), U8(5), // TODO(oth): Unreachable jump after return
763 B(LdaSmi8), U8(-1), //
764 B(Return), //
765 B(LdaUndefined), //
766 B(Return)}, //
767 1,
768 {helper.factory()->NewStringFromStaticChars("lucky"), unused,
769 unused, unused}},
770 {"function f() { if (false) { return 1; } else { return -1; } }",
771 0,
772 1,
773 13,
774 {B(LdaFalse), //
775 B(JumpIfFalse), U8(7), //
776 B(LdaSmi8), U8(1), //
777 B(Return), //
778 B(Jump), U8(5), // TODO(oth): Unreachable jump after return
779 B(LdaSmi8), U8(-1), //
780 B(Return), //
781 B(LdaUndefined), //
782 B(Return)}, //
783 0,
784 {unused, unused, unused, unused}},
785 {"function f(a) { if (a <= 0) { return 200; } else { return -200; } }",
786 kPointerSize,
787 2,
788 19,
789 {B(Ldar), R(-5), //
790 B(Star), R(0), //
791 B(LdaZero), //
792 B(TestLessThanEqual), R(0), //
793 B(JumpIfFalse), U8(7), //
794 B(LdaConstant), U8(0), //
795 B(Return), //
796 B(Jump), U8(5), // TODO(oth): Unreachable jump after return
797 B(LdaConstant), U8(1), //
798 B(Return), //
799 B(LdaUndefined), //
800 B(Return)}, //
801 2,
802 {helper.factory()->NewNumberFromInt(200),
803 helper.factory()->NewNumberFromInt(-200), unused, unused}},
804 {"function f(a, b) { if (a in b) { return 200; } }",
805 kPointerSize,
806 3,
807 17,
808 {B(Ldar), R(-6), //
809 B(Star), R(0), //
810 B(Ldar), R(-5), //
811 B(TestIn), R(0), //
812 B(JumpIfFalse), U8(7), //
813 B(LdaConstant), U8(0), //
814 B(Return), //
815 B(Jump), U8(2), // TODO(oth): Unreachable jump after return
816 B(LdaUndefined), //
817 B(Return)}, //
818 1,
819 {helper.factory()->NewNumberFromInt(200), unused, unused, unused}},
820 {"function f(a, b) { if (a instanceof b) { return 200; } }",
821 kPointerSize,
822 3,
823 17,
824 {B(Ldar), R(-6), //
825 B(Star), R(0), //
826 B(Ldar), R(-5), //
827 B(TestInstanceOf), R(0), //
828 B(JumpIfFalse), U8(7), //
829 B(LdaConstant), U8(0), //
830 B(Return), //
831 B(Jump), U8(2), // TODO(oth): Unreachable jump after return
832 B(LdaUndefined), //
833 B(Return)}, //
834 1,
835 {helper.factory()->NewNumberFromInt(200), unused, unused, unused}},
836 {"function f(z) { var a = 0; var b = 0; if (a === 0.01) { "
837 #define X "b = a; a = b; "
838 X X X X X X X X X X X X X X X X X X X X X X X X
839 #undef X
840 " return 200; } else { return -200; } }",
841 3 * kPointerSize,
842 2,
843 218,
844 {B(LdaZero), //
845 B(Star), R(0), //
846 B(LdaZero), //
847 B(Star), R(1), //
848 B(Ldar), R(0), //
849 B(Star), R(2), //
850 B(LdaConstant), U8(0), //
851 B(TestEqualStrict), R(2), //
852 B(JumpIfFalseConstant), U8(2), //
853 #define X B(Ldar), R(0), B(Star), R(1), B(Ldar), R(1), B(Star), R(0),
854 X X X X X X X X X X X X X X X X X X X X X X X X
855 #undef X
856 B(LdaConstant),
857 U8(1), //
858 B(Return), //
859 B(Jump), U8(5), // TODO(oth): Unreachable jump after return
860 B(LdaConstant), U8(3), //
861 B(Return), //
862 B(LdaUndefined), //
863 B(Return)}, //
864 4,
865 {helper.factory()->NewHeapNumber(0.01),
866 helper.factory()->NewNumberFromInt(200),
867 helper.factory()->NewNumberFromInt(199),
868 helper.factory()->NewNumberFromInt(-200)}}};
869
870 for (size_t i = 0; i < arraysize(snippets); i++) {
871 Handle<BytecodeArray> bytecode_array =
872 helper.MakeBytecodeForFunction(snippets[i].code_snippet);
873 CheckBytecodeArrayEqual(snippets[i], bytecode_array);
874 }
875 }
876
877
686 } // namespace interpreter 878 } // namespace interpreter
687 } // namespace internal 879 } // namespace internal
688 } // namespance v8 880 } // namespance v8
OLDNEW
« no previous file with comments | « src/interpreter/interpreter.cc ('k') | test/cctest/interpreter/test-interpreter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698