recv_obj = self;
}
Local<Value> result;
- has_pending_exception = !ToLocal<Value>(
- i::Execution::Call(isolate, fun, recv_obj, argc, args), &result);
+ has_pending_exception =
+ !ToLocal<Value>(
+ i::Execution::Call(isolate, fun, recv_obj, argc, args, true),
+ &result);
RETURN_ON_FAILED_EXECUTION(Value);
RETURN_ESCAPED(result);
}
STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Object**));
i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
Local<Value> result;
- has_pending_exception = !ToLocal<Value>(
- i::Execution::Call(isolate, self, recv_obj, argc, args), &result);
+ has_pending_exception =
+ !ToLocal<Value>(
+ i::Execution::Call(isolate, self, recv_obj, argc, args, true),
+ &result);
RETURN_ON_FAILED_EXECUTION(Value);
RETURN_ESCAPED(result);
}
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
has_pending_exception =
!ToLocal<Value>(i::Execution::Call(isolate, isolate->map_get(), self,
- arraysize(argv), argv),
+ arraysize(argv), argv, false),
&result);
RETURN_ON_FAILED_EXECUTION(Value);
RETURN_ESCAPED(result);
i::Handle<i::Object> result;
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key),
Utils::OpenHandle(*value)};
- has_pending_exception = !i::Execution::Call(isolate, isolate->map_set(), self,
- arraysize(argv), argv)
- .ToHandle(&result);
+ has_pending_exception =
+ !i::Execution::Call(isolate, isolate->map_set(), self, arraysize(argv),
+ argv, false).ToHandle(&result);
RETURN_ON_FAILED_EXECUTION(Map);
RETURN_ESCAPED(Local<Map>::Cast(Utils::ToLocal(result)));
}
auto self = Utils::OpenHandle(this);
i::Handle<i::Object> result;
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
- has_pending_exception = !i::Execution::Call(isolate, isolate->map_has(), self,
- arraysize(argv), argv)
- .ToHandle(&result);
+ has_pending_exception =
+ !i::Execution::Call(isolate, isolate->map_has(), self, arraysize(argv),
+ argv, false).ToHandle(&result);
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
return Just(result->IsTrue());
}
auto self = Utils::OpenHandle(this);
i::Handle<i::Object> result;
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
- has_pending_exception = !i::Execution::Call(isolate, isolate->map_delete(),
- self, arraysize(argv), argv)
- .ToHandle(&result);
+ has_pending_exception =
+ !i::Execution::Call(isolate, isolate->map_delete(), self, arraysize(argv),
+ argv, false).ToHandle(&result);
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
return Just(result->IsTrue());
}
has_pending_exception =
!i::Execution::Call(isolate, isolate->map_from_array(),
isolate->factory()->undefined_value(),
- arraysize(argv), argv)
- .ToHandle(&result);
+ arraysize(argv), argv, false).ToHandle(&result);
RETURN_ON_FAILED_EXECUTION(Map);
RETURN_ESCAPED(Local<Map>::Cast(Utils::ToLocal(result)));
}
auto self = Utils::OpenHandle(this);
i::Handle<i::Object> result;
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
- has_pending_exception = !i::Execution::Call(isolate, isolate->set_add(), self,
- arraysize(argv), argv)
- .ToHandle(&result);
+ has_pending_exception =
+ !i::Execution::Call(isolate, isolate->set_add(), self, arraysize(argv),
+ argv, false).ToHandle(&result);
RETURN_ON_FAILED_EXECUTION(Set);
RETURN_ESCAPED(Local<Set>::Cast(Utils::ToLocal(result)));
}
auto self = Utils::OpenHandle(this);
i::Handle<i::Object> result;
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
- has_pending_exception = !i::Execution::Call(isolate, isolate->set_has(), self,
- arraysize(argv), argv)
- .ToHandle(&result);
+ has_pending_exception =
+ !i::Execution::Call(isolate, isolate->set_has(), self, arraysize(argv),
+ argv, false).ToHandle(&result);
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
return Just(result->IsTrue());
}
auto self = Utils::OpenHandle(this);
i::Handle<i::Object> result;
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
- has_pending_exception = !i::Execution::Call(isolate, isolate->set_delete(),
- self, arraysize(argv), argv)
- .ToHandle(&result);
+ has_pending_exception =
+ !i::Execution::Call(isolate, isolate->set_delete(), self, arraysize(argv),
+ argv, false).ToHandle(&result);
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
return Just(result->IsTrue());
}
has_pending_exception =
!i::Execution::Call(isolate, isolate->set_from_array(),
isolate->factory()->undefined_value(),
- arraysize(argv), argv)
- .ToHandle(&result);
+ arraysize(argv), argv, false).ToHandle(&result);
RETURN_ON_FAILED_EXECUTION(Set);
RETURN_ESCAPED(Local<Set>::Cast(Utils::ToLocal(result)));
}
MaybeLocal<Promise::Resolver> Promise::Resolver::New(Local<Context> context) {
PREPARE_FOR_EXECUTION(context, "Promise::Resolver::New", Resolver);
i::Handle<i::Object> result;
- has_pending_exception =
- !i::Execution::Call(isolate, isolate->promise_create(),
- isolate->factory()->undefined_value(), 0, NULL)
- .ToHandle(&result);
+ has_pending_exception = !i::Execution::Call(
+ isolate,
+ isolate->promise_create(),
+ isolate->factory()->undefined_value(),
+ 0, NULL,
+ false).ToHandle(&result);
RETURN_ON_FAILED_EXECUTION(Promise::Resolver);
RETURN_ESCAPED(Local<Promise::Resolver>::Cast(Utils::ToLocal(result)));
}
PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Promise::Resolver::Resolve", bool);
auto self = Utils::OpenHandle(this);
i::Handle<i::Object> argv[] = {self, Utils::OpenHandle(*value)};
- has_pending_exception =
- i::Execution::Call(isolate, isolate->promise_resolve(),
- isolate->factory()->undefined_value(), arraysize(argv),
- argv)
- .is_null();
+ has_pending_exception = i::Execution::Call(
+ isolate,
+ isolate->promise_resolve(),
+ isolate->factory()->undefined_value(),
+ arraysize(argv), argv,
+ false).is_null();
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
return Just(true);
}
PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Promise::Resolver::Resolve", bool);
auto self = Utils::OpenHandle(this);
i::Handle<i::Object> argv[] = {self, Utils::OpenHandle(*value)};
- has_pending_exception =
- i::Execution::Call(isolate, isolate->promise_reject(),
- isolate->factory()->undefined_value(), arraysize(argv),
- argv)
- .is_null();
+ has_pending_exception = i::Execution::Call(
+ isolate,
+ isolate->promise_reject(),
+ isolate->factory()->undefined_value(),
+ arraysize(argv), argv,
+ false).is_null();
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
return Just(true);
}
auto self = Utils::OpenHandle(this);
i::Handle<i::Object> argv[] = {Utils::OpenHandle(*handler)};
i::Handle<i::Object> result;
- has_pending_exception = !i::Execution::Call(isolate, isolate->promise_chain(),
- self, arraysize(argv), argv)
- .ToHandle(&result);
+ has_pending_exception =
+ !i::Execution::Call(isolate, isolate->promise_chain(), self,
+ arraysize(argv), argv, false).ToHandle(&result);
RETURN_ON_FAILED_EXECUTION(Promise);
RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
}
auto self = Utils::OpenHandle(this);
i::Handle<i::Object> argv[] = { Utils::OpenHandle(*handler) };
i::Handle<i::Object> result;
- has_pending_exception = !i::Execution::Call(isolate, isolate->promise_catch(),
- self, arraysize(argv), argv)
- .ToHandle(&result);
+ has_pending_exception =
+ !i::Execution::Call(isolate, isolate->promise_catch(), self,
+ arraysize(argv), argv, false).ToHandle(&result);
RETURN_ON_FAILED_EXECUTION(Promise);
RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
}
auto self = Utils::OpenHandle(this);
i::Handle<i::Object> argv[] = { Utils::OpenHandle(*handler) };
i::Handle<i::Object> result;
- has_pending_exception = !i::Execution::Call(isolate, isolate->promise_then(),
- self, arraysize(argv), argv)
- .ToHandle(&result);
+ has_pending_exception =
+ !i::Execution::Call(isolate, isolate->promise_then(), self,
+ arraysize(argv), argv, false).ToHandle(&result);
RETURN_ON_FAILED_EXECUTION(Promise);
RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
}
CallConstructStub stub(masm->isolate(), NO_CALL_CONSTRUCTOR_FLAGS);
__ CallStub(&stub);
} else {
- __ Call(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
+ ParameterCount actual(r0);
+ __ InvokeFunction(r1, actual, CALL_FUNCTION, NullCallWrapper());
}
// Exit the JS frame and remove the parameters (except function), and
// return.
CallConstructStub stub(masm->isolate(), NO_CALL_CONSTRUCTOR_FLAGS);
__ CallStub(&stub);
} else {
- __ Call(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
+ ParameterCount actual(x0);
+ __ InvokeFunction(function, actual, CALL_FUNCTION, NullCallWrapper());
}
// Exit the JS internal frame and remove the parameters (except function),
// and return.
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);
+ MaybeHandle<Object> result = Execution::Call(
+ isolate(), outer, factory->undefined_value(), 2, args, false);
Handle<JSFunction> inner = Handle<JSFunction>::cast(result.ToHandleChecked());
// Just to make sure nobody calls this...
inner->set_code(isolate()->builtins()->builtin(Builtins::kIllegal));
}
-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);
- }
+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();
// 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());
+ }
DCHECK(function->context()->global_object()->IsGlobalObject());
auto value = Builtins::InvokeApiFunction(function, receiver, argc, args);
bool has_exception = value.is_null();
? 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());
JSEntryFunction stub_entry = FUNCTION_CAST<JSEntryFunction>(code->entry());
// Call the function through the right JS entry stub.
- byte* ignored = nullptr; // TODO(bmeurer): Remove this altogether.
+ byte* function_entry = function->code()->entry();
JSFunction* func = *function;
Object* recv = *receiver;
Object*** argv = reinterpret_cast<Object***>(args);
if (FLAG_profile_deserialization) PrintDeserializedCodeInfo(function);
- value = CALL_GENERATED_CODE(stub_entry, ignored, func, recv, argc, argv);
+ value =
+ CALL_GENERATED_CODE(stub_entry, function_entry, func, recv, argc, argv);
}
#ifdef VERIFY_HEAP
return Handle<Object>(value, isolate);
}
-} // namespace
-
-MaybeHandle<Object> Execution::Call(Isolate* isolate, Handle<Object> callable,
- Handle<Object> receiver, int argc,
- Handle<Object> argv[]) {
+MaybeHandle<Object> Execution::Call(Isolate* isolate,
+ Handle<Object> callable,
+ Handle<Object> receiver,
+ int argc,
+ Handle<Object> argv[],
+ bool convert_receiver) {
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);
}
catcher.SetVerbose(false);
catcher.SetCaptureMessage(false);
- maybe_result = Call(isolate, func, receiver, argc, args);
+ maybe_result = Invoke(false, func, receiver, argc, args);
if (maybe_result.is_null()) {
DCHECK(catcher.HasCaught());
class Execution final : public AllStatic {
public:
// Call a function, the caller supplies a receiver and an array
- // of arguments.
+ // 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.
//
- // When the function called is not in strict mode, receiver is
- // converted to an object.
+ // 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.
//
- MUST_USE_RESULT static MaybeHandle<Object> Call(Isolate* isolate,
- Handle<Object> callable,
- Handle<Object> receiver,
- int argc,
- Handle<Object> argv[]);
+ MUST_USE_RESULT static MaybeHandle<Object> Call(
+ Isolate* isolate,
+ Handle<Object> callable,
+ Handle<Object> receiver,
+ int argc,
+ Handle<Object> argv[],
+ bool convert_receiver = false);
// Construct object from function, the caller supplies an array of
// arguments. Arguments are Object* type. After function returns,
CallConstructStub stub(masm->isolate(), NO_CALL_CONSTRUCTOR_FLAGS);
__ CallStub(&stub);
} else {
- __ Call(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
+ ParameterCount actual(eax);
+ __ InvokeFunction(edi, actual, CALL_FUNCTION,
+ NullCallWrapper());
}
// Exit the internal frame. Notice that this also removes the empty.
CallConstructStub stub(masm->isolate(), NO_CALL_CONSTRUCTOR_FLAGS);
__ CallStub(&stub);
} else {
- __ Call(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
+ ParameterCount actual(a0);
+ __ InvokeFunction(a1, actual, CALL_FUNCTION, NullCallWrapper());
}
// Leave internal frame.
CallConstructStub stub(masm->isolate(), NO_CALL_CONSTRUCTOR_FLAGS);
__ CallStub(&stub);
} else {
- __ Call(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
+ ParameterCount actual(a0);
+ __ InvokeFunction(a1, actual, CALL_FUNCTION, NullCallWrapper());
}
// Leave internal frame.
// 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);
+ return Execution::Call(isolate, getter, receiver, 0, NULL, true);
}
Handle<Object> argv[] = { value };
RETURN_ON_EXCEPTION(isolate, Execution::Call(isolate, setter, receiver,
- arraysize(argv), argv),
+ arraysize(argv), argv, true),
Object);
return value;
}
Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result,
- Execution::Call(isolate, target, receiver, argc, argv.start()));
+ Execution::Call(isolate, target, receiver, argc, argv.start(), true));
return *result;
}
Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, result, Execution::Call(isolate, fun, receiver, argc, argv));
+ isolate, result,
+ Execution::Call(isolate, fun, receiver, argc, argv, true));
return *result;
}
Handle<Object> hreceiver(receiver, isolate);
Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, result, Execution::Call(isolate, hfun, hreceiver, argc, argv));
+ isolate, result,
+ Execution::Call(isolate, hfun, hreceiver, argc, argv, true));
return *result;
}
CallConstructStub stub(masm->isolate(), NO_CALL_CONSTRUCTOR_FLAGS);
__ CallStub(&stub);
} else {
- __ Call(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
+ ParameterCount actual(rax);
+ // Function must be in rdi.
+ __ InvokeFunction(rdi, actual, CALL_FUNCTION, NullCallWrapper());
}
// Exit the internal frame. Notice that this also removes the empty
// context and the function left on the stack by the code
MaybeHandle<Object> Call(Handle<Object> a, Handle<Object> b) {
Handle<Object> args[] = {a, b};
- return Execution::Call(isolate, function, undefined(), 2, args);
+ return Execution::Call(isolate, function, undefined(), 2, args, false);
}
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);
+ return Execution::Call(isolate, function, undefined(), 4, args, false);
}
void CheckThrows(Handle<Object> a, Handle<Object> b) {
static MaybeHandle<Object> CallFunction(Isolate* isolate,
Handle<JSFunction> function) {
return Execution::Call(isolate, function,
- isolate->factory()->undefined_value(), 0, nullptr);
+ isolate->factory()->undefined_value(), 0, nullptr,
+ false);
}
Handle<Object> argv[] = {args...};
return Execution::Call(isolate, function,
isolate->factory()->undefined_value(), sizeof...(args),
- argv);
+ argv, false);
}
Handle<JSFunction> fun = FunctionTester::ForMachineGraph(this->graph());
Handle<Object>* args = NULL;
MaybeHandle<Object> result = Execution::Call(
- this->isolate(), fun, factory()->undefined_value(), 0, args);
+ this->isolate(), fun, factory()->undefined_value(), 0, args, false);
return T::cast(*result.ToHandleChecked());
}
static MaybeHandle<Object> CallInterpreter(Isolate* isolate,
Handle<JSFunction> function) {
return Execution::Call(isolate, function,
- isolate->factory()->undefined_value(), 0, nullptr);
+ isolate->factory()->undefined_value(), 0, nullptr,
+ false);
}
Handle<Object> argv[] = { args... };
return Execution::Call(isolate, function,
isolate->factory()->undefined_value(), sizeof...(args),
- argv);
+ argv, false);
}