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