5 #include "src/api-arguments-inl.h" 6 #include "src/api-natives.h" 7 #include "src/builtins/builtins-utils-inl.h" 8 #include "src/builtins/builtins.h" 9 #include "src/counters.h" 11 #include "src/objects-inl.h" 12 #include "src/objects/templates.h" 13 #include "src/prototype.h" 14 #include "src/visitors.h" 24 JSReceiver* GetCompatibleReceiver(Isolate* isolate, FunctionTemplateInfo* info,
25 JSReceiver* receiver) {
26 Object* recv_type = info->signature();
28 if (!recv_type->IsFunctionTemplateInfo())
return receiver;
30 if (!receiver->IsJSObject())
return nullptr;
32 JSObject* js_obj_receiver = JSObject::cast(receiver);
33 FunctionTemplateInfo* signature = FunctionTemplateInfo::cast(recv_type);
36 if (signature->IsTemplateFor(js_obj_receiver))
return receiver;
37 if (!js_obj_receiver->map()->has_hidden_prototype())
return nullptr;
38 for (PrototypeIterator iter(isolate, js_obj_receiver, kStartAtPrototype,
39 PrototypeIterator::END_AT_NON_HIDDEN);
40 !iter.IsAtEnd(); iter.Advance()) {
41 JSObject* current = iter.GetCurrent<JSObject>();
42 if (signature->IsTemplateFor(current))
return current;
47 template <
bool is_construct>
48 V8_WARN_UNUSED_RESULT MaybeHandle<Object> HandleApiCallHelper(
49 Isolate* isolate, Handle<HeapObject>
function,
50 Handle<HeapObject> new_target, Handle<FunctionTemplateInfo> fun_data,
51 Handle<Object> receiver, BuiltinArguments args) {
52 Handle<JSReceiver> js_receiver;
53 JSReceiver* raw_holder;
55 DCHECK(args.receiver()->IsTheHole(isolate));
56 if (fun_data->GetInstanceTemplate()->IsUndefined(isolate)) {
59 ToApiHandle<v8::FunctionTemplate>(fun_data));
60 FunctionTemplateInfo::SetInstanceTemplate(isolate, fun_data,
61 Utils::OpenHandle(*templ));
63 Handle<ObjectTemplateInfo> instance_template(
64 ObjectTemplateInfo::cast(fun_data->GetInstanceTemplate()), isolate);
65 ASSIGN_RETURN_ON_EXCEPTION(
67 ApiNatives::InstantiateObject(isolate, instance_template,
68 Handle<JSReceiver>::cast(new_target)),
70 args.set_at(0, *js_receiver);
71 DCHECK_EQ(*js_receiver, *args.receiver());
73 raw_holder = *js_receiver;
75 DCHECK(receiver->IsJSReceiver());
76 js_receiver = Handle<JSReceiver>::cast(receiver);
78 if (!fun_data->accept_any_receiver() &&
79 js_receiver->IsAccessCheckNeeded()) {
81 DCHECK(js_receiver->IsJSObject());
82 Handle<JSObject> js_obj_receiver = Handle<JSObject>::cast(js_receiver);
83 if (!isolate->MayAccess(handle(isolate->context(), isolate),
85 isolate->ReportFailedAccessCheck(js_obj_receiver);
86 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
87 return isolate->factory()->undefined_value();
91 raw_holder = GetCompatibleReceiver(isolate, *fun_data, *js_receiver);
93 if (raw_holder ==
nullptr) {
96 isolate, NewTypeError(MessageTemplate::kIllegalInvocation), Object);
100 Object* raw_call_data = fun_data->call_code();
101 if (!raw_call_data->IsUndefined(isolate)) {
102 DCHECK(raw_call_data->IsCallHandlerInfo());
103 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data);
104 Object* data_obj = call_data->data();
106 FunctionCallbackArguments custom(isolate, data_obj, *
function, raw_holder,
107 *new_target, args.address_of_arg_at(1),
109 Handle<Object> result = custom.Call(call_data);
111 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
112 if (result.is_null()) {
113 if (is_construct)
return js_receiver;
114 return isolate->factory()->undefined_value();
117 result->VerifyApiCallResultType();
118 if (!is_construct || result->IsJSReceiver())
119 return handle(*result, isolate);
127 BUILTIN(HandleApiCall) {
128 HandleScope scope(isolate);
129 Handle<JSFunction>
function = args.target();
130 Handle<Object> receiver = args.receiver();
131 Handle<HeapObject> new_target = args.new_target();
132 Handle<FunctionTemplateInfo> fun_data(function->shared()->get_api_func_data(),
134 if (new_target->IsJSReceiver()) {
135 RETURN_RESULT_OR_FAILURE(
136 isolate, HandleApiCallHelper<true>(isolate,
function, new_target,
137 fun_data, receiver, args));
139 RETURN_RESULT_OR_FAILURE(
140 isolate, HandleApiCallHelper<false>(isolate,
function, new_target,
141 fun_data, receiver, args));
147 class RelocatableArguments :
public BuiltinArguments,
public Relocatable {
149 RelocatableArguments(Isolate* isolate,
int length, Address* arguments)
150 : BuiltinArguments(length, arguments), Relocatable(isolate) {}
152 inline void IterateInstance(RootVisitor* v)
override {
153 if (length() == 0)
return;
154 v->VisitRootPointers(Root::kRelocatable,
nullptr, first_slot(),
159 DISALLOW_COPY_AND_ASSIGN(RelocatableArguments);
164 MaybeHandle<Object> Builtins::InvokeApiFunction(Isolate* isolate,
166 Handle<HeapObject>
function,
167 Handle<Object> receiver,
168 int argc, Handle<Object> args[],
169 Handle<HeapObject> new_target) {
170 DCHECK(function->IsFunctionTemplateInfo() ||
171 (
function->IsJSFunction() &&
172 JSFunction::cast(*function)->shared()->IsApiFunction()));
175 if (!is_construct && !receiver->IsJSReceiver()) {
176 if (function->IsFunctionTemplateInfo() ||
177 is_sloppy(JSFunction::cast(*function)->shared()->language_mode())) {
178 ASSIGN_RETURN_ON_EXCEPTION(isolate, receiver,
179 Object::ConvertReceiver(isolate, receiver),
184 if (function->IsFunctionTemplateInfo()) {
185 Handle<FunctionTemplateInfo> info =
186 Handle<FunctionTemplateInfo>::cast(
function);
189 if (info->BreakAtEntry()) {
190 DCHECK(!is_construct);
191 DCHECK(new_target->IsUndefined(isolate));
192 Handle<JSFunction>
function;
193 ASSIGN_RETURN_ON_EXCEPTION(isolate,
function,
194 ApiNatives::InstantiateFunction(
195 info, MaybeHandle<v8::internal::Name>()),
197 Handle<Code> trampoline = BUILTIN_CODE(isolate, DebugBreakTrampoline);
198 function->set_code(*trampoline);
199 return Execution::Call(isolate,
function, receiver, argc, args);
203 Handle<FunctionTemplateInfo> fun_data =
204 function->IsFunctionTemplateInfo()
205 ? Handle<FunctionTemplateInfo>::cast(
function)
206 : handle(JSFunction::cast(*function)->shared()->get_api_func_data(),
210 const int kBufferSize = 32;
211 Address small_argv[kBufferSize];
213 const int frame_argc = argc + BuiltinArguments::kNumExtraArgsWithReceiver;
214 if (frame_argc <= kBufferSize) {
217 argv =
new Address[frame_argc];
219 int cursor = frame_argc - 1;
220 argv[cursor--] = receiver->ptr();
221 for (
int i = 0;
i < argc; ++
i) {
222 argv[cursor--] = args[
i]->ptr();
224 DCHECK_EQ(cursor, BuiltinArguments::kPaddingOffset);
225 argv[BuiltinArguments::kPaddingOffset] =
226 ReadOnlyRoots(isolate).the_hole_value()->ptr();
227 argv[BuiltinArguments::kArgcOffset] = Smi::FromInt(frame_argc)->ptr();
228 argv[BuiltinArguments::kTargetOffset] =
function->ptr();
229 argv[BuiltinArguments::kNewTargetOffset] = new_target->ptr();
230 MaybeHandle<Object> result;
232 RelocatableArguments arguments(isolate, frame_argc, &argv[frame_argc - 1]);
234 result = HandleApiCallHelper<true>(isolate,
function, new_target,
235 fun_data, receiver, arguments);
237 result = HandleApiCallHelper<false>(isolate,
function, new_target,
238 fun_data, receiver, arguments);
241 if (argv != small_argv)
delete[] argv;
248 V8_WARN_UNUSED_RESULT
static Object* HandleApiCallAsFunctionOrConstructor(
249 Isolate* isolate,
bool is_construct_call, BuiltinArguments args) {
250 Handle<Object> receiver = args.receiver();
253 JSObject* obj = JSObject::cast(*receiver);
256 HeapObject* new_target;
257 if (is_construct_call) {
264 new_target = ReadOnlyRoots(isolate).undefined_value();
269 DCHECK(obj->map()->is_callable());
270 JSFunction* constructor = JSFunction::cast(obj->map()->GetConstructor());
272 CHECK(constructor->shared()->IsApiFunction());
274 constructor->shared()->get_api_func_data()->GetInstanceCallHandler();
275 DCHECK(!handler->IsUndefined(isolate));
276 CallHandlerInfo* call_data = CallHandlerInfo::cast(handler);
281 HandleScope scope(isolate);
282 LOG(isolate, ApiObjectAccess(
"call non-function", obj));
283 FunctionCallbackArguments custom(isolate, call_data->data(), constructor,
284 obj, new_target, args.address_of_arg_at(1),
286 Handle<Object> result_handle = custom.Call(call_data);
287 if (result_handle.is_null()) {
288 result = ReadOnlyRoots(isolate).undefined_value();
290 result = *result_handle;
294 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
300 BUILTIN(HandleApiCallAsFunction) {
301 return HandleApiCallAsFunctionOrConstructor(isolate,
false, args);
306 BUILTIN(HandleApiCallAsConstructor) {
307 return HandleApiCallAsFunctionOrConstructor(isolate,
true, args);
static Local< ObjectTemplate > New(Isolate *isolate, Local< FunctionTemplate > constructor=Local< FunctionTemplate >())