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 |