OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |