// Copyright 2018 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef V8_OBJECTS_API_CALLBACKS_INL_H_ #define V8_OBJECTS_API_CALLBACKS_INL_H_ #include "src/objects/api-callbacks.h" #include "src/heap/heap-inl.h" #include "src/objects/name.h" #include "src/objects/templates.h" // Has to be the last include (doesn't have include guards): #include "src/objects/object-macros.h" namespace v8 { namespace internal { CAST_ACCESSOR(AccessorInfo) CAST_ACCESSOR(AccessCheckInfo) CAST_ACCESSOR(InterceptorInfo) CAST_ACCESSOR(CallHandlerInfo) ACCESSORS(AccessorInfo, name, Name, kNameOffset) SMI_ACCESSORS(AccessorInfo, flags, kFlagsOffset) ACCESSORS(AccessorInfo, expected_receiver_type, Object, kExpectedReceiverTypeOffset) ACCESSORS_CHECKED2(AccessorInfo, getter, Object, kGetterOffset, true, Foreign::IsNormalized(value)) ACCESSORS_CHECKED2(AccessorInfo, setter, Object, kSetterOffset, true, Foreign::IsNormalized(value)); ACCESSORS(AccessorInfo, js_getter, Object, kJsGetterOffset) ACCESSORS(AccessorInfo, data, Object, kDataOffset) bool AccessorInfo::has_getter() { bool result = getter() != Smi::kZero; DCHECK_EQ(result, getter() != Smi::kZero && Foreign::cast(getter())->foreign_address() != kNullAddress); return result; } bool AccessorInfo::has_setter() { bool result = setter() != Smi::kZero; DCHECK_EQ(result, setter() != Smi::kZero && Foreign::cast(setter())->foreign_address() != kNullAddress); return result; } BIT_FIELD_ACCESSORS(AccessorInfo, flags, all_can_read, AccessorInfo::AllCanReadBit) BIT_FIELD_ACCESSORS(AccessorInfo, flags, all_can_write, AccessorInfo::AllCanWriteBit) BIT_FIELD_ACCESSORS(AccessorInfo, flags, is_special_data_property, AccessorInfo::IsSpecialDataPropertyBit) BIT_FIELD_ACCESSORS(AccessorInfo, flags, replace_on_access, AccessorInfo::ReplaceOnAccessBit) BIT_FIELD_ACCESSORS(AccessorInfo, flags, is_sloppy, AccessorInfo::IsSloppyBit) BIT_FIELD_ACCESSORS(AccessorInfo, flags, has_no_side_effect, AccessorInfo::HasNoSideEffectBit) BIT_FIELD_ACCESSORS(AccessorInfo, flags, initial_property_attributes, AccessorInfo::InitialAttributesBits) bool AccessorInfo::IsCompatibleReceiver(Object* receiver) { if (!HasExpectedReceiverType()) return true; if (!receiver->IsJSObject()) return false; return FunctionTemplateInfo::cast(expected_receiver_type()) ->IsTemplateFor(JSObject::cast(receiver)->map()); } bool AccessorInfo::HasExpectedReceiverType() { return expected_receiver_type()->IsFunctionTemplateInfo(); } ACCESSORS(AccessCheckInfo, callback, Object, kCallbackOffset) ACCESSORS(AccessCheckInfo, named_interceptor, Object, kNamedInterceptorOffset) ACCESSORS(AccessCheckInfo, indexed_interceptor, Object, kIndexedInterceptorOffset) ACCESSORS(AccessCheckInfo, data, Object, kDataOffset) ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset) ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset) ACCESSORS(InterceptorInfo, query, Object, kQueryOffset) ACCESSORS(InterceptorInfo, descriptor, Object, kDescriptorOffset) ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset) ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset) ACCESSORS(InterceptorInfo, definer, Object, kDefinerOffset) ACCESSORS(InterceptorInfo, data, Object, kDataOffset) SMI_ACCESSORS(InterceptorInfo, flags, kFlagsOffset) BOOL_ACCESSORS(InterceptorInfo, flags, can_intercept_symbols, kCanInterceptSymbolsBit) BOOL_ACCESSORS(InterceptorInfo, flags, all_can_read, kAllCanReadBit) BOOL_ACCESSORS(InterceptorInfo, flags, non_masking, kNonMasking) BOOL_ACCESSORS(InterceptorInfo, flags, is_named, kNamed) BOOL_ACCESSORS(InterceptorInfo, flags, has_no_side_effect, kHasNoSideEffect) ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset) ACCESSORS(CallHandlerInfo, js_callback, Object, kJsCallbackOffset) ACCESSORS(CallHandlerInfo, data, Object, kDataOffset) bool CallHandlerInfo::IsSideEffectFreeCallHandlerInfo() const { ReadOnlyRoots roots = GetReadOnlyRoots(); DCHECK(map() == roots.side_effect_call_handler_info_map() || map() == roots.side_effect_free_call_handler_info_map() || map() == roots.next_call_side_effect_free_call_handler_info_map()); return map() == roots.side_effect_free_call_handler_info_map(); } bool CallHandlerInfo::IsSideEffectCallHandlerInfo() const { ReadOnlyRoots roots = GetReadOnlyRoots(); DCHECK(map() == roots.side_effect_call_handler_info_map() || map() == roots.side_effect_free_call_handler_info_map() || map() == roots.next_call_side_effect_free_call_handler_info_map()); return map() == roots.side_effect_call_handler_info_map(); } void CallHandlerInfo::SetNextCallHasNoSideEffect() { set_map( GetReadOnlyRoots().next_call_side_effect_free_call_handler_info_map()); } bool CallHandlerInfo::NextCallHasNoSideEffect() { ReadOnlyRoots roots = GetReadOnlyRoots(); if (map() == roots.next_call_side_effect_free_call_handler_info_map()) { set_map(roots.side_effect_call_handler_info_map()); return true; } return false; } } // namespace internal } // namespace v8 #include "src/objects/object-macros-undef.h" #endif // V8_OBJECTS_API_CALLBACKS_INL_H_