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 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
469 .ToHandleChecked(); | 469 .ToHandleChecked(); |
470 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(36)); | 470 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(36)); |
471 } | 471 } |
472 | 472 |
473 | 473 |
474 TEST(InterpreterLoadNamedProperty) { | 474 TEST(InterpreterLoadNamedProperty) { |
475 HandleAndZoneScope handles; | 475 HandleAndZoneScope handles; |
476 i::Isolate* isolate = handles.main_isolate(); | 476 i::Isolate* isolate = handles.main_isolate(); |
477 i::Factory* factory = isolate->factory(); | 477 i::Factory* factory = isolate->factory(); |
478 | 478 |
479 i::Code::Kind ic_kinds[] = { i::Code::LOAD_IC }; | 479 i::Code::Kind ic_kinds[] = {i::Code::LOAD_IC}; |
480 i::FeedbackVectorSpec feedback_spec(0, 1, ic_kinds); | 480 i::FeedbackVectorSpec feedback_spec(0, 1, ic_kinds); |
481 Handle<i::TypeFeedbackVector> vector = | 481 Handle<i::TypeFeedbackVector> vector = |
482 factory->NewTypeFeedbackVector(&feedback_spec); | 482 factory->NewTypeFeedbackVector(&feedback_spec); |
483 | 483 |
484 Handle<i::String> name = factory->NewStringFromAsciiChecked("val"); | 484 Handle<i::String> name = factory->NewStringFromAsciiChecked("val"); |
485 name = factory->string_table()->LookupString(isolate, name); | 485 name = factory->string_table()->LookupString(isolate, name); |
486 | 486 |
487 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone()); | 487 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone()); |
488 builder.set_locals_count(0); | 488 builder.set_locals_count(0); |
489 builder.set_parameter_count(1); | 489 builder.set_parameter_count(1); |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
655 callable(object).ToHandleChecked(); | 655 callable(object).ToHandleChecked(); |
656 CHECK(Runtime::GetObjectProperty(isolate, object, name).ToHandle(&result)); | 656 CHECK(Runtime::GetObjectProperty(isolate, object, name).ToHandle(&result)); |
657 CHECK_EQ(Smi::cast(*result), Smi::FromInt(999)); | 657 CHECK_EQ(Smi::cast(*result), Smi::FromInt(999)); |
658 | 658 |
659 // Test transition to megamorphic IC. | 659 // Test transition to megamorphic IC. |
660 Handle<Object> object2 = tester.NewObject("({ val : 456, other : 123 })"); | 660 Handle<Object> object2 = tester.NewObject("({ val : 456, other : 123 })"); |
661 callable(object2).ToHandleChecked(); | 661 callable(object2).ToHandleChecked(); |
662 CHECK(Runtime::GetObjectProperty(isolate, object2, name).ToHandle(&result)); | 662 CHECK(Runtime::GetObjectProperty(isolate, object2, name).ToHandle(&result)); |
663 CHECK_EQ(Smi::cast(*result), Smi::FromInt(999)); | 663 CHECK_EQ(Smi::cast(*result), Smi::FromInt(999)); |
664 } | 664 } |
| 665 |
| 666 |
| 667 TEST(InterpreterCall) { |
| 668 HandleAndZoneScope handles; |
| 669 i::Isolate* isolate = handles.main_isolate(); |
| 670 i::Factory* factory = isolate->factory(); |
| 671 |
| 672 i::Code::Kind ic_kinds[] = { i::Code::LOAD_IC }; |
| 673 i::FeedbackVectorSpec feedback_spec(0, 1, ic_kinds); |
| 674 Handle<i::TypeFeedbackVector> vector = |
| 675 factory->NewTypeFeedbackVector(&feedback_spec); |
| 676 |
| 677 Handle<i::String> name = factory->NewStringFromAsciiChecked("func"); |
| 678 name = factory->string_table()->LookupString(isolate, name); |
| 679 |
| 680 // Check with no args. |
| 681 { |
| 682 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone()); |
| 683 builder.set_locals_count(1); |
| 684 builder.set_parameter_count(1); |
| 685 builder.LoadLiteral(name) |
| 686 .LoadNamedProperty(builder.Parameter(0), vector->first_ic_slot_index(), |
| 687 i::SLOPPY) |
| 688 .StoreAccumulatorInRegister(Register(0)) |
| 689 .Call(Register(0), builder.Parameter(0), 0) |
| 690 .Return(); |
| 691 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 692 |
| 693 InterpreterTester tester(handles.main_isolate(), bytecode_array, vector); |
| 694 auto callable = tester.GetCallable<Handle<Object>>(); |
| 695 |
| 696 Handle<Object> object = tester.NewObject( |
| 697 "new (function Obj() { this.func = function() { return 0x265; }})()"); |
| 698 Handle<Object> return_val = callable(object).ToHandleChecked(); |
| 699 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(0x265)); |
| 700 } |
| 701 |
| 702 // Check that receiver is passed properly. |
| 703 { |
| 704 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone()); |
| 705 builder.set_locals_count(1); |
| 706 builder.set_parameter_count(1); |
| 707 builder.LoadLiteral(name) |
| 708 .LoadNamedProperty(builder.Parameter(0), vector->first_ic_slot_index(), |
| 709 i::SLOPPY) |
| 710 .StoreAccumulatorInRegister(Register(0)) |
| 711 .Call(Register(0), builder.Parameter(0), 0) |
| 712 .Return(); |
| 713 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 714 |
| 715 InterpreterTester tester(handles.main_isolate(), bytecode_array, vector); |
| 716 auto callable = tester.GetCallable<Handle<Object>>(); |
| 717 |
| 718 Handle<Object> object = tester.NewObject( |
| 719 "new (function Obj() {" |
| 720 " this.val = 1234;" |
| 721 " this.func = function() { return this.val; };" |
| 722 "})()"); |
| 723 Handle<Object> return_val = callable(object).ToHandleChecked(); |
| 724 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(1234)); |
| 725 } |
| 726 |
| 727 // Check with two parameters (+ receiver). |
| 728 { |
| 729 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone()); |
| 730 builder.set_locals_count(4); |
| 731 builder.set_parameter_count(1); |
| 732 builder.LoadLiteral(name) |
| 733 .LoadNamedProperty(builder.Parameter(0), vector->first_ic_slot_index(), |
| 734 i::SLOPPY) |
| 735 .StoreAccumulatorInRegister(Register(0)) |
| 736 .LoadAccumulatorWithRegister(builder.Parameter(0)) |
| 737 .StoreAccumulatorInRegister(Register(1)) |
| 738 .LoadLiteral(Smi::FromInt(51)) |
| 739 .StoreAccumulatorInRegister(Register(2)) |
| 740 .LoadLiteral(Smi::FromInt(11)) |
| 741 .StoreAccumulatorInRegister(Register(3)) |
| 742 .Call(Register(0), Register(1), 2) |
| 743 .Return(); |
| 744 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 745 |
| 746 InterpreterTester tester(handles.main_isolate(), bytecode_array, vector); |
| 747 auto callable = tester.GetCallable<Handle<Object>>(); |
| 748 |
| 749 Handle<Object> object = tester.NewObject( |
| 750 "new (function Obj() { " |
| 751 " this.func = function(a, b) { return a - b; }" |
| 752 "})()"); |
| 753 Handle<Object> return_val = callable(object).ToHandleChecked(); |
| 754 CHECK(return_val->SameValue(Smi::FromInt(40))); |
| 755 } |
| 756 |
| 757 // Check with 10 parameters (+ receiver). |
| 758 { |
| 759 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone()); |
| 760 builder.set_locals_count(12); |
| 761 builder.set_parameter_count(1); |
| 762 builder.LoadLiteral(name) |
| 763 .LoadNamedProperty(builder.Parameter(0), vector->first_ic_slot_index(), |
| 764 i::SLOPPY) |
| 765 .StoreAccumulatorInRegister(Register(0)) |
| 766 .LoadAccumulatorWithRegister(builder.Parameter(0)) |
| 767 .StoreAccumulatorInRegister(Register(1)) |
| 768 .LoadLiteral(factory->NewStringFromAsciiChecked("a")) |
| 769 .StoreAccumulatorInRegister(Register(2)) |
| 770 .LoadLiteral(factory->NewStringFromAsciiChecked("b")) |
| 771 .StoreAccumulatorInRegister(Register(3)) |
| 772 .LoadLiteral(factory->NewStringFromAsciiChecked("c")) |
| 773 .StoreAccumulatorInRegister(Register(4)) |
| 774 .LoadLiteral(factory->NewStringFromAsciiChecked("d")) |
| 775 .StoreAccumulatorInRegister(Register(5)) |
| 776 .LoadLiteral(factory->NewStringFromAsciiChecked("e")) |
| 777 .StoreAccumulatorInRegister(Register(6)) |
| 778 .LoadLiteral(factory->NewStringFromAsciiChecked("f")) |
| 779 .StoreAccumulatorInRegister(Register(7)) |
| 780 .LoadLiteral(factory->NewStringFromAsciiChecked("g")) |
| 781 .StoreAccumulatorInRegister(Register(8)) |
| 782 .LoadLiteral(factory->NewStringFromAsciiChecked("h")) |
| 783 .StoreAccumulatorInRegister(Register(9)) |
| 784 .LoadLiteral(factory->NewStringFromAsciiChecked("i")) |
| 785 .StoreAccumulatorInRegister(Register(10)) |
| 786 .LoadLiteral(factory->NewStringFromAsciiChecked("j")) |
| 787 .StoreAccumulatorInRegister(Register(11)) |
| 788 .Call(Register(0), Register(1), 10) |
| 789 .Return(); |
| 790 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 791 |
| 792 InterpreterTester tester(handles.main_isolate(), bytecode_array, vector); |
| 793 auto callable = tester.GetCallable<Handle<Object>>(); |
| 794 |
| 795 Handle<Object> object = tester.NewObject( |
| 796 "new (function Obj() { " |
| 797 " this.prefix = \"prefix_\";" |
| 798 " this.func = function(a, b, c, d, e, f, g, h, i, j) {" |
| 799 " return this.prefix + a + b + c + d + e + f + g + h + i + j;" |
| 800 " }" |
| 801 "})()"); |
| 802 Handle<Object> return_val = callable(object).ToHandleChecked(); |
| 803 Handle<i::String> expected = |
| 804 factory->NewStringFromAsciiChecked("prefix_abcdefghij"); |
| 805 CHECK(i::String::cast(*return_val)->Equals(*expected)); |
| 806 } |
| 807 } |
OLD | NEW |