| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 1 | // Copyright 2016 the V8 project authors. All rights reserved. | 
 | 2 | // Use of this source code is governed by a BSD-style license that can be | 
 | 3 | // found in the LICENSE file. | 
 | 4 |  | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 5 | #include "src/api/api-arguments-inl.h" | 
 | 6 | #include "src/api/api-natives.h" | 
 | 7 | #include "src/builtins/builtins-utils-inl.h" | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 8 | #include "src/builtins/builtins.h" | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 9 | #include "src/logging/counters.h" | 
 | 10 | #include "src/logging/log.h" | 
 | 11 | #include "src/objects/objects-inl.h" | 
 | 12 | #include "src/objects/prototype.h" | 
 | 13 | #include "src/objects/templates.h" | 
 | 14 | #include "src/objects/visitors.h" | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 15 |  | 
 | 16 | namespace v8 { | 
 | 17 | namespace internal { | 
 | 18 |  | 
 | 19 | namespace { | 
 | 20 |  | 
 | 21 | // Returns the holder JSObject if the function can legally be called with this | 
 | 22 | // receiver.  Returns nullptr if the call is illegal. | 
 | 23 | // TODO(dcarney): CallOptimization duplicates this logic, merge. | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 24 | JSReceiver GetCompatibleReceiver(Isolate* isolate, FunctionTemplateInfo info, | 
 | 25 |                                  JSReceiver receiver) { | 
 | 26 |   Object recv_type = info.signature(); | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 27 |   // No signature, return holder. | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 28 |   if (!recv_type.IsFunctionTemplateInfo()) return receiver; | 
 | 29 |   // A Proxy cannot have been created from the signature template. | 
 | 30 |   if (!receiver.IsJSObject()) return JSReceiver(); | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 31 |  | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 32 |   JSObject js_obj_receiver = JSObject::cast(receiver); | 
 | 33 |   FunctionTemplateInfo signature = FunctionTemplateInfo::cast(recv_type); | 
 | 34 |  | 
 | 35 |   // Check the receiver. | 
 | 36 |   if (signature.IsTemplateFor(js_obj_receiver)) return receiver; | 
 | 37 |  | 
 | 38 |   // The JSGlobalProxy might have a hidden prototype. | 
 | 39 |   if (V8_UNLIKELY(js_obj_receiver.IsJSGlobalProxy())) { | 
 | 40 |     HeapObject prototype = js_obj_receiver.map().prototype(); | 
 | 41 |     if (!prototype.IsNull(isolate)) { | 
 | 42 |       JSObject js_obj_prototype = JSObject::cast(prototype); | 
 | 43 |       if (signature.IsTemplateFor(js_obj_prototype)) return js_obj_prototype; | 
 | 44 |     } | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 45 |   } | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 46 |   return JSReceiver(); | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 47 | } | 
 | 48 |  | 
 | 49 | template <bool is_construct> | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 50 | V8_WARN_UNUSED_RESULT MaybeHandle<Object> HandleApiCallHelper( | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 51 |     Isolate* isolate, Handle<HeapObject> function, | 
 | 52 |     Handle<HeapObject> new_target, Handle<FunctionTemplateInfo> fun_data, | 
 | 53 |     Handle<Object> receiver, BuiltinArguments args) { | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 54 |   Handle<JSReceiver> js_receiver; | 
 | 55 |   JSReceiver raw_holder; | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 56 |   if (is_construct) { | 
 | 57 |     DCHECK(args.receiver()->IsTheHole(isolate)); | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 58 |     if (fun_data->GetInstanceTemplate().IsUndefined(isolate)) { | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 59 |       v8::Local<ObjectTemplate> templ = | 
 | 60 |           ObjectTemplate::New(reinterpret_cast<v8::Isolate*>(isolate), | 
 | 61 |                               ToApiHandle<v8::FunctionTemplate>(fun_data)); | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 62 |       FunctionTemplateInfo::SetInstanceTemplate(isolate, fun_data, | 
 | 63 |                                                 Utils::OpenHandle(*templ)); | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 64 |     } | 
 | 65 |     Handle<ObjectTemplateInfo> instance_template( | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 66 |         ObjectTemplateInfo::cast(fun_data->GetInstanceTemplate()), isolate); | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 67 |     ASSIGN_RETURN_ON_EXCEPTION( | 
 | 68 |         isolate, js_receiver, | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 69 |         ApiNatives::InstantiateObject(isolate, instance_template, | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 70 |                                       Handle<JSReceiver>::cast(new_target)), | 
 | 71 |         Object); | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 72 |     args.set_at(0, *js_receiver); | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 73 |     DCHECK_EQ(*js_receiver, *args.receiver()); | 
 | 74 |  | 
 | 75 |     raw_holder = *js_receiver; | 
 | 76 |   } else { | 
 | 77 |     DCHECK(receiver->IsJSReceiver()); | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 78 |     js_receiver = Handle<JSReceiver>::cast(receiver); | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 79 |  | 
 | 80 |     if (!fun_data->accept_any_receiver() && | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 81 |         js_receiver->IsAccessCheckNeeded()) { | 
 | 82 |       // Proxies never need access checks. | 
 | 83 |       DCHECK(js_receiver->IsJSObject()); | 
 | 84 |       Handle<JSObject> js_obj_receiver = Handle<JSObject>::cast(js_receiver); | 
 | 85 |       if (!isolate->MayAccess(handle(isolate->context(), isolate), | 
 | 86 |                               js_obj_receiver)) { | 
 | 87 |         isolate->ReportFailedAccessCheck(js_obj_receiver); | 
 | 88 |         RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 
 | 89 |         return isolate->factory()->undefined_value(); | 
 | 90 |       } | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 91 |     } | 
 | 92 |  | 
 | 93 |     raw_holder = GetCompatibleReceiver(isolate, *fun_data, *js_receiver); | 
 | 94 |  | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 95 |     if (raw_holder.is_null()) { | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 96 |       // This function cannot be called with the given receiver.  Abort! | 
 | 97 |       THROW_NEW_ERROR( | 
 | 98 |           isolate, NewTypeError(MessageTemplate::kIllegalInvocation), Object); | 
 | 99 |     } | 
 | 100 |   } | 
 | 101 |  | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 102 |   Object raw_call_data = fun_data->call_code(kAcquireLoad); | 
 | 103 |   if (!raw_call_data.IsUndefined(isolate)) { | 
 | 104 |     DCHECK(raw_call_data.IsCallHandlerInfo()); | 
 | 105 |     CallHandlerInfo call_data = CallHandlerInfo::cast(raw_call_data); | 
 | 106 |     Object data_obj = call_data.data(); | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 107 |  | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 108 |     FunctionCallbackArguments custom( | 
 | 109 |         isolate, data_obj, *function, raw_holder, *new_target, | 
 | 110 |         args.address_of_first_argument(), args.length() - 1); | 
 | 111 |     Handle<Object> result = custom.Call(call_data); | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 112 |  | 
 | 113 |     RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 
 | 114 |     if (result.is_null()) { | 
 | 115 |       if (is_construct) return js_receiver; | 
 | 116 |       return isolate->factory()->undefined_value(); | 
 | 117 |     } | 
 | 118 |     // Rebox the result. | 
 | 119 |     result->VerifyApiCallResultType(); | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 120 |     if (!is_construct || result->IsJSReceiver()) | 
 | 121 |       return handle(*result, isolate); | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 122 |   } | 
 | 123 |  | 
 | 124 |   return js_receiver; | 
 | 125 | } | 
 | 126 |  | 
 | 127 | }  // anonymous namespace | 
 | 128 |  | 
 | 129 | BUILTIN(HandleApiCall) { | 
 | 130 |   HandleScope scope(isolate); | 
| Ben Murdoch | c8c1d9e | 2017-03-08 14:04:23 +0000 | [diff] [blame] | 131 |   Handle<JSFunction> function = args.target(); | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 132 |   Handle<Object> receiver = args.receiver(); | 
 | 133 |   Handle<HeapObject> new_target = args.new_target(); | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 134 |   Handle<FunctionTemplateInfo> fun_data(function->shared().get_api_func_data(), | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 135 |                                         isolate); | 
 | 136 |   if (new_target->IsJSReceiver()) { | 
 | 137 |     RETURN_RESULT_OR_FAILURE( | 
 | 138 |         isolate, HandleApiCallHelper<true>(isolate, function, new_target, | 
 | 139 |                                            fun_data, receiver, args)); | 
 | 140 |   } else { | 
 | 141 |     RETURN_RESULT_OR_FAILURE( | 
 | 142 |         isolate, HandleApiCallHelper<false>(isolate, function, new_target, | 
 | 143 |                                             fun_data, receiver, args)); | 
 | 144 |   } | 
 | 145 | } | 
 | 146 |  | 
 | 147 | namespace { | 
 | 148 |  | 
 | 149 | class RelocatableArguments : public BuiltinArguments, public Relocatable { | 
 | 150 |  public: | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 151 |   RelocatableArguments(Isolate* isolate, int length, Address* arguments) | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 152 |       : BuiltinArguments(length, arguments), Relocatable(isolate) {} | 
 | 153 |  | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 154 |   inline void IterateInstance(RootVisitor* v) override { | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 155 |     if (length() == 0) return; | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 156 |     v->VisitRootPointers(Root::kRelocatable, nullptr, first_slot(), | 
 | 157 |                          last_slot() + 1); | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 158 |   } | 
 | 159 |  | 
 | 160 |  private: | 
 | 161 |   DISALLOW_COPY_AND_ASSIGN(RelocatableArguments); | 
 | 162 | }; | 
 | 163 |  | 
 | 164 | }  // namespace | 
 | 165 |  | 
 | 166 | MaybeHandle<Object> Builtins::InvokeApiFunction(Isolate* isolate, | 
 | 167 |                                                 bool is_construct, | 
 | 168 |                                                 Handle<HeapObject> function, | 
 | 169 |                                                 Handle<Object> receiver, | 
 | 170 |                                                 int argc, Handle<Object> args[], | 
 | 171 |                                                 Handle<HeapObject> new_target) { | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 172 |   RuntimeCallTimerScope timer(isolate, | 
 | 173 |                               RuntimeCallCounterId::kInvokeApiFunction); | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 174 |   DCHECK(function->IsFunctionTemplateInfo() || | 
 | 175 |          (function->IsJSFunction() && | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 176 |           JSFunction::cast(*function).shared().IsApiFunction())); | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 177 |  | 
 | 178 |   // Do proper receiver conversion for non-strict mode api functions. | 
 | 179 |   if (!is_construct && !receiver->IsJSReceiver()) { | 
 | 180 |     if (function->IsFunctionTemplateInfo() || | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 181 |         is_sloppy(JSFunction::cast(*function).shared().language_mode())) { | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 182 |       ASSIGN_RETURN_ON_EXCEPTION(isolate, receiver, | 
 | 183 |                                  Object::ConvertReceiver(isolate, receiver), | 
 | 184 |                                  Object); | 
 | 185 |     } | 
 | 186 |   } | 
 | 187 |  | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 188 |   // We assume that all lazy accessor pairs have been instantiated when setting | 
 | 189 |   // a break point on any API function. | 
 | 190 |   DCHECK_IMPLIES(function->IsFunctionTemplateInfo(), | 
 | 191 |                  !Handle<FunctionTemplateInfo>::cast(function)->BreakAtEntry()); | 
 | 192 |  | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 193 |   Handle<FunctionTemplateInfo> fun_data = | 
 | 194 |       function->IsFunctionTemplateInfo() | 
 | 195 |           ? Handle<FunctionTemplateInfo>::cast(function) | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 196 |           : handle(JSFunction::cast(*function).shared().get_api_func_data(), | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 197 |                    isolate); | 
 | 198 |   // Construct BuiltinArguments object: | 
 | 199 |   // new target, function, arguments reversed, receiver. | 
 | 200 |   const int kBufferSize = 32; | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 201 |   Address small_argv[kBufferSize]; | 
 | 202 |   Address* argv; | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 203 |   const int frame_argc = argc + BuiltinArguments::kNumExtraArgsWithReceiver; | 
 | 204 |   if (frame_argc <= kBufferSize) { | 
 | 205 |     argv = small_argv; | 
 | 206 |   } else { | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 207 |     argv = new Address[frame_argc]; | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 208 |   } | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 209 |   argv[BuiltinArguments::kNewTargetOffset] = new_target->ptr(); | 
 | 210 |   argv[BuiltinArguments::kTargetOffset] = function->ptr(); | 
 | 211 |   argv[BuiltinArguments::kArgcOffset] = Smi::FromInt(frame_argc).ptr(); | 
 | 212 |   argv[BuiltinArguments::kPaddingOffset] = | 
 | 213 |       ReadOnlyRoots(isolate).the_hole_value().ptr(); | 
 | 214 |   int cursor = BuiltinArguments::kNumExtraArgs; | 
 | 215 |   argv[cursor++] = receiver->ptr(); | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 216 |   for (int i = 0; i < argc; ++i) { | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 217 |     argv[cursor++] = args[i]->ptr(); | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 218 |   } | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 219 |   MaybeHandle<Object> result; | 
 | 220 |   { | 
 | 221 |     RelocatableArguments arguments(isolate, frame_argc, &argv[frame_argc - 1]); | 
 | 222 |     if (is_construct) { | 
 | 223 |       result = HandleApiCallHelper<true>(isolate, function, new_target, | 
 | 224 |                                          fun_data, receiver, arguments); | 
 | 225 |     } else { | 
 | 226 |       result = HandleApiCallHelper<false>(isolate, function, new_target, | 
 | 227 |                                           fun_data, receiver, arguments); | 
 | 228 |     } | 
 | 229 |   } | 
 | 230 |   if (argv != small_argv) delete[] argv; | 
 | 231 |   return result; | 
 | 232 | } | 
 | 233 |  | 
 | 234 | // Helper function to handle calls to non-function objects created through the | 
 | 235 | // API. The object can be called as either a constructor (using new) or just as | 
 | 236 | // a function (without new). | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 237 | V8_WARN_UNUSED_RESULT static Object HandleApiCallAsFunctionOrConstructor( | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 238 |     Isolate* isolate, bool is_construct_call, BuiltinArguments args) { | 
 | 239 |   Handle<Object> receiver = args.receiver(); | 
 | 240 |  | 
 | 241 |   // Get the object called. | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 242 |   JSObject obj = JSObject::cast(*receiver); | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 243 |  | 
 | 244 |   // Set the new target. | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 245 |   HeapObject new_target; | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 246 |   if (is_construct_call) { | 
 | 247 |     // TODO(adamk): This should be passed through in args instead of | 
 | 248 |     // being patched in here. We need to set a non-undefined value | 
 | 249 |     // for v8::FunctionCallbackInfo::IsConstructCall() to get the | 
 | 250 |     // right answer. | 
 | 251 |     new_target = obj; | 
 | 252 |   } else { | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 253 |     new_target = ReadOnlyRoots(isolate).undefined_value(); | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 254 |   } | 
 | 255 |  | 
 | 256 |   // Get the invocation callback from the function descriptor that was | 
 | 257 |   // used to create the called object. | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 258 |   DCHECK(obj.map().is_callable()); | 
 | 259 |   JSFunction constructor = JSFunction::cast(obj.map().GetConstructor()); | 
 | 260 |   DCHECK(constructor.shared().IsApiFunction()); | 
 | 261 |   Object handler = | 
 | 262 |       constructor.shared().get_api_func_data().GetInstanceCallHandler(); | 
 | 263 |   DCHECK(!handler.IsUndefined(isolate)); | 
 | 264 |   CallHandlerInfo call_data = CallHandlerInfo::cast(handler); | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 265 |  | 
 | 266 |   // Get the data for the call and perform the callback. | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 267 |   Object result; | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 268 |   { | 
 | 269 |     HandleScope scope(isolate); | 
 | 270 |     LOG(isolate, ApiObjectAccess("call non-function", obj)); | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 271 |     FunctionCallbackArguments custom( | 
 | 272 |         isolate, call_data.data(), constructor, obj, new_target, | 
 | 273 |         args.address_of_first_argument(), args.length() - 1); | 
 | 274 |     Handle<Object> result_handle = custom.Call(call_data); | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 275 |     if (result_handle.is_null()) { | 
| Rubin Xu | 7bc1b61 | 2021-02-16 09:38:50 +0000 | [diff] [blame^] | 276 |       result = ReadOnlyRoots(isolate).undefined_value(); | 
| Ben Murdoch | f91f061 | 2016-11-29 16:50:11 +0000 | [diff] [blame] | 277 |     } else { | 
 | 278 |       result = *result_handle; | 
 | 279 |     } | 
 | 280 |   } | 
 | 281 |   // Check for exceptions and return result. | 
 | 282 |   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); | 
 | 283 |   return result; | 
 | 284 | } | 
 | 285 |  | 
 | 286 | // Handle calls to non-function objects created through the API. This delegate | 
 | 287 | // function is used when the call is a normal function call. | 
 | 288 | BUILTIN(HandleApiCallAsFunction) { | 
 | 289 |   return HandleApiCallAsFunctionOrConstructor(isolate, false, args); | 
 | 290 | } | 
 | 291 |  | 
 | 292 | // Handle calls to non-function objects created through the API. This delegate | 
 | 293 | // function is used when the call is a construct call. | 
 | 294 | BUILTIN(HandleApiCallAsConstructor) { | 
 | 295 |   return HandleApiCallAsFunctionOrConstructor(isolate, true, args); | 
 | 296 | } | 
 | 297 |  | 
 | 298 | }  // namespace internal | 
 | 299 | }  // namespace v8 |