5 #ifndef V8_API_ARGUMENTS_INL_H_ 6 #define V8_API_ARGUMENTS_INL_H_ 8 #include "src/api-arguments.h" 10 #include "src/api-inl.h" 11 #include "src/debug/debug.h" 12 #include "src/objects/api-callbacks.h" 13 #include "src/objects/slots-inl.h" 14 #include "src/tracing/trace-event.h" 15 #include "src/vm-state-inl.h" 20 CustomArgumentsBase::CustomArgumentsBase(Isolate* isolate)
21 : Relocatable(isolate) {}
24 CustomArguments<T>::~CustomArguments() {
25 slot_at(kReturnValueOffset).store(ObjectPtr(kHandleZapValue));
30 Handle<V> CustomArguments<T>::GetReturnValue(Isolate* isolate) {
32 ObjectSlot slot = slot_at(kReturnValueOffset);
34 if ((*slot)->IsTheHole(isolate))
return Handle<V>();
35 Handle<V> result = Handle<V>::cast(Handle<Object>(slot.location()));
36 result->VerifyApiCallResultType();
40 inline JSObject* PropertyCallbackArguments::holder() {
41 return JSObject::cast(*slot_at(T::kHolderIndex));
44 inline Object* PropertyCallbackArguments::receiver() {
45 return Object::cast(*slot_at(T::kThisIndex));
48 inline JSObject* FunctionCallbackArguments::holder() {
49 return JSObject::cast(*slot_at(T::kHolderIndex));
52 #define FOR_EACH_CALLBACK(F) \ 53 F(Query, query, Object, v8::Integer, interceptor) \ 54 F(Deleter, deleter, Object, v8::Boolean, Handle<Object>()) 56 #define DCHECK_NAME_COMPATIBLE(interceptor, name) \ 57 DCHECK(interceptor->is_named()); \ 58 DCHECK(!name->IsPrivate()); \ 59 DCHECK_IMPLIES(name->IsSymbol(), interceptor->can_intercept_symbols()); 61 #define PREPARE_CALLBACK_INFO(ISOLATE, F, RETURN_VALUE, API_RETURN_TYPE, \ 62 CALLBACK_INFO, RECEIVER, ACCESSOR_KIND) \ 63 if (ISOLATE->debug_execution_mode() == DebugInfo::kSideEffects && \ 64 !ISOLATE->debug()->PerformSideEffectCheckForCallback( \ 65 CALLBACK_INFO, RECEIVER, Debug::k##ACCESSOR_KIND)) { \ 66 return RETURN_VALUE(); \ 68 VMState<EXTERNAL> state(ISOLATE); \ 69 ExternalCallbackScope call_scope(ISOLATE, FUNCTION_ADDR(F)); \ 70 PropertyCallbackInfo<API_RETURN_TYPE> callback_info(values_); 72 #define PREPARE_CALLBACK_INFO_FAIL_SIDE_EFFECT_CHECK(ISOLATE, F, RETURN_VALUE, \ 74 if (ISOLATE->debug_execution_mode() == DebugInfo::kSideEffects) { \ 75 return RETURN_VALUE(); \ 77 VMState<EXTERNAL> state(ISOLATE); \ 78 ExternalCallbackScope call_scope(ISOLATE, FUNCTION_ADDR(F)); \ 79 PropertyCallbackInfo<API_RETURN_TYPE> callback_info(values_); 81 #define CREATE_NAMED_CALLBACK(FUNCTION, TYPE, RETURN_TYPE, API_RETURN_TYPE, \ 82 INFO_FOR_SIDE_EFFECT) \ 83 Handle<RETURN_TYPE> PropertyCallbackArguments::CallNamed##FUNCTION( \ 84 Handle<InterceptorInfo> interceptor, Handle<Name> name) { \ 85 DCHECK_NAME_COMPATIBLE(interceptor, name); \ 86 Isolate* isolate = this->isolate(); \ 87 RuntimeCallTimerScope timer( \ 88 isolate, RuntimeCallCounterId::kNamed##FUNCTION##Callback); \ 89 Handle<Object> receiver_check_unsupported; \ 90 GenericNamedProperty##FUNCTION##Callback f = \ 91 ToCData<GenericNamedProperty##FUNCTION##Callback>( \ 92 interceptor->TYPE()); \ 93 PREPARE_CALLBACK_INFO(isolate, f, Handle<RETURN_TYPE>, API_RETURN_TYPE, \ 94 INFO_FOR_SIDE_EFFECT, receiver_check_unsupported, \ 97 ApiNamedPropertyAccess("interceptor-named-" #TYPE, holder(), *name)); \ 98 f(v8::Utils::ToLocal(name), callback_info); \ 99 return GetReturnValue<RETURN_TYPE>(isolate); \ 102 FOR_EACH_CALLBACK(CREATE_NAMED_CALLBACK)
103 #undef CREATE_NAMED_CALLBACK 105 #define CREATE_INDEXED_CALLBACK(FUNCTION, TYPE, RETURN_TYPE, API_RETURN_TYPE, \ 106 INFO_FOR_SIDE_EFFECT) \ 107 Handle<RETURN_TYPE> PropertyCallbackArguments::CallIndexed##FUNCTION( \ 108 Handle<InterceptorInfo> interceptor, uint32_t index) { \ 109 DCHECK(!interceptor->is_named()); \ 110 Isolate* isolate = this->isolate(); \ 111 RuntimeCallTimerScope timer( \ 112 isolate, RuntimeCallCounterId::kIndexed##FUNCTION##Callback); \ 113 Handle<Object> receiver_check_unsupported; \ 114 IndexedProperty##FUNCTION##Callback f = \ 115 ToCData<IndexedProperty##FUNCTION##Callback>(interceptor->TYPE()); \ 116 PREPARE_CALLBACK_INFO(isolate, f, Handle<RETURN_TYPE>, API_RETURN_TYPE, \ 117 INFO_FOR_SIDE_EFFECT, receiver_check_unsupported, \ 119 LOG(isolate, ApiIndexedPropertyAccess("interceptor-indexed-" #TYPE, \ 121 f(index, callback_info); \ 122 return GetReturnValue<RETURN_TYPE>(isolate); \ 125 FOR_EACH_CALLBACK(CREATE_INDEXED_CALLBACK)
127 #undef FOR_EACH_CALLBACK 128 #undef CREATE_INDEXED_CALLBACK 130 Handle<Object> FunctionCallbackArguments::Call(CallHandlerInfo* handler) {
131 Isolate* isolate = this->isolate();
132 LOG(isolate, ApiObjectAccess(
"call", holder()));
133 RuntimeCallTimerScope timer(isolate, RuntimeCallCounterId::kFunctionCallback);
134 v8::FunctionCallback f =
135 v8::ToCData<v8::FunctionCallback>(handler->callback());
136 Handle<Object> receiver_check_unsupported;
137 if (isolate->debug_execution_mode() == DebugInfo::kSideEffects &&
138 !isolate->debug()->PerformSideEffectCheckForCallback(
139 handle(handler, isolate), receiver_check_unsupported,
140 Debug::kNotAccessor)) {
141 return Handle<Object>();
143 VMState<EXTERNAL> state(isolate);
144 ExternalCallbackScope call_scope(isolate, FUNCTION_ADDR(f));
145 FunctionCallbackInfo<v8::Value> info(values_, argv_, argc_);
147 return GetReturnValue<Object>(isolate);
150 Handle<JSObject> PropertyCallbackArguments::CallNamedEnumerator(
151 Handle<InterceptorInfo> interceptor) {
152 DCHECK(interceptor->is_named());
153 LOG(isolate(), ApiObjectAccess(
"interceptor-named-enumerator", holder()));
154 RuntimeCallTimerScope timer(isolate(),
155 RuntimeCallCounterId::kNamedEnumeratorCallback);
156 return CallPropertyEnumerator(interceptor);
159 Handle<JSObject> PropertyCallbackArguments::CallIndexedEnumerator(
160 Handle<InterceptorInfo> interceptor) {
161 DCHECK(!interceptor->is_named());
162 LOG(isolate(), ApiObjectAccess(
"interceptor-indexed-enumerator", holder()));
163 RuntimeCallTimerScope timer(isolate(),
164 RuntimeCallCounterId::kIndexedEnumeratorCallback);
165 return CallPropertyEnumerator(interceptor);
168 Handle<Object> PropertyCallbackArguments::CallNamedGetter(
169 Handle<InterceptorInfo> interceptor, Handle<Name> name) {
170 DCHECK_NAME_COMPATIBLE(interceptor, name);
171 Isolate* isolate = this->isolate();
172 RuntimeCallTimerScope timer(isolate,
173 RuntimeCallCounterId::kNamedGetterCallback);
175 ApiNamedPropertyAccess(
"interceptor-named-getter", holder(), *name));
177 ToCData<GenericNamedPropertyGetterCallback>(interceptor->getter());
178 return BasicCallNamedGetterCallback(f, name, interceptor);
181 Handle<Object> PropertyCallbackArguments::CallNamedDescriptor(
182 Handle<InterceptorInfo> interceptor, Handle<Name> name) {
183 DCHECK_NAME_COMPATIBLE(interceptor, name);
184 Isolate* isolate = this->isolate();
185 RuntimeCallTimerScope timer(isolate,
186 RuntimeCallCounterId::kNamedDescriptorCallback);
188 ApiNamedPropertyAccess(
"interceptor-named-descriptor", holder(), *name));
190 ToCData<GenericNamedPropertyDescriptorCallback>(
191 interceptor->descriptor());
192 return BasicCallNamedGetterCallback(f, name, interceptor);
195 Handle<Object> PropertyCallbackArguments::BasicCallNamedGetterCallback(
197 Handle<Object> info, Handle<Object> receiver) {
198 DCHECK(!name->IsPrivate());
199 Isolate* isolate = this->isolate();
200 PREPARE_CALLBACK_INFO(isolate, f, Handle<Object>,
v8::Value, info, receiver,
202 f(v8::Utils::ToLocal(name), callback_info);
203 return GetReturnValue<Object>(isolate);
206 Handle<Object> PropertyCallbackArguments::CallNamedSetter(
207 Handle<InterceptorInfo> interceptor, Handle<Name> name,
208 Handle<Object> value) {
209 DCHECK_NAME_COMPATIBLE(interceptor, name);
211 ToCData<GenericNamedPropertySetterCallback>(interceptor->setter());
212 Isolate* isolate = this->isolate();
213 RuntimeCallTimerScope timer(isolate,
214 RuntimeCallCounterId::kNamedSetterCallback);
215 PREPARE_CALLBACK_INFO_FAIL_SIDE_EFFECT_CHECK(isolate, f, Handle<Object>,
218 ApiNamedPropertyAccess(
"interceptor-named-set", holder(), *name));
219 f(v8::Utils::ToLocal(name), v8::Utils::ToLocal(value), callback_info);
220 return GetReturnValue<Object>(isolate);
223 Handle<Object> PropertyCallbackArguments::CallNamedDefiner(
224 Handle<InterceptorInfo> interceptor, Handle<Name> name,
226 DCHECK_NAME_COMPATIBLE(interceptor, name);
227 Isolate* isolate = this->isolate();
228 RuntimeCallTimerScope timer(isolate,
229 RuntimeCallCounterId::kNamedDefinerCallback);
231 ToCData<GenericNamedPropertyDefinerCallback>(interceptor->definer());
232 PREPARE_CALLBACK_INFO_FAIL_SIDE_EFFECT_CHECK(isolate, f, Handle<Object>,
235 ApiNamedPropertyAccess(
"interceptor-named-define", holder(), *name));
236 f(v8::Utils::ToLocal(name), desc, callback_info);
237 return GetReturnValue<Object>(isolate);
240 Handle<Object> PropertyCallbackArguments::CallIndexedSetter(
241 Handle<InterceptorInfo> interceptor,
uint32_t index, Handle<Object> value) {
242 DCHECK(!interceptor->is_named());
243 Isolate* isolate = this->isolate();
244 RuntimeCallTimerScope timer(isolate,
245 RuntimeCallCounterId::kIndexedSetterCallback);
247 ToCData<IndexedPropertySetterCallback>(interceptor->setter());
248 PREPARE_CALLBACK_INFO_FAIL_SIDE_EFFECT_CHECK(isolate, f, Handle<Object>,
251 ApiIndexedPropertyAccess(
"interceptor-indexed-set", holder(), index));
252 f(index, v8::Utils::ToLocal(value), callback_info);
253 return GetReturnValue<Object>(isolate);
256 Handle<Object> PropertyCallbackArguments::CallIndexedDefiner(
257 Handle<InterceptorInfo> interceptor,
uint32_t index,
259 DCHECK(!interceptor->is_named());
260 Isolate* isolate = this->isolate();
261 RuntimeCallTimerScope timer(isolate,
262 RuntimeCallCounterId::kIndexedDefinerCallback);
264 ToCData<IndexedPropertyDefinerCallback>(interceptor->definer());
265 PREPARE_CALLBACK_INFO_FAIL_SIDE_EFFECT_CHECK(isolate, f, Handle<Object>,
268 ApiIndexedPropertyAccess(
"interceptor-indexed-define", holder(), index));
269 f(index, desc, callback_info);
270 return GetReturnValue<Object>(isolate);
273 Handle<Object> PropertyCallbackArguments::CallIndexedGetter(
274 Handle<InterceptorInfo> interceptor,
uint32_t index) {
275 DCHECK(!interceptor->is_named());
276 Isolate* isolate = this->isolate();
277 RuntimeCallTimerScope timer(isolate,
278 RuntimeCallCounterId::kNamedGetterCallback);
280 ApiIndexedPropertyAccess(
"interceptor-indexed-getter", holder(), index));
282 ToCData<IndexedPropertyGetterCallback>(interceptor->getter());
283 return BasicCallIndexedGetterCallback(f, index, interceptor);
286 Handle<Object> PropertyCallbackArguments::CallIndexedDescriptor(
287 Handle<InterceptorInfo> interceptor,
uint32_t index) {
288 DCHECK(!interceptor->is_named());
289 Isolate* isolate = this->isolate();
290 RuntimeCallTimerScope timer(isolate,
291 RuntimeCallCounterId::kIndexedDescriptorCallback);
292 LOG(isolate, ApiIndexedPropertyAccess(
"interceptor-indexed-descriptor",
295 ToCData<IndexedPropertyDescriptorCallback>(interceptor->descriptor());
296 return BasicCallIndexedGetterCallback(f, index, interceptor);
299 Handle<Object> PropertyCallbackArguments::BasicCallIndexedGetterCallback(
301 Isolate* isolate = this->isolate();
302 Handle<Object> receiver_check_unsupported;
303 PREPARE_CALLBACK_INFO(isolate, f, Handle<Object>,
v8::Value, info,
304 receiver_check_unsupported, Getter);
305 f(index, callback_info);
306 return GetReturnValue<Object>(isolate);
309 Handle<JSObject> PropertyCallbackArguments::CallPropertyEnumerator(
310 Handle<InterceptorInfo> interceptor) {
313 v8::ToCData<IndexedPropertyEnumeratorCallback>(interceptor->enumerator());
315 Isolate* isolate = this->isolate();
316 Handle<Object> receiver_check_unsupported;
317 PREPARE_CALLBACK_INFO(isolate, f, Handle<JSObject>,
v8::Array, interceptor,
318 receiver_check_unsupported, NotAccessor);
320 return GetReturnValue<JSObject>(isolate);
326 Handle<Object> PropertyCallbackArguments::CallAccessorGetter(
327 Handle<AccessorInfo> info, Handle<Name> name) {
328 Isolate* isolate = this->isolate();
329 RuntimeCallTimerScope timer(isolate,
330 RuntimeCallCounterId::kAccessorGetterCallback);
331 LOG(isolate, ApiNamedPropertyAccess(
"accessor-getter", holder(), *name));
332 AccessorNameGetterCallback f =
333 ToCData<AccessorNameGetterCallback>(info->getter());
334 return BasicCallNamedGetterCallback(f, name, info,
335 handle(receiver(), isolate));
338 Handle<Object> PropertyCallbackArguments::CallAccessorSetter(
339 Handle<AccessorInfo> accessor_info, Handle<Name> name,
340 Handle<Object> value) {
341 Isolate* isolate = this->isolate();
342 RuntimeCallTimerScope timer(isolate,
343 RuntimeCallCounterId::kAccessorSetterCallback);
344 AccessorNameSetterCallback f =
345 ToCData<AccessorNameSetterCallback>(accessor_info->setter());
346 PREPARE_CALLBACK_INFO(isolate, f, Handle<Object>,
void, accessor_info,
347 handle(receiver(), isolate), Setter);
348 LOG(isolate, ApiNamedPropertyAccess(
"accessor-setter", holder(), *name));
349 f(v8::Utils::ToLocal(name), v8::Utils::ToLocal(value), callback_info);
350 return GetReturnValue<Object>(isolate);
353 #undef PREPARE_CALLBACK_INFO 354 #undef PREPARE_CALLBACK_INFO_FAIL_SIDE_EFFECT_CHECK 359 #endif // V8_API_ARGUMENTS_INL_H_ void(* GenericNamedPropertyDefinerCallback)(Local< Name > property, const PropertyDescriptor &desc, const PropertyCallbackInfo< Value > &info)
void(* IndexedPropertyDescriptorCallback)(uint32_t index, const PropertyCallbackInfo< Value > &info)
void(* IndexedPropertyDefinerCallback)(uint32_t index, const PropertyDescriptor &desc, const PropertyCallbackInfo< Value > &info)
void(* GenericNamedPropertyDescriptorCallback)(Local< Name > property, const PropertyCallbackInfo< Value > &info)
void(* IndexedPropertyGetterCallback)(uint32_t index, const PropertyCallbackInfo< Value > &info)
void(* IndexedPropertySetterCallback)(uint32_t index, Local< Value > value, const PropertyCallbackInfo< Value > &info)
void(* IndexedPropertyEnumeratorCallback)(const PropertyCallbackInfo< Array > &info)
void(* GenericNamedPropertyGetterCallback)(Local< Name > property, const PropertyCallbackInfo< Value > &info)
void(* GenericNamedPropertySetterCallback)(Local< Name > property, Local< Value > value, const PropertyCallbackInfo< Value > &info)