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_H_
6 #define V8_OBJECTS_API_CALLBACKS_H_
7 
8 #include "src/objects.h"
9 
10 // Has to be the last include (doesn't have include guards):
11 #include "src/objects/object-macros.h"
12 
13 namespace v8 {
14 namespace internal {
15 
16 // An accessor must have a getter, but can have no setter.
17 //
18 // When setting a property, V8 searches accessors in prototypes.
19 // If an accessor was found and it does not have a setter,
20 // the request is ignored.
21 //
22 // If the accessor in the prototype has the READ_ONLY property attribute, then
23 // a new value is added to the derived object when the property is set.
24 // This shadows the accessor in the prototype.
25 class AccessorInfo : public Struct {
26  public:
27   DECL_ACCESSORS(name, Name)
28   DECL_INT_ACCESSORS(flags)
29   DECL_ACCESSORS(expected_receiver_type, Object)
30   // This directly points at a foreign C function to be used from the runtime.
31   DECL_ACCESSORS(getter, Object)
32   inline bool has_getter();
33   DECL_ACCESSORS(setter, Object)
34   inline bool has_setter();
35   // This either points at the same as above, or a trampoline in case we are
36   // running with the simulator. Use these entries from generated code.
37   DECL_ACCESSORS(js_getter, Object)
38   DECL_ACCESSORS(data, Object)
39 
40   static Address redirect(Address address, AccessorComponent component);
41   Address redirected_getter() const;
42 
43   // Dispatched behavior.
44   DECL_PRINTER(AccessorInfo)
45 
46   DECL_BOOLEAN_ACCESSORS(all_can_read)
47   DECL_BOOLEAN_ACCESSORS(all_can_write)
48   DECL_BOOLEAN_ACCESSORS(is_special_data_property)
49   DECL_BOOLEAN_ACCESSORS(replace_on_access)
50   DECL_BOOLEAN_ACCESSORS(is_sloppy)
51   DECL_BOOLEAN_ACCESSORS(has_no_side_effect)
52 
53   // The property attributes used when an API object template is instantiated
54   // for the first time. Changing of this value afterwards does not affect
55   // the actual attributes of a property.
56   inline PropertyAttributes initial_property_attributes() const;
57   inline void set_initial_property_attributes(PropertyAttributes attributes);
58 
59   // Checks whether the given receiver is compatible with this accessor.
60   static bool IsCompatibleReceiverMap(Handle<AccessorInfo> info,
61                                       Handle<Map> map);
62   inline bool IsCompatibleReceiver(Object* receiver);
63 
64   DECL_CAST(AccessorInfo)
65 
66   // Dispatched behavior.
67   DECL_VERIFIER(AccessorInfo)
68 
69   // Append all descriptors to the array that are not already there.
70   // Return number added.
71   static int AppendUnique(Isolate* isolate, Handle<Object> descriptors,
72                           Handle<FixedArray> array, int valid_descriptors);
73 
74 // Layout description.
75 #define ACCESSOR_INFO_FIELDS(V)                \
76   V(kNameOffset, kPointerSize)                 \
77   V(kFlagsOffset, kPointerSize)                \
78   V(kExpectedReceiverTypeOffset, kPointerSize) \
79   V(kSetterOffset, kPointerSize)               \
80   V(kGetterOffset, kPointerSize)               \
81   V(kJsGetterOffset, kPointerSize)             \
82   V(kDataOffset, kPointerSize)                 \
83   V(kSize, 0)
84 
85   DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, ACCESSOR_INFO_FIELDS)
86 #undef ACCESSOR_INFO_FIELDS
87 
88  private:
89   inline bool HasExpectedReceiverType();
90 
91 // Bit positions in |flags|.
92 #define ACCESSOR_INFO_FLAGS_BIT_FIELDS(V, _) \
93   V(AllCanReadBit, bool, 1, _)               \
94   V(AllCanWriteBit, bool, 1, _)              \
95   V(IsSpecialDataPropertyBit, bool, 1, _)    \
96   V(IsSloppyBit, bool, 1, _)                 \
97   V(ReplaceOnAccessBit, bool, 1, _)          \
98   V(HasNoSideEffectBit, bool, 1, _)          \
99   V(InitialAttributesBits, PropertyAttributes, 3, _)
100 
101   DEFINE_BIT_FIELDS(ACCESSOR_INFO_FLAGS_BIT_FIELDS)
102 #undef ACCESSOR_INFO_FLAGS_BIT_FIELDS
103 
104   DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorInfo);
105 };
106 
107 class AccessCheckInfo : public Struct {
108  public:
109   DECL_ACCESSORS(callback, Object)
110   DECL_ACCESSORS(named_interceptor, Object)
111   DECL_ACCESSORS(indexed_interceptor, Object)
112   DECL_ACCESSORS(data, Object)
113 
114   DECL_CAST(AccessCheckInfo)
115 
116   // Dispatched behavior.
117   DECL_PRINTER(AccessCheckInfo)
118   DECL_VERIFIER(AccessCheckInfo)
119 
120   static AccessCheckInfo* Get(Isolate* isolate, Handle<JSObject> receiver);
121 
122   static const int kCallbackOffset = HeapObject::kHeaderSize;
123   static const int kNamedInterceptorOffset = kCallbackOffset + kPointerSize;
124   static const int kIndexedInterceptorOffset =
125       kNamedInterceptorOffset + kPointerSize;
126   static const int kDataOffset = kIndexedInterceptorOffset + kPointerSize;
127   static const int kSize = kDataOffset + kPointerSize;
128 
129  private:
130   DISALLOW_IMPLICIT_CONSTRUCTORS(AccessCheckInfo);
131 };
132 
133 class InterceptorInfo : public Struct {
134  public:
135   DECL_ACCESSORS(getter, Object)
136   DECL_ACCESSORS(setter, Object)
137   DECL_ACCESSORS(query, Object)
138   DECL_ACCESSORS(descriptor, Object)
139   DECL_ACCESSORS(deleter, Object)
140   DECL_ACCESSORS(enumerator, Object)
141   DECL_ACCESSORS(definer, Object)
142   DECL_ACCESSORS(data, Object)
143   DECL_BOOLEAN_ACCESSORS(can_intercept_symbols)
144   DECL_BOOLEAN_ACCESSORS(all_can_read)
145   DECL_BOOLEAN_ACCESSORS(non_masking)
146   DECL_BOOLEAN_ACCESSORS(is_named)
147   DECL_BOOLEAN_ACCESSORS(has_no_side_effect)
148 
149   inline int flags() const;
150   inline void set_flags(int flags);
151 
152   DECL_CAST(InterceptorInfo)
153 
154   // Dispatched behavior.
155   DECL_PRINTER(InterceptorInfo)
156   DECL_VERIFIER(InterceptorInfo)
157 
158   static const int kGetterOffset = HeapObject::kHeaderSize;
159   static const int kSetterOffset = kGetterOffset + kPointerSize;
160   static const int kQueryOffset = kSetterOffset + kPointerSize;
161   static const int kDescriptorOffset = kQueryOffset + kPointerSize;
162   static const int kDeleterOffset = kDescriptorOffset + kPointerSize;
163   static const int kEnumeratorOffset = kDeleterOffset + kPointerSize;
164   static const int kDefinerOffset = kEnumeratorOffset + kPointerSize;
165   static const int kDataOffset = kDefinerOffset + kPointerSize;
166   static const int kFlagsOffset = kDataOffset + kPointerSize;
167   static const int kSize = kFlagsOffset + kPointerSize;
168 
169   static const int kCanInterceptSymbolsBit = 0;
170   static const int kAllCanReadBit = 1;
171   static const int kNonMasking = 2;
172   static const int kNamed = 3;
173   static const int kHasNoSideEffect = 4;
174 
175  private:
176   DISALLOW_IMPLICIT_CONSTRUCTORS(InterceptorInfo);
177 };
178 
179 class CallHandlerInfo : public Tuple3 {
180  public:
181   DECL_ACCESSORS(callback, Object)
182   DECL_ACCESSORS(js_callback, Object)
183   DECL_ACCESSORS(data, Object)
184 
185   DECL_CAST(CallHandlerInfo)
186 
187   inline bool IsSideEffectFreeCallHandlerInfo() const;
188   inline bool IsSideEffectCallHandlerInfo() const;
189   inline void SetNextCallHasNoSideEffect();
190   // Returns whether or not the next call can be side effect free.
191   // Calling this will change the state back to having a side effect.
192   inline bool NextCallHasNoSideEffect();
193 
194   // Dispatched behavior.
195   DECL_PRINTER(CallHandlerInfo)
196   DECL_VERIFIER(CallHandlerInfo)
197 
198   Address redirected_callback() const;
199 
200   static const int kCallbackOffset = kValue1Offset;
201   static const int kJsCallbackOffset = kValue2Offset;
202   static const int kDataOffset = kValue3Offset;
203 
204  private:
205   DISALLOW_IMPLICIT_CONSTRUCTORS(CallHandlerInfo);
206 };
207 
208 }  // namespace internal
209 }  // namespace v8
210 
211 #include "src/objects/object-macros-undef.h"
212 
213 #endif  // V8_OBJECTS_API_CALLBACKS_H_
214