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
23OBJECT_CONSTRUCTORS_IMPL(AccessCheckInfo, Struct)
24OBJECT_CONSTRUCTORS_IMPL(AccessorInfo, Struct)
25OBJECT_CONSTRUCTORS_IMPL(InterceptorInfo, Struct)
26OBJECT_CONSTRUCTORS_IMPL(CallHandlerInfo, Tuple3)
27
28CAST_ACCESSOR(AccessorInfo)
29CAST_ACCESSOR(AccessCheckInfo)
30CAST_ACCESSOR(InterceptorInfo)
31CAST_ACCESSOR(CallHandlerInfo)
32
33ACCESSORS(AccessorInfo, name, Name, kNameOffset)
34SMI_ACCESSORS(AccessorInfo, flags, kFlagsOffset)
35ACCESSORS(AccessorInfo, expected_receiver_type, Object,
36 kExpectedReceiverTypeOffset)
37
38ACCESSORS_CHECKED2(AccessorInfo, getter, Object, kGetterOffset, true,
39 Foreign::IsNormalized(value))
40ACCESSORS_CHECKED2(AccessorInfo, setter, Object, kSetterOffset, true,
41 Foreign::IsNormalized(value))
42ACCESSORS(AccessorInfo, js_getter, Object, kJsGetterOffset)
43ACCESSORS(AccessorInfo, data, Object, kDataOffset)
44
45bool AccessorInfo::has_getter() {
46 bool result = getter() != Smi::kZero;
47 DCHECK_EQ(result,
48 getter() != Smi::kZero &&
49 Foreign::cast(getter())->foreign_address() != kNullAddress);
50 return result;
51}
52
53bool AccessorInfo::has_setter() {
54 bool result = setter() != Smi::kZero;
55 DCHECK_EQ(result,
56 setter() != Smi::kZero &&
57 Foreign::cast(setter())->foreign_address() != kNullAddress);
58 return result;
59}
60
61BIT_FIELD_ACCESSORS(AccessorInfo, flags, all_can_read,
62 AccessorInfo::AllCanReadBit)
63BIT_FIELD_ACCESSORS(AccessorInfo, flags, all_can_write,
64 AccessorInfo::AllCanWriteBit)
65BIT_FIELD_ACCESSORS(AccessorInfo, flags, is_special_data_property,
66 AccessorInfo::IsSpecialDataPropertyBit)
67BIT_FIELD_ACCESSORS(AccessorInfo, flags, replace_on_access,
68 AccessorInfo::ReplaceOnAccessBit)
69BIT_FIELD_ACCESSORS(AccessorInfo, flags, is_sloppy, AccessorInfo::IsSloppyBit)
70BIT_FIELD_ACCESSORS(AccessorInfo, flags, getter_side_effect_type,
71 AccessorInfo::GetterSideEffectTypeBits)
72
73SideEffectType AccessorInfo::setter_side_effect_type() const {
74 return SetterSideEffectTypeBits::decode(flags());
75}
76
77void AccessorInfo::set_setter_side_effect_type(SideEffectType value) {
78 // We do not support describing setters as having no side effect, since
79 // calling set accessors must go through a store bytecode. Store bytecodes
80 // support checking receivers for temporary objects, but still expect
81 // the receiver to be written to.
82 CHECK_NE(value, SideEffectType::kHasNoSideEffect);
83 set_flags(SetterSideEffectTypeBits::update(flags(), value));
84}
85
86BIT_FIELD_ACCESSORS(AccessorInfo, flags, initial_property_attributes,
87 AccessorInfo::InitialAttributesBits)
88
89bool AccessorInfo::IsCompatibleReceiver(Object receiver) {
90 if (!HasExpectedReceiverType()) return true;
91 if (!receiver->IsJSObject()) return false;
92 return FunctionTemplateInfo::cast(expected_receiver_type())
93 ->IsTemplateFor(JSObject::cast(receiver)->map());
94}
95
96bool AccessorInfo::HasExpectedReceiverType() {
97 return expected_receiver_type()->IsFunctionTemplateInfo();
98}
99
100ACCESSORS(AccessCheckInfo, callback, Object, kCallbackOffset)
101ACCESSORS(AccessCheckInfo, named_interceptor, Object, kNamedInterceptorOffset)
102ACCESSORS(AccessCheckInfo, indexed_interceptor, Object,
103 kIndexedInterceptorOffset)
104ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
105
106ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
107ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
108ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
109ACCESSORS(InterceptorInfo, descriptor, Object, kDescriptorOffset)
110ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
111ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
112ACCESSORS(InterceptorInfo, definer, Object, kDefinerOffset)
113ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
114SMI_ACCESSORS(InterceptorInfo, flags, kFlagsOffset)
115BOOL_ACCESSORS(InterceptorInfo, flags, can_intercept_symbols,
116 kCanInterceptSymbolsBit)
117BOOL_ACCESSORS(InterceptorInfo, flags, all_can_read, kAllCanReadBit)
118BOOL_ACCESSORS(InterceptorInfo, flags, non_masking, kNonMasking)
119BOOL_ACCESSORS(InterceptorInfo, flags, is_named, kNamed)
120BOOL_ACCESSORS(InterceptorInfo, flags, has_no_side_effect, kHasNoSideEffect)
121
122ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
123ACCESSORS(CallHandlerInfo, js_callback, Object, kJsCallbackOffset)
124ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
125
126bool CallHandlerInfo::IsSideEffectFreeCallHandlerInfo() const {
127 ReadOnlyRoots roots = GetReadOnlyRoots();
128 DCHECK(map() == roots.side_effect_call_handler_info_map() ||
129 map() == roots.side_effect_free_call_handler_info_map() ||
130 map() == roots.next_call_side_effect_free_call_handler_info_map());
131 return map() == roots.side_effect_free_call_handler_info_map();
132}
133
134bool CallHandlerInfo::IsSideEffectCallHandlerInfo() const {
135 ReadOnlyRoots roots = GetReadOnlyRoots();
136 DCHECK(map() == roots.side_effect_call_handler_info_map() ||
137 map() == roots.side_effect_free_call_handler_info_map() ||
138 map() == roots.next_call_side_effect_free_call_handler_info_map());
139 return map() == roots.side_effect_call_handler_info_map();
140}
141
142void CallHandlerInfo::SetNextCallHasNoSideEffect() {
143 set_map(
144 GetReadOnlyRoots().next_call_side_effect_free_call_handler_info_map());
145}
146
147bool CallHandlerInfo::NextCallHasNoSideEffect() {
148 ReadOnlyRoots roots = GetReadOnlyRoots();
149 if (map() == roots.next_call_side_effect_free_call_handler_info_map()) {
150 set_map(roots.side_effect_call_handler_info_map());
151 return true;
152 }
153 return false;
154}
155
156} // namespace internal
157} // namespace v8
158
159#include "src/objects/object-macros-undef.h"
160
161#endif // V8_OBJECTS_API_CALLBACKS_INL_H_
162