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/execution.h" | 7 #include "src/execution.h" |
8 #include "src/handles.h" | 8 #include "src/handles.h" |
9 #include "src/interpreter/bytecode-array-builder.h" | 9 #include "src/interpreter/bytecode-array-builder.h" |
10 #include "src/interpreter/interpreter.h" | 10 #include "src/interpreter/interpreter.h" |
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
551 | 551 |
552 // Test transition to monomorphic IC. | 552 // Test transition to monomorphic IC. |
553 return_val = callable(object).ToHandleChecked(); | 553 return_val = callable(object).ToHandleChecked(); |
554 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(123)); | 554 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(123)); |
555 | 555 |
556 // Test transition to megamorphic IC. | 556 // Test transition to megamorphic IC. |
557 Handle<Object> object3 = tester.NewObject("({ key : 789, val2 : 123 })"); | 557 Handle<Object> object3 = tester.NewObject("({ key : 789, val2 : 123 })"); |
558 return_val = callable(object3).ToHandleChecked(); | 558 return_val = callable(object3).ToHandleChecked(); |
559 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(789)); | 559 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(789)); |
560 } | 560 } |
| 561 |
| 562 |
| 563 TEST(InterpreterCallJS) { |
| 564 HandleAndZoneScope handles; |
| 565 i::Isolate* isolate = handles.main_isolate(); |
| 566 i::Factory* factory = isolate->factory(); |
| 567 |
| 568 i::Code::Kind ic_kinds[] = {i::Code::LOAD_IC}; |
| 569 i::FeedbackVectorSpec feedback_spec(0, 1, ic_kinds); |
| 570 Handle<i::TypeFeedbackVector> vector = |
| 571 factory->NewTypeFeedbackVector(&feedback_spec); |
| 572 |
| 573 Handle<i::String> name = factory->NewStringFromAsciiChecked("func"); |
| 574 name = factory->string_table()->LookupString(isolate, name); |
| 575 |
| 576 // Check with no args. |
| 577 { |
| 578 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone()); |
| 579 builder.set_locals_count(0); |
| 580 builder.set_parameter_count(1); |
| 581 builder.LoadLiteral(name) |
| 582 .LoadNamedProperty(builder.Parameter(0), vector->first_ic_slot_index(), |
| 583 i::SLOPPY) |
| 584 .CallJS(builder.Parameter(0), 1) |
| 585 .Return(); |
| 586 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 587 |
| 588 InterpreterTester tester(handles.main_isolate(), bytecode_array, vector); |
| 589 auto callable = tester.GetCallable<Handle<Object>>(); |
| 590 |
| 591 Handle<Object> object = tester.NewObject( |
| 592 "new (function Obj() { this.func = function() { return 0x265; }})()"); |
| 593 Handle<Object> return_val = callable(object).ToHandleChecked(); |
| 594 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(0x265)); |
| 595 } |
| 596 |
| 597 // Check that reciever is passed properly. |
| 598 { |
| 599 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone()); |
| 600 builder.set_locals_count(0); |
| 601 builder.set_parameter_count(1); |
| 602 builder.LoadLiteral(name) |
| 603 .LoadNamedProperty(builder.Parameter(0), vector->first_ic_slot_index(), |
| 604 i::SLOPPY) |
| 605 .CallJS(builder.Parameter(0), 1) |
| 606 .Return(); |
| 607 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 608 |
| 609 InterpreterTester tester(handles.main_isolate(), bytecode_array, vector); |
| 610 auto callable = tester.GetCallable<Handle<Object>>(); |
| 611 |
| 612 Handle<Object> object = tester.NewObject( |
| 613 "new (function Obj() {" |
| 614 " this.val = 1234;" |
| 615 " this.func = function() { return this.val; };" |
| 616 "})()"); |
| 617 Handle<Object> return_val = callable(object).ToHandleChecked(); |
| 618 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(1234)); |
| 619 } |
| 620 |
| 621 // Check with two parameters (+ reciever). |
| 622 { |
| 623 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone()); |
| 624 builder.set_locals_count(3); |
| 625 builder.set_parameter_count(1); |
| 626 builder.LoadAccumulatorWithRegister(builder.Parameter(0)) |
| 627 .StoreAccumulatorInRegister(Register(0)) |
| 628 .LoadLiteral(Smi::FromInt(51)) |
| 629 .StoreAccumulatorInRegister(Register(1)) |
| 630 .LoadLiteral(Smi::FromInt(11)) |
| 631 .StoreAccumulatorInRegister(Register(2)) |
| 632 .LoadLiteral(name) |
| 633 .LoadNamedProperty(builder.Parameter(0), vector->first_ic_slot_index(), |
| 634 i::SLOPPY) |
| 635 .CallJS(Register(0), 3) |
| 636 .Return(); |
| 637 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 638 |
| 639 InterpreterTester tester(handles.main_isolate(), bytecode_array, vector); |
| 640 auto callable = tester.GetCallable<Handle<Object>>(); |
| 641 |
| 642 Handle<Object> object = tester.NewObject( |
| 643 "new (function Obj() { " |
| 644 " this.func = function(a, b) { return a - b; }" |
| 645 "})()"); |
| 646 Handle<Object> return_val = callable(object).ToHandleChecked(); |
| 647 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(40)); |
| 648 } |
| 649 |
| 650 // Check with 10 parameters (+ reciever). |
| 651 { |
| 652 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone()); |
| 653 builder.set_locals_count(11); |
| 654 builder.set_parameter_count(1); |
| 655 builder.LoadAccumulatorWithRegister(builder.Parameter(0)) |
| 656 .StoreAccumulatorInRegister(Register(0)) |
| 657 .LoadLiteral(factory->NewStringFromAsciiChecked("a")) |
| 658 .StoreAccumulatorInRegister(Register(1)) |
| 659 .LoadLiteral(factory->NewStringFromAsciiChecked("b")) |
| 660 .StoreAccumulatorInRegister(Register(2)) |
| 661 .LoadLiteral(factory->NewStringFromAsciiChecked("c")) |
| 662 .StoreAccumulatorInRegister(Register(3)) |
| 663 .LoadLiteral(factory->NewStringFromAsciiChecked("d")) |
| 664 .StoreAccumulatorInRegister(Register(4)) |
| 665 .LoadLiteral(factory->NewStringFromAsciiChecked("e")) |
| 666 .StoreAccumulatorInRegister(Register(5)) |
| 667 .LoadLiteral(factory->NewStringFromAsciiChecked("f")) |
| 668 .StoreAccumulatorInRegister(Register(6)) |
| 669 .LoadLiteral(factory->NewStringFromAsciiChecked("g")) |
| 670 .StoreAccumulatorInRegister(Register(7)) |
| 671 .LoadLiteral(factory->NewStringFromAsciiChecked("h")) |
| 672 .StoreAccumulatorInRegister(Register(8)) |
| 673 .LoadLiteral(factory->NewStringFromAsciiChecked("i")) |
| 674 .StoreAccumulatorInRegister(Register(9)) |
| 675 .LoadLiteral(factory->NewStringFromAsciiChecked("j")) |
| 676 .StoreAccumulatorInRegister(Register(10)) |
| 677 .LoadLiteral(name) |
| 678 .LoadNamedProperty(builder.Parameter(0), vector->first_ic_slot_index(), |
| 679 i::SLOPPY) |
| 680 .CallJS(Register(0), 11) |
| 681 .Return(); |
| 682 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 683 |
| 684 InterpreterTester tester(handles.main_isolate(), bytecode_array, vector); |
| 685 auto callable = tester.GetCallable<Handle<Object>>(); |
| 686 |
| 687 Handle<Object> object = tester.NewObject( |
| 688 "new (function Obj() { " |
| 689 " this.prefix = \"prefix_\";" |
| 690 " this.func = function(a, b, c, d, e, f, g, h, i, j) {" |
| 691 " return this.prefix + a + b + c + d + e + f + g + h + i + j;" |
| 692 " }" |
| 693 "})()"); |
| 694 Handle<Object> return_val = callable(object).ToHandleChecked(); |
| 695 Handle<i::String> expected = |
| 696 factory->NewStringFromAsciiChecked("prefix_abcdefghij"); |
| 697 CHECK(i::String::cast(*return_val)->Equals(*expected)); |
| 698 } |
| 699 } |
OLD | NEW |