• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 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 INCLUDE_V8_OBJECT_H_
6 #define INCLUDE_V8_OBJECT_H_
7 
8 #include "v8-local-handle.h"       // NOLINT(build/include_directory)
9 #include "v8-maybe.h"              // NOLINT(build/include_directory)
10 #include "v8-persistent-handle.h"  // NOLINT(build/include_directory)
11 #include "v8-primitive.h"          // NOLINT(build/include_directory)
12 #include "v8-traced-handle.h"      // NOLINT(build/include_directory)
13 #include "v8-value.h"              // NOLINT(build/include_directory)
14 #include "v8config.h"              // NOLINT(build/include_directory)
15 
16 namespace v8 {
17 
18 class Array;
19 class Function;
20 class FunctionTemplate;
21 template <typename T>
22 class PropertyCallbackInfo;
23 class Module;
24 class UnboundScript;
25 
26 /**
27  * A private symbol
28  *
29  * This is an experimental feature. Use at your own risk.
30  */
31 class V8_EXPORT Private : public Data {
32  public:
33   /**
34    * Returns the print name string of the private symbol, or undefined if none.
35    */
36   Local<Value> Name() const;
37 
38   /**
39    * Create a private symbol. If name is not empty, it will be the description.
40    */
41   static Local<Private> New(Isolate* isolate,
42                             Local<String> name = Local<String>());
43 
44   /**
45    * Retrieve a global private symbol. If a symbol with this name has not
46    * been retrieved in the same isolate before, it is created.
47    * Note that private symbols created this way are never collected, so
48    * they should only be used for statically fixed properties.
49    * Also, there is only one global name space for the names used as keys.
50    * To minimize the potential for clashes, use qualified names as keys,
51    * e.g., "Class#property".
52    */
53   static Local<Private> ForApi(Isolate* isolate, Local<String> name);
54 
55   V8_INLINE static Private* Cast(Data* data);
56 
57  private:
58   Private();
59 
60   static void CheckCast(Data* that);
61 };
62 
63 /**
64  * An instance of a Property Descriptor, see Ecma-262 6.2.4.
65  *
66  * Properties in a descriptor are present or absent. If you do not set
67  * `enumerable`, `configurable`, and `writable`, they are absent. If `value`,
68  * `get`, or `set` are absent, but you must specify them in the constructor, use
69  * empty handles.
70  *
71  * Accessors `get` and `set` must be callable or undefined if they are present.
72  *
73  * \note Only query properties if they are present, i.e., call `x()` only if
74  * `has_x()` returns true.
75  *
76  * \code
77  * // var desc = {writable: false}
78  * v8::PropertyDescriptor d(Local<Value>()), false);
79  * d.value(); // error, value not set
80  * if (d.has_writable()) {
81  *   d.writable(); // false
82  * }
83  *
84  * // var desc = {value: undefined}
85  * v8::PropertyDescriptor d(v8::Undefined(isolate));
86  *
87  * // var desc = {get: undefined}
88  * v8::PropertyDescriptor d(v8::Undefined(isolate), Local<Value>()));
89  * \endcode
90  */
91 class V8_EXPORT PropertyDescriptor {
92  public:
93   // GenericDescriptor
94   PropertyDescriptor();
95 
96   // DataDescriptor
97   explicit PropertyDescriptor(Local<Value> value);
98 
99   // DataDescriptor with writable property
100   PropertyDescriptor(Local<Value> value, bool writable);
101 
102   // AccessorDescriptor
103   PropertyDescriptor(Local<Value> get, Local<Value> set);
104 
105   ~PropertyDescriptor();
106 
107   Local<Value> value() const;
108   bool has_value() const;
109 
110   Local<Value> get() const;
111   bool has_get() const;
112   Local<Value> set() const;
113   bool has_set() const;
114 
115   void set_enumerable(bool enumerable);
116   bool enumerable() const;
117   bool has_enumerable() const;
118 
119   void set_configurable(bool configurable);
120   bool configurable() const;
121   bool has_configurable() const;
122 
123   bool writable() const;
124   bool has_writable() const;
125 
126   struct PrivateData;
get_private()127   PrivateData* get_private() const { return private_; }
128 
129   PropertyDescriptor(const PropertyDescriptor&) = delete;
130   void operator=(const PropertyDescriptor&) = delete;
131 
132  private:
133   PrivateData* private_;
134 };
135 
136 /**
137  * PropertyAttribute.
138  */
139 enum PropertyAttribute {
140   /** None. **/
141   None = 0,
142   /** ReadOnly, i.e., not writable. **/
143   ReadOnly = 1 << 0,
144   /** DontEnum, i.e., not enumerable. **/
145   DontEnum = 1 << 1,
146   /** DontDelete, i.e., not configurable. **/
147   DontDelete = 1 << 2
148 };
149 
150 /**
151  * Accessor[Getter|Setter] are used as callback functions when
152  * setting|getting a particular property. See Object and ObjectTemplate's
153  * method SetAccessor.
154  */
155 using AccessorGetterCallback =
156     void (*)(Local<String> property, const PropertyCallbackInfo<Value>& info);
157 using AccessorNameGetterCallback =
158     void (*)(Local<Name> property, const PropertyCallbackInfo<Value>& info);
159 
160 using AccessorSetterCallback = void (*)(Local<String> property,
161                                         Local<Value> value,
162                                         const PropertyCallbackInfo<void>& info);
163 using AccessorNameSetterCallback =
164     void (*)(Local<Name> property, Local<Value> value,
165              const PropertyCallbackInfo<void>& info);
166 
167 /**
168  * Access control specifications.
169  *
170  * Some accessors should be accessible across contexts.  These
171  * accessors have an explicit access control parameter which specifies
172  * the kind of cross-context access that should be allowed.
173  *
174  * TODO(dcarney): Remove PROHIBITS_OVERWRITING as it is now unused.
175  */
176 enum AccessControl {
177   DEFAULT = 0,
178   ALL_CAN_READ = 1,
179   ALL_CAN_WRITE = 1 << 1,
180   PROHIBITS_OVERWRITING = 1 << 2
181 };
182 
183 /**
184  * Property filter bits. They can be or'ed to build a composite filter.
185  */
186 enum PropertyFilter {
187   ALL_PROPERTIES = 0,
188   ONLY_WRITABLE = 1,
189   ONLY_ENUMERABLE = 2,
190   ONLY_CONFIGURABLE = 4,
191   SKIP_STRINGS = 8,
192   SKIP_SYMBOLS = 16
193 };
194 
195 /**
196  * Options for marking whether callbacks may trigger JS-observable side effects.
197  * Side-effect-free callbacks are allowlisted during debug evaluation with
198  * throwOnSideEffect. It applies when calling a Function, FunctionTemplate,
199  * or an Accessor callback. For Interceptors, please see
200  * PropertyHandlerFlags's kHasNoSideEffect.
201  * Callbacks that only cause side effects to the receiver are allowlisted if
202  * invoked on receiver objects that are created within the same debug-evaluate
203  * call, as these objects are temporary and the side effect does not escape.
204  */
205 enum class SideEffectType {
206   kHasSideEffect,
207   kHasNoSideEffect,
208   kHasSideEffectToReceiver
209 };
210 
211 /**
212  * Keys/Properties filter enums:
213  *
214  * KeyCollectionMode limits the range of collected properties. kOwnOnly limits
215  * the collected properties to the given Object only. kIncludesPrototypes will
216  * include all keys of the objects's prototype chain as well.
217  */
218 enum class KeyCollectionMode { kOwnOnly, kIncludePrototypes };
219 
220 /**
221  * kIncludesIndices allows for integer indices to be collected, while
222  * kSkipIndices will exclude integer indices from being collected.
223  */
224 enum class IndexFilter { kIncludeIndices, kSkipIndices };
225 
226 /**
227  * kConvertToString will convert integer indices to strings.
228  * kKeepNumbers will return numbers for integer indices.
229  */
230 enum class KeyConversionMode { kConvertToString, kKeepNumbers, kNoNumbers };
231 
232 /**
233  * Integrity level for objects.
234  */
235 enum class IntegrityLevel { kFrozen, kSealed };
236 
237 /**
238  * A JavaScript object (ECMA-262, 4.3.3)
239  */
240 class V8_EXPORT Object : public Value {
241  public:
242   /**
243    * Set only return Just(true) or Empty(), so if it should never fail, use
244    * result.Check().
245    */
246   V8_WARN_UNUSED_RESULT Maybe<bool> Set(Local<Context> context,
247                                         Local<Value> key, Local<Value> value);
248 
249   V8_WARN_UNUSED_RESULT Maybe<bool> Set(Local<Context> context, uint32_t index,
250                                         Local<Value> value);
251 
252   // Implements CreateDataProperty (ECMA-262, 7.3.4).
253   //
254   // Defines a configurable, writable, enumerable property with the given value
255   // on the object unless the property already exists and is not configurable
256   // or the object is not extensible.
257   //
258   // Returns true on success.
259   V8_WARN_UNUSED_RESULT Maybe<bool> CreateDataProperty(Local<Context> context,
260                                                        Local<Name> key,
261                                                        Local<Value> value);
262   V8_WARN_UNUSED_RESULT Maybe<bool> CreateDataProperty(Local<Context> context,
263                                                        uint32_t index,
264                                                        Local<Value> value);
265 
266   // Implements DefineOwnProperty.
267   //
268   // In general, CreateDataProperty will be faster, however, does not allow
269   // for specifying attributes.
270   //
271   // Returns true on success.
272   V8_WARN_UNUSED_RESULT Maybe<bool> DefineOwnProperty(
273       Local<Context> context, Local<Name> key, Local<Value> value,
274       PropertyAttribute attributes = None);
275 
276   // Implements Object.DefineProperty(O, P, Attributes), see Ecma-262 19.1.2.4.
277   //
278   // The defineProperty function is used to add an own property or
279   // update the attributes of an existing own property of an object.
280   //
281   // Both data and accessor descriptors can be used.
282   //
283   // In general, CreateDataProperty is faster, however, does not allow
284   // for specifying attributes or an accessor descriptor.
285   //
286   // The PropertyDescriptor can change when redefining a property.
287   //
288   // Returns true on success.
289   V8_WARN_UNUSED_RESULT Maybe<bool> DefineProperty(
290       Local<Context> context, Local<Name> key, PropertyDescriptor& descriptor);
291 
292   V8_WARN_UNUSED_RESULT MaybeLocal<Value> Get(Local<Context> context,
293                                               Local<Value> key);
294 
295   V8_WARN_UNUSED_RESULT MaybeLocal<Value> Get(Local<Context> context,
296                                               uint32_t index);
297 
298   /**
299    * Gets the property attributes of a property which can be None or
300    * any combination of ReadOnly, DontEnum and DontDelete. Returns
301    * None when the property doesn't exist.
302    */
303   V8_WARN_UNUSED_RESULT Maybe<PropertyAttribute> GetPropertyAttributes(
304       Local<Context> context, Local<Value> key);
305 
306   /**
307    * Returns Object.getOwnPropertyDescriptor as per ES2016 section 19.1.2.6.
308    */
309   V8_WARN_UNUSED_RESULT MaybeLocal<Value> GetOwnPropertyDescriptor(
310       Local<Context> context, Local<Name> key);
311 
312   /**
313    * Object::Has() calls the abstract operation HasProperty(O, P) described
314    * in ECMA-262, 7.3.10. Has() returns
315    * true, if the object has the property, either own or on the prototype chain.
316    * Interceptors, i.e., PropertyQueryCallbacks, are called if present.
317    *
318    * Has() has the same side effects as JavaScript's `variable in object`.
319    * For example, calling Has() on a revoked proxy will throw an exception.
320    *
321    * \note Has() converts the key to a name, which possibly calls back into
322    * JavaScript.
323    *
324    * See also v8::Object::HasOwnProperty() and
325    * v8::Object::HasRealNamedProperty().
326    */
327   V8_WARN_UNUSED_RESULT Maybe<bool> Has(Local<Context> context,
328                                         Local<Value> key);
329 
330   V8_WARN_UNUSED_RESULT Maybe<bool> Delete(Local<Context> context,
331                                            Local<Value> key);
332 
333   V8_WARN_UNUSED_RESULT Maybe<bool> Has(Local<Context> context, uint32_t index);
334 
335   V8_WARN_UNUSED_RESULT Maybe<bool> Delete(Local<Context> context,
336                                            uint32_t index);
337 
338   /**
339    * Note: SideEffectType affects the getter only, not the setter.
340    */
341   V8_WARN_UNUSED_RESULT Maybe<bool> SetAccessor(
342       Local<Context> context, Local<Name> name,
343       AccessorNameGetterCallback getter,
344       AccessorNameSetterCallback setter = nullptr,
345       MaybeLocal<Value> data = MaybeLocal<Value>(),
346       AccessControl settings = DEFAULT, PropertyAttribute attribute = None,
347       SideEffectType getter_side_effect_type = SideEffectType::kHasSideEffect,
348       SideEffectType setter_side_effect_type = SideEffectType::kHasSideEffect);
349 
350   void SetAccessorProperty(Local<Name> name, Local<Function> getter,
351                            Local<Function> setter = Local<Function>(),
352                            PropertyAttribute attribute = None,
353                            AccessControl settings = DEFAULT);
354 
355   /**
356    * Sets a native data property like Template::SetNativeDataProperty, but
357    * this method sets on this object directly.
358    */
359   V8_WARN_UNUSED_RESULT Maybe<bool> SetNativeDataProperty(
360       Local<Context> context, Local<Name> name,
361       AccessorNameGetterCallback getter,
362       AccessorNameSetterCallback setter = nullptr,
363       Local<Value> data = Local<Value>(), PropertyAttribute attributes = None,
364       SideEffectType getter_side_effect_type = SideEffectType::kHasSideEffect,
365       SideEffectType setter_side_effect_type = SideEffectType::kHasSideEffect);
366 
367   /**
368    * Attempts to create a property with the given name which behaves like a data
369    * property, except that the provided getter is invoked (and provided with the
370    * data value) to supply its value the first time it is read. After the
371    * property is accessed once, it is replaced with an ordinary data property.
372    *
373    * Analogous to Template::SetLazyDataProperty.
374    */
375   V8_WARN_UNUSED_RESULT Maybe<bool> SetLazyDataProperty(
376       Local<Context> context, Local<Name> name,
377       AccessorNameGetterCallback getter, Local<Value> data = Local<Value>(),
378       PropertyAttribute attributes = None,
379       SideEffectType getter_side_effect_type = SideEffectType::kHasSideEffect,
380       SideEffectType setter_side_effect_type = SideEffectType::kHasSideEffect);
381 
382   /**
383    * Functionality for private properties.
384    * This is an experimental feature, use at your own risk.
385    * Note: Private properties are not inherited. Do not rely on this, since it
386    * may change.
387    */
388   Maybe<bool> HasPrivate(Local<Context> context, Local<Private> key);
389   Maybe<bool> SetPrivate(Local<Context> context, Local<Private> key,
390                          Local<Value> value);
391   Maybe<bool> DeletePrivate(Local<Context> context, Local<Private> key);
392   MaybeLocal<Value> GetPrivate(Local<Context> context, Local<Private> key);
393 
394   /**
395    * Returns an array containing the names of the enumerable properties
396    * of this object, including properties from prototype objects.  The
397    * array returned by this method contains the same values as would
398    * be enumerated by a for-in statement over this object.
399    */
400   V8_WARN_UNUSED_RESULT MaybeLocal<Array> GetPropertyNames(
401       Local<Context> context);
402   V8_WARN_UNUSED_RESULT MaybeLocal<Array> GetPropertyNames(
403       Local<Context> context, KeyCollectionMode mode,
404       PropertyFilter property_filter, IndexFilter index_filter,
405       KeyConversionMode key_conversion = KeyConversionMode::kKeepNumbers);
406 
407   /**
408    * This function has the same functionality as GetPropertyNames but
409    * the returned array doesn't contain the names of properties from
410    * prototype objects.
411    */
412   V8_WARN_UNUSED_RESULT MaybeLocal<Array> GetOwnPropertyNames(
413       Local<Context> context);
414 
415   /**
416    * Returns an array containing the names of the filtered properties
417    * of this object, including properties from prototype objects.  The
418    * array returned by this method contains the same values as would
419    * be enumerated by a for-in statement over this object.
420    */
421   V8_WARN_UNUSED_RESULT MaybeLocal<Array> GetOwnPropertyNames(
422       Local<Context> context, PropertyFilter filter,
423       KeyConversionMode key_conversion = KeyConversionMode::kKeepNumbers);
424 
425   /**
426    * Get the prototype object.  This does not skip objects marked to
427    * be skipped by __proto__ and it does not consult the security
428    * handler.
429    */
430   Local<Value> GetPrototype();
431 
432   /**
433    * Set the prototype object.  This does not skip objects marked to
434    * be skipped by __proto__ and it does not consult the security
435    * handler.
436    */
437   V8_WARN_UNUSED_RESULT Maybe<bool> SetPrototype(Local<Context> context,
438                                                  Local<Value> prototype);
439 
440   /**
441    * Finds an instance of the given function template in the prototype
442    * chain.
443    */
444   Local<Object> FindInstanceInPrototypeChain(Local<FunctionTemplate> tmpl);
445 
446   /**
447    * Call builtin Object.prototype.toString on this object.
448    * This is different from Value::ToString() that may call
449    * user-defined toString function. This one does not.
450    */
451   V8_WARN_UNUSED_RESULT MaybeLocal<String> ObjectProtoToString(
452       Local<Context> context);
453 
454   /**
455    * Returns the name of the function invoked as a constructor for this object.
456    */
457   Local<String> GetConstructorName();
458 
459   /**
460    * Sets the integrity level of the object.
461    */
462   Maybe<bool> SetIntegrityLevel(Local<Context> context, IntegrityLevel level);
463 
464   /** Gets the number of internal fields for this Object. */
465   int InternalFieldCount() const;
466 
467   /** Same as above, but works for PersistentBase. */
InternalFieldCount(const PersistentBase<Object> & object)468   V8_INLINE static int InternalFieldCount(
469       const PersistentBase<Object>& object) {
470     return object.val_->InternalFieldCount();
471   }
472 
473   /** Same as above, but works for BasicTracedReference. */
InternalFieldCount(const BasicTracedReference<Object> & object)474   V8_INLINE static int InternalFieldCount(
475       const BasicTracedReference<Object>& object) {
476     return object->InternalFieldCount();
477   }
478 
479   /** Gets the value from an internal field. */
480   V8_INLINE Local<Value> GetInternalField(int index);
481 
482   /** Sets the value in an internal field. */
483   void SetInternalField(int index, Local<Value> value);
484 
485   /**
486    * Warning: These are Node.js-specific extentions used to avoid breaking
487    * changes in Node.js v18.x. They do not exist in V8 upstream and will
488    * not exist in Node.js v21.x. Node.js embedders and addon authors should
489    * not use them from v18.x.
490    */
491 #ifndef NODE_WANT_INTERNALS
492   V8_DEPRECATED("This extention should only be used by Node.js core")
493 #endif
494   void SetInternalFieldForNodeCore(int index, Local<Module> value);
495 #ifndef NODE_WANT_INTERNALS
496   V8_DEPRECATED("This extention should only be used by Node.js core")
497 #endif
498   void SetInternalFieldForNodeCore(int index, Local<UnboundScript> value);
499 
500   /**
501    * Gets a 2-byte-aligned native pointer from an internal field. This field
502    * must have been set by SetAlignedPointerInInternalField, everything else
503    * leads to undefined behavior.
504    */
505   V8_INLINE void* GetAlignedPointerFromInternalField(int index);
506 
507   /** Same as above, but works for PersistentBase. */
GetAlignedPointerFromInternalField(const PersistentBase<Object> & object,int index)508   V8_INLINE static void* GetAlignedPointerFromInternalField(
509       const PersistentBase<Object>& object, int index) {
510     return object.val_->GetAlignedPointerFromInternalField(index);
511   }
512 
513   /** Same as above, but works for TracedReference. */
GetAlignedPointerFromInternalField(const BasicTracedReference<Object> & object,int index)514   V8_INLINE static void* GetAlignedPointerFromInternalField(
515       const BasicTracedReference<Object>& object, int index) {
516     return object->GetAlignedPointerFromInternalField(index);
517   }
518 
519   /**
520    * Sets a 2-byte-aligned native pointer in an internal field. To retrieve such
521    * a field, GetAlignedPointerFromInternalField must be used, everything else
522    * leads to undefined behavior.
523    */
524   void SetAlignedPointerInInternalField(int index, void* value);
525   void SetAlignedPointerInInternalFields(int argc, int indices[],
526                                          void* values[]);
527 
528   /**
529    * HasOwnProperty() is like JavaScript's Object.prototype.hasOwnProperty().
530    *
531    * See also v8::Object::Has() and v8::Object::HasRealNamedProperty().
532    */
533   V8_WARN_UNUSED_RESULT Maybe<bool> HasOwnProperty(Local<Context> context,
534                                                    Local<Name> key);
535   V8_WARN_UNUSED_RESULT Maybe<bool> HasOwnProperty(Local<Context> context,
536                                                    uint32_t index);
537   /**
538    * Use HasRealNamedProperty() if you want to check if an object has an own
539    * property without causing side effects, i.e., without calling interceptors.
540    *
541    * This function is similar to v8::Object::HasOwnProperty(), but it does not
542    * call interceptors.
543    *
544    * \note Consider using non-masking interceptors, i.e., the interceptors are
545    * not called if the receiver has the real named property. See
546    * `v8::PropertyHandlerFlags::kNonMasking`.
547    *
548    * See also v8::Object::Has().
549    */
550   V8_WARN_UNUSED_RESULT Maybe<bool> HasRealNamedProperty(Local<Context> context,
551                                                          Local<Name> key);
552   V8_WARN_UNUSED_RESULT Maybe<bool> HasRealIndexedProperty(
553       Local<Context> context, uint32_t index);
554   V8_WARN_UNUSED_RESULT Maybe<bool> HasRealNamedCallbackProperty(
555       Local<Context> context, Local<Name> key);
556 
557   /**
558    * If result.IsEmpty() no real property was located in the prototype chain.
559    * This means interceptors in the prototype chain are not called.
560    */
561   V8_WARN_UNUSED_RESULT MaybeLocal<Value> GetRealNamedPropertyInPrototypeChain(
562       Local<Context> context, Local<Name> key);
563 
564   /**
565    * Gets the property attributes of a real property in the prototype chain,
566    * which can be None or any combination of ReadOnly, DontEnum and DontDelete.
567    * Interceptors in the prototype chain are not called.
568    */
569   V8_WARN_UNUSED_RESULT Maybe<PropertyAttribute>
570   GetRealNamedPropertyAttributesInPrototypeChain(Local<Context> context,
571                                                  Local<Name> key);
572 
573   /**
574    * If result.IsEmpty() no real property was located on the object or
575    * in the prototype chain.
576    * This means interceptors in the prototype chain are not called.
577    */
578   V8_WARN_UNUSED_RESULT MaybeLocal<Value> GetRealNamedProperty(
579       Local<Context> context, Local<Name> key);
580 
581   /**
582    * Gets the property attributes of a real property which can be
583    * None or any combination of ReadOnly, DontEnum and DontDelete.
584    * Interceptors in the prototype chain are not called.
585    */
586   V8_WARN_UNUSED_RESULT Maybe<PropertyAttribute> GetRealNamedPropertyAttributes(
587       Local<Context> context, Local<Name> key);
588 
589   /** Tests for a named lookup interceptor.*/
590   bool HasNamedLookupInterceptor() const;
591 
592   /** Tests for an index lookup interceptor.*/
593   bool HasIndexedLookupInterceptor() const;
594 
595   /**
596    * Returns the identity hash for this object. The current implementation
597    * uses a hidden property on the object to store the identity hash.
598    *
599    * The return value will never be 0. Also, it is not guaranteed to be
600    * unique.
601    */
602   int GetIdentityHash();
603 
604   /**
605    * Clone this object with a fast but shallow copy.  Values will point
606    * to the same values as the original object.
607    */
608   // TODO(dcarney): take an isolate and optionally bail out?
609   Local<Object> Clone();
610 
611   /**
612    * Returns the context in which the object was created.
613    */
614   V8_DEPRECATED("Use MaybeLocal<Context> GetCreationContext()")
615   Local<Context> CreationContext();
616   MaybeLocal<Context> GetCreationContext();
617 
618   /**
619    * Shortcut for GetCreationContext().ToLocalChecked().
620    **/
621   Local<Context> GetCreationContextChecked();
622 
623   /** Same as above, but works for Persistents */
624   V8_DEPRECATED(
625       "Use MaybeLocal<Context> GetCreationContext(const "
626       "PersistentBase<Object>& object)")
627   static Local<Context> CreationContext(const PersistentBase<Object>& object);
GetCreationContext(const PersistentBase<Object> & object)628   V8_INLINE static MaybeLocal<Context> GetCreationContext(
629       const PersistentBase<Object>& object) {
630     return object.val_->GetCreationContext();
631   }
632 
633   /**
634    * Checks whether a callback is set by the
635    * ObjectTemplate::SetCallAsFunctionHandler method.
636    * When an Object is callable this method returns true.
637    */
638   bool IsCallable() const;
639 
640   /**
641    * True if this object is a constructor.
642    */
643   bool IsConstructor() const;
644 
645   /**
646    * True if this object can carry information relevant to the embedder in its
647    * embedder fields, false otherwise. This is generally true for objects
648    * constructed through function templates but also holds for other types where
649    * V8 automatically adds internal fields at compile time, such as e.g.
650    * v8::ArrayBuffer.
651    */
652   bool IsApiWrapper() const;
653 
654   /**
655    * True if this object was created from an object template which was marked
656    * as undetectable. See v8::ObjectTemplate::MarkAsUndetectable for more
657    * information.
658    */
659   bool IsUndetectable() const;
660 
661   /**
662    * Call an Object as a function if a callback is set by the
663    * ObjectTemplate::SetCallAsFunctionHandler method.
664    */
665   V8_WARN_UNUSED_RESULT MaybeLocal<Value> CallAsFunction(Local<Context> context,
666                                                          Local<Value> recv,
667                                                          int argc,
668                                                          Local<Value> argv[]);
669 
670   /**
671    * Call an Object as a constructor if a callback is set by the
672    * ObjectTemplate::SetCallAsFunctionHandler method.
673    * Note: This method behaves like the Function::NewInstance method.
674    */
675   V8_WARN_UNUSED_RESULT MaybeLocal<Value> CallAsConstructor(
676       Local<Context> context, int argc, Local<Value> argv[]);
677 
678   /**
679    * Return the isolate to which the Object belongs to.
680    */
681   Isolate* GetIsolate();
682 
683   /**
684    * If this object is a Set, Map, WeakSet or WeakMap, this returns a
685    * representation of the elements of this object as an array.
686    * If this object is a SetIterator or MapIterator, this returns all
687    * elements of the underlying collection, starting at the iterator's current
688    * position.
689    * For other types, this will return an empty MaybeLocal<Array> (without
690    * scheduling an exception).
691    */
692   MaybeLocal<Array> PreviewEntries(bool* is_key_value);
693 
694   static Local<Object> New(Isolate* isolate);
695 
696   /**
697    * Creates a JavaScript object with the given properties, and
698    * a the given prototype_or_null (which can be any JavaScript
699    * value, and if it's null, the newly created object won't have
700    * a prototype at all). This is similar to Object.create().
701    * All properties will be created as enumerable, configurable
702    * and writable properties.
703    */
704   static Local<Object> New(Isolate* isolate, Local<Value> prototype_or_null,
705                            Local<Name>* names, Local<Value>* values,
706                            size_t length);
707 
708   V8_INLINE static Object* Cast(Value* obj);
709 
710   /**
711    * Support for TC39 "dynamic code brand checks" proposal.
712    *
713    * This API allows to query whether an object was constructed from a
714    * "code like" ObjectTemplate.
715    *
716    * See also: v8::ObjectTemplate::SetCodeLike
717    */
718   bool IsCodeLike(Isolate* isolate) const;
719 
720  private:
721   Object();
722   static void CheckCast(Value* obj);
723   Local<Value> SlowGetInternalField(int index);
724   void* SlowGetAlignedPointerFromInternalField(int index);
725 };
726 
727 // --- Implementation ---
728 
GetInternalField(int index)729 Local<Value> Object::GetInternalField(int index) {
730 #ifndef V8_ENABLE_CHECKS
731   using A = internal::Address;
732   using I = internal::Internals;
733   A obj = *reinterpret_cast<A*>(this);
734   // Fast path: If the object is a plain JSObject, which is the common case, we
735   // know where to find the internal fields and can return the value directly.
736   int instance_type = I::GetInstanceType(obj);
737   if (v8::internal::CanHaveInternalField(instance_type)) {
738     int offset = I::kJSObjectHeaderSize + (I::kEmbedderDataSlotSize * index);
739     A value = I::ReadRawField<A>(obj, offset);
740 #ifdef V8_COMPRESS_POINTERS
741     // We read the full pointer value and then decompress it in order to avoid
742     // dealing with potential endiannes issues.
743     value = I::DecompressTaggedAnyField(obj, static_cast<uint32_t>(value));
744 #endif
745     internal::Isolate* isolate =
746         internal::IsolateFromNeverReadOnlySpaceObject(obj);
747     A* result = HandleScope::CreateHandle(isolate, value);
748     return Local<Value>(reinterpret_cast<Value*>(result));
749   }
750 #endif
751   return SlowGetInternalField(index);
752 }
753 
GetAlignedPointerFromInternalField(int index)754 void* Object::GetAlignedPointerFromInternalField(int index) {
755 #if !defined(V8_ENABLE_CHECKS)
756   using A = internal::Address;
757   using I = internal::Internals;
758   A obj = *reinterpret_cast<A*>(this);
759   // Fast path: If the object is a plain JSObject, which is the common case, we
760   // know where to find the internal fields and can return the value directly.
761   auto instance_type = I::GetInstanceType(obj);
762   if (v8::internal::CanHaveInternalField(instance_type)) {
763     int offset = I::kJSObjectHeaderSize + (I::kEmbedderDataSlotSize * index);
764 #ifdef V8_SANDBOXED_EXTERNAL_POINTERS
765     offset += I::kEmbedderDataSlotRawPayloadOffset;
766 #endif
767     internal::Isolate* isolate = I::GetIsolateForSandbox(obj);
768     A value = I::ReadExternalPointerField(
769         isolate, obj, offset, internal::kEmbedderDataSlotPayloadTag);
770     return reinterpret_cast<void*>(value);
771   }
772 #endif
773   return SlowGetAlignedPointerFromInternalField(index);
774 }
775 
Cast(Data * data)776 Private* Private::Cast(Data* data) {
777 #ifdef V8_ENABLE_CHECKS
778   CheckCast(data);
779 #endif
780   return reinterpret_cast<Private*>(data);
781 }
782 
Cast(v8::Value * value)783 Object* Object::Cast(v8::Value* value) {
784 #ifdef V8_ENABLE_CHECKS
785   CheckCast(value);
786 #endif
787   return static_cast<Object*>(value);
788 }
789 
790 }  // namespace v8
791 
792 #endif  // INCLUDE_V8_OBJECT_H_
793