| Index: src/builtins.cc
|
| diff --git a/src/builtins.cc b/src/builtins.cc
|
| index 6562067686e12f4057d7d9fcd740c716740365aa..91ea49b4ca0da1b7d05a4dcc040e6cf18fae6917 100644
|
| --- a/src/builtins.cc
|
| +++ b/src/builtins.cc
|
| @@ -5123,21 +5123,12 @@ JSObject* GetCompatibleReceiver(Isolate* isolate, FunctionTemplateInfo* info,
|
| return nullptr;
|
| }
|
|
|
| -MUST_USE_RESULT MaybeHandle<Object> HandleApiCallHelper(Isolate* isolate,
|
| - BuiltinArguments args) {
|
| - HandleScope scope(isolate);
|
| - Handle<HeapObject> function = args.target<HeapObject>();
|
| - Handle<HeapObject> new_target = args.new_target();
|
| - bool is_construct = !new_target->IsUndefined(isolate);
|
| +template <bool is_construct>
|
| +MUST_USE_RESULT MaybeHandle<Object> HandleApiCallHelper(
|
| + Isolate* isolate, Handle<HeapObject> function,
|
| + Handle<HeapObject> new_target, Handle<FunctionTemplateInfo> fun_data,
|
| + BuiltinArguments args) {
|
| Handle<JSObject> 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());
|
| JSObject* raw_holder;
|
| if (is_construct) {
|
| DCHECK(args.receiver()->IsTheHole(isolate));
|
| @@ -5201,15 +5192,18 @@ MUST_USE_RESULT MaybeHandle<Object> HandleApiCallHelper(Isolate* isolate,
|
| args.length() - 1);
|
|
|
| Handle<Object> result = custom.Call(callback);
|
| - if (result.is_null()) result = isolate->factory()->undefined_value();
|
|
|
| RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
|
| - if (!is_construct || result->IsJSObject()) {
|
| - return scope.CloseAndEscape(result);
|
| + if (result.is_null()) {
|
| + if (is_construct) return receiver;
|
| + return isolate->factory()->undefined_value();
|
| }
|
| + // Rebox the result.
|
| + result->VerifyApiCallResultType();
|
| + if (!is_construct || result->IsJSObject()) return handle(*result, isolate);
|
| }
|
|
|
| - return scope.CloseAndEscape(receiver);
|
| + return receiver;
|
| }
|
|
|
| } // namespace
|
| @@ -5217,7 +5211,19 @@ MUST_USE_RESULT MaybeHandle<Object> HandleApiCallHelper(Isolate* isolate,
|
|
|
| BUILTIN(HandleApiCall) {
|
| HandleScope scope(isolate);
|
| - RETURN_RESULT_OR_FAILURE(isolate, HandleApiCallHelper(isolate, args));
|
| + Handle<JSFunction> function = args.target<JSFunction>();
|
| + Handle<HeapObject> new_target = args.new_target();
|
| + Handle<FunctionTemplateInfo> fun_data(function->shared()->get_api_func_data(),
|
| + isolate);
|
| + if (new_target->IsJSReceiver()) {
|
| + RETURN_RESULT_OR_FAILURE(
|
| + isolate, HandleApiCallHelper<true>(isolate, function, new_target,
|
| + fun_data, args));
|
| + } else {
|
| + RETURN_RESULT_OR_FAILURE(
|
| + isolate, HandleApiCallHelper<false>(isolate, function, new_target,
|
| + fun_data, args));
|
| + }
|
| }
|
|
|
|
|
| @@ -5317,14 +5323,17 @@ class RelocatableArguments : public BuiltinArguments, public Relocatable {
|
|
|
| } // namespace
|
|
|
| -MaybeHandle<Object> Builtins::InvokeApiFunction(Handle<HeapObject> function,
|
| +MaybeHandle<Object> Builtins::InvokeApiFunction(Isolate* isolate,
|
| + Handle<HeapObject> function,
|
| Handle<Object> receiver,
|
| int argc,
|
| Handle<Object> args[]) {
|
| - Isolate* isolate = function->GetIsolate();
|
| + DCHECK(function->IsFunctionTemplateInfo() ||
|
| + (function->IsJSFunction() &&
|
| + JSFunction::cast(*function)->shared()->IsApiFunction()));
|
| +
|
| // Do proper receiver conversion for non-strict mode api functions.
|
| if (!receiver->IsJSReceiver()) {
|
| - DCHECK(function->IsFunctionTemplateInfo() || function->IsJSFunction());
|
| if (function->IsFunctionTemplateInfo() ||
|
| is_sloppy(JSFunction::cast(*function)->shared()->language_mode())) {
|
| ASSIGN_RETURN_ON_EXCEPTION(isolate, receiver,
|
| @@ -5332,6 +5341,13 @@ MaybeHandle<Object> Builtins::InvokeApiFunction(Handle<HeapObject> function,
|
| Object);
|
| }
|
| }
|
| +
|
| + Handle<FunctionTemplateInfo> fun_data =
|
| + function->IsFunctionTemplateInfo()
|
| + ? Handle<FunctionTemplateInfo>::cast(function)
|
| + : handle(JSFunction::cast(*function)->shared()->get_api_func_data(),
|
| + isolate);
|
| + Handle<HeapObject> new_target = isolate->factory()->undefined_value();
|
| // Construct BuiltinArguments object:
|
| // new target, function, arguments reversed, receiver.
|
| const int kBufferSize = 32;
|
| @@ -5347,15 +5363,14 @@ MaybeHandle<Object> Builtins::InvokeApiFunction(Handle<HeapObject> function,
|
| argv[argc - i + 1] = *args[i];
|
| }
|
| argv[1] = *function;
|
| - argv[0] = isolate->heap()->undefined_value(); // new target
|
| + argv[0] = *new_target;
|
| MaybeHandle<Object> result;
|
| {
|
| RelocatableArguments arguments(isolate, argc + 3, &argv[argc] + 2);
|
| - result = HandleApiCallHelper(isolate, arguments);
|
| - }
|
| - if (argv != small_argv) {
|
| - delete[] argv;
|
| + result = HandleApiCallHelper<false>(isolate, function, new_target, fun_data,
|
| + arguments);
|
| }
|
| + if (argv != small_argv) delete[] argv;
|
| return result;
|
| }
|
|
|
|
|