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