xref: /third_party/node/deps/v8/include/v8-object.h (revision 1cb0ef41)
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
16namespace v8 {
17
18class Array;
19class Function;
20class FunctionTemplate;
21template <typename T>
22class PropertyCallbackInfo;
23class Module;
24class UnboundScript;
25
26/**
27 * A private symbol
28 *
29 * This is an experimental feature. Use at your own risk.
30 */
31class 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 */
91class 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;
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 */
139enum 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 */
155using AccessorGetterCallback =
156    void (*)(Local<String> property, const PropertyCallbackInfo<Value>& info);
157using AccessorNameGetterCallback =
158    void (*)(Local<Name> property, const PropertyCallbackInfo<Value>& info);
159
160using AccessorSetterCallback = void (*)(Local<String> property,
161                                        Local<Value> value,
162                                        const PropertyCallbackInfo<void>& info);
163using 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 */
176enum 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 */
186enum 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 */
205enum 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 */
218enum 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 */
224enum class IndexFilter { kIncludeIndices, kSkipIndices };
225
226/**
227 * kConvertToString will convert integer indices to strings.
228 * kKeepNumbers will return numbers for integer indices.
229 */
230enum class KeyConversionMode { kConvertToString, kKeepNumbers, kNoNumbers };
231
232/**
233 * Integrity level for objects.
234 */
235enum class IntegrityLevel { kFrozen, kSealed };
236
237/**
238 * A JavaScript object (ECMA-262, 4.3.3)
239 */
240class 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. */
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. */
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. */
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. */
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);
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
729Local<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
754void* 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
776Private* Private::Cast(Data* data) {
777#ifdef V8_ENABLE_CHECKS
778  CheckCast(data);
779#endif
780  return reinterpret_cast<Private*>(data);
781}
782
783Object* 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