v8  10.1.124 (node 18.2.0)
V8 is Google's open source JavaScript engine
v8-object.h
Go to the documentation of this file.
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>
23 
24 /**
25  * A private symbol
26  *
27  * This is an experimental feature. Use at your own risk.
28  */
29 class 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  */
90  public:
91  // GenericDescriptor
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
102 
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 
128  void operator=(const PropertyDescriptor&) = delete;
129 
130  private:
131  PrivateData* private_;
132 };
133 
134 /**
135  * PropertyAttribute.
136  */
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  */
153 using AccessorGetterCallback =
154  void (*)(Local<String> property, const PropertyCallbackInfo<Value>& info);
155 using AccessorNameGetterCallback =
156  void (*)(Local<Name> property, const PropertyCallbackInfo<Value>& info);
157 
158 using AccessorSetterCallback = void (*)(Local<String> property,
159  Local<Value> value,
160  const PropertyCallbackInfo<void>& info);
161 using 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  */
175  DEFAULT = 0,
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  */
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  */
203 enum class SideEffectType {
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  */
217 
218 /**
219  * kIncludesIndices allows for integer indices to be collected, while
220  * kSkipIndices will exclude integer indices from being collected.
221  */
223 
224 /**
225  * kConvertToString will convert integer indices to strings.
226  * kKeepNumbers will return numbers for integer indices.
227  */
229 
230 /**
231  * Integrity level for objects.
232  */
234 
235 /**
236  * A JavaScript object (ECMA-262, 4.3.3)
237  */
238 class 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  */
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  // Implements CreateDataProperty (ECMA-262, 7.3.4).
251  //
252  // Defines a configurable, writable, enumerable property with the given value
253  // on the object unless the property already exists and is not configurable
254  // or the object is not extensible.
255  //
256  // Returns true on success.
258  Local<Name> key,
259  Local<Value> value);
261  uint32_t index,
262  Local<Value> value);
263 
264  // Implements DefineOwnProperty.
265  //
266  // In general, CreateDataProperty will be faster, however, does not allow
267  // for specifying attributes.
268  //
269  // Returns true on success.
271  Local<Context> context, Local<Name> key, Local<Value> value,
272  PropertyAttribute attributes = None);
273 
274  // Implements Object.DefineProperty(O, P, Attributes), see Ecma-262 19.1.2.4.
275  //
276  // The defineProperty function is used to add an own property or
277  // update the attributes of an existing own property of an object.
278  //
279  // Both data and accessor descriptors can be used.
280  //
281  // In general, CreateDataProperty is faster, however, does not allow
282  // for specifying attributes or an accessor descriptor.
283  //
284  // The PropertyDescriptor can change when redefining a property.
285  //
286  // Returns true on success.
288  Local<Context> context, Local<Name> key, PropertyDescriptor& descriptor);
289 
291  Local<Value> key);
292 
294  uint32_t index);
295 
296  /**
297  * Gets the property attributes of a property which can be None or
298  * any combination of ReadOnly, DontEnum and DontDelete. Returns
299  * None when the property doesn't exist.
300  */
302  Local<Context> context, Local<Value> key);
303 
304  /**
305  * Returns Object.getOwnPropertyDescriptor as per ES2016 section 19.1.2.6.
306  */
308  Local<Context> context, Local<Name> key);
309 
310  /**
311  * Object::Has() calls the abstract operation HasProperty(O, P) described
312  * in ECMA-262, 7.3.10. Has() returns
313  * true, if the object has the property, either own or on the prototype chain.
314  * Interceptors, i.e., PropertyQueryCallbacks, are called if present.
315  *
316  * Has() has the same side effects as JavaScript's `variable in object`.
317  * For example, calling Has() on a revoked proxy will throw an exception.
318  *
319  * \note Has() converts the key to a name, which possibly calls back into
320  * JavaScript.
321  *
322  * See also v8::Object::HasOwnProperty() and
323  * v8::Object::HasRealNamedProperty().
324  */
326  Local<Value> key);
327 
329  Local<Value> key);
330 
331  V8_WARN_UNUSED_RESULT Maybe<bool> Has(Local<Context> context, uint32_t index);
332 
334  uint32_t index);
335 
336  /**
337  * Note: SideEffectType affects the getter only, not the setter.
338  */
340  Local<Context> context, Local<Name> name,
341  AccessorNameGetterCallback getter,
342  AccessorNameSetterCallback setter = nullptr,
344  AccessControl settings = DEFAULT, PropertyAttribute attribute = None,
345  SideEffectType getter_side_effect_type = SideEffectType::kHasSideEffect,
346  SideEffectType setter_side_effect_type = SideEffectType::kHasSideEffect);
347 
349  Local<Function> setter = Local<Function>(),
350  PropertyAttribute attribute = None,
351  AccessControl settings = DEFAULT);
352 
353  /**
354  * Sets a native data property like Template::SetNativeDataProperty, but
355  * this method sets on this object directly.
356  */
358  Local<Context> context, Local<Name> name,
359  AccessorNameGetterCallback getter,
360  AccessorNameSetterCallback setter = nullptr,
361  Local<Value> data = Local<Value>(), PropertyAttribute attributes = None,
362  SideEffectType getter_side_effect_type = SideEffectType::kHasSideEffect,
363  SideEffectType setter_side_effect_type = SideEffectType::kHasSideEffect);
364 
365  /**
366  * Attempts to create a property with the given name which behaves like a data
367  * property, except that the provided getter is invoked (and provided with the
368  * data value) to supply its value the first time it is read. After the
369  * property is accessed once, it is replaced with an ordinary data property.
370  *
371  * Analogous to Template::SetLazyDataProperty.
372  */
374  Local<Context> context, Local<Name> name,
375  AccessorNameGetterCallback getter, Local<Value> data = Local<Value>(),
376  PropertyAttribute attributes = None,
377  SideEffectType getter_side_effect_type = SideEffectType::kHasSideEffect,
378  SideEffectType setter_side_effect_type = SideEffectType::kHasSideEffect);
379 
380  /**
381  * Functionality for private properties.
382  * This is an experimental feature, use at your own risk.
383  * Note: Private properties are not inherited. Do not rely on this, since it
384  * may change.
385  */
386  Maybe<bool> HasPrivate(Local<Context> context, Local<Private> key);
387  Maybe<bool> SetPrivate(Local<Context> context, Local<Private> key,
388  Local<Value> value);
389  Maybe<bool> DeletePrivate(Local<Context> context, Local<Private> key);
391 
392  /**
393  * Returns an array containing the names of the enumerable properties
394  * of this object, including properties from prototype objects. The
395  * array returned by this method contains the same values as would
396  * be enumerated by a for-in statement over this object.
397  */
399  Local<Context> context);
401  Local<Context> context, KeyCollectionMode mode,
402  PropertyFilter property_filter, IndexFilter index_filter,
404 
405  /**
406  * This function has the same functionality as GetPropertyNames but
407  * the returned array doesn't contain the names of properties from
408  * prototype objects.
409  */
411  Local<Context> context);
412 
413  /**
414  * Returns an array containing the names of the filtered properties
415  * of this object, including properties from prototype objects. The
416  * array returned by this method contains the same values as would
417  * be enumerated by a for-in statement over this object.
418  */
420  Local<Context> context, PropertyFilter filter,
422 
423  /**
424  * Get the prototype object. This does not skip objects marked to
425  * be skipped by __proto__ and it does not consult the security
426  * handler.
427  */
429 
430  /**
431  * Set the prototype object. This does not skip objects marked to
432  * be skipped by __proto__ and it does not consult the security
433  * handler.
434  */
436  Local<Value> prototype);
437 
438  /**
439  * Finds an instance of the given function template in the prototype
440  * chain.
441  */
443 
444  /**
445  * Call builtin Object.prototype.toString on this object.
446  * This is different from Value::ToString() that may call
447  * user-defined toString function. This one does not.
448  */
450  Local<Context> context);
451 
452  /**
453  * Returns the name of the function invoked as a constructor for this object.
454  */
456 
457  /**
458  * Sets the integrity level of the object.
459  */
461 
462  /** Gets the number of internal fields for this Object. */
463  int InternalFieldCount() const;
464 
465  /** Same as above, but works for PersistentBase. */
467  const PersistentBase<Object>& object) {
468  return object.val_->InternalFieldCount();
469  }
470 
471  /** Same as above, but works for BasicTracedReference. */
473  const BasicTracedReference<Object>& object) {
474  return object->InternalFieldCount();
475  }
476 
477  /** Gets the value from an internal field. */
479 
480  /** Sets the value in an internal field. */
481  void SetInternalField(int index, Local<Value> value);
482 
483  /**
484  * Gets a 2-byte-aligned native pointer from an internal field. This field
485  * must have been set by SetAlignedPointerInInternalField, everything else
486  * leads to undefined behavior.
487  */
489 
490  /** Same as above, but works for PersistentBase. */
492  const PersistentBase<Object>& object, int index) {
493  return object.val_->GetAlignedPointerFromInternalField(index);
494  }
495 
496  /** Same as above, but works for TracedGlobal. */
498  const BasicTracedReference<Object>& object, int index) {
499  return object->GetAlignedPointerFromInternalField(index);
500  }
501 
502  /**
503  * Sets a 2-byte-aligned native pointer in an internal field. To retrieve such
504  * a field, GetAlignedPointerFromInternalField must be used, everything else
505  * leads to undefined behavior.
506  */
507  void SetAlignedPointerInInternalField(int index, void* value);
508  void SetAlignedPointerInInternalFields(int argc, int indices[],
509  void* values[]);
510 
511  /**
512  * HasOwnProperty() is like JavaScript's Object.prototype.hasOwnProperty().
513  *
514  * See also v8::Object::Has() and v8::Object::HasRealNamedProperty().
515  */
517  Local<Name> key);
519  uint32_t index);
520  /**
521  * Use HasRealNamedProperty() if you want to check if an object has an own
522  * property without causing side effects, i.e., without calling interceptors.
523  *
524  * This function is similar to v8::Object::HasOwnProperty(), but it does not
525  * call interceptors.
526  *
527  * \note Consider using non-masking interceptors, i.e., the interceptors are
528  * not called if the receiver has the real named property. See
529  * `v8::PropertyHandlerFlags::kNonMasking`.
530  *
531  * See also v8::Object::Has().
532  */
534  Local<Name> key);
536  Local<Context> context, uint32_t index);
538  Local<Context> context, Local<Name> key);
539 
540  /**
541  * If result.IsEmpty() no real property was located in the prototype chain.
542  * This means interceptors in the prototype chain are not called.
543  */
545  Local<Context> context, Local<Name> key);
546 
547  /**
548  * Gets the property attributes of a real property in the prototype chain,
549  * which can be None or any combination of ReadOnly, DontEnum and DontDelete.
550  * Interceptors in the prototype chain are not called.
551  */
554  Local<Name> key);
555 
556  /**
557  * If result.IsEmpty() no real property was located on the object or
558  * in the prototype chain.
559  * This means interceptors in the prototype chain are not called.
560  */
562  Local<Context> context, Local<Name> key);
563 
564  /**
565  * Gets the property attributes of a real property which can be
566  * None or any combination of ReadOnly, DontEnum and DontDelete.
567  * Interceptors in the prototype chain are not called.
568  */
570  Local<Context> context, Local<Name> key);
571 
572  /** Tests for a named lookup interceptor.*/
574 
575  /** Tests for an index lookup interceptor.*/
577 
578  /**
579  * Returns the identity hash for this object. The current implementation
580  * uses a hidden property on the object to store the identity hash.
581  *
582  * The return value will never be 0. Also, it is not guaranteed to be
583  * unique.
584  */
586 
587  /**
588  * Clone this object with a fast but shallow copy. Values will point
589  * to the same values as the original object.
590  */
591  // TODO(dcarney): take an isolate and optionally bail out?
593 
594  /**
595  * Returns the context in which the object was created.
596  */
597  V8_DEPRECATED("Use MaybeLocal<Context> GetCreationContext()")
600 
601  /**
602  * Shortcut for GetCreationContext().ToLocalChecked().
603  **/
605 
606  /** Same as above, but works for Persistents */
608  "Use MaybeLocal<Context> GetCreationContext(const "
609  "PersistentBase<Object>& object)")
610  static Local<Context> CreationContext(const PersistentBase<Object>& object);
612  const PersistentBase<Object>& object) {
613  return object.val_->GetCreationContext();
614  }
615 
616  /**
617  * Checks whether a callback is set by the
618  * ObjectTemplate::SetCallAsFunctionHandler method.
619  * When an Object is callable this method returns true.
620  */
621  bool IsCallable() const;
622 
623  /**
624  * True if this object is a constructor.
625  */
626  bool IsConstructor() const;
627 
628  /**
629  * True if this object can carry information relevant to the embedder in its
630  * embedder fields, false otherwise. This is generally true for objects
631  * constructed through function templates but also holds for other types where
632  * V8 automatically adds internal fields at compile time, such as e.g.
633  * v8::ArrayBuffer.
634  */
635  bool IsApiWrapper() const;
636 
637  /**
638  * True if this object was created from an object template which was marked
639  * as undetectable. See v8::ObjectTemplate::MarkAsUndetectable for more
640  * information.
641  */
642  bool IsUndetectable() const;
643 
644  /**
645  * Call an Object as a function if a callback is set by the
646  * ObjectTemplate::SetCallAsFunctionHandler method.
647  */
649  Local<Value> recv,
650  int argc,
651  Local<Value> argv[]);
652 
653  /**
654  * Call an Object as a constructor if a callback is set by the
655  * ObjectTemplate::SetCallAsFunctionHandler method.
656  * Note: This method behaves like the Function::NewInstance method.
657  */
659  Local<Context> context, int argc, Local<Value> argv[]);
660 
661  /**
662  * Return the isolate to which the Object belongs to.
663  */
665 
666  /**
667  * If this object is a Set, Map, WeakSet or WeakMap, this returns a
668  * representation of the elements of this object as an array.
669  * If this object is a SetIterator or MapIterator, this returns all
670  * elements of the underlying collection, starting at the iterator's current
671  * position.
672  * For other types, this will return an empty MaybeLocal<Array> (without
673  * scheduling an exception).
674  */
675  MaybeLocal<Array> PreviewEntries(bool* is_key_value);
676 
677  static Local<Object> New(Isolate* isolate);
678 
679  /**
680  * Creates a JavaScript object with the given properties, and
681  * a the given prototype_or_null (which can be any JavaScript
682  * value, and if it's null, the newly created object won't have
683  * a prototype at all). This is similar to Object.create().
684  * All properties will be created as enumerable, configurable
685  * and writable properties.
686  */
687  static Local<Object> New(Isolate* isolate, Local<Value> prototype_or_null,
688  Local<Name>* names, Local<Value>* values,
689  size_t length);
690 
691  V8_INLINE static Object* Cast(Value* obj);
692 
693  /**
694  * Support for TC39 "dynamic code brand checks" proposal.
695  *
696  * This API allows to query whether an object was constructed from a
697  * "code like" ObjectTemplate.
698  *
699  * See also: v8::ObjectTemplate::SetCodeLike
700  */
701  bool IsCodeLike(Isolate* isolate) const;
702 
703  private:
704  Object();
705  static void CheckCast(Value* obj);
706  Local<Value> SlowGetInternalField(int index);
707  void* SlowGetAlignedPointerFromInternalField(int index);
708 };
709 
710 // --- Implementation ---
711 
713 #ifndef V8_ENABLE_CHECKS
714  using A = internal::Address;
715  using I = internal::Internals;
716  A obj = *reinterpret_cast<A*>(this);
717  // Fast path: If the object is a plain JSObject, which is the common case, we
718  // know where to find the internal fields and can return the value directly.
719  int instance_type = I::GetInstanceType(obj);
720  if (v8::internal::CanHaveInternalField(instance_type)) {
721  int offset = I::kJSObjectHeaderSize + (I::kEmbedderDataSlotSize * index);
722  A value = I::ReadRawField<A>(obj, offset);
723 #ifdef V8_COMPRESS_POINTERS
724  // We read the full pointer value and then decompress it in order to avoid
725  // dealing with potential endiannes issues.
726  value = I::DecompressTaggedAnyField(obj, static_cast<uint32_t>(value));
727 #endif
728  internal::Isolate* isolate =
730  A* result = HandleScope::CreateHandle(isolate, value);
731  return Local<Value>(reinterpret_cast<Value*>(result));
732  }
733 #endif
734  return SlowGetInternalField(index);
735 }
736 
738 #if !defined(V8_ENABLE_CHECKS)
739  using A = internal::Address;
740  using I = internal::Internals;
741  A obj = *reinterpret_cast<A*>(this);
742  // Fast path: If the object is a plain JSObject, which is the common case, we
743  // know where to find the internal fields and can return the value directly.
744  auto instance_type = I::GetInstanceType(obj);
745  if (v8::internal::CanHaveInternalField(instance_type)) {
746  int offset = I::kJSObjectHeaderSize + (I::kEmbedderDataSlotSize * index);
747 #ifdef V8_SANDBOXED_EXTERNAL_POINTERS
748  offset += I::kEmbedderDataSlotRawPayloadOffset;
749 #endif
750  internal::Isolate* isolate = I::GetIsolateForSandbox(obj);
751  A value = I::ReadExternalPointerField(
753  return reinterpret_cast<void*>(value);
754  }
755 #endif
756  return SlowGetAlignedPointerFromInternalField(index);
757 }
758 
760 #ifdef V8_ENABLE_CHECKS
761  CheckCast(data);
762 #endif
763  return reinterpret_cast<Private*>(data);
764 }
765 
766 Object* Object::Cast(v8::Value* value) {
767 #ifdef V8_ENABLE_CHECKS
768  CheckCast(value);
769 #endif
770  return static_cast<Object*>(value);
771 }
772 
773 } // namespace v8
774 
775 #endif // INCLUDE_V8_OBJECT_H_