1// Copyright 2018 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef V8_OBJECTS_API_CALLBACKS_INL_H_ 6#define V8_OBJECTS_API_CALLBACKS_INL_H_ 7 8#include "src/objects/api-callbacks.h" 9 10#include "src/heap/heap-write-barrier-inl.h" 11#include "src/heap/heap-write-barrier.h" 12#include "src/objects/foreign-inl.h" 13#include "src/objects/js-objects-inl.h" 14#include "src/objects/name.h" 15#include "src/objects/templates.h" 16 17// Has to be the last include (doesn't have include guards): 18#include "src/objects/object-macros.h" 19 20namespace v8 { 21namespace internal { 22 23#include "torque-generated/src/objects/api-callbacks-tq-inl.inc" 24 25TQ_OBJECT_CONSTRUCTORS_IMPL(AccessCheckInfo) 26TQ_OBJECT_CONSTRUCTORS_IMPL(AccessorInfo) 27TQ_OBJECT_CONSTRUCTORS_IMPL(InterceptorInfo) 28 29TQ_OBJECT_CONSTRUCTORS_IMPL(CallHandlerInfo) 30 31ACCESSORS_CHECKED2(AccessorInfo, getter, Object, kGetterOffset, true, 32 Foreign::IsNormalized(value)) 33ACCESSORS_CHECKED2(AccessorInfo, setter, Object, kSetterOffset, true, 34 Foreign::IsNormalized(value)) 35 36bool AccessorInfo::has_getter() { 37 bool result = getter() != Smi::zero(); 38 DCHECK_EQ(result, 39 getter() != Smi::zero() && 40 Foreign::cast(getter()).foreign_address() != kNullAddress); 41 return result; 42} 43 44bool AccessorInfo::has_setter() { 45 bool result = setter() != Smi::zero(); 46 DCHECK_EQ(result, 47 setter() != Smi::zero() && 48 Foreign::cast(setter()).foreign_address() != kNullAddress); 49 return result; 50} 51 52BIT_FIELD_ACCESSORS(AccessorInfo, flags, all_can_read, 53 AccessorInfo::AllCanReadBit) 54BIT_FIELD_ACCESSORS(AccessorInfo, flags, all_can_write, 55 AccessorInfo::AllCanWriteBit) 56BIT_FIELD_ACCESSORS(AccessorInfo, flags, is_special_data_property, 57 AccessorInfo::IsSpecialDataPropertyBit) 58BIT_FIELD_ACCESSORS(AccessorInfo, flags, replace_on_access, 59 AccessorInfo::ReplaceOnAccessBit) 60BIT_FIELD_ACCESSORS(AccessorInfo, flags, is_sloppy, AccessorInfo::IsSloppyBit) 61BIT_FIELD_ACCESSORS(AccessorInfo, flags, getter_side_effect_type, 62 AccessorInfo::GetterSideEffectTypeBits) 63 64SideEffectType AccessorInfo::setter_side_effect_type() const { 65 return SetterSideEffectTypeBits::decode(flags()); 66} 67 68void AccessorInfo::set_setter_side_effect_type(SideEffectType value) { 69 // We do not support describing setters as having no side effect, since 70 // calling set accessors must go through a store bytecode. Store bytecodes 71 // support checking receivers for temporary objects, but still expect 72 // the receiver to be written to. 73 CHECK_NE(value, SideEffectType::kHasNoSideEffect); 74 set_flags(SetterSideEffectTypeBits::update(flags(), value)); 75} 76 77BIT_FIELD_ACCESSORS(AccessorInfo, flags, initial_property_attributes, 78 AccessorInfo::InitialAttributesBits) 79 80bool AccessorInfo::IsCompatibleReceiver(Object receiver) { 81 if (!HasExpectedReceiverType()) return true; 82 if (!receiver.IsJSObject()) return false; 83 return FunctionTemplateInfo::cast(expected_receiver_type()) 84 .IsTemplateFor(JSObject::cast(receiver).map()); 85} 86 87bool AccessorInfo::HasExpectedReceiverType() { 88 return expected_receiver_type().IsFunctionTemplateInfo(); 89} 90 91BOOL_ACCESSORS(InterceptorInfo, flags, can_intercept_symbols, 92 CanInterceptSymbolsBit::kShift) 93BOOL_ACCESSORS(InterceptorInfo, flags, all_can_read, AllCanReadBit::kShift) 94BOOL_ACCESSORS(InterceptorInfo, flags, non_masking, NonMaskingBit::kShift) 95BOOL_ACCESSORS(InterceptorInfo, flags, is_named, NamedBit::kShift) 96BOOL_ACCESSORS(InterceptorInfo, flags, has_no_side_effect, 97 HasNoSideEffectBit::kShift) 98 99bool CallHandlerInfo::IsSideEffectFreeCallHandlerInfo() const { 100 ReadOnlyRoots roots = GetReadOnlyRoots(); 101 DCHECK(map() == roots.side_effect_call_handler_info_map() || 102 map() == roots.side_effect_free_call_handler_info_map() || 103 map() == roots.next_call_side_effect_free_call_handler_info_map()); 104 return map() == roots.side_effect_free_call_handler_info_map(); 105} 106 107bool CallHandlerInfo::IsSideEffectCallHandlerInfo() const { 108 ReadOnlyRoots roots = GetReadOnlyRoots(); 109 DCHECK(map() == roots.side_effect_call_handler_info_map() || 110 map() == roots.side_effect_free_call_handler_info_map() || 111 map() == roots.next_call_side_effect_free_call_handler_info_map()); 112 return map() == roots.side_effect_call_handler_info_map(); 113} 114 115void CallHandlerInfo::SetNextCallHasNoSideEffect() { 116 set_map( 117 GetReadOnlyRoots().next_call_side_effect_free_call_handler_info_map()); 118} 119 120bool CallHandlerInfo::NextCallHasNoSideEffect() { 121 ReadOnlyRoots roots = GetReadOnlyRoots(); 122 if (map() == roots.next_call_side_effect_free_call_handler_info_map()) { 123 set_map(roots.side_effect_call_handler_info_map()); 124 return true; 125 } 126 return false; 127} 128 129} // namespace internal 130} // namespace v8 131 132#include "src/objects/object-macros-undef.h" 133 134#endif // V8_OBJECTS_API_CALLBACKS_INL_H_ 135