| 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 |