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_TEMPLATES_H_ 6 #define V8_OBJECTS_TEMPLATES_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 class TemplateInfo : public Struct, public NeverReadOnlySpaceObject { 17 public: 18 using NeverReadOnlySpaceObject::GetHeap; 19 using NeverReadOnlySpaceObject::GetIsolate; 20 21 DECL_ACCESSORS(tag, Object) 22 DECL_ACCESSORS(serial_number, Object) 23 DECL_INT_ACCESSORS(number_of_properties) 24 DECL_ACCESSORS(property_list, Object) 25 DECL_ACCESSORS(property_accessors, Object) 26 27 DECL_VERIFIER(TemplateInfo) 28 29 DECL_CAST(TemplateInfo) 30 31 static const int kTagOffset = HeapObject::kHeaderSize; 32 static const int kSerialNumberOffset = kTagOffset + kPointerSize; 33 static const int kNumberOfProperties = kSerialNumberOffset + kPointerSize; 34 static const int kPropertyListOffset = kNumberOfProperties + kPointerSize; 35 static const int kPropertyAccessorsOffset = 36 kPropertyListOffset + kPointerSize; 37 static const int kHeaderSize = kPropertyAccessorsOffset + kPointerSize; 38 39 static const int kFastTemplateInstantiationsCacheSize = 1 * KB; 40 41 // While we could grow the slow cache until we run out of memory, we put 42 // a limit on it anyway to not crash for embedders that re-create templates 43 // instead of caching them. 44 static const int kSlowTemplateInstantiationsCacheSize = 1 * MB; 45 46 private: 47 DISALLOW_IMPLICIT_CONSTRUCTORS(TemplateInfo); 48 }; 49 50 // See the api-exposed FunctionTemplate for more information. 51 class FunctionTemplateInfo : public TemplateInfo { 52 public: 53 // Handler invoked when calling an instance of this FunctionTemplateInfo. 54 // Either CallInfoHandler or Undefined. 55 DECL_ACCESSORS(call_code, Object) 56 57 // ObjectTemplateInfo or Undefined, used for the prototype property of the 58 // resulting JSFunction instance of this FunctionTemplate. 59 DECL_ACCESSORS(prototype_template, Object) 60 61 // In the case the prototype_template is Undefined we use the 62 // protoype_provider_template to retrieve the instance prototype. Either 63 // contains an ObjectTemplateInfo or Undefined. 64 DECL_ACCESSORS(prototype_provider_template, Object) 65 66 // Used to create protoype chains. The parent_template's prototype is set as 67 // __proto__ of this FunctionTemplate's instance prototype. Is either a 68 // FunctionTemplateInfo or Undefined. 69 DECL_ACCESSORS(parent_template, Object) 70 71 // Returns an InterceptorInfo or Undefined for named properties. 72 DECL_ACCESSORS(named_property_handler, Object) 73 // Returns an InterceptorInfo or Undefined for indexed properties/elements. 74 DECL_ACCESSORS(indexed_property_handler, Object) 75 76 // An ObjectTemplateInfo that is used when instantiating the JSFunction 77 // associated with this FunctionTemplateInfo. Contains either an 78 // ObjectTemplateInfo or Undefined. A default instance_template is assigned 79 // upon first instantiation if it's Undefined. 80 DECL_ACCESSORS(instance_template, Object) 81 82 DECL_ACCESSORS(class_name, Object) 83 84 // If the signature is a FunctionTemplateInfo it is used to check whether the 85 // receiver calling the associated JSFunction is a compatible receiver, i.e. 86 // it is an instance of the signare FunctionTemplateInfo or any of the 87 // receiver's prototypes are. 88 DECL_ACCESSORS(signature, Object) 89 90 // Either a CallHandlerInfo or Undefined. If an instance_call_handler is 91 // provided the instances created from the associated JSFunction are marked as 92 // callable. 93 DECL_ACCESSORS(instance_call_handler, Object) 94 95 DECL_ACCESSORS(access_check_info, Object) 96 DECL_ACCESSORS(shared_function_info, Object) 97 98 // Internal field to store a flag bitfield. 99 DECL_INT_ACCESSORS(flag) 100 101 // "length" property of the final JSFunction. 102 DECL_INT_ACCESSORS(length) 103 104 // Either the_hole or a private symbol. Used to cache the result on 105 // the receiver under the the cached_property_name when this 106 // FunctionTemplateInfo is used as a getter. 107 DECL_ACCESSORS(cached_property_name, Object) 108 109 // Begin flag bits --------------------- 110 DECL_BOOLEAN_ACCESSORS(hidden_prototype) 111 DECL_BOOLEAN_ACCESSORS(undetectable) 112 113 // If set, object instances created by this function 114 // requires access check. 115 DECL_BOOLEAN_ACCESSORS(needs_access_check) 116 117 DECL_BOOLEAN_ACCESSORS(read_only_prototype) 118 119 // If set, do not create a prototype property for the associated 120 // JSFunction. This bit implies that neither the prototype_template nor the 121 // prototype_provoider_template are instantiated. 122 DECL_BOOLEAN_ACCESSORS(remove_prototype) 123 124 // If set, do not attach a serial number to this FunctionTemplate and thus do 125 // not keep an instance boilerplate around. 126 DECL_BOOLEAN_ACCESSORS(do_not_cache) 127 128 // If not set an access may be performed on calling the associated JSFunction. 129 DECL_BOOLEAN_ACCESSORS(accept_any_receiver) 130 // End flag bits --------------------- 131 132 DECL_CAST(FunctionTemplateInfo) 133 134 // Dispatched behavior. 135 DECL_PRINTER(FunctionTemplateInfo) 136 DECL_VERIFIER(FunctionTemplateInfo) 137 138 static const int kInvalidSerialNumber = 0; 139 140 static const int kCallCodeOffset = TemplateInfo::kHeaderSize; 141 static const int kPrototypeTemplateOffset = kCallCodeOffset + kPointerSize; 142 static const int kPrototypeProviderTemplateOffset = 143 kPrototypeTemplateOffset + kPointerSize; 144 static const int kParentTemplateOffset = 145 kPrototypeProviderTemplateOffset + kPointerSize; 146 static const int kNamedPropertyHandlerOffset = 147 kParentTemplateOffset + kPointerSize; 148 static const int kIndexedPropertyHandlerOffset = 149 kNamedPropertyHandlerOffset + kPointerSize; 150 static const int kInstanceTemplateOffset = 151 kIndexedPropertyHandlerOffset + kPointerSize; 152 static const int kClassNameOffset = kInstanceTemplateOffset + kPointerSize; 153 static const int kSignatureOffset = kClassNameOffset + kPointerSize; 154 static const int kInstanceCallHandlerOffset = kSignatureOffset + kPointerSize; 155 static const int kAccessCheckInfoOffset = 156 kInstanceCallHandlerOffset + kPointerSize; 157 static const int kSharedFunctionInfoOffset = 158 kAccessCheckInfoOffset + kPointerSize; 159 static const int kFlagOffset = kSharedFunctionInfoOffset + kPointerSize; 160 static const int kLengthOffset = kFlagOffset + kPointerSize; 161 static const int kCachedPropertyNameOffset = kLengthOffset + kPointerSize; 162 static const int kSize = kCachedPropertyNameOffset + kPointerSize; 163 164 static Handle<SharedFunctionInfo> GetOrCreateSharedFunctionInfo( 165 Isolate* isolate, Handle<FunctionTemplateInfo> info, 166 MaybeHandle<Name> maybe_name); 167 // Returns parent function template or null. 168 inline FunctionTemplateInfo* GetParent(Isolate* isolate); 169 // Returns true if |object| is an instance of this function template. 170 inline bool IsTemplateFor(JSObject* object); 171 bool IsTemplateFor(Map* map); 172 inline bool instantiated(); 173 174 inline bool BreakAtEntry(); 175 176 // Helper function for cached accessors. 177 static MaybeHandle<Name> TryGetCachedPropertyName(Isolate* isolate, 178 Handle<Object> getter); 179 180 private: 181 // Bit position in the flag, from least significant bit position. 182 static const int kHiddenPrototypeBit = 0; 183 static const int kUndetectableBit = 1; 184 static const int kNeedsAccessCheckBit = 2; 185 static const int kReadOnlyPrototypeBit = 3; 186 static const int kRemovePrototypeBit = 4; 187 static const int kDoNotCacheBit = 5; 188 static const int kAcceptAnyReceiver = 6; 189 190 DISALLOW_IMPLICIT_CONSTRUCTORS(FunctionTemplateInfo); 191 }; 192 193 class ObjectTemplateInfo : public TemplateInfo { 194 public: 195 DECL_ACCESSORS(constructor, Object) 196 DECL_ACCESSORS(data, Object) 197 DECL_INT_ACCESSORS(embedder_field_count) 198 DECL_BOOLEAN_ACCESSORS(immutable_proto) 199 200 DECL_CAST(ObjectTemplateInfo) 201 202 // Dispatched behavior. 203 DECL_PRINTER(ObjectTemplateInfo) 204 DECL_VERIFIER(ObjectTemplateInfo) 205 206 static const int kConstructorOffset = TemplateInfo::kHeaderSize; 207 // LSB is for immutable_proto, higher bits for embedder_field_count 208 static const int kDataOffset = kConstructorOffset + kPointerSize; 209 static const int kSize = kDataOffset + kPointerSize; 210 211 // Starting from given object template's constructor walk up the inheritance 212 // chain till a function template that has an instance template is found. 213 inline ObjectTemplateInfo* GetParent(Isolate* isolate); 214 215 private: 216 class IsImmutablePrototype : public BitField<bool, 0, 1> {}; 217 class EmbedderFieldCount 218 : public BitField<int, IsImmutablePrototype::kNext, 29> {}; 219 }; 220 221 } // namespace internal 222 } // namespace v8 223 224 #include "src/objects/object-macros-undef.h" 225 226 #endif // V8_OBJECTS_TEMPLATES_H_ 227