Index: src/builtins.cc |
diff --git a/src/builtins.cc b/src/builtins.cc |
index d910c01101d3879a015f211492d66a4dc1e8af3f..a0b6408e4d20e3794296095e707650905bc38773 100644 |
--- a/src/builtins.cc |
+++ b/src/builtins.cc |
@@ -4540,12 +4540,9 @@ MUST_USE_RESULT MaybeHandle<Object> HandleApiCallHelper( |
LOG(isolate, ApiObjectAccess("call", JSObject::cast(*args.receiver()))); |
DCHECK(raw_holder->IsJSObject()); |
- FunctionCallbackArguments custom(isolate, |
- data_obj, |
- *function, |
- raw_holder, |
- &args[0] - 1, |
- args.length() - 1, |
+ FunctionCallbackArguments custom(isolate, data_obj, *function, raw_holder, |
+ isolate->heap()->undefined_value(), |
+ &args[0] - 1, args.length() - 1, |
is_construct); |
Handle<Object> result = custom.Call(callback); |
@@ -4574,10 +4571,65 @@ BUILTIN(HandleApiCall) { |
BUILTIN(HandleApiCallConstruct) { |
HandleScope scope(isolate); |
- Handle<Object> result; |
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
- HandleApiCallHelper<true>(isolate, args)); |
- return *result; |
+ Handle<HeapObject> function = args.target<HeapObject>(); |
+ Handle<HeapObject> new_target = args.new_target(); |
+ Handle<JSReceiver> receiver; |
+ |
+ DCHECK(function->IsFunctionTemplateInfo() || |
+ Handle<JSFunction>::cast(function)->shared()->IsApiFunction()); |
+ |
+ Handle<FunctionTemplateInfo> fun_data = |
+ function->IsFunctionTemplateInfo() |
+ ? Handle<FunctionTemplateInfo>::cast(function) |
+ : handle(JSFunction::cast(*function)->shared()->get_api_func_data()); |
+ DCHECK(args.receiver()->IsTheHole()); |
+ if (fun_data->instance_template()->IsUndefined()) { |
+ v8::Local<ObjectTemplate> templ = |
+ ObjectTemplate::New(reinterpret_cast<v8::Isolate*>(isolate), |
+ ToApiHandle<v8::FunctionTemplate>(fun_data)); |
+ fun_data->set_instance_template(*Utils::OpenHandle(*templ)); |
+ } |
+ Handle<ObjectTemplateInfo> instance_template( |
+ ObjectTemplateInfo::cast(fun_data->instance_template()), isolate); |
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
+ isolate, receiver, ApiNatives::InstantiateObject(instance_template)); |
+ args[0] = *receiver; |
+ DCHECK_EQ(*receiver, *args.receiver()); |
+ |
+ Object* raw_holder = fun_data->GetCompatibleReceiver(isolate, *receiver); |
+ |
+ if (raw_holder->IsNull()) { |
+ // This function cannot be called with the given receiver. Abort! |
+ THROW_NEW_ERROR_RETURN_FAILURE( |
+ isolate, NewTypeError(MessageTemplate::kIllegalInvocation)); |
+ } |
+ |
+ Object* raw_call_data = fun_data->call_code(); |
+ if (!raw_call_data->IsUndefined()) { |
+ DCHECK(raw_call_data->IsCallHandlerInfo()); |
+ CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); |
+ Object* callback_obj = call_data->callback(); |
+ v8::FunctionCallback callback = |
+ v8::ToCData<v8::FunctionCallback>(callback_obj); |
+ Object* data_obj = call_data->data(); |
+ |
+ LOG(isolate, ApiObjectAccess("call", JSObject::cast(*args.receiver()))); |
+ DCHECK(raw_holder->IsJSObject()); |
+ |
+ FunctionCallbackArguments custom(isolate, data_obj, *function, raw_holder, |
+ *new_target, &args[0] - 1, |
+ args.length() - 1, true); |
+ |
+ Handle<Object> result = custom.Call(callback); |
+ if (result.is_null()) result = isolate->factory()->undefined_value(); |
+ |
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); |
+ if (result->IsJSObject()) { |
+ return *result; |
+ } |
+ } |
+ |
+ return *receiver; |
} |
Handle<Code> Builtins::CallFunction(ConvertReceiverMode mode, |
@@ -4756,12 +4808,9 @@ MUST_USE_RESULT static Object* HandleApiCallAsFunctionOrConstructor( |
HandleScope scope(isolate); |
LOG(isolate, ApiObjectAccess("call non-function", obj)); |
- FunctionCallbackArguments custom(isolate, |
- call_data->data(), |
- constructor, |
- obj, |
- &args[0] - 1, |
- args.length() - 1, |
+ FunctionCallbackArguments custom(isolate, call_data->data(), constructor, |
+ obj, isolate->heap()->undefined_value(), |
+ &args[0] - 1, args.length() - 1, |
is_construct_call); |
Handle<Object> result_handle = custom.Call(callback); |
if (result_handle.is_null()) { |