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