#ifndef V8_API_API_ARGUMENTS_INL_H_
#define V8_API_API_ARGUMENTS_INL_H_
#include "src/api/api-arguments.h"
#include "src/api/api-inl.h"
#include "src/debug/debug.h"
#include "src/execution/vm-state-inl.h"
#include "src/logging/runtime-call-stats-scope.h"
#include "src/objects/api-callbacks.h"
#include "src/objects/instance-type.h"
#include "src/objects/slots-inl.h"
namespace v8 {
namespace internal {
CustomArgumentsBase::CustomArgumentsBase(Isolate* isolate)
: Relocatable(isolate) {}
template <typename T>
CustomArguments<T>::~CustomArguments() {
slot_at(kReturnValueIndex).store(Tagged<Object>(kHandleZapValue));
}
template <typename T>
template <typename V>
Handle<V> CustomArguments<T>::GetReturnValue(Isolate* isolate) const {
FullObjectSlot slot = slot_at(kReturnValueIndex);
DCHECK(Is<JSAny>(*slot));
return Cast<V>(Handle<Object>(slot.location()));
}
inline DirectHandle<JSObject> PropertyCallbackArguments::holder() const {
return DirectHandle<JSObject>::FromSlot(slot_at(T::kHolderIndex).location());
}
inline DirectHandle<Object> PropertyCallbackArguments::receiver() const {
return DirectHandle<Object>::FromSlot(slot_at(T::kThisIndex).location());
}
#define DCHECK_NAME_COMPATIBLE(interceptor, name) \
DCHECK(interceptor->is_named()); \
DCHECK(!name->IsPrivate()); \
DCHECK_IMPLIES(IsSymbol(*name), interceptor->can_intercept_symbols());
#define PREPARE_CALLBACK_INFO_ACCESSOR(ISOLATE, F, API_RETURN_TYPE, \
ACCESSOR_INFO, RECEIVER, ACCESSOR_KIND, \
EXCEPTION_CONTEXT) \
if (ISOLATE->should_check_side_effects() && \
!ISOLATE->debug()->PerformSideEffectCheckForAccessor( \
ACCESSOR_INFO, RECEIVER, ACCESSOR_KIND)) { \
return {}; \
} \
const PropertyCallbackInfo<API_RETURN_TYPE>& callback_info = \
GetPropertyCallbackInfo<API_RETURN_TYPE>(); \
ExternalCallbackScope call_scope(ISOLATE, FUNCTION_ADDR(F), \
EXCEPTION_CONTEXT, &callback_info);
#define PREPARE_CALLBACK_INFO_INTERCEPTOR(ISOLATE, F, API_RETURN_TYPE, \
INTERCEPTOR_INFO, EXCEPTION_CONTEXT) \
if (ISOLATE->should_check_side_effects() && \
!ISOLATE->debug()->PerformSideEffectCheckForInterceptor( \
INTERCEPTOR_INFO)) { \
return {}; \
} \
const PropertyCallbackInfo<API_RETURN_TYPE>& callback_info = \
GetPropertyCallbackInfo<API_RETURN_TYPE>(); \
ExternalCallbackScope call_scope(ISOLATE, FUNCTION_ADDR(F), \
EXCEPTION_CONTEXT, &callback_info);
FunctionCallbackArguments::FunctionCallbackArguments(
Isolate* isolate, Tagged<FunctionTemplateInfo> target,
Tagged<HeapObject> new_target, Address* argv, int argc)
: Super(isolate), argv_(argv), argc_(argc) {
slot_at(T::kTargetIndex).store(target);
slot_at(T::kUnusedIndex).store(ReadOnlyRoots(isolate).undefined_value());
slot_at(T::kNewTargetIndex).store(new_target);
slot_at(T::kIsolateIndex)
.store(Tagged<Object>(reinterpret_cast<Address>(isolate)));
slot_at(T::kReturnValueIndex).store(ReadOnlyRoots(isolate).undefined_value());
slot_at(T::kContextIndex).store(isolate->context());
DCHECK(IsSmi(*slot_at(T::kIsolateIndex)));
}
DirectHandle<Object> FunctionCallbackArguments::CallOrConstruct(
Tagged<FunctionTemplateInfo> function, bool is_construct) {
Isolate* isolate = this->isolate();
RCS_SCOPE(isolate, RuntimeCallCounterId::kFunctionCallback);
HITRACE_RCS_SCOPE(isolate, RuntimeCallCounterId::kFunctionCallback);
v8::FunctionCallback f =
reinterpret_cast<v8::FunctionCallback>(function->callback(isolate));
if (isolate->should_check_side_effects() &&
!isolate->debug()->PerformSideEffectCheckForCallback(
handle(function, isolate))) {
return {};
}
FunctionCallbackInfo<v8::Value> info(values_, argv_, argc_);
ExternalCallbackScope call_scope(isolate, FUNCTION_ADDR(f),
is_construct ? ExceptionContext::kConstructor
: ExceptionContext::kOperation,
&info);
f(info);
return GetReturnValue<Object>(isolate);
}
PropertyCallbackArguments::PropertyCallbackArguments(
Isolate* isolate, Tagged<Object> self, Tagged<JSObject> holder,
Maybe<ShouldThrow> should_throw)
: Super(isolate)
#ifdef DEBUG
,
javascript_execution_counter_(isolate->javascript_execution_counter())
#endif
{
if (DEBUG_BOOL) {
Tagged<Object> zap_value(kZapValue);
slot_at(T::kPropertyKeyIndex).store(zap_value);
slot_at(T::kReturnValueIndex).store(zap_value);
slot_at(T::kCallbackInfoIndex).store(zap_value);
}
slot_at(T::kThisIndex).store(self);
slot_at(T::kHolderIndex).store(holder);
DCHECK(!IsJSGlobalObject(*holder));
slot_at(T::kIsolateIndex)
.store(Tagged<Object>(reinterpret_cast<Address>(isolate)));
int value = Internals::kInferShouldThrowMode;
if (should_throw.IsJust()) {
value = should_throw.FromJust();
}
slot_at(T::kShouldThrowOnErrorIndex).store(Smi::FromInt(value));
slot_at(T::kUnusedIndex).store(Smi::zero());
DCHECK(IsSmi(*slot_at(T::kIsolateIndex)));
}
PropertyCallbackArguments::~PropertyCallbackArguments(){
#ifdef DEBUG
#endif
}
Maybe<InterceptorResult> PropertyCallbackArguments::GetBooleanReturnValue(
v8::Intercepted intercepted, const char* callback_kind_for_error_message,
bool ignore_return_value) {
Isolate* isolate = this->isolate();
if (isolate->has_exception()) {
if ((false) && DEBUG_BOOL && (intercepted == v8::Intercepted::kNo)) {
FATAL(
"Check failed: %s interceptor callback has thrown an "
"exception but hasn't returned v8::Intercepted::kYes.",
callback_kind_for_error_message);
}
return Nothing<InterceptorResult>();
}
if (intercepted == v8::Intercepted::kNo) {
DCHECK(!isolate->has_exception());
return Just(InterceptorResult::kNotIntercepted);
}
DCHECK_EQ(intercepted, v8::Intercepted::kYes);
AcceptSideEffects();
if (ignore_return_value) return Just(InterceptorResult::kTrue);
bool result = IsTrue(*GetReturnValue<Boolean>(isolate), isolate);
return Just(result ? InterceptorResult::kTrue : InterceptorResult::kFalse);
}
DirectHandle<JSObjectOrUndefined>
PropertyCallbackArguments::CallNamedEnumerator(
DirectHandle<InterceptorInfo> interceptor) {
DCHECK(interceptor->is_named());
RCS_SCOPE(isolate(), RuntimeCallCounterId::kNamedEnumeratorCallback);
HITRACE_RCS_SCOPE(isolate(), RuntimeCallCounterId::kNamedEnumeratorCallback);
return CallPropertyEnumerator(interceptor);
}
DirectHandle<Object> PropertyCallbackArguments::CallNamedQuery(
DirectHandle<InterceptorInfo> interceptor, DirectHandle<Name> name) {
DCHECK_NAME_COMPATIBLE(interceptor, name);
Isolate* isolate = this->isolate();
RCS_SCOPE(isolate, RuntimeCallCounterId::kNamedQueryCallback);
HITRACE_RCS_SCOPE(isolate, RuntimeCallCounterId::kNamedQueryCallback);
slot_at(kCallbackInfoIndex).store(*interceptor);
slot_at(kPropertyKeyIndex).store(*name);
slot_at(kReturnValueIndex).store(Smi::FromInt(v8::None));
NamedPropertyQueryCallback f = reinterpret_cast<NamedPropertyQueryCallback>(
interceptor->named_query(isolate));
PREPARE_CALLBACK_INFO_INTERCEPTOR(isolate, f, v8::Integer, interceptor,
ExceptionContext::kNamedQuery);
v8::Intercepted intercepted = f(v8::Utils::ToLocal(name), callback_info);
if (intercepted == v8::Intercepted::kNo) return {};
return GetReturnValue<Object>(isolate);
}
DirectHandle<JSAny> PropertyCallbackArguments::CallNamedGetter(
DirectHandle<InterceptorInfo> interceptor, DirectHandle<Name> name) {
DCHECK_NAME_COMPATIBLE(interceptor, name);
Isolate* isolate = this->isolate();
RCS_SCOPE(isolate, RuntimeCallCounterId::kNamedGetterCallback);
HITRACE_RCS_SCOPE(isolate, RuntimeCallCounterId::kNamedGetterCallback);
slot_at(kCallbackInfoIndex).store(*interceptor);
slot_at(kPropertyKeyIndex).store(*name);
slot_at(kReturnValueIndex).store(ReadOnlyRoots(isolate).undefined_value());
NamedPropertyGetterCallback f = reinterpret_cast<NamedPropertyGetterCallback>(
interceptor->named_getter(isolate));
PREPARE_CALLBACK_INFO_INTERCEPTOR(isolate, f, v8::Value, interceptor,
ExceptionContext::kNamedGetter);
v8::Intercepted intercepted = f(v8::Utils::ToLocal(name), callback_info);
if (intercepted == v8::Intercepted::kNo) return {};
return GetReturnValue<JSAny>(isolate);
}
Handle<JSAny> PropertyCallbackArguments::CallNamedDescriptor(
DirectHandle<InterceptorInfo> interceptor, DirectHandle<Name> name) {
DCHECK_NAME_COMPATIBLE(interceptor, name);
Isolate* isolate = this->isolate();
RCS_SCOPE(isolate, RuntimeCallCounterId::kNamedDescriptorCallback);
HITRACE_RCS_SCOPE(isolate, RuntimeCallCounterId::kNamedDescriptorCallback);
slot_at(kCallbackInfoIndex).store(*interceptor);
slot_at(kPropertyKeyIndex).store(*name);
slot_at(kReturnValueIndex).store(ReadOnlyRoots(isolate).undefined_value());
NamedPropertyDescriptorCallback f =
reinterpret_cast<NamedPropertyDescriptorCallback>(
interceptor->named_descriptor(isolate));
PREPARE_CALLBACK_INFO_INTERCEPTOR(isolate, f, v8::Value, interceptor,
ExceptionContext::kNamedDescriptor);
v8::Intercepted intercepted = f(v8::Utils::ToLocal(name), callback_info);
if (intercepted == v8::Intercepted::kNo) return {};
return GetReturnValue<JSAny>(isolate);
}
v8::Intercepted PropertyCallbackArguments::CallNamedSetter(
DirectHandle<InterceptorInfo> interceptor, DirectHandle<Name> name,
DirectHandle<Object> value) {
DCHECK_NAME_COMPATIBLE(interceptor, name);
Isolate* isolate = this->isolate();
RCS_SCOPE(isolate, RuntimeCallCounterId::kNamedSetterCallback);
HITRACE_RCS_SCOPE(isolate, RuntimeCallCounterId::kNamedSetterCallback);
slot_at(kCallbackInfoIndex).store(*interceptor);
slot_at(kPropertyKeyIndex).store(*name);
slot_at(kReturnValueIndex).store(ReadOnlyRoots(isolate).true_value());
NamedPropertySetterCallback f = reinterpret_cast<NamedPropertySetterCallback>(
interceptor->named_setter(isolate));
DirectHandle<InterceptorInfo> has_side_effects;
PREPARE_CALLBACK_INFO_INTERCEPTOR(isolate, f, void, has_side_effects,
ExceptionContext::kNamedSetter);
v8::Intercepted intercepted =
f(v8::Utils::ToLocal(name), v8::Utils::ToLocal(value), callback_info);
return intercepted;
}
v8::Intercepted PropertyCallbackArguments::CallNamedDefiner(
DirectHandle<InterceptorInfo> interceptor, DirectHandle<Name> name,
const v8::PropertyDescriptor& desc) {
DCHECK_NAME_COMPATIBLE(interceptor, name);
Isolate* isolate = this->isolate();
RCS_SCOPE(isolate, RuntimeCallCounterId::kNamedDefinerCallback);
HITRACE_RCS_SCOPE(isolate, RuntimeCallCounterId::kNamedDefinerCallback);
slot_at(kCallbackInfoIndex).store(*interceptor);
slot_at(kPropertyKeyIndex).store(*name);
slot_at(kReturnValueIndex).store(ReadOnlyRoots(isolate).true_value());
NamedPropertyDefinerCallback f =
reinterpret_cast<NamedPropertyDefinerCallback>(
interceptor->named_definer(isolate));
DirectHandle<InterceptorInfo> has_side_effects;
PREPARE_CALLBACK_INFO_INTERCEPTOR(isolate, f, void, has_side_effects,
ExceptionContext::kNamedDefiner);
v8::Intercepted intercepted =
f(v8::Utils::ToLocal(name), desc, callback_info);
return intercepted;
}
v8::Intercepted PropertyCallbackArguments::CallNamedDeleter(
DirectHandle<InterceptorInfo> interceptor, DirectHandle<Name> name) {
DCHECK_NAME_COMPATIBLE(interceptor, name);
Isolate* isolate = this->isolate();
RCS_SCOPE(isolate, RuntimeCallCounterId::kNamedDeleterCallback);
HITRACE_RCS_SCOPE(isolate, RuntimeCallCounterId::kNamedDeleterCallback);
slot_at(kCallbackInfoIndex).store(*interceptor);
slot_at(kPropertyKeyIndex).store(*name);
slot_at(kReturnValueIndex).store(ReadOnlyRoots(isolate).true_value());
NamedPropertyDeleterCallback f =
reinterpret_cast<NamedPropertyDeleterCallback>(
interceptor->named_deleter(isolate));
DirectHandle<InterceptorInfo> has_side_effects;
PREPARE_CALLBACK_INFO_INTERCEPTOR(isolate, f, v8::Boolean, has_side_effects,
ExceptionContext::kNamedDeleter);
v8::Intercepted intercepted = f(v8::Utils::ToLocal(name), callback_info);
return intercepted;
}
DirectHandle<JSObjectOrUndefined>
PropertyCallbackArguments::CallIndexedEnumerator(
DirectHandle<InterceptorInfo> interceptor) {
DCHECK(!interceptor->is_named());
RCS_SCOPE(isolate(), RuntimeCallCounterId::kIndexedEnumeratorCallback);
HITRACE_RCS_SCOPE(isolate(), RuntimeCallCounterId::kIndexedEnumeratorCallback);
return CallPropertyEnumerator(interceptor);
}
DirectHandle<Object> PropertyCallbackArguments::CallIndexedQuery(
DirectHandle<InterceptorInfo> interceptor, uint32_t index) {
DCHECK(!interceptor->is_named());
Isolate* isolate = this->isolate();
RCS_SCOPE(isolate, RuntimeCallCounterId::kIndexedQueryCallback);
HITRACE_RCS_SCOPE(isolate, RuntimeCallCounterId::kIndexedQueryCallback);
index_ = index;
slot_at(kCallbackInfoIndex).store(*interceptor);
slot_at(kPropertyKeyIndex).store(Smi::zero());
slot_at(kReturnValueIndex).store(Smi::FromInt(v8::None));
IndexedPropertyQueryCallbackV2 f =
reinterpret_cast<IndexedPropertyQueryCallbackV2>(
interceptor->indexed_query(isolate));
PREPARE_CALLBACK_INFO_INTERCEPTOR(isolate, f, v8::Integer, interceptor,
ExceptionContext::kIndexedQuery);
v8::Intercepted intercepted = f(index, callback_info);
if (intercepted == v8::Intercepted::kNo) return {};
return GetReturnValue<Object>(isolate);
}
DirectHandle<JSAny> PropertyCallbackArguments::CallIndexedGetter(
DirectHandle<InterceptorInfo> interceptor, uint32_t index) {
DCHECK(!interceptor->is_named());
Isolate* isolate = this->isolate();
RCS_SCOPE(isolate, RuntimeCallCounterId::kNamedGetterCallback);
HITRACE_RCS_SCOPE(isolate, RuntimeCallCounterId::kNamedGetterCallback);
index_ = index;
slot_at(kCallbackInfoIndex).store(*interceptor);
slot_at(kPropertyKeyIndex).store(Smi::zero());
slot_at(kReturnValueIndex).store(ReadOnlyRoots(isolate).undefined_value());
IndexedPropertyGetterCallbackV2 f =
reinterpret_cast<IndexedPropertyGetterCallbackV2>(
interceptor->indexed_getter(isolate));
PREPARE_CALLBACK_INFO_INTERCEPTOR(isolate, f, v8::Value, interceptor,
ExceptionContext::kIndexedGetter);
v8::Intercepted intercepted = f(index, callback_info);
if (intercepted == v8::Intercepted::kNo) return {};
return GetReturnValue<JSAny>(isolate);
}
Handle<JSAny> PropertyCallbackArguments::CallIndexedDescriptor(
DirectHandle<InterceptorInfo> interceptor, uint32_t index) {
DCHECK(!interceptor->is_named());
Isolate* isolate = this->isolate();
RCS_SCOPE(isolate, RuntimeCallCounterId::kIndexedDescriptorCallback);
HITRACE_RCS_SCOPE(isolate, RuntimeCallCounterId::kIndexedDescriptorCallback);
index_ = index;
slot_at(kCallbackInfoIndex).store(*interceptor);
slot_at(kPropertyKeyIndex).store(Smi::zero());
slot_at(kReturnValueIndex).store(ReadOnlyRoots(isolate).undefined_value());
IndexedPropertyDescriptorCallbackV2 f =
reinterpret_cast<IndexedPropertyDescriptorCallbackV2>(
interceptor->indexed_descriptor(isolate));
PREPARE_CALLBACK_INFO_INTERCEPTOR(isolate, f, v8::Value, interceptor,
ExceptionContext::kIndexedDescriptor);
v8::Intercepted intercepted = f(index, callback_info);
if (intercepted == v8::Intercepted::kNo) return {};
return GetReturnValue<JSAny>(isolate);
}
v8::Intercepted PropertyCallbackArguments::CallIndexedSetter(
DirectHandle<InterceptorInfo> interceptor, uint32_t index,
DirectHandle<Object> value) {
DCHECK(!interceptor->is_named());
Isolate* isolate = this->isolate();
RCS_SCOPE(isolate, RuntimeCallCounterId::kIndexedSetterCallback);
HITRACE_RCS_SCOPE(isolate, RuntimeCallCounterId::kIndexedSetterCallback);
index_ = index;
slot_at(kCallbackInfoIndex).store(*interceptor);
slot_at(kPropertyKeyIndex).store(Smi::zero());
slot_at(kReturnValueIndex).store(ReadOnlyRoots(isolate).true_value());
IndexedPropertySetterCallbackV2 f =
reinterpret_cast<IndexedPropertySetterCallbackV2>(
interceptor->indexed_setter(isolate));
DirectHandle<InterceptorInfo> has_side_effects;
PREPARE_CALLBACK_INFO_INTERCEPTOR(isolate, f, void, has_side_effects,
ExceptionContext::kIndexedSetter);
v8::Intercepted intercepted =
f(index, v8::Utils::ToLocal(value), callback_info);
return intercepted;
}
v8::Intercepted PropertyCallbackArguments::CallIndexedDefiner(
DirectHandle<InterceptorInfo> interceptor, uint32_t index,
const v8::PropertyDescriptor& desc) {
DCHECK(!interceptor->is_named());
Isolate* isolate = this->isolate();
RCS_SCOPE(isolate, RuntimeCallCounterId::kIndexedDefinerCallback);
HITRACE_RCS_SCOPE(isolate, RuntimeCallCounterId::kIndexedDefinerCallback);
index_ = index;
slot_at(kCallbackInfoIndex).store(*interceptor);
slot_at(kPropertyKeyIndex).store(Smi::zero());
slot_at(kReturnValueIndex).store(ReadOnlyRoots(isolate).true_value());
IndexedPropertyDefinerCallbackV2 f =
reinterpret_cast<IndexedPropertyDefinerCallbackV2>(
interceptor->indexed_definer(isolate));
DirectHandle<InterceptorInfo> has_side_effects;
PREPARE_CALLBACK_INFO_INTERCEPTOR(isolate, f, void, has_side_effects,
ExceptionContext::kIndexedDefiner);
v8::Intercepted intercepted = f(index, desc, callback_info);
return intercepted;
}
v8::Intercepted PropertyCallbackArguments::CallIndexedDeleter(
DirectHandle<InterceptorInfo> interceptor, uint32_t index) {
DCHECK(!interceptor->is_named());
Isolate* isolate = this->isolate();
RCS_SCOPE(isolate, RuntimeCallCounterId::kIndexedDeleterCallback);
HITRACE_RCS_SCOPE(isolate, RuntimeCallCounterId::kIndexedDeleterCallback);
index_ = index;
slot_at(kCallbackInfoIndex).store(*interceptor);
slot_at(kPropertyKeyIndex).store(Smi::zero());
slot_at(kReturnValueIndex).store(ReadOnlyRoots(isolate).true_value());
IndexedPropertyDeleterCallbackV2 f =
reinterpret_cast<IndexedPropertyDeleterCallbackV2>(
interceptor->indexed_deleter(isolate));
PREPARE_CALLBACK_INFO_INTERCEPTOR(isolate, f, v8::Boolean, interceptor,
ExceptionContext::kIndexedDeleter);
v8::Intercepted intercepted = f(index, callback_info);
return intercepted;
}
DirectHandle<JSObjectOrUndefined>
PropertyCallbackArguments::CallPropertyEnumerator(
DirectHandle<InterceptorInfo> interceptor) {
static_assert(std::is_same_v<NamedPropertyEnumeratorCallback,
IndexedPropertyEnumeratorCallback>);
Isolate* isolate = this->isolate();
slot_at(kCallbackInfoIndex).store(*interceptor);
slot_at(kPropertyKeyIndex).store(Smi::zero());
slot_at(kReturnValueIndex).store(ReadOnlyRoots(isolate).undefined_value());
IndexedPropertyEnumeratorCallback f;
if (interceptor->is_named()) {
f = reinterpret_cast<NamedPropertyEnumeratorCallback>(
interceptor->named_enumerator(isolate));
} else {
f = reinterpret_cast<IndexedPropertyEnumeratorCallback>(
interceptor->indexed_enumerator(isolate));
}
PREPARE_CALLBACK_INFO_INTERCEPTOR(isolate, f, v8::Array, interceptor,
ExceptionContext::kNamedEnumerator);
f(callback_info);
DirectHandle<JSAny> result = GetReturnValue<JSAny>(isolate);
DCHECK(IsUndefined(*result) || IsJSObject(*result));
return Cast<JSObjectOrUndefined>(result);
}
DirectHandle<JSAny> PropertyCallbackArguments::CallAccessorGetter(
DirectHandle<AccessorInfo> accessor_info, DirectHandle<Name> name) {
Isolate* isolate = this->isolate();
RCS_SCOPE(isolate, RuntimeCallCounterId::kAccessorGetterCallback);
HITRACE_RCS_SCOPE(isolate, RuntimeCallCounterId::kAccessorGetterCallback);
AcceptSideEffects();
slot_at(kCallbackInfoIndex).store(*accessor_info);
slot_at(kPropertyKeyIndex).store(*name);
slot_at(kReturnValueIndex).store(ReadOnlyRoots(isolate).undefined_value());
AccessorNameGetterCallback f = reinterpret_cast<AccessorNameGetterCallback>(
accessor_info->getter(isolate));
PREPARE_CALLBACK_INFO_ACCESSOR(isolate, f, v8::Value, accessor_info,
receiver(), ACCESSOR_GETTER,
ExceptionContext::kAttributeGet);
f(v8::Utils::ToLocal(name), callback_info);
return GetReturnValue<JSAny>(isolate);
}
bool PropertyCallbackArguments::CallAccessorSetter(
DirectHandle<AccessorInfo> accessor_info, DirectHandle<Name> name,
DirectHandle<Object> value) {
Isolate* isolate = this->isolate();
RCS_SCOPE(isolate, RuntimeCallCounterId::kAccessorSetterCallback);
HITRACE_RCS_SCOPE(isolate, RuntimeCallCounterId::kAccessorSetterCallback);
AcceptSideEffects();
slot_at(kCallbackInfoIndex).store(*accessor_info);
slot_at(kPropertyKeyIndex).store(*name);
slot_at(kReturnValueIndex).store(ReadOnlyRoots(isolate).true_value());
AccessorNameSetterCallback f = reinterpret_cast<AccessorNameSetterCallback>(
accessor_info->setter(isolate));
PREPARE_CALLBACK_INFO_ACCESSOR(isolate, f, void, accessor_info, receiver(),
ACCESSOR_SETTER,
ExceptionContext::kAttributeSet);
f(v8::Utils::ToLocal(name), v8::Utils::ToLocal(value), callback_info);
DirectHandle<Boolean> result = GetReturnValue<Boolean>(isolate);
return IsTrue(*result, isolate);
}
#undef PREPARE_CALLBACK_INFO_ACCESSOR
#undef PREPARE_CALLBACK_INFO_INTERCEPTOR
}
}
#endif