| // 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-write-barrier-inl.h" |
| #include "src/heap/heap-write-barrier.h" |
| #include "src/objects/foreign-inl.h" |
| #include "src/objects/js-objects-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 { |
| |
| #include "torque-generated/src/objects/api-callbacks-tq-inl.inc" |
| |
| TQ_OBJECT_CONSTRUCTORS_IMPL(AccessCheckInfo) |
| TQ_OBJECT_CONSTRUCTORS_IMPL(AccessorInfo) |
| TQ_OBJECT_CONSTRUCTORS_IMPL(InterceptorInfo) |
| |
| TQ_OBJECT_CONSTRUCTORS_IMPL(CallHandlerInfo) |
| |
| ACCESSORS_CHECKED2(AccessorInfo, getter, Object, kGetterOffset, true, |
| Foreign::IsNormalized(value)) |
| ACCESSORS_CHECKED2(AccessorInfo, setter, Object, kSetterOffset, true, |
| Foreign::IsNormalized(value)) |
| |
| bool AccessorInfo::has_getter() { |
| bool result = getter() != Smi::zero(); |
| DCHECK_EQ(result, |
| getter() != Smi::zero() && |
| Foreign::cast(getter()).foreign_address() != kNullAddress); |
| return result; |
| } |
| |
| bool AccessorInfo::has_setter() { |
| bool result = setter() != Smi::zero(); |
| DCHECK_EQ(result, |
| setter() != Smi::zero() && |
| 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, getter_side_effect_type, |
| AccessorInfo::GetterSideEffectTypeBits) |
| |
| SideEffectType AccessorInfo::setter_side_effect_type() const { |
| return SetterSideEffectTypeBits::decode(flags()); |
| } |
| |
| void AccessorInfo::set_setter_side_effect_type(SideEffectType value) { |
| // We do not support describing setters as having no side effect, since |
| // calling set accessors must go through a store bytecode. Store bytecodes |
| // support checking receivers for temporary objects, but still expect |
| // the receiver to be written to. |
| CHECK_NE(value, SideEffectType::kHasNoSideEffect); |
| set_flags(SetterSideEffectTypeBits::update(flags(), value)); |
| } |
| |
| 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(); |
| } |
| |
| BOOL_ACCESSORS(InterceptorInfo, flags, can_intercept_symbols, |
| CanInterceptSymbolsBit::kShift) |
| BOOL_ACCESSORS(InterceptorInfo, flags, all_can_read, AllCanReadBit::kShift) |
| BOOL_ACCESSORS(InterceptorInfo, flags, non_masking, NonMaskingBit::kShift) |
| BOOL_ACCESSORS(InterceptorInfo, flags, is_named, NamedBit::kShift) |
| BOOL_ACCESSORS(InterceptorInfo, flags, has_no_side_effect, |
| HasNoSideEffectBit::kShift) |
| |
| 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_ |