Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-21 10:05:25

0001 // Copyright 2021 the V8 project authors. All rights reserved.
0002 // Use of this source code is governed by a BSD-style license that can be
0003 // found in the LICENSE file.
0004 
0005 #ifndef INCLUDE_V8_OBJECT_H_
0006 #define INCLUDE_V8_OBJECT_H_
0007 
0008 #include "v8-local-handle.h"       // NOLINT(build/include_directory)
0009 #include "v8-maybe.h"              // NOLINT(build/include_directory)
0010 #include "v8-persistent-handle.h"  // NOLINT(build/include_directory)
0011 #include "v8-primitive.h"          // NOLINT(build/include_directory)
0012 #include "v8-traced-handle.h"      // NOLINT(build/include_directory)
0013 #include "v8-value.h"              // NOLINT(build/include_directory)
0014 #include "v8config.h"              // NOLINT(build/include_directory)
0015 
0016 namespace v8 {
0017 
0018 class Array;
0019 class Function;
0020 class FunctionTemplate;
0021 template <typename T>
0022 class PropertyCallbackInfo;
0023 
0024 /**
0025  * A private symbol
0026  *
0027  * This is an experimental feature. Use at your own risk.
0028  */
0029 class V8_EXPORT Private : public Data {
0030  public:
0031   /**
0032    * Returns the print name string of the private symbol, or undefined if none.
0033    */
0034   Local<Value> Name() const;
0035 
0036   /**
0037    * Create a private symbol. If name is not empty, it will be the description.
0038    */
0039   static Local<Private> New(Isolate* isolate,
0040                             Local<String> name = Local<String>());
0041 
0042   /**
0043    * Retrieve a global private symbol. If a symbol with this name has not
0044    * been retrieved in the same isolate before, it is created.
0045    * Note that private symbols created this way are never collected, so
0046    * they should only be used for statically fixed properties.
0047    * Also, there is only one global name space for the names used as keys.
0048    * To minimize the potential for clashes, use qualified names as keys,
0049    * e.g., "Class#property".
0050    */
0051   static Local<Private> ForApi(Isolate* isolate, Local<String> name);
0052 
0053   V8_INLINE static Private* Cast(Data* data);
0054 
0055  private:
0056   Private();
0057 
0058   static void CheckCast(Data* that);
0059 };
0060 
0061 /**
0062  * An instance of a Property Descriptor, see Ecma-262 6.2.4.
0063  *
0064  * Properties in a descriptor are present or absent. If you do not set
0065  * `enumerable`, `configurable`, and `writable`, they are absent. If `value`,
0066  * `get`, or `set` are absent, but you must specify them in the constructor, use
0067  * empty handles.
0068  *
0069  * Accessors `get` and `set` must be callable or undefined if they are present.
0070  *
0071  * \note Only query properties if they are present, i.e., call `x()` only if
0072  * `has_x()` returns true.
0073  *
0074  * \code
0075  * // var desc = {writable: false}
0076  * v8::PropertyDescriptor d(Local<Value>()), false);
0077  * d.value(); // error, value not set
0078  * if (d.has_writable()) {
0079  *   d.writable(); // false
0080  * }
0081  *
0082  * // var desc = {value: undefined}
0083  * v8::PropertyDescriptor d(v8::Undefined(isolate));
0084  *
0085  * // var desc = {get: undefined}
0086  * v8::PropertyDescriptor d(v8::Undefined(isolate), Local<Value>()));
0087  * \endcode
0088  */
0089 class V8_EXPORT PropertyDescriptor {
0090  public:
0091   // GenericDescriptor
0092   PropertyDescriptor();
0093 
0094   // DataDescriptor
0095   explicit PropertyDescriptor(Local<Value> value);
0096 
0097   // DataDescriptor with writable property
0098   PropertyDescriptor(Local<Value> value, bool writable);
0099 
0100   // AccessorDescriptor
0101   PropertyDescriptor(Local<Value> get, Local<Value> set);
0102 
0103   ~PropertyDescriptor();
0104 
0105   Local<Value> value() const;
0106   bool has_value() const;
0107 
0108   Local<Value> get() const;
0109   bool has_get() const;
0110   Local<Value> set() const;
0111   bool has_set() const;
0112 
0113   void set_enumerable(bool enumerable);
0114   bool enumerable() const;
0115   bool has_enumerable() const;
0116 
0117   void set_configurable(bool configurable);
0118   bool configurable() const;
0119   bool has_configurable() const;
0120 
0121   bool writable() const;
0122   bool has_writable() const;
0123 
0124   struct PrivateData;
0125   PrivateData* get_private() const { return private_; }
0126 
0127   PropertyDescriptor(const PropertyDescriptor&) = delete;
0128   void operator=(const PropertyDescriptor&) = delete;
0129 
0130  private:
0131   PrivateData* private_;
0132 };
0133 
0134 /**
0135  * PropertyAttribute.
0136  */
0137 enum PropertyAttribute {
0138   /** None. **/
0139   None = 0,
0140   /** ReadOnly, i.e., not writable. **/
0141   ReadOnly = 1 << 0,
0142   /** DontEnum, i.e., not enumerable. **/
0143   DontEnum = 1 << 1,
0144   /** DontDelete, i.e., not configurable. **/
0145   DontDelete = 1 << 2
0146 };
0147 
0148 /**
0149  * Accessor[Getter|Setter] are used as callback functions when
0150  * setting|getting a particular property. See Object and ObjectTemplate's
0151  * method SetAccessor.
0152  */
0153 using AccessorGetterCallback =
0154     void (*)(Local<String> property, const PropertyCallbackInfo<Value>& info);
0155 using AccessorNameGetterCallback =
0156     void (*)(Local<Name> property, const PropertyCallbackInfo<Value>& info);
0157 
0158 using AccessorSetterCallback = void (*)(Local<String> property,
0159                                         Local<Value> value,
0160                                         const PropertyCallbackInfo<void>& info);
0161 using AccessorNameSetterCallback =
0162     void (*)(Local<Name> property, Local<Value> value,
0163              const PropertyCallbackInfo<void>& info);
0164 
0165 /**
0166  * Access control specifications.
0167  *
0168  * Some accessors should be accessible across contexts. These
0169  * accessors have an explicit access control parameter which specifies
0170  * the kind of cross-context access that should be allowed.
0171  *
0172  */
0173 enum AccessControl {
0174   DEFAULT = 0,
0175 };
0176 
0177 /**
0178  * Property filter bits. They can be or'ed to build a composite filter.
0179  */
0180 enum PropertyFilter {
0181   ALL_PROPERTIES = 0,
0182   ONLY_WRITABLE = 1,
0183   ONLY_ENUMERABLE = 2,
0184   ONLY_CONFIGURABLE = 4,
0185   SKIP_STRINGS = 8,
0186   SKIP_SYMBOLS = 16
0187 };
0188 
0189 /**
0190  * Options for marking whether callbacks may trigger JS-observable side effects.
0191  * Side-effect-free callbacks are allowlisted during debug evaluation with
0192  * throwOnSideEffect. It applies when calling a Function, FunctionTemplate,
0193  * or an Accessor callback. For Interceptors, please see
0194  * PropertyHandlerFlags's kHasNoSideEffect.
0195  * Callbacks that only cause side effects to the receiver are allowlisted if
0196  * invoked on receiver objects that are created within the same debug-evaluate
0197  * call, as these objects are temporary and the side effect does not escape.
0198  */
0199 enum class SideEffectType {
0200   kHasSideEffect,
0201   kHasNoSideEffect,
0202   kHasSideEffectToReceiver
0203 };
0204 
0205 /**
0206  * Keys/Properties filter enums:
0207  *
0208  * KeyCollectionMode limits the range of collected properties. kOwnOnly limits
0209  * the collected properties to the given Object only. kIncludesPrototypes will
0210  * include all keys of the objects's prototype chain as well.
0211  */
0212 enum class KeyCollectionMode { kOwnOnly, kIncludePrototypes };
0213 
0214 /**
0215  * kIncludesIndices allows for integer indices to be collected, while
0216  * kSkipIndices will exclude integer indices from being collected.
0217  */
0218 enum class IndexFilter { kIncludeIndices, kSkipIndices };
0219 
0220 /**
0221  * kConvertToString will convert integer indices to strings.
0222  * kKeepNumbers will return numbers for integer indices.
0223  */
0224 enum class KeyConversionMode { kConvertToString, kKeepNumbers, kNoNumbers };
0225 
0226 /**
0227  * Integrity level for objects.
0228  */
0229 enum class IntegrityLevel { kFrozen, kSealed };
0230 
0231 /**
0232  * A JavaScript object (ECMA-262, 4.3.3)
0233  */
0234 class V8_EXPORT Object : public Value {
0235  public:
0236   /**
0237    * Set only return Just(true) or Empty(), so if it should never fail, use
0238    * result.Check().
0239    */
0240   V8_WARN_UNUSED_RESULT Maybe<bool> Set(Local<Context> context,
0241                                         Local<Value> key, Local<Value> value);
0242 
0243   V8_WARN_UNUSED_RESULT Maybe<bool> Set(Local<Context> context, uint32_t index,
0244                                         Local<Value> value);
0245 
0246   /**
0247    * Implements CreateDataProperty(O, P, V), see
0248    * https://tc39.es/ecma262/#sec-createdataproperty.
0249    *
0250    * Defines a configurable, writable, enumerable property with the given value
0251    * on the object unless the property already exists and is not configurable
0252    * or the object is not extensible.
0253    *
0254    * Returns true on success.
0255    */
0256   V8_WARN_UNUSED_RESULT Maybe<bool> CreateDataProperty(Local<Context> context,
0257                                                        Local<Name> key,
0258                                                        Local<Value> value);
0259   V8_WARN_UNUSED_RESULT Maybe<bool> CreateDataProperty(Local<Context> context,
0260                                                        uint32_t index,
0261                                                        Local<Value> value);
0262 
0263   /**
0264    * Implements [[DefineOwnProperty]] for data property case, see
0265    * https://tc39.es/ecma262/#table-essential-internal-methods.
0266    *
0267    * In general, CreateDataProperty will be faster, however, does not allow
0268    * for specifying attributes.
0269    *
0270    * Returns true on success.
0271    */
0272   V8_WARN_UNUSED_RESULT Maybe<bool> DefineOwnProperty(
0273       Local<Context> context, Local<Name> key, Local<Value> value,
0274       PropertyAttribute attributes = None);
0275 
0276   /**
0277    * Implements Object.defineProperty(O, P, Attributes), see
0278    * https://tc39.es/ecma262/#sec-object.defineproperty.
0279    *
0280    * The defineProperty function is used to add an own property or
0281    * update the attributes of an existing own property of an object.
0282    *
0283    * Both data and accessor descriptors can be used.
0284    *
0285    * In general, CreateDataProperty is faster, however, does not allow
0286    * for specifying attributes or an accessor descriptor.
0287    *
0288    * The PropertyDescriptor can change when redefining a property.
0289    *
0290    * Returns true on success.
0291    */
0292   V8_WARN_UNUSED_RESULT Maybe<bool> DefineProperty(
0293       Local<Context> context, Local<Name> key, PropertyDescriptor& descriptor);
0294 
0295   V8_WARN_UNUSED_RESULT MaybeLocal<Value> Get(Local<Context> context,
0296                                               Local<Value> key);
0297 
0298   V8_WARN_UNUSED_RESULT MaybeLocal<Value> Get(Local<Context> context,
0299                                               uint32_t index);
0300 
0301   /**
0302    * Gets the property attributes of a property which can be None or
0303    * any combination of ReadOnly, DontEnum and DontDelete. Returns
0304    * None when the property doesn't exist.
0305    */
0306   V8_WARN_UNUSED_RESULT Maybe<PropertyAttribute> GetPropertyAttributes(
0307       Local<Context> context, Local<Value> key);
0308 
0309   /**
0310    * Implements Object.getOwnPropertyDescriptor(O, P), see
0311    * https://tc39.es/ecma262/#sec-object.getownpropertydescriptor.
0312    */
0313   V8_WARN_UNUSED_RESULT MaybeLocal<Value> GetOwnPropertyDescriptor(
0314       Local<Context> context, Local<Name> key);
0315 
0316   /**
0317    * Object::Has() calls the abstract operation HasProperty(O, P), see
0318    * https://tc39.es/ecma262/#sec-hasproperty. Has() returns
0319    * true, if the object has the property, either own or on the prototype chain.
0320    * Interceptors, i.e., PropertyQueryCallbacks, are called if present.
0321    *
0322    * Has() has the same side effects as JavaScript's `variable in object`.
0323    * For example, calling Has() on a revoked proxy will throw an exception.
0324    *
0325    * \note Has() converts the key to a name, which possibly calls back into
0326    * JavaScript.
0327    *
0328    * See also v8::Object::HasOwnProperty() and
0329    * v8::Object::HasRealNamedProperty().
0330    */
0331   V8_WARN_UNUSED_RESULT Maybe<bool> Has(Local<Context> context,
0332                                         Local<Value> key);
0333 
0334   V8_WARN_UNUSED_RESULT Maybe<bool> Delete(Local<Context> context,
0335                                            Local<Value> key);
0336 
0337   V8_WARN_UNUSED_RESULT Maybe<bool> Has(Local<Context> context, uint32_t index);
0338 
0339   V8_WARN_UNUSED_RESULT Maybe<bool> Delete(Local<Context> context,
0340                                            uint32_t index);
0341 
0342   V8_DEPRECATE_SOON("Use SetNativeDataProperty instead")
0343   V8_WARN_UNUSED_RESULT Maybe<bool> SetAccessor(
0344       Local<Context> context, Local<Name> name,
0345       AccessorNameGetterCallback getter,
0346       AccessorNameSetterCallback setter = nullptr,
0347       MaybeLocal<Value> data = MaybeLocal<Value>(),
0348       AccessControl deprecated_settings = DEFAULT,
0349       PropertyAttribute attribute = None,
0350       SideEffectType getter_side_effect_type = SideEffectType::kHasSideEffect,
0351       SideEffectType setter_side_effect_type = SideEffectType::kHasSideEffect);
0352 
0353   void SetAccessorProperty(Local<Name> name, Local<Function> getter,
0354                            Local<Function> setter = Local<Function>(),
0355                            PropertyAttribute attributes = None);
0356 
0357   /**
0358    * Sets a native data property like Template::SetNativeDataProperty, but
0359    * this method sets on this object directly.
0360    */
0361   V8_WARN_UNUSED_RESULT Maybe<bool> SetNativeDataProperty(
0362       Local<Context> context, Local<Name> name,
0363       AccessorNameGetterCallback getter,
0364       AccessorNameSetterCallback setter = nullptr,
0365       Local<Value> data = Local<Value>(), PropertyAttribute attributes = None,
0366       SideEffectType getter_side_effect_type = SideEffectType::kHasSideEffect,
0367       SideEffectType setter_side_effect_type = SideEffectType::kHasSideEffect);
0368 
0369   /**
0370    * Attempts to create a property with the given name which behaves like a data
0371    * property, except that the provided getter is invoked (and provided with the
0372    * data value) to supply its value the first time it is read. After the
0373    * property is accessed once, it is replaced with an ordinary data property.
0374    *
0375    * Analogous to Template::SetLazyDataProperty.
0376    */
0377   V8_WARN_UNUSED_RESULT Maybe<bool> SetLazyDataProperty(
0378       Local<Context> context, Local<Name> name,
0379       AccessorNameGetterCallback getter, Local<Value> data = Local<Value>(),
0380       PropertyAttribute attributes = None,
0381       SideEffectType getter_side_effect_type = SideEffectType::kHasSideEffect,
0382       SideEffectType setter_side_effect_type = SideEffectType::kHasSideEffect);
0383 
0384   /**
0385    * Functionality for private properties.
0386    * This is an experimental feature, use at your own risk.
0387    * Note: Private properties are not inherited. Do not rely on this, since it
0388    * may change.
0389    */
0390   Maybe<bool> HasPrivate(Local<Context> context, Local<Private> key);
0391   Maybe<bool> SetPrivate(Local<Context> context, Local<Private> key,
0392                          Local<Value> value);
0393   Maybe<bool> DeletePrivate(Local<Context> context, Local<Private> key);
0394   MaybeLocal<Value> GetPrivate(Local<Context> context, Local<Private> key);
0395 
0396   /**
0397    * Returns an array containing the names of the enumerable properties
0398    * of this object, including properties from prototype objects.  The
0399    * array returned by this method contains the same values as would
0400    * be enumerated by a for-in statement over this object.
0401    */
0402   V8_WARN_UNUSED_RESULT MaybeLocal<Array> GetPropertyNames(
0403       Local<Context> context);
0404   V8_WARN_UNUSED_RESULT MaybeLocal<Array> GetPropertyNames(
0405       Local<Context> context, KeyCollectionMode mode,
0406       PropertyFilter property_filter, IndexFilter index_filter,
0407       KeyConversionMode key_conversion = KeyConversionMode::kKeepNumbers);
0408 
0409   /**
0410    * This function has the same functionality as GetPropertyNames but
0411    * the returned array doesn't contain the names of properties from
0412    * prototype objects.
0413    */
0414   V8_WARN_UNUSED_RESULT MaybeLocal<Array> GetOwnPropertyNames(
0415       Local<Context> context);
0416 
0417   /**
0418    * Returns an array containing the names of the filtered properties
0419    * of this object, including properties from prototype objects.  The
0420    * array returned by this method contains the same values as would
0421    * be enumerated by a for-in statement over this object.
0422    */
0423   V8_WARN_UNUSED_RESULT MaybeLocal<Array> GetOwnPropertyNames(
0424       Local<Context> context, PropertyFilter filter,
0425       KeyConversionMode key_conversion = KeyConversionMode::kKeepNumbers);
0426 
0427   /**
0428    * Get the prototype object.  This does not skip objects marked to
0429    * be skipped by __proto__ and it does not consult the security
0430    * handler.
0431    */
0432   Local<Value> GetPrototype();
0433 
0434   /**
0435    * Set the prototype object.  This does not skip objects marked to
0436    * be skipped by __proto__ and it does not consult the security
0437    * handler.
0438    */
0439   V8_WARN_UNUSED_RESULT Maybe<bool> SetPrototype(Local<Context> context,
0440                                                  Local<Value> prototype);
0441 
0442   /**
0443    * Finds an instance of the given function template in the prototype
0444    * chain.
0445    */
0446   Local<Object> FindInstanceInPrototypeChain(Local<FunctionTemplate> tmpl);
0447 
0448   /**
0449    * Call builtin Object.prototype.toString on this object.
0450    * This is different from Value::ToString() that may call
0451    * user-defined toString function. This one does not.
0452    */
0453   V8_WARN_UNUSED_RESULT MaybeLocal<String> ObjectProtoToString(
0454       Local<Context> context);
0455 
0456   /**
0457    * Returns the name of the function invoked as a constructor for this object.
0458    */
0459   Local<String> GetConstructorName();
0460 
0461   /**
0462    * Sets the integrity level of the object.
0463    */
0464   Maybe<bool> SetIntegrityLevel(Local<Context> context, IntegrityLevel level);
0465 
0466   /** Gets the number of internal fields for this Object. */
0467   int InternalFieldCount() const;
0468 
0469   /** Same as above, but works for PersistentBase. */
0470   V8_INLINE static int InternalFieldCount(
0471       const PersistentBase<Object>& object) {
0472     return object.template value<Object>()->InternalFieldCount();
0473   }
0474 
0475   /** Same as above, but works for BasicTracedReference. */
0476   V8_INLINE static int InternalFieldCount(
0477       const BasicTracedReference<Object>& object) {
0478     return object.template value<Object>()->InternalFieldCount();
0479   }
0480 
0481   /**
0482    * Gets the data from an internal field.
0483    * To cast the return value into v8::Value subtypes, it needs to be
0484    * casted to a v8::Value first. For example, to cast it into v8::External:
0485    *
0486    * object->GetInternalField(index).As<v8::Value>().As<v8::External>();
0487    *
0488    * The embedder should make sure that the internal field being retrieved
0489    * using this method has already been set with SetInternalField() before.
0490    **/
0491   V8_INLINE Local<Data> GetInternalField(int index);
0492 
0493   /** Sets the data in an internal field. */
0494   void SetInternalField(int index, Local<Data> data);
0495 
0496   /**
0497    * Gets a 2-byte-aligned native pointer from an internal field. This field
0498    * must have been set by SetAlignedPointerInInternalField, everything else
0499    * leads to undefined behavior.
0500    */
0501   V8_INLINE void* GetAlignedPointerFromInternalField(int index);
0502   V8_INLINE void* GetAlignedPointerFromInternalField(v8::Isolate* isolate,
0503                                                      int index);
0504 
0505   /** Same as above, but works for PersistentBase. */
0506   V8_INLINE static void* GetAlignedPointerFromInternalField(
0507       const PersistentBase<Object>& object, int index) {
0508     return object.template value<Object>()->GetAlignedPointerFromInternalField(
0509         index);
0510   }
0511 
0512   /** Same as above, but works for TracedReference. */
0513   V8_INLINE static void* GetAlignedPointerFromInternalField(
0514       const BasicTracedReference<Object>& object, int index) {
0515     return object.template value<Object>()->GetAlignedPointerFromInternalField(
0516         index);
0517   }
0518 
0519   /**
0520    * Sets a 2-byte-aligned native pointer in an internal field. To retrieve such
0521    * a field, GetAlignedPointerFromInternalField must be used, everything else
0522    * leads to undefined behavior.
0523    */
0524   void SetAlignedPointerInInternalField(int index, void* value);
0525   void SetAlignedPointerInInternalFields(int argc, int indices[],
0526                                          void* values[]);
0527 
0528   /**
0529    * HasOwnProperty() is like JavaScript's Object.prototype.hasOwnProperty().
0530    *
0531    * See also v8::Object::Has() and v8::Object::HasRealNamedProperty().
0532    */
0533   V8_WARN_UNUSED_RESULT Maybe<bool> HasOwnProperty(Local<Context> context,
0534                                                    Local<Name> key);
0535   V8_WARN_UNUSED_RESULT Maybe<bool> HasOwnProperty(Local<Context> context,
0536                                                    uint32_t index);
0537   /**
0538    * Use HasRealNamedProperty() if you want to check if an object has an own
0539    * property without causing side effects, i.e., without calling interceptors.
0540    *
0541    * This function is similar to v8::Object::HasOwnProperty(), but it does not
0542    * call interceptors.
0543    *
0544    * \note Consider using non-masking interceptors, i.e., the interceptors are
0545    * not called if the receiver has the real named property. See
0546    * `v8::PropertyHandlerFlags::kNonMasking`.
0547    *
0548    * See also v8::Object::Has().
0549    */
0550   V8_WARN_UNUSED_RESULT Maybe<bool> HasRealNamedProperty(Local<Context> context,
0551                                                          Local<Name> key);
0552   V8_WARN_UNUSED_RESULT Maybe<bool> HasRealIndexedProperty(
0553       Local<Context> context, uint32_t index);
0554   V8_WARN_UNUSED_RESULT Maybe<bool> HasRealNamedCallbackProperty(
0555       Local<Context> context, Local<Name> key);
0556 
0557   /**
0558    * If result.IsEmpty() no real property was located in the prototype chain.
0559    * This means interceptors in the prototype chain are not called.
0560    */
0561   V8_WARN_UNUSED_RESULT MaybeLocal<Value> GetRealNamedPropertyInPrototypeChain(
0562       Local<Context> context, Local<Name> key);
0563 
0564   /**
0565    * Gets the property attributes of a real property in the prototype chain,
0566    * which can be None or any combination of ReadOnly, DontEnum and DontDelete.
0567    * Interceptors in the prototype chain are not called.
0568    */
0569   V8_WARN_UNUSED_RESULT Maybe<PropertyAttribute>
0570   GetRealNamedPropertyAttributesInPrototypeChain(Local<Context> context,
0571                                                  Local<Name> key);
0572 
0573   /**
0574    * If result.IsEmpty() no real property was located on the object or
0575    * in the prototype chain.
0576    * This means interceptors in the prototype chain are not called.
0577    */
0578   V8_WARN_UNUSED_RESULT MaybeLocal<Value> GetRealNamedProperty(
0579       Local<Context> context, Local<Name> key);
0580 
0581   /**
0582    * Gets the property attributes of a real property which can be
0583    * None or any combination of ReadOnly, DontEnum and DontDelete.
0584    * Interceptors in the prototype chain are not called.
0585    */
0586   V8_WARN_UNUSED_RESULT Maybe<PropertyAttribute> GetRealNamedPropertyAttributes(
0587       Local<Context> context, Local<Name> key);
0588 
0589   /** Tests for a named lookup interceptor.*/
0590   bool HasNamedLookupInterceptor() const;
0591 
0592   /** Tests for an index lookup interceptor.*/
0593   bool HasIndexedLookupInterceptor() const;
0594 
0595   /**
0596    * Returns the identity hash for this object. The current implementation
0597    * uses a hidden property on the object to store the identity hash.
0598    *
0599    * The return value will never be 0. Also, it is not guaranteed to be
0600    * unique.
0601    */
0602   int GetIdentityHash();
0603 
0604   /**
0605    * Clone this object with a fast but shallow copy.  Values will point
0606    * to the same values as the original object.
0607    */
0608   // TODO(dcarney): take an isolate and optionally bail out?
0609   Local<Object> Clone();
0610 
0611   /**
0612    * Returns the context in which the object was created.
0613    */
0614   MaybeLocal<Context> GetCreationContext();
0615 
0616   /**
0617    * Shortcut for GetCreationContext().ToLocalChecked().
0618    **/
0619   Local<Context> GetCreationContextChecked();
0620 
0621   /** Same as above, but works for Persistents */
0622   V8_INLINE static MaybeLocal<Context> GetCreationContext(
0623       const PersistentBase<Object>& object) {
0624     return object.template value<Object>()->GetCreationContext();
0625   }
0626 
0627   /**
0628    * Gets the context in which the object was created (see GetCreationContext())
0629    * and if it's available reads respective embedder field value.
0630    * If the context can't be obtained nullptr is returned.
0631    * Basically it's a shortcut for
0632    *   obj->GetCreationContext().GetAlignedPointerFromEmbedderData(index)
0633    * which doesn't create a handle for Context object on the way and doesn't
0634    * try to expand the embedder data attached to the context.
0635    * In case the Local<Context> is already available because of other reasons,
0636    * it's fine to keep using Context::GetAlignedPointerFromEmbedderData().
0637    */
0638   void* GetAlignedPointerFromEmbedderDataInCreationContext(int index);
0639 
0640   /**
0641    * Checks whether a callback is set by the
0642    * ObjectTemplate::SetCallAsFunctionHandler method.
0643    * When an Object is callable this method returns true.
0644    */
0645   bool IsCallable() const;
0646 
0647   /**
0648    * True if this object is a constructor.
0649    */
0650   bool IsConstructor() const;
0651 
0652   /**
0653    * True if this object can carry information relevant to the embedder in its
0654    * embedder fields, false otherwise. This is generally true for objects
0655    * constructed through function templates but also holds for other types where
0656    * V8 automatically adds internal fields at compile time, such as e.g.
0657    * v8::ArrayBuffer.
0658    */
0659   bool IsApiWrapper() const;
0660 
0661   /**
0662    * True if this object was created from an object template which was marked
0663    * as undetectable. See v8::ObjectTemplate::MarkAsUndetectable for more
0664    * information.
0665    */
0666   bool IsUndetectable() const;
0667 
0668   /**
0669    * Call an Object as a function if a callback is set by the
0670    * ObjectTemplate::SetCallAsFunctionHandler method.
0671    */
0672   V8_WARN_UNUSED_RESULT MaybeLocal<Value> CallAsFunction(Local<Context> context,
0673                                                          Local<Value> recv,
0674                                                          int argc,
0675                                                          Local<Value> argv[]);
0676 
0677   /**
0678    * Call an Object as a constructor if a callback is set by the
0679    * ObjectTemplate::SetCallAsFunctionHandler method.
0680    * Note: This method behaves like the Function::NewInstance method.
0681    */
0682   V8_WARN_UNUSED_RESULT MaybeLocal<Value> CallAsConstructor(
0683       Local<Context> context, int argc, Local<Value> argv[]);
0684 
0685   /**
0686    * Return the isolate to which the Object belongs to.
0687    */
0688   Isolate* GetIsolate();
0689 
0690   V8_INLINE static Isolate* GetIsolate(const TracedReference<Object>& handle) {
0691     return handle.template value<Object>()->GetIsolate();
0692   }
0693 
0694   /**
0695    * If this object is a Set, Map, WeakSet or WeakMap, this returns a
0696    * representation of the elements of this object as an array.
0697    * If this object is a SetIterator or MapIterator, this returns all
0698    * elements of the underlying collection, starting at the iterator's current
0699    * position.
0700    * For other types, this will return an empty MaybeLocal<Array> (without
0701    * scheduling an exception).
0702    */
0703   MaybeLocal<Array> PreviewEntries(bool* is_key_value);
0704 
0705   static Local<Object> New(Isolate* isolate);
0706 
0707   /**
0708    * Creates a JavaScript object with the given properties, and
0709    * a the given prototype_or_null (which can be any JavaScript
0710    * value, and if it's null, the newly created object won't have
0711    * a prototype at all). This is similar to Object.create().
0712    * All properties will be created as enumerable, configurable
0713    * and writable properties.
0714    */
0715   static Local<Object> New(Isolate* isolate, Local<Value> prototype_or_null,
0716                            Local<Name>* names, Local<Value>* values,
0717                            size_t length);
0718 
0719   V8_INLINE static Object* Cast(Value* obj);
0720 
0721   /**
0722    * Support for TC39 "dynamic code brand checks" proposal.
0723    *
0724    * This API allows to query whether an object was constructed from a
0725    * "code like" ObjectTemplate.
0726    *
0727    * See also: v8::ObjectTemplate::SetCodeLike
0728    */
0729   bool IsCodeLike(Isolate* isolate) const;
0730 
0731  private:
0732   Object();
0733   static void CheckCast(Value* obj);
0734   Local<Data> SlowGetInternalField(int index);
0735   void* SlowGetAlignedPointerFromInternalField(int index);
0736   void* SlowGetAlignedPointerFromInternalField(v8::Isolate* isolate, int index);
0737 };
0738 
0739 // --- Implementation ---
0740 
0741 Local<Data> Object::GetInternalField(int index) {
0742 #ifndef V8_ENABLE_CHECKS
0743   using A = internal::Address;
0744   using I = internal::Internals;
0745   A obj = internal::ValueHelper::ValueAsAddress(this);
0746   // Fast path: If the object is a plain JSObject, which is the common case, we
0747   // know where to find the internal fields and can return the value directly.
0748   int instance_type = I::GetInstanceType(obj);
0749   if (I::CanHaveInternalField(instance_type)) {
0750     int offset = I::kJSObjectHeaderSize + (I::kEmbedderDataSlotSize * index);
0751     A value = I::ReadRawField<A>(obj, offset);
0752 #ifdef V8_COMPRESS_POINTERS
0753     // We read the full pointer value and then decompress it in order to avoid
0754     // dealing with potential endiannes issues.
0755     value = I::DecompressTaggedField(obj, static_cast<uint32_t>(value));
0756 #endif
0757 
0758     auto isolate = reinterpret_cast<v8::Isolate*>(
0759         internal::IsolateFromNeverReadOnlySpaceObject(obj));
0760     return Local<Data>::New(isolate, value);
0761   }
0762 #endif
0763   return SlowGetInternalField(index);
0764 }
0765 
0766 void* Object::GetAlignedPointerFromInternalField(v8::Isolate* isolate,
0767                                                  int index) {
0768 #if !defined(V8_ENABLE_CHECKS)
0769   using A = internal::Address;
0770   using I = internal::Internals;
0771   A obj = internal::ValueHelper::ValueAsAddress(this);
0772   // Fast path: If the object is a plain JSObject, which is the common case, we
0773   // know where to find the internal fields and can return the value directly.
0774   auto instance_type = I::GetInstanceType(obj);
0775   if (V8_LIKELY(I::CanHaveInternalField(instance_type))) {
0776     int offset = I::kJSObjectHeaderSize + (I::kEmbedderDataSlotSize * index) +
0777                  I::kEmbedderDataSlotExternalPointerOffset;
0778     A value =
0779         I::ReadExternalPointerField<internal::kEmbedderDataSlotPayloadTag>(
0780             isolate, obj, offset);
0781     return reinterpret_cast<void*>(value);
0782   }
0783 #endif
0784   return SlowGetAlignedPointerFromInternalField(isolate, index);
0785 }
0786 
0787 void* Object::GetAlignedPointerFromInternalField(int index) {
0788 #if !defined(V8_ENABLE_CHECKS)
0789   using A = internal::Address;
0790   using I = internal::Internals;
0791   A obj = internal::ValueHelper::ValueAsAddress(this);
0792   // Fast path: If the object is a plain JSObject, which is the common case, we
0793   // know where to find the internal fields and can return the value directly.
0794   auto instance_type = I::GetInstanceType(obj);
0795   if (V8_LIKELY(I::CanHaveInternalField(instance_type))) {
0796     int offset = I::kJSObjectHeaderSize + (I::kEmbedderDataSlotSize * index) +
0797                  I::kEmbedderDataSlotExternalPointerOffset;
0798     Isolate* isolate = I::GetIsolateForSandbox(obj);
0799     A value =
0800         I::ReadExternalPointerField<internal::kEmbedderDataSlotPayloadTag>(
0801             isolate, obj, offset);
0802     return reinterpret_cast<void*>(value);
0803   }
0804 #endif
0805   return SlowGetAlignedPointerFromInternalField(index);
0806 }
0807 
0808 Private* Private::Cast(Data* data) {
0809 #ifdef V8_ENABLE_CHECKS
0810   CheckCast(data);
0811 #endif
0812   return reinterpret_cast<Private*>(data);
0813 }
0814 
0815 Object* Object::Cast(v8::Value* value) {
0816 #ifdef V8_ENABLE_CHECKS
0817   CheckCast(value);
0818 #endif
0819   return static_cast<Object*>(value);
0820 }
0821 
0822 }  // namespace v8
0823 
0824 #endif  // INCLUDE_V8_OBJECT_H_