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