Edit: /usr/include/node/v8.h (377827B)
// Copyright 2012 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.
/** \mainpage V8 API Reference Guide
*
* V8 is Google's open source JavaScript engine.
*
* This set of documents provides reference material generated from the
* V8 header file, include/v8.h.
*
* For other documentation see http://code.google.com/apis/v8/
*/
#ifndef INCLUDE_V8_H_
#define INCLUDE_V8_H_
#include
#include
#include
#include
#include
#include
#include
#include
#include "v8-internal.h" // NOLINT(build/include)
#include "v8-version.h" // NOLINT(build/include)
#include "v8config.h" // NOLINT(build/include)
// We reserve the V8_* prefix for macros defined in V8 public API and
// assume there are no name conflicts with the embedder's code.
/**
* The v8 JavaScript engine.
*/
namespace v8 {
class AccessorSignature;
class Array;
class ArrayBuffer;
class BigInt;
class BigIntObject;
class Boolean;
class BooleanObject;
class Context;
class Data;
class Date;
class External;
class Function;
class FunctionTemplate;
class HeapProfiler;
class ImplementationUtilities;
class Int32;
class Integer;
class Isolate;
template
class Maybe;
class MicrotaskQueue;
class Name;
class Number;
class NumberObject;
class Object;
class ObjectOperationDescriptor;
class ObjectTemplate;
class Platform;
class Primitive;
class Promise;
class PropertyDescriptor;
class Proxy;
class RawOperationDescriptor;
class Script;
class SharedArrayBuffer;
class Signature;
class StartupData;
class StackFrame;
class StackTrace;
class String;
class StringObject;
class Symbol;
class SymbolObject;
class PrimitiveArray;
class Private;
class Uint32;
class Utils;
class Value;
class WasmModuleObject;
template class Local;
template
class MaybeLocal;
template class Eternal;
template class NonCopyablePersistentTraits;
template class PersistentBase;
template >
class Persistent;
template
class Global;
template
class TracedGlobal;
template class PersistentValueMap;
template
class PersistentValueMapBase;
template
class GlobalValueMap;
template class PersistentValueVector;
template class WeakCallbackObject;
class FunctionTemplate;
class ObjectTemplate;
template class FunctionCallbackInfo;
template class PropertyCallbackInfo;
class StackTrace;
class StackFrame;
class Isolate;
class CallHandlerHelper;
class EscapableHandleScope;
template class ReturnValue;
namespace internal {
class Arguments;
class DeferredHandles;
class Heap;
class HeapObject;
class ExternalString;
class Isolate;
class LocalEmbedderHeapTracer;
class MicrotaskQueue;
class NeverReadOnlySpaceObject;
struct ScriptStreamingData;
template class CustomArguments;
class PropertyCallbackArguments;
class FunctionCallbackArguments;
class GlobalHandles;
class ScopedExternalStringLock;
class ThreadLocalTop;
namespace wasm {
class NativeModule;
class StreamingDecoder;
} // namespace wasm
} // namespace internal
namespace debug {
class ConsoleCallArguments;
} // namespace debug
// --- Handles ---
#define TYPE_CHECK(T, S) \
while (false) { \
*(static_cast(0)) = static_cast(0); \
}
/**
* An object reference managed by the v8 garbage collector.
*
* All objects returned from v8 have to be tracked by the garbage
* collector so that it knows that the objects are still alive. Also,
* because the garbage collector may move objects, it is unsafe to
* point directly to an object. Instead, all objects are stored in
* handles which are known by the garbage collector and updated
* whenever an object moves. Handles should always be passed by value
* (except in cases like out-parameters) and they should never be
* allocated on the heap.
*
* There are two types of handles: local and persistent handles.
*
* Local handles are light-weight and transient and typically used in
* local operations. They are managed by HandleScopes. That means that a
* HandleScope must exist on the stack when they are created and that they are
* only valid inside of the HandleScope active during their creation.
* For passing a local handle to an outer HandleScope, an EscapableHandleScope
* and its Escape() method must be used.
*
* Persistent handles can be used when storing objects across several
* independent operations and have to be explicitly deallocated when they're no
* longer used.
*
* It is safe to extract the object stored in the handle by
* dereferencing the handle (for instance, to extract the Object* from
* a Local); the value will still be governed by a handle
* behind the scenes and the same rules apply to these values as to
* their handles.
*/
template
class Local {
public:
V8_INLINE Local() : val_(nullptr) {}
template
V8_INLINE Local(Local that)
: val_(reinterpret_cast(*that)) {
/**
* This check fails when trying to convert between incompatible
* handles. For example, converting from a Local to a
* Local.
*/
TYPE_CHECK(T, S);
}
/**
* Returns true if the handle is empty.
*/
V8_INLINE bool IsEmpty() const { return val_ == nullptr; }
/**
* Sets the handle to be empty. IsEmpty() will then return true.
*/
V8_INLINE void Clear() { val_ = nullptr; }
V8_INLINE T* operator->() const { return val_; }
V8_INLINE T* operator*() const { return val_; }
/**
* Checks whether two handles are the same.
* Returns true if both are empty, or if the objects
* to which they refer are identical.
* The handles' references are not checked.
*/
template
V8_INLINE bool operator==(const Local& that) const {
internal::Address* a = reinterpret_cast(this->val_);
internal::Address* b = reinterpret_cast(that.val_);
if (a == nullptr) return b == nullptr;
if (b == nullptr) return false;
return *a == *b;
}
template V8_INLINE bool operator==(
const PersistentBase& that) const {
internal::Address* a = reinterpret_cast(this->val_);
internal::Address* b = reinterpret_cast(that.val_);
if (a == nullptr) return b == nullptr;
if (b == nullptr) return false;
return *a == *b;
}
/**
* Checks whether two handles are different.
* Returns true if only one of the handles is empty, or if
* the objects to which they refer are different.
* The handles' references are not checked.
*/
template
V8_INLINE bool operator!=(const Local& that) const {
return !operator==(that);
}
template V8_INLINE bool operator!=(
const Persistent& that) const {
return !operator==(that);
}
/**
* Cast a handle to a subclass, e.g. Local to Local.
* This is only valid if the handle actually refers to a value of the
* target type.
*/
template V8_INLINE static Local Cast(Local that) {
#ifdef V8_ENABLE_CHECKS
// If we're going to perform the type check then we have to check
// that the handle isn't empty before doing the checked cast.
if (that.IsEmpty()) return Local();
#endif
return Local(T::Cast(*that));
}
/**
* Calling this is equivalent to Local::Cast().
* In particular, this is only valid if the handle actually refers to a value
* of the target type.
*/
template
V8_INLINE Local As() const {
return Local::Cast(*this);
}
/**
* Create a local handle for the content of another handle.
* The referee is kept alive by the local handle even when
* the original handle is destroyed/disposed.
*/
V8_INLINE static Local New(Isolate* isolate, Local that);
V8_INLINE static Local New(Isolate* isolate,
const PersistentBase& that);
V8_INLINE static Local New(Isolate* isolate, const TracedGlobal& that);
private:
friend class Utils;
template friend class Eternal;
template friend class PersistentBase;
template friend class Persistent;
template friend class Local;
template
friend class MaybeLocal;
template friend class FunctionCallbackInfo;
template friend class PropertyCallbackInfo;
friend class String;
friend class Object;
friend class Context;
friend class Isolate;
friend class Private;
template friend class internal::CustomArguments;
friend Local Undefined(Isolate* isolate);
friend Local Null(Isolate* isolate);
friend Local True(Isolate* isolate);
friend Local False(Isolate* isolate);
friend class HandleScope;
friend class EscapableHandleScope;
template
friend class PersistentValueMapBase;
template friend class PersistentValueVector;
template
friend class ReturnValue;
template
friend class TracedGlobal;
explicit V8_INLINE Local(T* that) : val_(that) {}
V8_INLINE static Local New(Isolate* isolate, T* that);
T* val_;
};
#if !defined(V8_IMMINENT_DEPRECATION_WARNINGS)
// Handle is an alias for Local for historical reasons.
template
using Handle = Local;
#endif
/**
* A MaybeLocal<> is a wrapper around Local<> that enforces a check whether
* the Local<> is empty before it can be used.
*
* If an API method returns a MaybeLocal<>, the API method can potentially fail
* either because an exception is thrown, or because an exception is pending,
* e.g. because a previous API call threw an exception that hasn't been caught
* yet, or because a TerminateExecution exception was thrown. In that case, an
* empty MaybeLocal is returned.
*/
template
class MaybeLocal {
public:
V8_INLINE MaybeLocal() : val_(nullptr) {}
template
V8_INLINE MaybeLocal(Local that)
: val_(reinterpret_cast(*that)) {
TYPE_CHECK(T, S);
}
V8_INLINE bool IsEmpty() const { return val_ == nullptr; }
/**
* Converts this MaybeLocal<> to a Local<>. If this MaybeLocal<> is empty,
* |false| is returned and |out| is left untouched.
*/
template
V8_WARN_UNUSED_RESULT V8_INLINE bool ToLocal(Local* out) const {
out->val_ = IsEmpty() ? nullptr : this->val_;
return !IsEmpty();
}
/**
* Converts this MaybeLocal<> to a Local<>. If this MaybeLocal<> is empty,
* V8 will crash the process.
*/
V8_INLINE Local ToLocalChecked();
/**
* Converts this MaybeLocal<> to a Local<>, using a default value if this
* MaybeLocal<> is empty.
*/
template
V8_INLINE Local FromMaybe(Local default_value) const {
return IsEmpty() ? default_value : Local(val_);
}
private:
T* val_;
};
/**
* Eternal handles are set-once handles that live for the lifetime of the
* isolate.
*/
template class Eternal {
public:
V8_INLINE Eternal() : val_(nullptr) {}
template
V8_INLINE Eternal(Isolate* isolate, Local handle) : val_(nullptr) {
Set(isolate, handle);
}
// Can only be safely called if already set.
V8_INLINE Local Get(Isolate* isolate) const;
V8_INLINE bool IsEmpty() const { return val_ == nullptr; }
template V8_INLINE void Set(Isolate* isolate, Local handle);
private:
T* val_;
};
static const int kInternalFieldsInWeakCallback = 2;
static const int kEmbedderFieldsInWeakCallback = 2;
template
class WeakCallbackInfo {
public:
typedef void (*Callback)(const WeakCallbackInfo& data);
WeakCallbackInfo(Isolate* isolate, T* parameter,
void* embedder_fields[kEmbedderFieldsInWeakCallback],
Callback* callback)
: isolate_(isolate), parameter_(parameter), callback_(callback) {
for (int i = 0; i < kEmbedderFieldsInWeakCallback; ++i) {
embedder_fields_[i] = embedder_fields[i];
}
}
V8_INLINE Isolate* GetIsolate() const { return isolate_; }
V8_INLINE T* GetParameter() const { return parameter_; }
V8_INLINE void* GetInternalField(int index) const;
// When first called, the embedder MUST Reset() the Global which triggered the
// callback. The Global itself is unusable for anything else. No v8 other api
// calls may be called in the first callback. Should additional work be
// required, the embedder must set a second pass callback, which will be
// called after all the initial callbacks are processed.
// Calling SetSecondPassCallback on the second pass will immediately crash.
void SetSecondPassCallback(Callback callback) const { *callback_ = callback; }
private:
Isolate* isolate_;
T* parameter_;
Callback* callback_;
void* embedder_fields_[kEmbedderFieldsInWeakCallback];
};
// kParameter will pass a void* parameter back to the callback, kInternalFields
// will pass the first two internal fields back to the callback, kFinalizer
// will pass a void* parameter back, but is invoked before the object is
// actually collected, so it can be resurrected. In the last case, it is not
// possible to request a second pass callback.
enum class WeakCallbackType { kParameter, kInternalFields, kFinalizer };
/**
* An object reference that is independent of any handle scope. Where
* a Local handle only lives as long as the HandleScope in which it was
* allocated, a PersistentBase handle remains valid until it is explicitly
* disposed using Reset().
*
* A persistent handle contains a reference to a storage cell within
* the V8 engine which holds an object value and which is updated by
* the garbage collector whenever the object is moved. A new storage
* cell can be created using the constructor or PersistentBase::Reset and
* existing handles can be disposed using PersistentBase::Reset.
*
*/
template class PersistentBase {
public:
/**
* If non-empty, destroy the underlying storage cell
* IsEmpty() will return true after this call.
*/
V8_INLINE void Reset();
/**
* If non-empty, destroy the underlying storage cell
* and create a new one with the contents of other if other is non empty
*/
template
V8_INLINE void Reset(Isolate* isolate, const Local& other);
/**
* If non-empty, destroy the underlying storage cell
* and create a new one with the contents of other if other is non empty
*/
template
V8_INLINE void Reset(Isolate* isolate, const PersistentBase& other);
V8_INLINE bool IsEmpty() const { return val_ == nullptr; }
V8_INLINE void Empty() { val_ = 0; }
V8_INLINE Local Get(Isolate* isolate) const {
return Local::New(isolate, *this);
}
template
V8_INLINE bool operator==(const PersistentBase& that) const {
internal::Address* a = reinterpret_cast(this->val_);
internal::Address* b = reinterpret_cast(that.val_);
if (a == nullptr) return b == nullptr;
if (b == nullptr) return false;
return *a == *b;
}
template
V8_INLINE bool operator==(const Local& that) const {
internal::Address* a = reinterpret_cast(this->val_);
internal::Address* b = reinterpret_cast(that.val_);
if (a == nullptr) return b == nullptr;
if (b == nullptr) return false;
return *a == *b;
}
template
V8_INLINE bool operator!=(const PersistentBase& that) const {
return !operator==(that);
}
template
V8_INLINE bool operator!=(const Local& that) const {
return !operator==(that);
}
/**
* Install a finalization callback on this object.
* NOTE: There is no guarantee as to *when* or even *if* the callback is
* invoked. The invocation is performed solely on a best effort basis.
* As always, GC-based finalization should *not* be relied upon for any
* critical form of resource management!
*/
template
V8_INLINE void SetWeak(P* parameter,
typename WeakCallbackInfo::Callback callback,
WeakCallbackType type);
/**
* Turns this handle into a weak phantom handle without finalization callback.
* The handle will be reset automatically when the garbage collector detects
* that the object is no longer reachable.
* A related function Isolate::NumberOfPhantomHandleResetsSinceLastCall
* returns how many phantom handles were reset by the garbage collector.
*/
V8_INLINE void SetWeak();
template
V8_INLINE P* ClearWeak();
// TODO(dcarney): remove this.
V8_INLINE void ClearWeak() { ClearWeak(); }
/**
* Annotates the strong handle with the given label, which is then used by the
* heap snapshot generator as a name of the edge from the root to the handle.
* The function does not take ownership of the label and assumes that the
* label is valid as long as the handle is valid.
*/
V8_INLINE void AnnotateStrongRetainer(const char* label);
/**
* Allows the embedder to tell the v8 garbage collector that a certain object
* is alive. Only allowed when the embedder is asked to trace its heap by
* EmbedderHeapTracer.
*/
V8_DEPRECATED(
"Used TracedGlobal and EmbedderHeapTracer::RegisterEmbedderReference",
V8_INLINE void RegisterExternalReference(Isolate* isolate) const);
/**
* Marks the reference to this object independent. Garbage collector is free
* to ignore any object groups containing this object. Weak callback for an
* independent handle should not assume that it will be preceded by a global
* GC prologue callback or followed by a global GC epilogue callback.
*/
V8_DEPRECATED(
"Weak objects are always considered independent. "
"Use TracedGlobal when trying to use EmbedderHeapTracer. "
"Use a strong handle when trying to keep an object alive.",
V8_INLINE void MarkIndependent());
/**
* Marks the reference to this object as active. The scavenge garbage
* collection should not reclaim the objects marked as active, even if the
* object held by the handle is otherwise unreachable.
*
* This bit is cleared after the each garbage collection pass.
*/
V8_DEPRECATED("Use TracedGlobal.", V8_INLINE void MarkActive());
V8_DEPRECATED("See MarkIndependent.", V8_INLINE bool IsIndependent() const);
/** Returns true if the handle's reference is weak. */
V8_INLINE bool IsWeak() const;
/**
* Assigns a wrapper class ID to the handle.
*/
V8_INLINE void SetWrapperClassId(uint16_t class_id);
/**
* Returns the class ID previously assigned to this handle or 0 if no class ID
* was previously assigned.
*/
V8_INLINE uint16_t WrapperClassId() const;
PersistentBase(const PersistentBase& other) = delete; // NOLINT
void operator=(const PersistentBase&) = delete;
private:
friend class Isolate;
friend class Utils;
template friend class Local;
template friend class Persistent;
template
friend class Global;
template friend class PersistentBase;
template friend class ReturnValue;
template
friend class PersistentValueMapBase;
template friend class PersistentValueVector;
friend class Object;
explicit V8_INLINE PersistentBase(T* val) : val_(val) {}
V8_INLINE static T* New(Isolate* isolate, T* that);
T* val_;
};
/**
* Default traits for Persistent. This class does not allow
* use of the copy constructor or assignment operator.
* At present kResetInDestructor is not set, but that will change in a future
* version.
*/
template
class NonCopyablePersistentTraits {
public:
typedef Persistent > NonCopyablePersistent;
static const bool kResetInDestructor = false;
template
V8_INLINE static void Copy(const Persistent& source,
NonCopyablePersistent* dest) {
Uncompilable();
}
// TODO(dcarney): come up with a good compile error here.
template V8_INLINE static void Uncompilable() {
TYPE_CHECK(O, Primitive);
}
};
/**
* Helper class traits to allow copying and assignment of Persistent.
* This will clone the contents of storage cell, but not any of the flags, etc.
*/
template
struct CopyablePersistentTraits {
typedef Persistent > CopyablePersistent;
static const bool kResetInDestructor = true;
template
static V8_INLINE void Copy(const Persistent& source,
CopyablePersistent* dest) {
// do nothing, just allow copy
}
};
/**
* A PersistentBase which allows copy and assignment.
*
* Copy, assignment and destructor behavior is controlled by the traits
* class M.
*
* Note: Persistent class hierarchy is subject to future changes.
*/
template class Persistent : public PersistentBase {
public:
/**
* A Persistent with no storage cell.
*/
V8_INLINE Persistent() : PersistentBase(nullptr) {}
/**
* Construct a Persistent from a Local.
* When the Local is non-empty, a new storage cell is created
* pointing to the same object, and no flags are set.
*/
template
V8_INLINE Persistent(Isolate* isolate, Local that)
: PersistentBase(PersistentBase::New(isolate, *that)) {
TYPE_CHECK(T, S);
}
/**
* Construct a Persistent from a Persistent.
* When the Persistent is non-empty, a new storage cell is created
* pointing to the same object, and no flags are set.
*/
template
V8_INLINE Persistent(Isolate* isolate, const Persistent& that)
: PersistentBase(PersistentBase::New(isolate, *that)) {
TYPE_CHECK(T, S);
}
/**
* The copy constructors and assignment operator create a Persistent
* exactly as the Persistent constructor, but the Copy function from the
* traits class is called, allowing the setting of flags based on the
* copied Persistent.
*/
V8_INLINE Persistent(const Persistent& that) : PersistentBase(nullptr) {
Copy(that);
}
template
V8_INLINE Persistent(const Persistent& that) : PersistentBase(0) {
Copy(that);
}
V8_INLINE Persistent& operator=(const Persistent& that) {
Copy(that);
return *this;
}
template
V8_INLINE Persistent& operator=(const Persistent& that) { // NOLINT
Copy(that);
return *this;
}
/**
* The destructor will dispose the Persistent based on the
* kResetInDestructor flags in the traits class. Since not calling dispose
* can result in a memory leak, it is recommended to always set this flag.
*/
V8_INLINE ~Persistent() {
if (M::kResetInDestructor) this->Reset();
}
// TODO(dcarney): this is pretty useless, fix or remove
template
V8_INLINE static Persistent& Cast(const Persistent& that) { // NOLINT
#ifdef V8_ENABLE_CHECKS
// If we're going to perform the type check then we have to check
// that the handle isn't empty before doing the checked cast.
if (!that.IsEmpty()) T::Cast(*that);
#endif
return reinterpret_cast&>(const_cast&>(that));
}
// TODO(dcarney): this is pretty useless, fix or remove
template
V8_INLINE Persistent& As() const { // NOLINT
return Persistent::Cast(*this);
}
private:
friend class Isolate;
friend class Utils;
template friend class Local;
template friend class Persistent;
template friend class ReturnValue;
explicit V8_INLINE Persistent(T* that) : PersistentBase(that) {}
V8_INLINE T* operator*() const { return this->val_; }
template
V8_INLINE void Copy(const Persistent& that);
};
/**
* A PersistentBase which has move semantics.
*
* Note: Persistent class hierarchy is subject to future changes.
*/
template
class Global : public PersistentBase {
public:
/**
* A Global with no storage cell.
*/
V8_INLINE Global() : PersistentBase(nullptr) {}
/**
* Construct a Global from a Local.
* When the Local is non-empty, a new storage cell is created
* pointing to the same object, and no flags are set.
*/
template
V8_INLINE Global(Isolate* isolate, Local that)
: PersistentBase(PersistentBase::New(isolate, *that)) {
TYPE_CHECK(T, S);
}
/**
* Construct a Global from a PersistentBase.
* When the Persistent is non-empty, a new storage cell is created
* pointing to the same object, and no flags are set.
*/
template
V8_INLINE Global(Isolate* isolate, const PersistentBase& that)
: PersistentBase(PersistentBase::New(isolate, that.val_)) {
TYPE_CHECK(T, S);
}
/**
* Move constructor.
*/
V8_INLINE Global(Global&& other);
V8_INLINE ~Global() { this->Reset(); }
/**
* Move via assignment.
*/
template
V8_INLINE Global& operator=(Global&& rhs);
/**
* Pass allows returning uniques from functions, etc.
*/
Global Pass() { return static_cast(*this); } // NOLINT
/*
* For compatibility with Chromium's base::Bind (base::Passed).
*/
typedef void MoveOnlyTypeForCPP03;
Global(const Global&) = delete;
void operator=(const Global&) = delete;
private:
template
friend class ReturnValue;
V8_INLINE T* operator*() const { return this->val_; }
};
// UniquePersistent is an alias for Global for historical reason.
template
using UniquePersistent = Global;
/**
* Trait specifying behavior of |TracedGlobal|.
*/
template
struct TracedGlobalTrait {
/**
* Specifies whether |TracedGlobal| should clear its handle on destruction.
*
* V8 will *not* clear the embedder-side memory of the handle. The embedder is
* expected to report all |TracedGlobal| handles through
* |EmbedderHeapTracer| upon garabge collection.
*
* See |EmbedderHeapTracer::IsRootForNonTracingGC| for handling with
* non-tracing GCs in V8.
*/
static constexpr bool kRequiresExplicitDestruction = true;
};
/**
* A traced handle with copy and move semantics. The handle is to be used
* together with |v8::EmbedderHeapTracer| and specifies edges from the embedder
* into V8's heap.
*
* The exact semantics are:
* - Tracing garbage collections use |v8::EmbedderHeapTracer|.
* - Non-tracing garbage collections refer to
* |v8::EmbedderHeapTracer::IsRootForNonTracingGC()| whether the handle should
* be treated as root or not.
*
* For destruction semantics see |TracedGlobalTrait|.
*/
template
class TracedGlobal {
public:
/**
* An empty TracedGlobal without storage cell.
*/
TracedGlobal() = default;
/**
* Construct a TracedGlobal from a Local.
*
* When the Local is non-empty, a new storage cell is created
* pointing to the same object.
*/
template
TracedGlobal(Isolate* isolate, Local that)
: val_(New(isolate, *that, &val_)) {
TYPE_CHECK(T, S);
}
/**
* Move constructor initializing TracedGlobal from an existing one.
*/
V8_INLINE TracedGlobal(TracedGlobal&& other) {
// Forward to operator=.
*this = std::move(other);
}
/**
* Move constructor initializing TracedGlobal from an existing one.
*/
template
V8_INLINE TracedGlobal(TracedGlobal&& other) {
// Forward to operator=.
*this = std::move(other);
}
/**
* Copy constructor initializing TracedGlobal from an existing one.
*/
V8_INLINE TracedGlobal(const TracedGlobal& other) {
// Forward to operator=;
*this = other;
}
/**
* Copy constructor initializing TracedGlobal from an existing one.
*/
template
V8_INLINE TracedGlobal(const TracedGlobal& other) {
// Forward to operator=;
*this = other;
}
/**
* Move assignment operator initializing TracedGlobal from an existing one.
*/
V8_INLINE TracedGlobal& operator=(TracedGlobal&& rhs);
/**
* Move assignment operator initializing TracedGlobal from an existing one.
*/
template
V8_INLINE TracedGlobal& operator=(TracedGlobal&& rhs);
/**
* Copy assignment operator initializing TracedGlobal from an existing one.
*
* Note: Prohibited when |other| has a finalization callback set through
* |SetFinalizationCallback|.
*/
V8_INLINE TracedGlobal& operator=(const TracedGlobal& rhs);
/**
* Copy assignment operator initializing TracedGlobal from an existing one.
*
* Note: Prohibited when |other| has a finalization callback set through
* |SetFinalizationCallback|.
*/
template
V8_INLINE TracedGlobal& operator=(const TracedGlobal& rhs);
/**
* Returns true if this TracedGlobal is empty, i.e., has not been assigned an
* object.
*/
bool IsEmpty() const { return val_ == nullptr; }
/**
* If non-empty, destroy the underlying storage cell. |IsEmpty| will return
* true after this call.
*/
V8_INLINE void Reset();
/**
* If non-empty, destroy the underlying storage cell and create a new one with
* the contents of other if other is non empty
*/
template
V8_INLINE void Reset(Isolate* isolate, const Local& other);
/**
* Construct a Local from this handle.
*/
Local Get(Isolate* isolate) const { return Local::New(isolate, *this); }
template
V8_INLINE TracedGlobal& As() const {
return reinterpret_cast&>(
const_cast&>(*this));
}
template
V8_INLINE bool operator==(const TracedGlobal& that) const {
internal::Address* a = reinterpret_cast(**this);
internal::Address* b = reinterpret_cast(*that);
if (a == nullptr) return b == nullptr;
if (b == nullptr) return false;
return *a == *b;
}
template
V8_INLINE bool operator==(const Local& that) const {
internal::Address* a = reinterpret_cast(**this);
internal::Address* b = reinterpret_cast(*that);
if (a == nullptr) return b == nullptr;
if (b == nullptr) return false;
return *a == *b;
}
template
V8_INLINE bool operator!=(const TracedGlobal& that) const {
return !operator==(that);
}
template
V8_INLINE bool operator!=(const Local& that) const {
return !operator==(that);
}
/**
* Assigns a wrapper class ID to the handle.
*/
V8_INLINE void SetWrapperClassId(uint16_t class_id);
/**
* Returns the class ID previously assigned to this handle or 0 if no class ID
* was previously assigned.
*/
V8_INLINE uint16_t WrapperClassId() const;
/**
* Adds a finalization callback to the handle. The type of this callback is
* similar to WeakCallbackType::kInternalFields, i.e., it will pass the
* parameter and the first two internal fields of the object.
*
* The callback is then supposed to reset the handle in the callback. No
* further V8 API may be called in this callback. In case additional work
* involving V8 needs to be done, a second callback can be scheduled using
* WeakCallbackInfo::SetSecondPassCallback.
*/
V8_INLINE void SetFinalizationCallback(
void* parameter, WeakCallbackInfo::Callback callback);
private:
// Wrapping type used when clearing on destruction is required.
struct WrappedForDestruction {
T* value;
explicit WrappedForDestruction(T* val) : value(val) {}
~WrappedForDestruction();
operator T*() const { return value; }
T* operator*() const { return value; }
T* operator->() const { return value; }
WrappedForDestruction& operator=(const WrappedForDestruction& other) {
value = other.value;
return *this;
}
WrappedForDestruction& operator=(T* val) {
value = val;
return *this;
}
};
V8_INLINE static T* New(Isolate* isolate, T* that, void* slot);
T* operator*() const { return this->val_; }
typename std::conditional<
TracedGlobalTrait>::kRequiresExplicitDestruction,
WrappedForDestruction, T*>::type val_{nullptr};
friend class EmbedderHeapTracer;
template
friend class Local;
friend class Object;
template
friend class ReturnValue;
};
/**
* A stack-allocated class that governs a number of local handles.
* After a handle scope has been created, all local handles will be
* allocated within that handle scope until either the handle scope is
* deleted or another handle scope is created. If there is already a
* handle scope and a new one is created, all allocations will take
* place in the new handle scope until it is deleted. After that,
* new handles will again be allocated in the original handle scope.
*
* After the handle scope of a local handle has been deleted the
* garbage collector will no longer track the object stored in the
* handle and may deallocate it. The behavior of accessing a handle
* for which the handle scope has been deleted is undefined.
*/
class V8_EXPORT HandleScope {
public:
explicit HandleScope(Isolate* isolate);
~HandleScope();
/**
* Counts the number of allocated handles.
*/
static int NumberOfHandles(Isolate* isolate);
V8_INLINE Isolate* GetIsolate() const {
return reinterpret_cast(isolate_);
}
HandleScope(const HandleScope&) = delete;
void operator=(const HandleScope&) = delete;
protected:
V8_INLINE HandleScope() = default;
void Initialize(Isolate* isolate);
static internal::Address* CreateHandle(internal::Isolate* isolate,
internal::Address value);
private:
// Declaring operator new and delete as deleted is not spec compliant.
// Therefore declare them private instead to disable dynamic alloc
void* operator new(size_t size);
void* operator new[](size_t size);
void operator delete(void*, size_t);
void operator delete[](void*, size_t);
internal::Isolate* isolate_;
internal::Address* prev_next_;
internal::Address* prev_limit_;
// Local::New uses CreateHandle with an Isolate* parameter.
template friend class Local;
// Object::GetInternalField and Context::GetEmbedderData use CreateHandle with
// a HeapObject in their shortcuts.
friend class Object;
friend class Context;
};
/**
* A HandleScope which first allocates a handle in the current scope
* which will be later filled with the escape value.
*/
class V8_EXPORT EscapableHandleScope : public HandleScope {
public:
explicit EscapableHandleScope(Isolate* isolate);
V8_INLINE ~EscapableHandleScope() = default;
/**
* Pushes the value into the previous scope and returns a handle to it.
* Cannot be called twice.
*/
template
V8_INLINE Local Escape(Local value) {
internal::Address* slot =
Escape(reinterpret_cast(*value));
return Local(reinterpret_cast(slot));
}
template
V8_INLINE MaybeLocal EscapeMaybe(MaybeLocal value) {
return Escape(value.FromMaybe(Local()));
}
EscapableHandleScope(const EscapableHandleScope&) = delete;
void operator=(const EscapableHandleScope&) = delete;
private:
// Declaring operator new and delete as deleted is not spec compliant.
// Therefore declare them private instead to disable dynamic alloc
void* operator new(size_t size);
void* operator new[](size_t size);
void operator delete(void*, size_t);
void operator delete[](void*, size_t);
internal::Address* Escape(internal::Address* escape_value);
internal::Address* escape_slot_;
};
/**
* A SealHandleScope acts like a handle scope in which no handle allocations
* are allowed. It can be useful for debugging handle leaks.
* Handles can be allocated within inner normal HandleScopes.
*/
class V8_EXPORT SealHandleScope {
public:
explicit SealHandleScope(Isolate* isolate);
~SealHandleScope();
SealHandleScope(const SealHandleScope&) = delete;
void operator=(const SealHandleScope&) = delete;
private:
// Declaring operator new and delete as deleted is not spec compliant.
// Therefore declare them private instead to disable dynamic alloc
void* operator new(size_t size);
void* operator new[](size_t size);
void operator delete(void*, size_t);
void operator delete[](void*, size_t);
internal::Isolate* const isolate_;
internal::Address* prev_limit_;
int prev_sealed_level_;
};
// --- Special objects ---
/**
* The superclass of values and API object templates.
*/
class V8_EXPORT Data {
private:
Data();
};
/**
* A container type that holds relevant metadata for module loading.
*
* This is passed back to the embedder as part of
* HostImportModuleDynamicallyCallback for module loading.
*/
class V8_EXPORT ScriptOrModule {
public:
/**
* The name that was passed by the embedder as ResourceName to the
* ScriptOrigin. This can be either a v8::String or v8::Undefined.
*/
Local GetResourceName();
/**
* The options that were passed by the embedder as HostDefinedOptions to
* the ScriptOrigin.
*/
Local GetHostDefinedOptions();
};
/**
* An array to hold Primitive values. This is used by the embedder to
* pass host defined options to the ScriptOptions during compilation.
*
* This is passed back to the embedder as part of
* HostImportModuleDynamicallyCallback for module loading.
*
*/
class V8_EXPORT PrimitiveArray {
public:
static Local New(Isolate* isolate, int length);
int Length() const;
void Set(Isolate* isolate, int index, Local item);
Local Get(Isolate* isolate, int index);
};
/**
* The optional attributes of ScriptOrigin.
*/
class ScriptOriginOptions {
public:
V8_INLINE ScriptOriginOptions(bool is_shared_cross_origin = false,
bool is_opaque = false, bool is_wasm = false,
bool is_module = false)
: flags_((is_shared_cross_origin ? kIsSharedCrossOrigin : 0) |
(is_wasm ? kIsWasm : 0) | (is_opaque ? kIsOpaque : 0) |
(is_module ? kIsModule : 0)) {}
V8_INLINE ScriptOriginOptions(int flags)
: flags_(flags &
(kIsSharedCrossOrigin | kIsOpaque | kIsWasm | kIsModule)) {}
bool IsSharedCrossOrigin() const {
return (flags_ & kIsSharedCrossOrigin) != 0;
}
bool IsOpaque() const { return (flags_ & kIsOpaque) != 0; }
bool IsWasm() const { return (flags_ & kIsWasm) != 0; }
bool IsModule() const { return (flags_ & kIsModule) != 0; }
int Flags() const { return flags_; }
private:
enum {
kIsSharedCrossOrigin = 1,
kIsOpaque = 1 << 1,
kIsWasm = 1 << 2,
kIsModule = 1 << 3
};
const int flags_;
};
/**
* The origin, within a file, of a script.
*/
class ScriptOrigin {
public:
V8_INLINE ScriptOrigin(
Local resource_name,
Local resource_line_offset = Local(),
Local resource_column_offset = Local