Chromium Code Reviews| 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" |
| 11 #include "test/cctest/cctest.h" | 11 #include "test/cctest/cctest.h" |
| 12 #include "test/cctest/test-feedback-vector.h" | 12 #include "test/cctest/test-feedback-vector.h" |
| 13 | 13 |
| 14 namespace v8 { | 14 namespace v8 { |
| 15 namespace internal { | 15 namespace internal { |
| 16 namespace interpreter { | 16 namespace interpreter { |
| 17 | 17 |
| 18 static const InstanceType kInstanceTypeDontCare = static_cast<InstanceType>(-1); | |
| 19 | |
| 18 class BytecodeGeneratorHelper { | 20 class BytecodeGeneratorHelper { |
| 19 public: | 21 public: |
| 20 const char* kFunctionName = "f"; | 22 const char* kFunctionName = "f"; |
| 21 | 23 |
| 22 static const int kLastParamIndex = | 24 static const int kLastParamIndex = |
| 23 -InterpreterFrameConstants::kLastParamFromRegisterPointer / kPointerSize; | 25 -InterpreterFrameConstants::kLastParamFromRegisterPointer / kPointerSize; |
| 24 | 26 |
| 25 BytecodeGeneratorHelper() { | 27 BytecodeGeneratorHelper() { |
| 26 i::FLAG_ignition = true; | 28 i::FLAG_ignition = true; |
| 27 i::FLAG_ignition_filter = StrDup(kFunctionName); | 29 i::FLAG_ignition_filter = StrDup(kFunctionName); |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 184 CHECK(String::cast(actual)->Equals(*expected_string)); | 186 CHECK(String::cast(actual)->Equals(*expected_string)); |
| 185 } | 187 } |
| 186 | 188 |
| 187 | 189 |
| 188 static void CheckConstant(Handle<Object> expected, Object* actual) { | 190 static void CheckConstant(Handle<Object> expected, Object* actual) { |
| 189 CHECK(actual == *expected || expected->StrictEquals(actual)); | 191 CHECK(actual == *expected || expected->StrictEquals(actual)); |
| 190 } | 192 } |
| 191 | 193 |
| 192 | 194 |
| 193 static void CheckConstant(InstanceType expected, Object* actual) { | 195 static void CheckConstant(InstanceType expected, Object* actual) { |
| 194 CHECK_EQ(expected, HeapObject::cast(actual)->map()->instance_type()); | 196 if (expected != kInstanceTypeDontCare) { |
| 197 CHECK_EQ(expected, HeapObject::cast(actual)->map()->instance_type()); | |
| 198 } | |
| 195 } | 199 } |
| 196 | 200 |
| 197 | 201 |
| 198 template <typename T, int C> | 202 template <typename T, int C> |
| 199 static void CheckBytecodeArrayEqual(const ExpectedSnippet<T, C>& expected, | 203 static void CheckBytecodeArrayEqual(const ExpectedSnippet<T, C>& expected, |
| 200 Handle<BytecodeArray> actual) { | 204 Handle<BytecodeArray> actual) { |
| 201 CHECK_EQ(expected.frame_size, actual->frame_size()); | 205 CHECK_EQ(expected.frame_size, actual->frame_size()); |
| 202 CHECK_EQ(expected.parameter_count, actual->parameter_count()); | 206 CHECK_EQ(expected.parameter_count, actual->parameter_count()); |
| 203 CHECK_EQ(expected.bytecode_length, actual->length()); | 207 CHECK_EQ(expected.bytecode_length, actual->length()); |
| 204 if (expected.constant_count == 0) { | 208 if (expected.constant_count == 0) { |
| (...skipping 8077 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8282 // clang-format on | 8286 // clang-format on |
| 8283 | 8287 |
| 8284 for (size_t i = 0; i < arraysize(snippets); i++) { | 8288 for (size_t i = 0; i < arraysize(snippets); i++) { |
| 8285 Handle<BytecodeArray> bytecode_array = | 8289 Handle<BytecodeArray> bytecode_array = |
| 8286 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | 8290 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); |
| 8287 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | 8291 CheckBytecodeArrayEqual(snippets[i], bytecode_array); |
| 8288 } | 8292 } |
| 8289 FLAG_harmony_do_expressions = old_flag; | 8293 FLAG_harmony_do_expressions = old_flag; |
| 8290 } | 8294 } |
| 8291 | 8295 |
| 8296 | |
| 8292 TEST(WithStatement) { | 8297 TEST(WithStatement) { |
| 8293 InitializedHandleScope handle_scope; | 8298 InitializedHandleScope handle_scope; |
| 8294 BytecodeGeneratorHelper helper; | 8299 BytecodeGeneratorHelper helper; |
| 8295 | 8300 |
| 8296 int deep_elements_flags = | 8301 int deep_elements_flags = |
| 8297 ObjectLiteral::kFastElements | ObjectLiteral::kDisableMementos; | 8302 ObjectLiteral::kFastElements | ObjectLiteral::kDisableMementos; |
| 8298 int context = Register::current_context().index(); | 8303 int context = Register::current_context().index(); |
| 8299 int closure = Register::function_closure().index(); | 8304 int closure = Register::function_closure().index(); |
| 8300 int new_target = Register::new_target().index(); | 8305 int new_target = Register::new_target().index(); |
| 8301 | 8306 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8334 }; | 8339 }; |
| 8335 // clang-format on | 8340 // clang-format on |
| 8336 | 8341 |
| 8337 for (size_t i = 0; i < arraysize(snippets); i++) { | 8342 for (size_t i = 0; i < arraysize(snippets); i++) { |
| 8338 Handle<BytecodeArray> bytecode_array = | 8343 Handle<BytecodeArray> bytecode_array = |
| 8339 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | 8344 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); |
| 8340 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | 8345 CheckBytecodeArrayEqual(snippets[i], bytecode_array); |
| 8341 } | 8346 } |
| 8342 } | 8347 } |
| 8343 | 8348 |
| 8349 | |
| 8350 TEST(ClassDeclarations) { | |
| 8351 InitializedHandleScope handle_scope; | |
| 8352 BytecodeGeneratorHelper helper; | |
| 8353 | |
| 8354 int closure = Register::function_closure().index(); | |
| 8355 int context = Register::current_context().index(); | |
| 8356 | |
|
rmcilroy
2016/02/04 14:56:41
nit - add // clang-format off / on around the snip
oth
2016/02/04 16:59:48
Done.
| |
| 8357 ExpectedSnippet<InstanceType, 12> snippets[] = { | |
| 8358 {"class Person {\n" | |
| 8359 " constructor(name) { this.name = name; }\n" | |
| 8360 " speak() { console.log(this.name + ' is speaking.'); }\n" | |
| 8361 "}\n", | |
| 8362 8 * kPointerSize, | |
| 8363 1, | |
| 8364 60, | |
| 8365 { | |
| 8366 B(LdaTheHole), // | |
| 8367 B(Star), R(1), // | |
| 8368 B(LdaTheHole), // | |
| 8369 B(Star), R(0), // | |
| 8370 B(LdaTheHole), // | |
| 8371 B(Star), R(2), // | |
| 8372 B(CreateClosure), U8(0), U8(0), // | |
| 8373 B(Star), R(3), // | |
| 8374 B(LdaSmi8), U8(15), // | |
| 8375 B(Star), R(4), // | |
| 8376 B(LdaConstant), U8(1), // | |
| 8377 B(Star), R(5), // | |
| 8378 B(CallRuntime), U16(Runtime::kDefineClass), R(2), U8(4), // | |
| 8379 B(Star), R(2), // | |
| 8380 B(LdaInitialMap), // | |
| 8381 B(Star), R(3), // | |
| 8382 B(Mov), R(3), R(4), // | |
| 8383 B(LdaConstant), U8(2), // | |
| 8384 B(Star), R(5), // | |
| 8385 B(CreateClosure), U8(3), U8(0), // | |
| 8386 B(Star), R(6), // | |
| 8387 B(CallRuntime), U16(Runtime::kDefineClassMethod), R(4), U8(3), // | |
| 8388 B(CallRuntime), U16(Runtime::kFinalizeClassDefinition), R(2), U8(2), // | |
| 8389 B(Star), R(0), // | |
| 8390 B(Star), R(1), // | |
| 8391 B(LdaUndefined), // | |
| 8392 B(Return) // | |
| 8393 }, | |
| 8394 4, | |
| 8395 { InstanceType::SHARED_FUNCTION_INFO_TYPE, kInstanceTypeDontCare, | |
| 8396 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
| 8397 InstanceType::SHARED_FUNCTION_INFO_TYPE}}, | |
| 8398 {"var n0 = 'a';" | |
| 8399 "var n1 = 'b';" | |
| 8400 "class N {\n" | |
| 8401 " [n0]() { return n0; }\n" | |
| 8402 " static [n1]() { return n1; }\n" | |
| 8403 "}\n", | |
| 8404 9 * kPointerSize, | |
| 8405 1, | |
| 8406 109, | |
| 8407 { | |
| 8408 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // | |
| 8409 /* */ U8(1), // | |
| 8410 B(PushContext), R(2), // | |
| 8411 B(LdaTheHole), // | |
| 8412 B(Star), R(1), // | |
| 8413 B(LdaConstant), U8(0), // | |
| 8414 B(StaContextSlot), R(context), U8(4), // | |
| 8415 B(LdaConstant), U8(1), // | |
| 8416 B(StaContextSlot), R(context), U8(5), // | |
| 8417 B(LdaTheHole), // | |
| 8418 B(Star), R(0), // | |
| 8419 B(LdaTheHole), // | |
| 8420 B(Star), R(3), // | |
| 8421 B(CreateClosure), U8(2), U8(0), // | |
| 8422 B(Star), R(4), // | |
| 8423 B(LdaSmi8), U8(41), // | |
| 8424 B(Star), R(5), // | |
| 8425 B(LdaSmi8), U8(107), // | |
| 8426 B(Star), R(6), // | |
| 8427 B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(4), // | |
| 8428 B(Star), R(3), // | |
| 8429 B(LdaInitialMap), // | |
| 8430 B(Star), R(4), // | |
| 8431 B(Mov), R(4), R(5), // | |
| 8432 B(LdaContextSlot), R(context), U8(4), // | |
| 8433 B(ToName), // | |
| 8434 B(Star), R(6), // | |
| 8435 B(CreateClosure), U8(3), U8(0), // | |
| 8436 B(Star), R(7), // | |
| 8437 B(CallRuntime), U16(Runtime::kDefineClassMethod), R(5), U8(3), // | |
| 8438 B(Mov), R(3), R(5), // | |
| 8439 B(LdaContextSlot), R(context), U8(5), // | |
| 8440 B(ToName), // | |
| 8441 B(Star), R(6), // | |
| 8442 B(LdaConstant), U8(4), // | |
| 8443 B(TestEqualStrict), R(6), // | |
| 8444 B(JumpIfFalse), U8(7), // | |
| 8445 B(CallRuntime), U16(Runtime::kThrowStaticPrototypeError), // | |
| 8446 /* */ R(0), U8(0), // | |
| 8447 B(CreateClosure), U8(5), U8(0), // | |
| 8448 B(Star), R(7), // | |
| 8449 B(CallRuntime), U16(Runtime::kDefineClassMethod), R(5), U8(3), // | |
| 8450 B(CallRuntime), U16(Runtime::kFinalizeClassDefinition), R(3), U8(2), // | |
| 8451 B(Star), R(0), // | |
| 8452 B(Star), R(1), // | |
| 8453 B(LdaUndefined), // | |
| 8454 B(Return), // | |
| 8455 }, | |
| 8456 6, | |
| 8457 { InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
| 8458 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
| 8459 InstanceType::SHARED_FUNCTION_INFO_TYPE, | |
| 8460 InstanceType::SHARED_FUNCTION_INFO_TYPE, | |
| 8461 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
| 8462 InstanceType::SHARED_FUNCTION_INFO_TYPE}}, | |
| 8463 {"class Person {\n" | |
| 8464 "}\n" | |
| 8465 "class Cyborg extends Person {\n" | |
| 8466 " constructor() { this.battery_ = 0; }" | |
| 8467 " get battery() { return battery_; }" | |
| 8468 " set battery(new_level) { battery_ = new_level; }" | |
| 8469 " charge() { battery(100); }" | |
| 8470 " static diet() { return 'metal bolts'; }\n" | |
| 8471 "}\n" | |
| 8472 "return new Cyborg();\n", | |
| 8473 10 * kPointerSize, | |
| 8474 1, | |
| 8475 156, | |
| 8476 { | |
| 8477 B(LdaTheHole), // | |
| 8478 B(Star), R(2), // | |
| 8479 B(LdaTheHole), // | |
| 8480 B(Star), R(3), // | |
| 8481 B(LdaTheHole), // | |
| 8482 B(Star), R(0), // | |
| 8483 B(LdaTheHole), // | |
| 8484 B(Star), R(4), // | |
| 8485 B(CreateClosure), U8(0), U8(0), // | |
| 8486 B(Star), R(5), // | |
| 8487 B(LdaSmi8), U8(15), // | |
| 8488 B(Star), R(6), // | |
| 8489 B(LdaSmi8), U8(31), // | |
| 8490 B(Star), R(7), // | |
| 8491 B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(4), // | |
| 8492 B(Star), R(4), // | |
| 8493 B(LdaInitialMap), // | |
| 8494 B(Star), R(5), // | |
| 8495 B(CallRuntime), U16(Runtime::kFinalizeClassDefinition), R(4), U8(2), // | |
| 8496 B(Star), R(0), // | |
| 8497 B(Star), R(2), // | |
| 8498 B(LdaTheHole), // | |
| 8499 B(Star), R(1), // | |
| 8500 B(Ldar), R(2), // | |
| 8501 B(Star), R(4), // | |
| 8502 B(CreateClosure), U8(1), U8(0), // | |
| 8503 B(Star), R(5), // | |
| 8504 B(LdaSmi8), U8(32), // | |
| 8505 B(Star), R(6), // | |
| 8506 B(LdaConstant), U8(2), // | |
| 8507 B(Star), R(7), // | |
| 8508 B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(4), // | |
| 8509 B(Star), R(4), // | |
| 8510 B(LdaInitialMap), // | |
| 8511 B(Star), R(5), // | |
| 8512 B(Mov), R(5), R(6), // | |
| 8513 B(LdaConstant), U8(3), // | |
| 8514 B(Star), R(7), // | |
| 8515 B(CreateClosure), U8(4), U8(0), // | |
| 8516 B(Star), R(8), // | |
| 8517 B(LdaSmi8), U8(2), // | |
| 8518 B(Star), R(9), // | |
| 8519 B(CallRuntime), U16(Runtime::kDefineGetterPropertyUnchecked), // | |
| 8520 /* */ R(6), U8(4), // | |
| 8521 B(LdaConstant), U8(3), // | |
| 8522 B(Star), R(7), // | |
| 8523 B(CreateClosure), U8(5), U8(0), // | |
| 8524 B(Star), R(8), // | |
| 8525 B(CallRuntime), U16(Runtime::kDefineSetterPropertyUnchecked), // | |
| 8526 /* */ R(6), U8(4), // | |
| 8527 B(LdaConstant), U8(6), // | |
| 8528 B(Star), R(7), // | |
| 8529 B(CreateClosure), U8(7), U8(0), // | |
| 8530 B(Star), R(8), // | |
| 8531 B(CallRuntime), U16(Runtime::kDefineClassMethod), R(6), U8(3), // | |
| 8532 B(Mov), R(4), R(6), // | |
| 8533 B(LdaConstant), U8(8), // | |
| 8534 B(Star), R(7), // | |
| 8535 B(CreateClosure), U8(9), U8(0), // | |
| 8536 B(Star), R(8), // | |
| 8537 B(CallRuntime), U16(Runtime::kDefineClassMethod), R(6), U8(3), // | |
| 8538 B(CallRuntime), U16(Runtime::kFinalizeClassDefinition), R(4), U8(2), // | |
| 8539 B(Star), R(1), // | |
| 8540 B(Star), R(3), // | |
| 8541 B(Star), R(4), // | |
| 8542 B(New), R(4), R(0), U8(0), // | |
| 8543 B(Return), // | |
| 8544 }, | |
| 8545 10, | |
| 8546 { InstanceType::SHARED_FUNCTION_INFO_TYPE, | |
| 8547 InstanceType::SHARED_FUNCTION_INFO_TYPE, | |
| 8548 kInstanceTypeDontCare, | |
| 8549 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
| 8550 InstanceType::SHARED_FUNCTION_INFO_TYPE, | |
| 8551 InstanceType::SHARED_FUNCTION_INFO_TYPE, | |
| 8552 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
| 8553 InstanceType::SHARED_FUNCTION_INFO_TYPE, | |
| 8554 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, | |
| 8555 InstanceType::SHARED_FUNCTION_INFO_TYPE, | |
| 8556 } | |
| 8557 }, | |
| 8558 {"var count = 0;\n" | |
| 8559 "class C { constructor() { count++; }}\n" | |
| 8560 "return new C();\n", | |
| 8561 9 * kPointerSize, | |
| 8562 1, | |
| 8563 59, | |
| 8564 { | |
| 8565 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1), // | |
| 8566 B(PushContext), R(2), // | |
| 8567 B(LdaTheHole), // | |
| 8568 B(Star), R(1), // | |
| 8569 B(LdaZero), // | |
| 8570 B(StaContextSlot), R(context), U8(4), // | |
| 8571 B(LdaTheHole), // | |
| 8572 B(Star), R(0), // | |
| 8573 B(LdaTheHole), // | |
| 8574 B(Star), R(3), // | |
| 8575 B(CreateClosure), U8(0), U8(0), // | |
| 8576 B(Star), R(4), // | |
| 8577 B(LdaSmi8), U8(30), // | |
| 8578 B(Star), R(5), // | |
| 8579 B(LdaSmi8), U8(67), // | |
| 8580 B(Star), R(6), // | |
| 8581 B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(4), // | |
| 8582 B(Star), R(3), // | |
| 8583 B(LdaInitialMap), // | |
| 8584 B(Star), R(4), // | |
| 8585 B(CallRuntime), U16(Runtime::kFinalizeClassDefinition), R(3), U8(2), // | |
| 8586 B(Star), R(0), // | |
| 8587 B(Star), R(1), // | |
| 8588 B(Star), R(3), // | |
| 8589 B(New), R(3), R(0), U8(0), // | |
| 8590 B(Return), // | |
| 8591 }, | |
| 8592 1, | |
| 8593 { InstanceType::SHARED_FUNCTION_INFO_TYPE}}, | |
| 8594 }; | |
| 8595 | |
| 8596 for (size_t i = 0; i < arraysize(snippets); i++) { | |
| 8597 Handle<BytecodeArray> bytecode_array = | |
| 8598 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
| 8599 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
| 8600 } | |
| 8601 } | |
| 8602 | |
| 8344 } // namespace interpreter | 8603 } // namespace interpreter |
| 8345 } // namespace internal | 8604 } // namespace internal |
| 8346 } // namespace v8 | 8605 } // namespace v8 |
| OLD | NEW |