• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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