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