Commit d5bbd45f authored by bmeurer's avatar bmeurer Committed by Commit bot

[runtime] Initial step towards switching Execution::Call to callable.

Currently Execution::Call (and friends) still duplicate a lot of the
Call sequence logic that should be encapsulated in the Call and
CallFunction builtins. So the plan now is to switch Execution::Call
to accept any Callable and just pass that through to the Call builtin.

CQ_INCLUDE_TRYBOTS=tryserver.v8:v8_linux_nosnap_dbg
R=jarin@chromium.org
BUG=v8:4413
LOG=n

Committed: https://crrev.com/359645f48156e15f235e9a9ede7910e0bcd9ae45
Cr-Commit-Position: refs/heads/master@{#30791}

Review URL: https://codereview.chromium.org/1353723002

Cr-Commit-Position: refs/heads/master@{#30808}
parent 632c3679
This diff is collapsed.
......@@ -798,8 +798,7 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
CallConstructStub stub(masm->isolate(), NO_CALL_CONSTRUCTOR_FLAGS);
__ CallStub(&stub);
} else {
ParameterCount actual(r0);
__ InvokeFunction(r1, actual, CALL_FUNCTION, NullCallWrapper());
__ Call(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
}
// Exit the JS frame and remove the parameters (except function), and
// return.
......
......@@ -835,8 +835,7 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
CallConstructStub stub(masm->isolate(), NO_CALL_CONSTRUCTOR_FLAGS);
__ CallStub(&stub);
} else {
ParameterCount actual(x0);
__ InvokeFunction(function, actual, CALL_FUNCTION, NullCallWrapper());
__ Call(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
}
// Exit the JS internal frame and remove the parameters (except function),
// and return.
......
......@@ -489,8 +489,8 @@ Handle<Code> TurboFanCodeStub::GenerateCode() {
Handle<Object> call_conv = factory->InternalizeUtf8String(name);
Handle<Object> minor_key = factory->NewNumber(MinorKey());
Handle<Object> args[] = {call_conv, minor_key};
MaybeHandle<Object> result = Execution::Call(
isolate(), outer, factory->undefined_value(), 2, args, false);
MaybeHandle<Object> result =
Execution::Call(isolate(), outer, factory->undefined_value(), 2, args);
Handle<JSFunction> inner = Handle<JSFunction>::cast(result.ToHandleChecked());
// Just to make sure nobody calls this...
inner->set_code(isolate()->builtins()->builtin(Builtins::kIllegal));
......
......@@ -53,20 +53,35 @@ static void PrintDeserializedCodeInfo(Handle<JSFunction> function) {
}
MUST_USE_RESULT static MaybeHandle<Object> Invoke(
bool is_construct,
Handle<JSFunction> function,
Handle<Object> receiver,
int argc,
Handle<Object> args[]) {
Isolate* isolate = function->GetIsolate();
namespace {
MUST_USE_RESULT MaybeHandle<Object> Invoke(bool is_construct,
Handle<JSFunction> function,
Handle<Object> receiver, int argc,
Handle<Object> args[]) {
Isolate* const isolate = function->GetIsolate();
// Convert calls on global objects to be calls on the global
// receiver instead to avoid having a 'this' pointer which refers
// directly to a global object.
if (receiver->IsGlobalObject()) {
receiver =
handle(Handle<GlobalObject>::cast(receiver)->global_proxy(), isolate);
}
// api callbacks can be called directly.
if (!is_construct && function->shared()->IsApiFunction()) {
SaveContext save(isolate);
isolate->set_context(function->context());
if (receiver->IsGlobalObject()) {
receiver = handle(Handle<GlobalObject>::cast(receiver)->global_proxy());
// Do proper receiver conversion for non-strict mode api functions.
if (!receiver->IsJSReceiver() &&
is_sloppy(function->shared()->language_mode())) {
if (receiver->IsUndefined() || receiver->IsNull()) {
receiver = handle(function->global_proxy(), isolate);
} else {
ASSIGN_RETURN_ON_EXCEPTION(
isolate, receiver, Execution::ToObject(isolate, receiver), Object);
}
}
DCHECK(function->context()->global_object()->IsGlobalObject());
auto value = Builtins::InvokeApiFunction(function, receiver, argc, args);
......@@ -103,13 +118,6 @@ MUST_USE_RESULT static MaybeHandle<Object> Invoke(
? isolate->factory()->js_construct_entry_code()
: isolate->factory()->js_entry_code();
// Convert calls on global objects to be calls on the global
// receiver instead to avoid having a 'this' pointer which refers
// directly to a global object.
if (receiver->IsGlobalObject()) {
receiver = handle(Handle<GlobalObject>::cast(receiver)->global_proxy());
}
// Make sure that the global object of the context we're about to
// make the current one is indeed a global object.
DCHECK(function->context()->global_object()->IsGlobalObject());
......@@ -122,13 +130,12 @@ MUST_USE_RESULT static MaybeHandle<Object> Invoke(
JSEntryFunction stub_entry = FUNCTION_CAST<JSEntryFunction>(code->entry());
// Call the function through the right JS entry stub.
byte* function_entry = function->code()->entry();
byte* ignored = nullptr; // TODO(bmeurer): Remove this altogether.
JSFunction* func = *function;
Object* recv = *receiver;
Object*** argv = reinterpret_cast<Object***>(args);
if (FLAG_profile_deserialization) PrintDeserializedCodeInfo(function);
value =
CALL_GENERATED_CODE(stub_entry, function_entry, func, recv, argc, argv);
value = CALL_GENERATED_CODE(stub_entry, ignored, func, recv, argc, argv);
}
#ifdef VERIFY_HEAP
......@@ -154,31 +161,18 @@ MUST_USE_RESULT static MaybeHandle<Object> Invoke(
return Handle<Object>(value, isolate);
}
} // namespace
MaybeHandle<Object> Execution::Call(Isolate* isolate,
Handle<Object> callable,
Handle<Object> receiver,
int argc,
Handle<Object> argv[],
bool convert_receiver) {
MaybeHandle<Object> Execution::Call(Isolate* isolate, Handle<Object> callable,
Handle<Object> receiver, int argc,
Handle<Object> argv[]) {
if (!callable->IsJSFunction()) {
ASSIGN_RETURN_ON_EXCEPTION(isolate, callable,
GetFunctionDelegate(isolate, callable), Object);
}
Handle<JSFunction> func = Handle<JSFunction>::cast(callable);
// In sloppy mode, convert receiver.
if (convert_receiver && !receiver->IsJSReceiver() &&
!func->shared()->native() && is_sloppy(func->shared()->language_mode())) {
if (receiver->IsUndefined() || receiver->IsNull()) {
receiver = handle(func->global_proxy());
DCHECK(!receiver->IsJSBuiltinsObject());
} else {
ASSIGN_RETURN_ON_EXCEPTION(
isolate, receiver, ToObject(isolate, receiver), Object);
}
}
return Invoke(false, func, receiver, argc, argv);
}
......@@ -207,7 +201,7 @@ MaybeHandle<Object> Execution::TryCall(Handle<JSFunction> func,
catcher.SetVerbose(false);
catcher.SetCaptureMessage(false);
maybe_result = Invoke(false, func, receiver, argc, args);
maybe_result = Call(isolate, func, receiver, argc, args);
if (maybe_result.is_null()) {
DCHECK(catcher.HasCaught());
......
......@@ -19,23 +19,16 @@ class JSRegExp;
class Execution final : public AllStatic {
public:
// Call a function, the caller supplies a receiver and an array
// of arguments. Arguments are Object* type. After function returns,
// pointers in 'args' might be invalid.
//
// *pending_exception tells whether the invoke resulted in
// a pending exception.
// of arguments.
//
// When convert_receiver is set, and the receiver is not an object,
// and the function called is not in strict mode, receiver is converted to
// an object.
// When the function called is not in strict mode, receiver is
// converted to an object.
//
MUST_USE_RESULT static MaybeHandle<Object> Call(
Isolate* isolate,
Handle<Object> callable,
Handle<Object> receiver,
int argc,
Handle<Object> argv[],
bool convert_receiver = false);
MUST_USE_RESULT static MaybeHandle<Object> Call(Isolate* isolate,
Handle<Object> callable,
Handle<Object> receiver,
int argc,
Handle<Object> argv[]);
// Construct object from function, the caller supplies an array of
// arguments. Arguments are Object* type. After function returns,
......
......@@ -534,9 +534,7 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
CallConstructStub stub(masm->isolate(), NO_CALL_CONSTRUCTOR_FLAGS);
__ CallStub(&stub);
} else {
ParameterCount actual(eax);
__ InvokeFunction(edi, actual, CALL_FUNCTION,
NullCallWrapper());
__ Call(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
}
// Exit the internal frame. Notice that this also removes the empty.
......
......@@ -796,8 +796,7 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
CallConstructStub stub(masm->isolate(), NO_CALL_CONSTRUCTOR_FLAGS);
__ CallStub(&stub);
} else {
ParameterCount actual(a0);
__ InvokeFunction(a1, actual, CALL_FUNCTION, NullCallWrapper());
__ Call(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
}
// Leave internal frame.
......
......@@ -794,8 +794,7 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
CallConstructStub stub(masm->isolate(), NO_CALL_CONSTRUCTOR_FLAGS);
__ CallStub(&stub);
} else {
ParameterCount actual(a0);
__ InvokeFunction(a1, actual, CALL_FUNCTION, NullCallWrapper());
__ Call(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
}
// Leave internal frame.
......
......@@ -841,7 +841,7 @@ MaybeHandle<Object> Object::GetPropertyWithDefinedGetter(
// TODO(rossberg): should this apply to getters that are function proxies?
if (debug->is_active()) debug->HandleStepIn(getter, false);
return Execution::Call(isolate, getter, receiver, 0, NULL, true);
return Execution::Call(isolate, getter, receiver, 0, NULL);
}
......@@ -858,7 +858,7 @@ MaybeHandle<Object> Object::SetPropertyWithDefinedSetter(
Handle<Object> argv[] = { value };
RETURN_ON_EXCEPTION(isolate, Execution::Call(isolate, setter, receiver,
arraysize(argv), argv, true),
arraysize(argv), argv),
Object);
return value;
}
......
......@@ -522,7 +522,7 @@ RUNTIME_FUNCTION(Runtime_Call) {
Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result,
Execution::Call(isolate, target, receiver, argc, argv.start(), true));
Execution::Call(isolate, target, receiver, argc, argv.start()));
return *result;
}
......@@ -559,8 +559,7 @@ RUNTIME_FUNCTION(Runtime_Apply) {
Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result,
Execution::Call(isolate, fun, receiver, argc, argv, true));
isolate, result, Execution::Call(isolate, fun, receiver, argc, argv));
return *result;
}
......@@ -627,8 +626,7 @@ RUNTIME_FUNCTION(Runtime_CallFunction) {
Handle<Object> hreceiver(receiver, isolate);
Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result,
Execution::Call(isolate, hfun, hreceiver, argc, argv, true));
isolate, result, Execution::Call(isolate, hfun, hreceiver, argc, argv));
return *result;
}
......
......@@ -593,9 +593,7 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
CallConstructStub stub(masm->isolate(), NO_CALL_CONSTRUCTOR_FLAGS);
__ CallStub(&stub);
} else {
ParameterCount actual(rax);
// Function must be in rdi.
__ InvokeFunction(rdi, actual, CALL_FUNCTION, NullCallWrapper());
__ Call(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
}
// Exit the internal frame. Notice that this also removes the empty
// context and the function left on the stack by the code
......
......@@ -51,13 +51,13 @@ class FunctionTester : public InitializedHandleScope {
MaybeHandle<Object> Call(Handle<Object> a, Handle<Object> b) {
Handle<Object> args[] = {a, b};
return Execution::Call(isolate, function, undefined(), 2, args, false);
return Execution::Call(isolate, function, undefined(), 2, args);
}
MaybeHandle<Object> Call(Handle<Object> a, Handle<Object> b, Handle<Object> c,
Handle<Object> d) {
Handle<Object> args[] = {a, b, c, d};
return Execution::Call(isolate, function, undefined(), 4, args, false);
return Execution::Call(isolate, function, undefined(), 4, args);
}
void CheckThrows(Handle<Object> a, Handle<Object> b) {
......
......@@ -25,8 +25,7 @@ static const char kFunctionName[] = "f";
static MaybeHandle<Object> CallFunction(Isolate* isolate,
Handle<JSFunction> function) {
return Execution::Call(isolate, function,
isolate->factory()->undefined_value(), 0, nullptr,
false);
isolate->factory()->undefined_value(), 0, nullptr);
}
......@@ -37,7 +36,7 @@ static MaybeHandle<Object> CallFunction(Isolate* isolate,
Handle<Object> argv[] = {args...};
return Execution::Call(isolate, function,
isolate->factory()->undefined_value(), sizeof...(args),
argv, false);
argv);
}
......
......@@ -82,7 +82,7 @@ class SimplifiedLoweringTester : public GraphBuilderTester<ReturnType> {
Handle<JSFunction> fun = FunctionTester::ForMachineGraph(this->graph());
Handle<Object>* args = NULL;
MaybeHandle<Object> result = Execution::Call(
this->isolate(), fun, factory()->undefined_value(), 0, args, false);
this->isolate(), fun, factory()->undefined_value(), 0, args);
return T::cast(*result.ToHandleChecked());
}
......
......@@ -18,8 +18,7 @@ namespace interpreter {
static MaybeHandle<Object> CallInterpreter(Isolate* isolate,
Handle<JSFunction> function) {
return Execution::Call(isolate, function,
isolate->factory()->undefined_value(), 0, nullptr,
false);
isolate->factory()->undefined_value(), 0, nullptr);
}
......@@ -30,7 +29,7 @@ static MaybeHandle<Object> CallInterpreter(Isolate* isolate,
Handle<Object> argv[] = { args... };
return Execution::Call(isolate, function,
isolate->factory()->undefined_value(), sizeof...(args),
argv, false);
argv);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment