| Index: test/cctest/interpreter/test-interpreter.cc
|
| diff --git a/test/cctest/interpreter/test-interpreter.cc b/test/cctest/interpreter/test-interpreter.cc
|
| index 56fa4c6257e39a6fb7870224336f1ea996066b71..f4159ab1b1627fb8e5666079ab38b3da76277621 100644
|
| --- a/test/cctest/interpreter/test-interpreter.cc
|
| +++ b/test/cctest/interpreter/test-interpreter.cc
|
| @@ -558,3 +558,142 @@ TEST(InterpreterLoadKeyedProperty) {
|
| return_val = callable(object3).ToHandleChecked();
|
| CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(789));
|
| }
|
| +
|
| +
|
| +TEST(InterpreterCallJS) {
|
| + HandleAndZoneScope handles;
|
| + i::Isolate* isolate = handles.main_isolate();
|
| + i::Factory* factory = isolate->factory();
|
| +
|
| + i::Code::Kind ic_kinds[] = {i::Code::LOAD_IC};
|
| + i::FeedbackVectorSpec feedback_spec(0, 1, ic_kinds);
|
| + Handle<i::TypeFeedbackVector> vector =
|
| + factory->NewTypeFeedbackVector(&feedback_spec);
|
| +
|
| + Handle<i::String> name = factory->NewStringFromAsciiChecked("func");
|
| + name = factory->string_table()->LookupString(isolate, name);
|
| +
|
| + // Check with no args.
|
| + {
|
| + BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone());
|
| + builder.set_locals_count(0);
|
| + builder.set_parameter_count(1);
|
| + builder.LoadLiteral(name)
|
| + .LoadNamedProperty(builder.Parameter(0), vector->first_ic_slot_index(),
|
| + i::SLOPPY)
|
| + .CallJS(builder.Parameter(0), 1)
|
| + .Return();
|
| + Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray();
|
| +
|
| + InterpreterTester tester(handles.main_isolate(), bytecode_array, vector);
|
| + auto callable = tester.GetCallable<Handle<Object>>();
|
| +
|
| + Handle<Object> object = tester.NewObject(
|
| + "new (function Obj() { this.func = function() { return 0x265; }})()");
|
| + Handle<Object> return_val = callable(object).ToHandleChecked();
|
| + CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(0x265));
|
| + }
|
| +
|
| + // Check that reciever is passed properly.
|
| + {
|
| + BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone());
|
| + builder.set_locals_count(0);
|
| + builder.set_parameter_count(1);
|
| + builder.LoadLiteral(name)
|
| + .LoadNamedProperty(builder.Parameter(0), vector->first_ic_slot_index(),
|
| + i::SLOPPY)
|
| + .CallJS(builder.Parameter(0), 1)
|
| + .Return();
|
| + Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray();
|
| +
|
| + InterpreterTester tester(handles.main_isolate(), bytecode_array, vector);
|
| + auto callable = tester.GetCallable<Handle<Object>>();
|
| +
|
| + Handle<Object> object = tester.NewObject(
|
| + "new (function Obj() {"
|
| + " this.val = 1234;"
|
| + " this.func = function() { return this.val; };"
|
| + "})()");
|
| + Handle<Object> return_val = callable(object).ToHandleChecked();
|
| + CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(1234));
|
| + }
|
| +
|
| + // Check with two parameters (+ reciever).
|
| + {
|
| + BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone());
|
| + builder.set_locals_count(3);
|
| + builder.set_parameter_count(1);
|
| + builder.LoadAccumulatorWithRegister(builder.Parameter(0))
|
| + .StoreAccumulatorInRegister(Register(0))
|
| + .LoadLiteral(Smi::FromInt(51))
|
| + .StoreAccumulatorInRegister(Register(1))
|
| + .LoadLiteral(Smi::FromInt(11))
|
| + .StoreAccumulatorInRegister(Register(2))
|
| + .LoadLiteral(name)
|
| + .LoadNamedProperty(builder.Parameter(0), vector->first_ic_slot_index(),
|
| + i::SLOPPY)
|
| + .CallJS(Register(0), 3)
|
| + .Return();
|
| + Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray();
|
| +
|
| + InterpreterTester tester(handles.main_isolate(), bytecode_array, vector);
|
| + auto callable = tester.GetCallable<Handle<Object>>();
|
| +
|
| + Handle<Object> object = tester.NewObject(
|
| + "new (function Obj() { "
|
| + " this.func = function(a, b) { return a - b; }"
|
| + "})()");
|
| + Handle<Object> return_val = callable(object).ToHandleChecked();
|
| + CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(40));
|
| + }
|
| +
|
| + // Check with 10 parameters (+ reciever).
|
| + {
|
| + BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone());
|
| + builder.set_locals_count(11);
|
| + builder.set_parameter_count(1);
|
| + builder.LoadAccumulatorWithRegister(builder.Parameter(0))
|
| + .StoreAccumulatorInRegister(Register(0))
|
| + .LoadLiteral(factory->NewStringFromAsciiChecked("a"))
|
| + .StoreAccumulatorInRegister(Register(1))
|
| + .LoadLiteral(factory->NewStringFromAsciiChecked("b"))
|
| + .StoreAccumulatorInRegister(Register(2))
|
| + .LoadLiteral(factory->NewStringFromAsciiChecked("c"))
|
| + .StoreAccumulatorInRegister(Register(3))
|
| + .LoadLiteral(factory->NewStringFromAsciiChecked("d"))
|
| + .StoreAccumulatorInRegister(Register(4))
|
| + .LoadLiteral(factory->NewStringFromAsciiChecked("e"))
|
| + .StoreAccumulatorInRegister(Register(5))
|
| + .LoadLiteral(factory->NewStringFromAsciiChecked("f"))
|
| + .StoreAccumulatorInRegister(Register(6))
|
| + .LoadLiteral(factory->NewStringFromAsciiChecked("g"))
|
| + .StoreAccumulatorInRegister(Register(7))
|
| + .LoadLiteral(factory->NewStringFromAsciiChecked("h"))
|
| + .StoreAccumulatorInRegister(Register(8))
|
| + .LoadLiteral(factory->NewStringFromAsciiChecked("i"))
|
| + .StoreAccumulatorInRegister(Register(9))
|
| + .LoadLiteral(factory->NewStringFromAsciiChecked("j"))
|
| + .StoreAccumulatorInRegister(Register(10))
|
| + .LoadLiteral(name)
|
| + .LoadNamedProperty(builder.Parameter(0), vector->first_ic_slot_index(),
|
| + i::SLOPPY)
|
| + .CallJS(Register(0), 11)
|
| + .Return();
|
| + Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray();
|
| +
|
| + InterpreterTester tester(handles.main_isolate(), bytecode_array, vector);
|
| + auto callable = tester.GetCallable<Handle<Object>>();
|
| +
|
| + Handle<Object> object = tester.NewObject(
|
| + "new (function Obj() { "
|
| + " this.prefix = \"prefix_\";"
|
| + " this.func = function(a, b, c, d, e, f, g, h, i, j) {"
|
| + " return this.prefix + a + b + c + d + e + f + g + h + i + j;"
|
| + " }"
|
| + "})()");
|
| + Handle<Object> return_val = callable(object).ToHandleChecked();
|
| + Handle<i::String> expected =
|
| + factory->NewStringFromAsciiChecked("prefix_abcdefghij");
|
| + CHECK(i::String::cast(*return_val)->Equals(*expected));
|
| + }
|
| +}
|
|
|