blob: ca96c32088df3983c796a807b2ce76017e0fa2df [file] [log] [blame]
// 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 <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <memory>
#include <utility>
#include <vector>
#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 T>
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 T> class Local;
template <class T>
class MaybeLocal;
template <class T> class Eternal;
template<class T> class NonCopyablePersistentTraits;
template<class T> class PersistentBase;
template <class T, class M = NonCopyablePersistentTraits<T> >
class Persistent;
template <class T>
class Global;
template <class T>
class TracedGlobal;
template<class K, class V, class T> class PersistentValueMap;
template <class K, class V, class T>
class PersistentValueMapBase;
template <class K, class V, class T>
class GlobalValueMap;
template<class V, class T> class PersistentValueVector;
template<class T, class P> class WeakCallbackObject;
class FunctionTemplate;
class ObjectTemplate;
template<typename T> class FunctionCallbackInfo;
template<typename T> class PropertyCallbackInfo;
class StackTrace;
class StackFrame;
class Isolate;
class CallHandlerHelper;
class EscapableHandleScope;
template<typename T> class ReturnValue;
namespace internal {
class Arguments;
class DeferredHandles;
class Heap;
class HeapObject;
class ExternalString;
class Isolate;
class LocalEmbedderHeapTracer;
class MicrotaskQueue;
struct ScriptStreamingData;
template<typename T> class CustomArguments;
class PropertyCallbackArguments;
class FunctionCallbackArguments;
class GlobalHandles;
class ScopedExternalStringLock;
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<T* volatile*>(0)) = static_cast<S*>(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<Object>); 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 T>
class Local {
public:
V8_INLINE Local() : val_(nullptr) {}
template <class S>
V8_INLINE Local(Local<S> that)
: val_(reinterpret_cast<T*>(*that)) {
/**
* This check fails when trying to convert between incompatible
* handles. For example, converting from a Local<String> to a
* Local<Number>.
*/
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 <class S>
V8_INLINE bool operator==(const Local<S>& that) const {
internal::Address* a = reinterpret_cast<internal::Address*>(this->val_);
internal::Address* b = reinterpret_cast<internal::Address*>(that.val_);
if (a == nullptr) return b == nullptr;
if (b == nullptr) return false;
return *a == *b;
}
template <class S> V8_INLINE bool operator==(
const PersistentBase<S>& that) const {
internal::Address* a = reinterpret_cast<internal::Address*>(this->val_);
internal::Address* b = reinterpret_cast<internal::Address*>(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 <class S>
V8_INLINE bool operator!=(const Local<S>& that) const {
return !operator==(that);
}
template <class S> V8_INLINE bool operator!=(
const Persistent<S>& that) const {
return !operator==(that);
}
/**
* Cast a handle to a subclass, e.g. Local<Value> to Local<Object>.
* This is only valid if the handle actually refers to a value of the
* target type.
*/
template <class S> V8_INLINE static Local<T> Cast(Local<S> 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<T>();
#endif
return Local<T>(T::Cast(*that));
}
/**
* Calling this is equivalent to Local<S>::Cast().
* In particular, this is only valid if the handle actually refers to a value
* of the target type.
*/
template <class S>
V8_INLINE Local<S> As() const {
return Local<S>::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<T> New(Isolate* isolate, Local<T> that);
V8_INLINE static Local<T> New(Isolate* isolate,
const PersistentBase<T>& that);
V8_INLINE static Local<T> New(Isolate* isolate, const TracedGlobal<T>& that);
private:
friend class Utils;
template<class F> friend class Eternal;
template<class F> friend class PersistentBase;
template<class F, class M> friend class Persistent;
template<class F> friend class Local;
template <class F>
friend class MaybeLocal;
template<class F> friend class FunctionCallbackInfo;
template<class F> friend class PropertyCallbackInfo;
friend class String;
friend class Object;
friend class Context;
friend class Isolate;
friend class Private;
template<class F> friend class internal::CustomArguments;
friend Local<Primitive> Undefined(Isolate* isolate);
friend Local<Primitive> Null(Isolate* isolate);
friend Local<Boolean> True(Isolate* isolate);
friend Local<Boolean> False(Isolate* isolate);
friend class HandleScope;
friend class EscapableHandleScope;
template <class F1, class F2, class F3>
friend class PersistentValueMapBase;
template<class F1, class F2> friend class PersistentValueVector;
template <class F>
friend class ReturnValue;
template <class F>
friend class TracedGlobal;
explicit V8_INLINE Local(T* that) : val_(that) {}
V8_INLINE static Local<T> New(Isolate* isolate, T* that);
T* val_;
};
#if !defined(V8_IMMINENT_DEPRECATION_WARNINGS)
// Handle is an alias for Local for historical reasons.
template <class T>
using Handle = Local<T>;
#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 T>
class MaybeLocal {
public:
V8_INLINE MaybeLocal() : val_(nullptr) {}
template <class S>
V8_INLINE MaybeLocal(Local<S> that)
: val_(reinterpret_cast<T*>(*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 <class S>
V8_WARN_UNUSED_RESULT V8_INLINE bool ToLocal(Local<S>* 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<T> ToLocalChecked();
/**
* Converts this MaybeLocal<> to a Local<>, using a default value if this
* MaybeLocal<> is empty.
*/
template <class S>
V8_INLINE Local<S> FromMaybe(Local<S> default_value) const {
return IsEmpty() ? default_value : Local<S>(val_);
}
private:
T* val_;
};
/**
* Eternal handles are set-once handles that live for the lifetime of the
* isolate.
*/
template <class T> class Eternal {
public:
V8_INLINE Eternal() : val_(nullptr) {}
template <class S>
V8_INLINE Eternal(Isolate* isolate, Local<S> handle) : val_(nullptr) {
Set(isolate, handle);
}
// Can only be safely called if already set.
V8_INLINE Local<T> Get(Isolate* isolate) const;
V8_INLINE bool IsEmpty() const { return val_ == nullptr; }
template<class S> V8_INLINE void Set(Isolate* isolate, Local<S> handle);
private:
T* val_;
};
static const int kInternalFieldsInWeakCallback = 2;
static const int kEmbedderFieldsInWeakCallback = 2;
template <typename T>
class WeakCallbackInfo {
public:
typedef void (*Callback)(const WeakCallbackInfo<T>& 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 T> 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 <class S>
V8_INLINE void Reset(Isolate* isolate, const Local<S>& 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 <class S>
V8_INLINE void Reset(Isolate* isolate, const PersistentBase<S>& other);
V8_INLINE bool IsEmpty() const { return val_ == nullptr; }
V8_INLINE void Empty() { val_ = 0; }
V8_INLINE Local<T> Get(Isolate* isolate) const {
return Local<T>::New(isolate, *this);
}
template <class S>
V8_INLINE bool operator==(const PersistentBase<S>& that) const {
internal::Address* a = reinterpret_cast<internal::Address*>(this->val_);
internal::Address* b = reinterpret_cast<internal::Address*>(that.val_);
if (a == nullptr) return b == nullptr;
if (b == nullptr) return false;
return *a == *b;
}
template <class S>
V8_INLINE bool operator==(const Local<S>& that) const {
internal::Address* a = reinterpret_cast<internal::Address*>(this->val_);
internal::Address* b = reinterpret_cast<internal::Address*>(that.val_);
if (a == nullptr) return b == nullptr;
if (b == nullptr) return false;
return *a == *b;
}
template <class S>
V8_INLINE bool operator!=(const PersistentBase<S>& that) const {
return !operator==(that);
}
template <class S>
V8_INLINE bool operator!=(const Local<S>& 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 <typename P>
V8_INLINE void SetWeak(P* parameter,
typename WeakCallbackInfo<P>::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<typename P>
V8_INLINE P* ClearWeak();
// TODO(dcarney): remove this.
V8_INLINE void ClearWeak() { ClearWeak<void>(); }
/**
* 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);
/** 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<class F> friend class Local;
template<class F1, class F2> friend class Persistent;
template <class F>
friend class Global;
template<class F> friend class PersistentBase;
template<class F> friend class ReturnValue;
template <class F1, class F2, class F3>
friend class PersistentValueMapBase;
template<class F1, class F2> 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 T>
class NonCopyablePersistentTraits {
public:
typedef Persistent<T, NonCopyablePersistentTraits<T> > NonCopyablePersistent;
static const bool kResetInDestructor = false;
template<class S, class M>
V8_INLINE static void Copy(const Persistent<S, M>& source,
NonCopyablePersistent* dest) {
Uncompilable<Object>();
}
// TODO(dcarney): come up with a good compile error here.
template<class O> 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<class T>
struct CopyablePersistentTraits {
typedef Persistent<T, CopyablePersistentTraits<T> > CopyablePersistent;
static const bool kResetInDestructor = true;
template<class S, class M>
static V8_INLINE void Copy(const Persistent<S, M>& 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 T, class M> class Persistent : public PersistentBase<T> {
public:
/**
* A Persistent with no storage cell.
*/
V8_INLINE Persistent() : PersistentBase<T>(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 <class S>
V8_INLINE Persistent(Isolate* isolate, Local<S> that)
: PersistentBase<T>(PersistentBase<T>::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 <class S, class M2>
V8_INLINE Persistent(Isolate* isolate, const Persistent<S, M2>& that)
: PersistentBase<T>(PersistentBase<T>::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<T>(nullptr) {
Copy(that);
}
template <class S, class M2>
V8_INLINE Persistent(const Persistent<S, M2>& that) : PersistentBase<T>(0) {
Copy(that);
}
V8_INLINE Persistent& operator=(const Persistent& that) {
Copy(that);
return *this;
}
template <class S, class M2>
V8_INLINE Persistent& operator=(const Persistent<S, M2>& 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 <class S>
V8_INLINE static Persistent<T>& Cast(const Persistent<S>& 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<Persistent<T>&>(const_cast<Persistent<S>&>(that));
}
// TODO(dcarney): this is pretty useless, fix or remove
template <class S>
V8_INLINE Persistent<S>& As() const { // NOLINT
return Persistent<S>::Cast(*this);
}
private:
friend class Isolate;
friend class Utils;
template<class F> friend class Local;
template<class F1, class F2> friend class Persistent;
template<class F> friend class ReturnValue;
explicit V8_INLINE Persistent(T* that) : PersistentBase<T>(that) {}
V8_INLINE T* operator*() const { return this->val_; }
template<class S, class M2>
V8_INLINE void Copy(const Persistent<S, M2>& that);
};
/**
* A PersistentBase which has move semantics.
*
* Note: Persistent class hierarchy is subject to future changes.
*/
template <class T>
class Global : public PersistentBase<T> {
public:
/**
* A Global with no storage cell.
*/
V8_INLINE Global() : PersistentBase<T>(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 <class S>
V8_INLINE Global(Isolate* isolate, Local<S> that)
: PersistentBase<T>(PersistentBase<T>::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 <class S>
V8_INLINE Global(Isolate* isolate, const PersistentBase<S>& that)
: PersistentBase<T>(PersistentBase<T>::New(isolate, that.val_)) {
TYPE_CHECK(T, S);
}
/**
* Move constructor.
*/
V8_INLINE Global(Global&& other);
V8_INLINE ~Global() { this->Reset(); }
/**
* Move via assignment.
*/
template <class S>
V8_INLINE Global& operator=(Global<S>&& rhs);
/**
* Pass allows returning uniques from functions, etc.
*/
Global Pass() { return static_cast<Global&&>(*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 <class F>
friend class ReturnValue;
V8_INLINE T* operator*() const { return this->val_; }
};
// UniquePersistent is an alias for Global for historical reason.
template <class T>
using UniquePersistent = Global<T>;
/**
* A traced handle with move semantics, similar to std::unique_ptr. 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.
*/
template <typename T>
class V8_EXPORT TracedGlobal {
public:
/**
* An empty TracedGlobal without storage cell.
*/
TracedGlobal() = default;
~TracedGlobal() { Reset(); }
/**
* Construct a TracedGlobal from a Local.
*
* When the Local is non-empty, a new storage cell is created
* pointing to the same object.
*/
template <class S>
TracedGlobal(Isolate* isolate, Local<S> that)
: val_(New(isolate, *that, &val_)) {
TYPE_CHECK(T, S);
}
/**
* Move constructor initializing TracedGlobal from an existing one.
*/
V8_INLINE TracedGlobal(TracedGlobal&& other);
/**
* Move assignment operator initializing TracedGlobal from an existing one.
*/
template <class S>
V8_INLINE TracedGlobal& operator=(TracedGlobal<S>&& rhs);
/**
* TracedGlobal only supports move semantics and forbids copying.
*/
TracedGlobal(const TracedGlobal&) = delete;
void operator=(const TracedGlobal&) = delete;
/**
* 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 <class S>
V8_INLINE void Reset(Isolate* isolate, const Local<S>& other);
/**
* Construct a Local<T> from this handle.
*/
Local<T> Get(Isolate* isolate) const { return Local<T>::New(isolate, *this); }
template <class S>
V8_INLINE TracedGlobal<S>& As() const {
return reinterpret_cast<TracedGlobal<S>&>(
const_cast<TracedGlobal<T>&>(*this));
}
template <class S>
V8_INLINE bool operator==(const TracedGlobal<S>& that) const {
internal::Address* a = reinterpret_cast<internal::Address*>(this->val_);
internal::Address* b = reinterpret_cast<internal::Address*>(that.val_);
if (a == nullptr) return b == nullptr;
if (b == nullptr) return false;
return *a == *b;
}
template <class S>
V8_INLINE bool operator==(const Local<S>& that) const {
internal::Address* a = reinterpret_cast<internal::Address*>(this->val_);
internal::Address* b = reinterpret_cast<internal::Address*>(that.val_);
if (a == nullptr) return b == nullptr;
if (b == nullptr) return false;
return *a == *b;
}
template <class S>
V8_INLINE bool operator!=(const TracedGlobal<S>& that) const {
return !operator==(that);
}
template <class S>
V8_INLINE bool operator!=(const Local<S>& 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<void>::SetSecondPassCallback.
*/
V8_INLINE void SetFinalizationCallback(
void* parameter, WeakCallbackInfo<void>::Callback callback);
private:
V8_INLINE static T* New(Isolate* isolate, T* that, T** slot);
T* operator*() const { return this->val_; }
T* val_ = nullptr;
friend class EmbedderHeapTracer;
template <typename F>
friend class Local;
friend class Object;
template <typename F>
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*>(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<class F> 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 <class T>
V8_INLINE Local<T> Escape(Local<T> value) {
internal::Address* slot =
Escape(reinterpret_cast<internal::Address*>(*value));
return Local<T>(reinterpret_cast<T*>(slot));
}
template <class T>
V8_INLINE MaybeLocal<T> EscapeMaybe(MaybeLocal<T> value) {
return Escape(value.FromMaybe(Local<T>()));
}
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<Value> GetResourceName();
/**
* The options that were passed by the embedder as HostDefinedOptions to
* the ScriptOrigin.
*/
Local<PrimitiveArray> 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<PrimitiveArray> New(Isolate* isolate, int length);
int Length() const;
void Set(Isolate* isolate, int index, Local<Primitive> item);
Local<Primitive> 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<Value> resource_name,
Local<Integer> resource_line_offset = Local<Integer>(),
Local<Integer> resource_column_offset = Local<Integer>(),
Local<Boolean> resource_is_shared_cross_origin = Local<Boolean>(),
Local<Integer> script_id = Local<Integer>(),
Local<Value> source_map_url = Local<Value>(),
Local<Boolean> resource_is_opaque = Local<Boolean>(),
Local<Boolean> is_wasm = Local<Boolean>(),
Local<Boolean> is_module = Local<Boolean>(),
Local<PrimitiveArray> host_defined_options = Local<PrimitiveArray>());
V8_INLINE Local<Value> ResourceName() const;
V8_INLINE Local<Integer> ResourceLineOffset() const;
V8_INLINE Local<Integer> ResourceColumnOffset() const;
V8_INLINE Local<Integer> ScriptID() const;
V8_INLINE Local<Value> SourceMapUrl() const;
V8_INLINE Local<PrimitiveArray> HostDefinedOptions() const;
V8_INLINE ScriptOriginOptions Options() const { return options_; }
private:
Local<Value> resource_name_;
Local<Integer> resource_line_offset_;
Local<Integer> resource_column_offset_;
ScriptOriginOptions options_;
Local<Integer> script_id_;
Local<Value> source_map_url_;
Local<PrimitiveArray> host_defined_options_;
};
/**
* A compiled JavaScript script, not yet tied to a Context.
*/
class V8_EXPORT UnboundScript {
public:
/**
* Binds the script to the currently entered context.
*/
Local<Script> BindToCurrentContext();
int GetId();
Local<Value> GetScriptName();
/**
* Data read from magic sourceURL comments.
*/
Local<Value> GetSourceURL();
/**
* Data read from magic sourceMappingURL comments.
*/
Local<Value> GetSourceMappingURL();
/**
* Returns zero based line number of the code_pos location in the script.
* -1 will be returned if no information available.
*/
int GetLineNumber(int code_pos);
static const int kNoScriptId = 0;
};
/**
* A compiled JavaScript module, not yet tied to a Context.
*/
class V8_EXPORT UnboundModuleScript {
// Only used as a container for code caching.
};
/**
* A location in JavaScript source.
*/
class V8_EXPORT Location {
public:
int GetLineNumber() { return line_number_; }
int GetColumnNumber() { return column_number_; }
Location(int line_number, int column_number)
: line_number_(line_number), column_number_(column_number) {}
private:
int line_number_;
int column_number_;
};
/**
* A compiled JavaScript module.
*/
class V8_EXPORT Module {
public:
/**
* The different states a module can be in.
*
* This corresponds to the states used in ECMAScript except that "evaluated"
* is split into kEvaluated and kErrored, indicating success and failure,
* respectively.
*/
enum Status {
kUninstantiated,
kInstantiating,
kInstantiated,
kEvaluating,
kEvaluated,
kErrored
};
/**
* Returns the module's current status.
*/
Status GetStatus() const;
/**
* For a module in kErrored status, this returns the corresponding exception.
*/
Local<Value> GetException() const;
/**
* Returns the number of modules requested by this module.
*/
int GetModuleRequestsLength() const;
/**
* Returns the ith module specifier in this module.
* i must be < GetModuleRequestsLength() and >= 0.
*/
Local<String> GetModuleRequest(int i) const;
/**
* Returns the source location (line number and column number) of the ith
* module specifier's first occurrence in this module.
*/
Location GetModuleRequestLocation(int i) const;
/**
* Returns the identity hash for this object.
*/
int GetIdentityHash() const;
typedef MaybeLocal<Module> (*ResolveCallback)(Local<Context> context,
Local<String> specifier,
Local<Module> referrer);
/**
* Instantiates the module and its dependencies.
*
* Returns an empty Maybe<bool> if an exception occurred during
* instantiation. (In the case where the callback throws an exception, that
* exception is propagated.)
*/
V8_WARN_UNUSED_RESULT Maybe<bool> InstantiateModule(Local<Context> context,
ResolveCallback callback);
/**
* Evaluates the module and its dependencies.
*
* If status is kInstantiated, run the module's code. On success, set status
* to kEvaluated and return the completion value; on failure, set status to
* kErrored and propagate the thrown exception (which is then also available
* via |GetException|).
*/
V8_WARN_UNUSED_RESULT MaybeLocal<Value> Evaluate(Local<Context> context);
/**
* Returns the namespace object of this module.
*
* The module's status must be at least kInstantiated.
*/
Local<Value> GetModuleNamespace();
/**
* Returns the corresponding context-unbound module script.
*
* The module must be unevaluated, i.e. its status must not be kEvaluating,
* kEvaluated or kErrored.
*/
Local<UnboundModuleScript> GetUnboundModuleScript();
/*
* Callback defined in the embedder. This is responsible for setting
* the module's exported values with calls to SetSyntheticModuleExport().
* The callback must return a Value to indicate success (where no
* exception was thrown) and return an empy MaybeLocal to indicate falure
* (where an exception was thrown).
*/
typedef MaybeLocal<Value> (*SyntheticModuleEvaluationSteps)(
Local<Context> context, Local<Module> module);
/**
* Creates a new SyntheticModule with the specified export names, where
* evaluation_steps will be executed upon module evaluation.
* export_names must not contain duplicates.
* module_name is used solely for logging/debugging and doesn't affect module
* behavior.
*/
static Local<Module> CreateSyntheticModule(
Isolate* isolate, Local<String> module_name,
const std::vector<Local<String>>& export_names,
SyntheticModuleEvaluationSteps evaluation_steps);
/**
* Set this module's exported value for the name export_name to the specified
* export_value. This method must be called only on Modules created via
* CreateSyntheticModule. export_name must be one of the export_names that
* were passed in that CreateSyntheticModule call.
*/
void SetSyntheticModuleExport(Local<String> export_name,
Local<Value> export_value);
};
/**
* A compiled JavaScript script, tied to a Context which was active when the
* script was compiled.
*/
class V8_EXPORT Script {
public:
/**
* A shorthand for ScriptCompiler::Compile().
*/
static V8_WARN_UNUSED_RESULT MaybeLocal<Script> Compile(
Local<Context> context, Local<String> source,
ScriptOrigin* origin = nullptr);
/**
* Runs the script returning the resulting value. It will be run in the
* context in which it was created (ScriptCompiler::CompileBound or
* UnboundScript::BindToCurrentContext()).
*/
V8_WARN_UNUSED_RESULT MaybeLocal<Value> Run(Local<Context> context);
/**
* Returns the corresponding context-unbound script.
*/
Local<UnboundScript> GetUnboundScript();
};
/**
* For compiling scripts.
*/
class V8_EXPORT ScriptCompiler {
public:
/**
* Compilation data that the embedder can cache and pass back to speed up
* future compilations. The data is produced if the CompilerOptions passed to
* the compilation functions in ScriptCompiler contains produce_data_to_cache
* = true. The data to cache can then can be retrieved from
* UnboundScript.
*/
struct V8_EXPORT CachedData {
enum BufferPolicy {
BufferNotOwned,
BufferOwned
};
CachedData()
: data(nullptr),
length(0),
rejected(false),
buffer_policy(BufferNotOwned) {}
// If buffer_policy is BufferNotOwned, the caller keeps the ownership of
// data and guarantees that it stays alive until the CachedData object is
// destroyed. If the policy is BufferOwned, the given data will be deleted
// (with delete[]) when the CachedData object is destroyed.
CachedData(const uint8_t* data, int length,
BufferPolicy buffer_policy = BufferNotOwned);
~CachedData();
// TODO(marja): Async compilation; add constructors which take a callback
// which will be called when V8 no longer needs the data.
const uint8_t* data;
int length;
bool rejected;
BufferPolicy buffer_policy;
// Prevent copying.
CachedData(const CachedData&) = delete;
CachedData& operator=(const CachedData&) = delete;
};
/**
* Source code which can be then compiled to a UnboundScript or Script.
*/
class Source {
public:
// Source takes ownership of CachedData.
V8_INLINE Source(Local<String> source_string, const ScriptOrigin& origin,
CachedData* cached_data = nullptr);
V8_INLINE Source(Local<String> source_string,
CachedData* cached_data = nullptr);
V8_INLINE ~Source();
// Ownership of the CachedData or its buffers is *not* transferred to the
// caller. The CachedData object is alive as long as the Source object is
// alive.
V8_INLINE const CachedData* GetCachedData() const;
V8_INLINE const ScriptOriginOptions& GetResourceOptions() const;
// Prevent copying.
Source(const Source&) = delete;
Source& operator=(const Source&) = delete;
private:
friend class ScriptCompiler;
Local<String> source_string;
// Origin information
Local<Value> resource_name;
Local<Integer> resource_line_offset;
Local<Integer> resource_column_offset;
ScriptOriginOptions resource_options;
Local<Value> source_map_url;
Local<PrimitiveArray> host_defined_options;
// Cached data from previous compilation (if a kConsume*Cache flag is
// set), or hold newly generated cache data (kProduce*Cache flags) are
// set when calling a compile method.
CachedData* cached_data;
};
/**
* For streaming incomplete script data to V8. The embedder should implement a
* subclass of this class.
*/
class V8_EXPORT ExternalSourceStream {
public:
virtual ~ExternalSourceStream() = default;
/**
* V8 calls this to request the next chunk of data from the embedder. This
* function will be called on a background thread, so it's OK to block and
* wait for the data, if the embedder doesn't have data yet. Returns the
* length of the data returned. When the data ends, GetMoreData should
* return 0. Caller takes ownership of the data.
*
* When streaming UTF-8 data, V8 handles multi-byte characters split between
* two data chunks, but doesn't handle multi-byte characters split between
* more than two data chunks. The embedder can avoid this problem by always
* returning at least 2 bytes of data.
*
* When streaming UTF-16 data, V8 does not handle characters split between
* two data chunks. The embedder has to make sure that chunks have an even
* length.
*
* If the embedder wants to cancel the streaming, they should make the next
* GetMoreData call return 0. V8 will interpret it as end of data (and most
* probably, parsing will fail). The streaming task will return as soon as
* V8 has parsed the data it received so far.
*/
virtual size_t GetMoreData(const uint8_t** src) = 0;
/**
* V8 calls this method to set a 'bookmark' at the current position in
* the source stream, for the purpose of (maybe) later calling
* ResetToBookmark. If ResetToBookmark is called later, then subsequent
* calls to GetMoreData should return the same data as they did when
* SetBookmark was called earlier.
*
* The embedder may return 'false' to indicate it cannot provide this
* functionality.
*/
virtual bool SetBookmark();
/**
* V8 calls this to return to a previously set bookmark.
*/
virtual void ResetToBookmark();
};
/**
* Source code which can be streamed into V8 in pieces. It will be parsed
* while streaming and compiled after parsing has completed. StreamedSource
* must be kept alive while the streaming task is run (see ScriptStreamingTask
* below).
*/
class V8_EXPORT StreamedSource {
public:
enum Encoding { ONE_BYTE, TWO_BYTE, UTF8 };
V8_DEPRECATE_SOON(
"This class takes ownership of source_stream, so use the constructor "
"taking a unique_ptr to make these semantics clearer",
StreamedSource(ExternalSourceStream* source_stream, Encoding encoding));
StreamedSource(std::unique_ptr<ExternalSourceStream> source_stream,
Encoding encoding);
~StreamedSource();
internal::ScriptStreamingData* impl() const { return impl_.get(); }
// Prevent copying.
StreamedSource(const StreamedSource&) = delete;
StreamedSource& operator=(const StreamedSource&) = delete;
private:
std::unique_ptr<internal::ScriptStreamingData> impl_;
};
/**
* A streaming task which the embedder must run on a background thread to
* stream scripts into V8. Returned by ScriptCompiler::StartStreamingScript.
*/
class V8_EXPORT ScriptStreamingTask final {
public:
void Run();
private:
friend class ScriptCompiler;
explicit ScriptStreamingTask(internal::ScriptStreamingData* data)
: data_(data) {}
internal::ScriptStreamingData* data_;
};
enum CompileOptions {
kNoCompileOptions = 0,
kConsumeCodeCache,
kEagerCompile
};
/**
* The reason for which we are not requesting or providing a code cache.
*/
enum NoCacheReason {
kNoCacheNoReason = 0,
kNoCacheBecauseCachingDisabled,
kNoCacheBecauseNoResource,
kNoCacheBecauseInlineScript,
kNoCacheBecauseModule,
kNoCacheBecauseStreamingSource,
kNoCacheBecauseInspector,
kNoCacheBecauseScriptTooSmall,
kNoCacheBecauseCacheTooCold,
kNoCacheBecauseV8Extension,
kNoCacheBecauseExtensionModule,
kNoCacheBecausePacScript,
kNoCacheBecauseInDocumentWrite,
kNoCacheBecauseResourceWithNoCacheHandler,
kNoCacheBecauseDeferredProduceCodeCache
};
/**
* Compiles the specified script (context-independent).
* Cached data as part of the source object can be optionally produced to be
* consumed later to speed up compilation of identical source scripts.
*
* Note that when producing cached data, the source must point to NULL for
* cached data. When consuming cached data, the cached data must have been
* produced by the same version of V8.
*
* \param source Script source code.
* \return Compiled script object (context independent; for running it must be
* bound to a context).
*/
static V8_WARN_UNUSED_RESULT MaybeLocal<UnboundScript> CompileUnboundScript(
Isolate* isolate, Source* source,
CompileOptions options = kNoCompileOptions,
NoCacheReason no_cache_reason = kNoCacheNoReason);
/**
* Compiles the specified script (bound to current context).
*
* \param source Script source code.
* \param pre_data Pre-parsing data, as obtained by ScriptData::PreCompile()
* using pre_data speeds compilation if it's done multiple times.
* Owned by caller, no references are kept when this function returns.
* \return Compiled script object, bound to the context that was active
* when this function was called. When run it will always use this
* context.
*/
static V8_WARN_UNUSED_RESULT MaybeLocal<Script> Compile(
Local<Context> context, Source* source,
CompileOptions options = kNoCompileOptions,
NoCacheReason no_cache_reason = kNoCacheNoReason);
/**
* Returns a task which streams script data into V8, or NULL if the script
* cannot be streamed. The user is responsible for running the task on a
* background thread and deleting it. When ran, the task starts parsing the
* script, and it will request data from the StreamedSource as needed. When
* ScriptStreamingTask::Run exits, all data has been streamed and the script
* can be compiled (see Compile below).
*
* This API allows to start the streaming with as little data as possible, and
* the remaining data (for example, the ScriptOrigin) is passed to Compile.
*/
static ScriptStreamingTask* StartStreamingScript(
Isolate* isolate, StreamedSource* source,
CompileOptions options = kNoCompileOptions);
/**
* Compiles a streamed script (bound to current context).
*
* This can only be called after the streaming has finished
* (ScriptStreamingTask has been run). V8 doesn't construct the source string
* during streaming, so the embedder needs to pass the full source here.
*/
static V8_WARN_UNUSED_RESULT MaybeLocal<Script> Compile(
Local<Context> context, StreamedSource* source,
Local<String> full_source_string, const ScriptOrigin& origin);
/**
* Return a version tag for CachedData for the current V8 version & flags.
*
* This value is meant only for determining whether a previously generated
* CachedData instance is still valid; the tag has no other meaing.
*
* Background: The data carried by CachedData may depend on the exact
* V8 version number or current compiler flags. This means that when
* persisting CachedData, the embedder must take care to not pass in
* data from another V8 version, or the same version with different
* features enabled.
*
* The easiest way to do so is to clear the embedder's cache on any
* such change.
*
* Alternatively, this tag can be stored alongside the cached data and
* compared when it is being used.
*/
static uint32_t CachedDataVersionTag();
/**
* Compile an ES module, returning a Module that encapsulates
* the compiled code.
*
* Corresponds to the ParseModule abstract operation in the
* ECMAScript specification.
*/
static V8_WARN_UNUSED_RESULT MaybeLocal<Module> CompileModule(
Isolate* isolate, Source* source,
CompileOptions options = kNoCompileOptions,
NoCacheReason no_cache_reason = kNoCacheNoReason);
/**
* Compile a function for a given context. This is equivalent to running
*
* with (obj) {
* return function(args) { ... }
* }
*
* It is possible to specify multiple context extensions (obj in the above
* example).
*/
static V8_WARN_UNUSED_RESULT MaybeLocal<Function> CompileFunctionInContext(
Local<Context> context, Source* source, size_t arguments_count,
Local<String> arguments[], size_t context_extension_count,
Local<Object> context_extensions[],
CompileOptions options = kNoCompileOptions,
NoCacheReason no_cache_reason = kNoCacheNoReason,
Local<ScriptOrModule>* script_or_module_out = nullptr);
/**
* Creates and returns code cache for the specified unbound_script.
* This will return nullptr if the script cannot be serialized. The
* CachedData returned by this function should be owned by the caller.
*/
static CachedData* CreateCodeCache(Local<UnboundScript> unbound_script);
/**
* Creates and returns code cache for the specified unbound_module_script.
* This will return nullptr if the script cannot be serialized. The
* CachedData returned by this function should be owned by the caller.
*/
static CachedData* CreateCodeCache(
Local<UnboundModuleScript> unbound_module_script);
/**
* Creates and returns code cache for the specified function that was
* previously produced by CompileFunctionInContext.
* This will return nullptr if the script cannot be serialized. The
* CachedData returned by this function should be owned by the caller.
*/
static CachedData* CreateCodeCacheForFunction(Local<Function> function);
private:
static V8_WARN_UNUSED_RESULT MaybeLocal<UnboundScript> CompileUnboundInternal(
Isolate* isolate, Source* source, CompileOptions options,
NoCacheReason no_cache_reason);
};
/**
* An error message.
*/
class V8_EXPORT Message {
public:
Local<String> Get() const;
/**
* Return the isolate to which the Message belongs.
*/
Isolate* GetIsolate() const;
V8_WARN_UNUSED_RESULT MaybeLocal<String> GetSourceLine(
Local<Context> context) const;
/**
* Returns the origin for the script from where the function causing the
* error originates.
*/
ScriptOrigin GetScriptOrigin() const;
/**
* Returns the resource name for the script from where the function causing
* the error originates.
*/
Local<Value> GetScriptResourceName() const;
/**
* Exception stack trace. By default stack traces are not captured for
* uncaught exceptions. SetCaptureStackTraceForUncaughtExceptions allows
* to change this option.
*/
Local<StackTrace> GetStackTrace() const;
/**
* Returns the number, 1-based, of the line where the error occurred.
*/
V8_WARN_UNUSED_RESULT Maybe<int> GetLineNumber(Local<Context> context) const;
/**
* Returns the index within the script of the first character where
* the error occurred.
*/
int GetStartPosition() const;
/**
* Returns the index within the script of the last character where
* the error occurred.
*/
int GetEndPosition() const;
/**
* Returns the error level of the message.
*/
int ErrorLevel() const;
/**
* Returns the index within the line of the first character where
* the error occurred.
*/
int GetStartColumn() const;
V8_WARN_UNUSED_RESULT Maybe<int> GetStartColumn(Local<Context> context) const;
/**
* Returns the index within the line of the last character where
* the error occurred.
*/
int GetEndColumn() const;
V8_WARN_UNUSED_RESULT Maybe<int> GetEndColumn(Local<Context> context) const;
/**
* Passes on the value set by the embedder when it fed the script from which
* this Message was generated to V8.
*/
bool IsSharedCrossOrigin() const;
bool IsOpaque() const;
// TODO(1245381): Print to a string instead of on a FILE.
static void PrintCurrentStackTrace(Isolate* isolate, FILE* out);
static const int kNoLineNumberInfo = 0;
static const int kNoColumnInfo = 0;
static const int kNoScriptIdInfo = 0;
};
/**
* Representation of a JavaScript stack trace. The information collected is a
* snapshot of the execution stack and the information remains valid after
* execution continues.
*/
class V8_EXPORT StackTrace {
public:
/**
* Flags that determine what information is placed captured for each
* StackFrame when grabbing the current stack trace.
* Note: these options are deprecated and we always collect all available
* information (kDetailed).
*/
enum StackTraceOptions {
kLineNumber = 1,
kColumnOffset = 1 << 1 | kLineNumber,
kScriptName = 1 << 2,
kFunctionName = 1 << 3,
kIsEval = 1 << 4,
kIsConstructor = 1 << 5,
kScriptNameOrSourceURL = 1 << 6,
kScriptId = 1 << 7,
kExposeFramesAcrossSecurityOrigins = 1 << 8,
kOverview = kLineNumber | kColumnOffset | kScriptName | kFunctionName,
kDetailed = kOverview | kIsEval | kIsConstructor | kScriptNameOrSourceURL
};
/**
* Returns a StackFrame at a particular index.
*/
Local<StackFrame> GetFrame(Isolate* isolate, uint32_t index) const;
/**
* Returns the number of StackFrames.
*/
int GetFrameCount() const;
/**
* Grab a snapshot of the current JavaScript execution stack.
*
* \param frame_limit The maximum number of stack frames we want to capture.
* \param options Enumerates the set of things we will capture for each
* StackFrame.
*/
static Local<StackTrace> CurrentStackTrace(
Isolate* isolate, int frame_limit, StackTraceOptions options = kDetailed);
};
/**
* A single JavaScript stack frame.
*/
class V8_EXPORT StackFrame {
public:
/**
* Returns the number, 1-based, of the line for the associate function call.
* This method will return Message::kNoLineNumberInfo if it is unable to
* retrieve the line number, or if kLineNumber was not passed as an option
* when capturing the StackTrace.
*/
int GetLineNumber() const;
/**
* Returns the 1-based column offset on the line for the associated function
* call.
* This method will return Message::kNoColumnInfo if it is unable to retrieve
* the column number, or if kColumnOffset was not passed as an option when
* capturing the StackTrace.
*/
int GetColumn() const;
/**
* Returns the id of the script for the function for this StackFrame.
* This method will return Message::kNoScriptIdInfo if it is unable to
* retrieve the script id, or if kScriptId was not passed as an option when
* capturing the StackTrace.
*/
int GetScriptId() const;
/**
* Returns the name of the resource that contains the script for the
* function for this StackFrame.
*/
Local<String> GetScriptName() const;
/**
* Returns the name of the resource that contains the script for the
* function for this StackFrame or sourceURL value if the script name
* is undefined and its source ends with //# sourceURL=... string or
* deprecated //@ sourceURL=... string.
*/
Local<String> GetScriptNameOrSourceURL() const;
/**
* Returns the name of the function associated with this stack frame.
*/
Local<String> GetFunctionName() const;
/**
* Returns whether or not the associated function is compiled via a call to
* eval().
*/
bool IsEval() const;
/**
* Returns whether or not the associated function is called as a
* constructor via "new".
*/
bool IsConstructor() const;
/**
* Returns whether or not the associated functions is defined in wasm.
*/
bool IsWasm() const;
/**
* Returns whether or not the associated function is defined by the user.
*/
bool IsUserJavaScript() const;
};
// A StateTag represents a possible state of the VM.
enum StateTag {
JS,
GC,
PARSER,
BYTECODE_COMPILER,
COMPILER,
OTHER,
EXTERNAL,
IDLE
};
// A RegisterState represents the current state of registers used
// by the sampling profiler API.
struct RegisterState {
RegisterState() : pc(nullptr), sp(nullptr), fp(nullptr), lr(nullptr) {}
void* pc; // Instruction pointer.
void* sp; // Stack pointer.
void* fp; // Frame pointer.
void* lr; // Link register (or nullptr on platforms without a link register).
};
// The output structure filled up by GetStackSample API function.
struct SampleInfo {
size_t frames_count; // Number of frames collected.
StateTag vm_state; // Current VM state.
void* external_callback_entry; // External callback address if VM is
// executing an external callback.
};
struct MemoryRange {
const void* start = nullptr;
size_t length_in_bytes = 0;
};
struct JSEntryStub {
MemoryRange code;
};
struct UnwindState {
MemoryRange code_range;
MemoryRange embedded_code_range;
JSEntryStub js_entry_stub;
};
/**
* A JSON Parser and Stringifier.
*/
class V8_EXPORT JSON {
public:
/**
* Tries to parse the string |json_string| and returns it as value if
* successful.
*
* \param the context in which to parse and create the value.
* \param json_string The string to parse.
* \return The corresponding value if successfully parsed.
*/
static V8_WARN_UNUSED_RESULT MaybeLocal<Value> Parse(
Local<Context> context, Local<String> json_string);
/**
* Tries to stringify the JSON-serializable object |json_object| and returns
* it as string if successful.
*
* \param json_object The JSON-serializable object to stringify.
* \return The corresponding string if successfully stringified.
*/
static V8_WARN_UNUSED_RESULT MaybeLocal<String> Stringify(
Local<Context> context, Local<Value> json_object,
Local<String> gap = Local<String>());
};
/**
* Value serialization compatible with the HTML structured clone algorithm.
* The format is backward-compatible (i.e. safe to store to disk).
*/
class V8_EXPORT ValueSerializer {
public:
class V8_EXPORT Delegate {
public:
virtual ~Delegate() = default;
/**
* Handles the case where a DataCloneError would be thrown in the structured
* clone spec. Other V8 embedders may throw some other appropriate exception
* type.
*/
virtual void ThrowDataCloneError(Local<String> message) = 0;
/**
* The embedder overrides this method to write some kind of host object, if
* possible. If not, a suitable exception should be thrown and
* Nothing<bool>() returned.
*/
virtual Maybe<bool> WriteHostObject(Isolate* isolate, Local<Object> object);
/**
* Called when the ValueSerializer is going to serialize a
* SharedArrayBuffer object. The embedder must return an ID for the
* object, using the same ID if this SharedArrayBuffer has already been
* serialized in this buffer. When deserializing, this ID will be passed to
* ValueDeserializer::GetSharedArrayBufferFromId as |clone_id|.
*
* If the object cannot be serialized, an
* exception should be thrown and Nothing<uint32_t>() returned.
*/
virtual Maybe<uint32_t> GetSharedArrayBufferId(
Isolate* isolate, Local<SharedArrayBuffer> shared_array_buffer);
virtual Maybe<uint32_t> GetWasmModuleTransferId(
Isolate* isolate, Local<WasmModuleObject> module);
/**
* Allocates memory for the buffer of at least the size provided. The actual
* size (which may be greater or equal) is written to |actual_size|. If no
* buffer has been allocated yet, nullptr will be provided.
*
* If the memory cannot be allocated, nullptr should be returned.
* |actual_size| will be ignored. It is assumed that |old_buffer| is still
* valid in this case and has not been modified.
*
* The default implementation uses the stdlib's `realloc()` function.
*/
virtual void* ReallocateBufferMemory(void* old_buffer, size_t size,
size_t* actual_size);
/**
* Frees a buffer allocated with |ReallocateBufferMemory|.
*
* The default implementation uses the stdlib's `free()` function.
*/
virtual void FreeBufferMemory(void* buffer);
};
explicit ValueSerializer(Isolate* isolate);
ValueSerializer(Isolate* isolate, Delegate* delegate);
~ValueSerializer();
/**
* Writes out a header, which includes the format version.
*/
void WriteHeader();
/**
* Serializes a JavaScript value into the buffer.
*/
V8_WARN_UNUSED_RESULT Maybe<bool> WriteValue(Local<Context> context,
Local<Value> value);
/**
* Returns the stored data (allocated using the delegate's
* ReallocateBufferMemory) and its size. This serializer should not be used
* once the buffer is released. The contents are undefined if a previous write
* has failed. Ownership of the buffer is transferred to the caller.
*/
V8_WARN_UNUSED_RESULT std::pair<uint8_t*, size_t> Release();
/**
* Marks an ArrayBuffer as havings its contents transferred out of band.
* Pass the corresponding ArrayBuffer in the deserializing context to
* ValueDeserializer::TransferArrayBuffer.
*/
void TransferArrayBuffer(uint32_t transfer_id,
Local<ArrayBuffer> array_buffer);
/**
* Indicate whether to treat ArrayBufferView objects as host objects,
* i.e. pass them to Delegate::WriteHostObject. This should not be
* called when no Delegate was passed.
*
* The default is not to treat ArrayBufferViews as host objects.
*/
void SetTreatArrayBufferViewsAsHostObjects(bool mode);
/**
* Write raw data in various common formats to the buffer.
* Note that integer types are written in base-128 varint format, not with a
* binary copy. For use during an override of Delegate::WriteHostObject.
*/
void WriteUint32(uint32_t value);
void WriteUint64(uint64_t value);
void WriteDouble(double value);
void WriteRawBytes(const void* source, size_t length);
ValueSerializer(const ValueSerializer&) = delete;
void operator=(const ValueSerializer&) = delete;
private:
struct PrivateData;
PrivateData* private_;
};
/**
* Deserializes values from data written with ValueSerializer, or a compatible
* implementation.
*/
class V8_EXPORT ValueDeserializer {
public:
class V8_EXPORT Delegate {
public:
virtual ~Delegate() = default;
/**
* The embedder overrides this method to read some kind of host object, if
* possible. If not, a suitable exception should be thrown and
* MaybeLocal<Object>() returned.
*/
virtual MaybeLocal<Object> ReadHostObject(Isolate* isolate);
/**
* Get a WasmModuleObject given a transfer_id previously provided
* by ValueSerializer::GetWasmModuleTransferId
*/
virtual MaybeLocal<WasmModuleObject> GetWasmModuleFromId(
Isolate* isolate, uint32_t transfer_id);
/**
* Get a SharedArrayBuffer given a clone_id previously provided
* by ValueSerializer::GetSharedArrayBufferId
*/
virtual MaybeLocal<SharedArrayBuffer> GetSharedArrayBufferFromId(
Isolate* isolate, uint32_t clone_id);
};
ValueDeserializer(Isolate* isolate, const uint8_t* data, size_t size);
ValueDeserializer(Isolate* isolate, const uint8_t* data, size_t size,
Delegate* delegate);
~ValueDeserializer();
/**
* Reads and validates a header (including the format version).
* May, for example, reject an invalid or unsupported wire format.
*/
V8_WARN_UNUSED_RESULT Maybe<bool> ReadHeader(Local<Context> context);
/**
* Deserializes a JavaScript value from the buffer.
*/
V8_WARN_UNUSED_RESULT MaybeLocal<Value> ReadValue(Local<Context> context);
/**
* Accepts the array buffer corresponding to the one passed previously to
* ValueSerializer::TransferArrayBuffer.
*/
void TransferArrayBuffer(uint32_t transfer_id,
Local<ArrayBuffer> array_buffer);
/**
* Similar to TransferArrayBuffer, but for SharedArrayBuffer.
* The id is not necessarily in the same namespace as unshared ArrayBuffer
* objects.
*/
void TransferSharedArrayBuffer(uint32_t id,
Local<SharedArrayBuffer> shared_array_buffer);
/**
* Must be called before ReadHeader to enable support for reading the legacy
* wire format (i.e., which predates this being shipped).
*
* Don't use this unless you need to read data written by previous versions of
* blink::ScriptValueSerializer.
*/
void SetSupportsLegacyWireFormat(bool supports_legacy_wire_format);
/**
* Expect inline wasm in the data stream (rather than in-memory transfer)
*/
void SetExpectInlineWasm(bool allow_inline_wasm);
/**
* Reads the underlying wire format version. Likely mostly to be useful to
* legacy code reading old wire format versions. Must be called after
* ReadHeader.
*/
uint32_t GetWireFormatVersion() const;
/**
* Reads raw data in various common formats to the buffer.
* Note that integer types are read in base-128 varint format, not with a
* binary copy. For use during an override of Delegate::ReadHostObject.
*/
V8_WARN_UNUSED_RESULT bool ReadUint32(uint32_t* value);
V8_WARN_UNUSED_RESULT bool ReadUint64(uint64_t* value);
V8_WARN_UNUSED_RESULT bool ReadDouble(double* value);
V8_WARN_UNUSED_RESULT bool ReadRawBytes(size_t length, const void** data);
ValueDeserializer(const ValueDeserializer&) = delete;
void operator=(const ValueDeserializer&) = delete;
private:
struct PrivateData;
PrivateData* private_;
};
// --- Value ---
/**
* The superclass of all JavaScript values and objects.
*/
class V8_EXPORT Value : public Data {
public:
/**
* Returns true if this value is the undefined value. See ECMA-262
* 4.3.10.
*/
V8_INLINE bool IsUndefined() const;
/**
* Returns true if this value is the null value. See ECMA-262
* 4.3.11.
*/
V8_INLINE bool IsNull() const;
/**
* Returns true if this value is either the null or the undefined value.
* See ECMA-262
* 4.3.11. and 4.3.12
*/
V8_INLINE bool IsNullOrUndefined() const;
/**
* Returns true if this value is true.
*/
bool IsTrue() const;
/**
* Returns true if this value is false.
*/
bool IsFalse() const;
/**
* Returns true if this value is a symbol or a string.
*/
bool IsName() const;
/**
* Returns true if this value is an instance of the String type.
* See ECMA-262 8.4.
*/
V8_INLINE bool IsString() const;
/**
* Returns true if this value is a symbol.
*/
bool IsSymbol() const;
/**
* Returns true if this value is a function.
*/
bool IsFunction() const;
/**
* Returns true if this value is an array. Note that it will return false for
* an Proxy for an array.
*/
bool IsArray() const;
/**
* Returns true if this value is an object.
*/
bool IsObject() const;
/**
* Returns true if this value is a bigint.
*/
bool IsBigInt() const;
/**
* Returns true if this value is boolean.
*/
bool IsBoolean() const;
/**
* Returns true if this value is a number.
*/
bool IsNumber() const;
/**
* Returns true if this value is external.
*/
bool IsExternal() const;
/**
* Returns true if this value is a 32-bit signed integer.
*/
bool IsInt32() const;
/**
* Returns true if this value is a 32-bit unsigned integer.
*/
bool IsUint32() const;
/**
* Returns true if this value is a Date.
*/
bool IsDate() const;
/**
* Returns true if this value is an Arguments object.
*/
bool IsArgumentsObject() const;
/**
* Returns true if this value is a BigInt object.
*/
bool IsBigIntObject() const;
/**
* Returns true if this value is a Boolean object.
*/
bool IsBooleanObject() const;
/**
* Returns true if this value is a Number object.
*/
bool IsNumberObject() const;
/**
* Returns true if this value is a String object.
*/
bool IsStringObject() const;
/**
* Returns true if this value is a Symbol object.
*/
bool IsSymbolObject() const;
/**
* Returns true if this value is a NativeError.
*/
bool IsNativeError() const;
/**
* Returns true if this value is a RegExp.
*/
bool IsRegExp() const;
/**
* Returns true if this value is an async function.
*/
bool IsAsyncFunction() const;
/**
* Returns true if this value is a Generator function.
*/
bool IsGeneratorFunction() const;
/**
* Returns true if this value is a Generator object (iterator).
*/
bool IsGeneratorObject() const;
/**
* Returns true if this value is a Promise.
*/
bool IsPromise() const;
/**
* Returns true if this value is a Map.
*/
bool IsMap() const;
/**
* Returns true if this value is a Set.
*/
bool IsSet() const;
/**
* Returns true if this value is a Map Iterator.
*/
bool IsMapIterator() const;
/**
* Returns true if this value is a Set Iterator.
*/
bool IsSetIterator() const;
/**
* Returns true if this value is a WeakMap.
*/
bool IsWeakMap() const;
/**
* Returns true if this value is a WeakSet.
*/
bool IsWeakSet() const;
/**
* Returns true if this value is an ArrayBuffer.
*/
bool IsArrayBuffer() const;
/**
* Returns true if this value is an ArrayBufferView.
*/
bool IsArrayBufferView() const;
/**
* Returns true if this value is one of TypedArrays.
*/
bool IsTypedArray() const;
/**
* Returns true if this value is an Uint8Array.
*/
bool IsUint8Array() const;
/**
* Returns true if this value is an Uint8ClampedArray.
*/
bool IsUint8ClampedArray() const;
/**
* Returns true if this value is an Int8Array.
*/
bool IsInt8Array() const;
/**
* Returns true if this value is an Uint16Array.
*/
bool IsUint16Array() const;
/**
* Returns true if this value is an Int16Array.
*/
bool IsInt16Array() const;
/**
* Returns true if this value is an Uint32Array.
*/
bool IsUint32Array() const;
/**
* Returns true if this value is an Int32Array.
*/
bool IsInt32Array() const;
/**
* Returns true if this value is a Float32Array.
*/
bool IsFloat32Array() const;
/**
* Returns true if this value is a Float64Array.
*/
bool IsFloat64Array() const;
/**
* Returns true if this value is a BigInt64Array.
*/
bool IsBigInt64Array() const;
/**
* Returns true if this value is a BigUint64Array.
*/
bool IsBigUint64Array() const;
/**
* Returns true if this value is a DataView.
*/
bool IsDataView() const;
/**
* Returns true if this value is a SharedArrayBuffer.
* This is an experimental feature.
*/
bool IsSharedArrayBuffer() const;
/**
* Returns true if this value is a JavaScript Proxy.
*/
bool IsProxy() const;
bool IsWebAssemblyCompiledModule() const;
/**
* Returns true if the value is a Module Namespace Object.
*/
bool IsModuleNamespaceObject() const;
V8_WARN_UNUSED_RESULT MaybeLocal<BigInt> ToBigInt(
Local<Context> context) const;
V8_WARN_UNUSED_RESULT MaybeLocal<Number> ToNumber(
Local<Context> context) const;
V8_WARN_UNUSED_RESULT MaybeLocal<String> ToString(
Local<Context> context) const;
V8_WARN_UNUSED_RESULT MaybeLocal<String> ToDetailString(
Local<Context> context) const;
V8_WARN_UNUSED_RESULT MaybeLocal<Object> ToObject(
Local<Context> context) const;
V8_WARN_UNUSED_RESULT MaybeLocal<Integer> ToInteger(
Local<Context> context) const;
V8_WARN_UNUSED_RESULT MaybeLocal<Uint32> ToUint32(
Local<Context> context) const;
V8_WARN_UNUSED_RESULT MaybeLocal<Int32> ToInt32(Local<Context> context) const;
Local<Boolean> ToBoolean(Isolate* isolate) const;
/**
* Attempts to convert a string to an array index.
* Returns an empty handle if the conversion fails.
*/
V8_WARN_UNUSED_RESULT MaybeLocal<Uint32> ToArrayIndex(
Local<Context> context) const;
bool BooleanValue(Isolate* isolate) const;
V8_WARN_UNUSED_RESULT Maybe<double> NumberValue(Local<Context> context) const;
V8_WARN_UNUSED_RESULT Maybe<int64_t> IntegerValue(
Local<Context> context) const;
V8_WARN_UNUSED_RESULT Maybe<uint32_t> Uint32Value(
Local<Context> context) const;
V8_WARN_UNUSED_RESULT Maybe<int32_t> Int32Value(Local<Context> context) const;
/** JS == */
V8_WARN_UNUSED_RESULT Maybe<bool> Equals(Local<Context> context,
Local<Value> that) const;
bool StrictEquals(Local<Value> that) const;
bool SameValue(Local<Value> that) const;
template <class T> V8_INLINE static Value* Cast(T* value);
Local<String> TypeOf(Isolate*);
Maybe<bool> InstanceOf(Local<Context> context, Local<Object> object);
private:
V8_INLINE bool QuickIsUndefined() const;
V8_INLINE bool QuickIsNull() const;
V8_INLINE bool QuickIsNullOrUndefined() const;
V8_INLINE bool QuickIsString() const;
bool FullIsUndefined() const;
bool FullIsNull() const;
bool FullIsString() const;
};
/**
* The superclass of primitive values. See ECMA-262 4.3.2.
*/
class V8_EXPORT Primitive : public Value { };
/**
* A primitive boolean value (ECMA-262, 4.3.14). Either the true
* or false value.
*/
class V8_EXPORT Boolean : public Primitive {
public:
bool Value() const;
V8_INLINE static Boolean* Cast(v8::Value* obj);
V8_INLINE static Local<Boolean> New(Isolate* isolate, bool value);
private:
static void CheckCast(v8::Value* obj);
};
/**
* A superclass for symbols and strings.
*/
class V8_EXPORT Name : public Primitive {
public:
/**
* Returns the identity hash for this object. The current implementation
* uses an inline 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();
V8_INLINE static Name* Cast(Value* obj);
private:
static void CheckCast(Value* obj);
};
/**
* A flag describing different modes of string creation.
*
* Aside from performance implications there are no differences between the two
* creation modes.
*/
enum class NewStringType {
/**
* Create a new string, always allocating new storage memory.
*/
kNormal,
/**
* Acts as a hint that the string should be created in the
* old generation heap space and be deduplicated if an identical string
* already exists.
*/
kInternalized
};
/**
* A JavaScript string value (ECMA-262, 4.3.17).
*/
class V8_EXPORT String : public Name {
public:
static constexpr int kMaxLength = internal::kApiTaggedSize == 4
? (1 << 28) - 16
: internal::kSmiMaxValue / 2 - 24;
enum Encoding {
UNKNOWN_ENCODING = 0x1,
TWO_BYTE_ENCODING = 0x0,
ONE_BYTE_ENCODING = 0x8
};
/**
* Returns the number of characters (UTF-16 code units) in this string.
*/
int Length() const;
/**
* Returns the number of bytes in the UTF-8 encoded
* representation of this string.
*/
int Utf8Length(Isolate* isolate) const;
/**
* Returns whether this string is known to contain only one byte data,
* i.e. ISO-8859-1 code points.
* Does not read the string.
* False negatives are possible.
*/
bool IsOneByte() const;
/**
* Returns whether this string contain only one byte data,
* i.e. ISO-8859-1 code points.
* Will read the entire string in some cases.
*/
bool ContainsOnlyOneByte() const;
/**
* Write the contents of the string to an external buffer.
* If no arguments are given, expects the buffer to be large
* enough to hold the entire string and NULL terminator. Copies
* the contents of the string and the NULL terminator into the
* buffer.
*
* WriteUtf8 will not write partial UTF-8 sequences, preferring to stop
* before the end of the buffer.
*
* Copies up to length characters into the output buffer.
* Only null-terminates if there is enough space in the buffer.
*
* \param buffer The buffer into which the string will be copied.
* \param start The starting position within the string at which
* copying begins.
* \param length The number of characters to copy from the string. For
* WriteUtf8 the number of bytes in the buffer.
* \param nchars_ref The number of characters written, can be NULL.
* \param options Various options that might affect performance of this or
* subsequent operations.
* \return The number of characters copied to the buffer excluding the null
* terminator. For WriteUtf8: The number of bytes copied to the buffer
* including the null terminator (if written).
*/
enum WriteOptions {
NO_OPTIONS = 0,
HINT_MANY_WRITES_EXPECTED = 1,
NO_NULL_TERMINATION = 2,
PRESERVE_ONE_BYTE_NULL = 4,
// Used by WriteUtf8 to replace orphan surrogate code units with the
// unicode replacement character. Needs to be set to guarantee valid UTF-8
// output.
REPLACE_INVALID_UTF8 = 8
};
// 16-bit character codes.
int Write(Isolate* isolate, uint16_t* buffer, int start = 0, int length = -1,
int options = NO_OPTIONS) const;
// One byte characters.
int WriteOneByte(Isolate* isolate, uint8_t* buffer, int start = 0,
int length = -1, int options = NO_OPTIONS) const;
// UTF-8 encoded characters.
int WriteUtf8(Isolate* isolate, char* buffer, int length = -1,
int* nchars_ref = nullptr, int options = NO_OPTIONS) const;
/**
* A zero length string.
*/
V8_INLINE static Local<String> Empty(Isolate* isolate);
/**
* Returns true if the string is external
*/
bool IsExternal() const;
/**
* Returns true if the string is both external and one-byte.
*/
bool IsExternalOneByte() const;
class V8_EXPORT ExternalStringResourceBase { // NOLINT
public:
virtual ~ExternalStringResourceBase() = default;
/**
* If a string is cacheable, the value returned by
* ExternalStringResource::data() may be cached, otherwise it is not
* expected to be stable beyond the current top-level task.
*/
virtual bool IsCacheable() const { return true; }
// Disallow copying and assigning.
ExternalStringResourceBase(const ExternalStringResourceBase&) = delete;
void operator=(const ExternalStringResourceBase&) = delete;
protected:
ExternalStringResourceBase() = default;
/**
* Internally V8 will call this Dispose method when the external string
* resource is no longer needed. The default implementation will use the
* delete operator. This method can be overridden in subclasses to
* control how allocated external string resources are disposed.
*/
virtual void Dispose() { delete this; }
/**
* For a non-cacheable string, the value returned by
* |ExternalStringResource::data()| has to be stable between |Lock()| and
* |Unlock()|, that is the string must behave as is |IsCacheable()| returned
* true.
*
* These two functions must be thread-safe, and can be called from anywhere.
* They also must handle lock depth, in the sense that each can be called
* several times, from different threads, and unlocking should only happen
* when the balance of Lock() and Unlock() calls is 0.
*/
virtual void Lock() const {}
/**
* Unlocks the string.
*/
virtual void Unlock() const {}
private:
friend class internal::ExternalString;
friend class v8::String;
friend class internal::ScopedExternalStringLock;
};
/**
* An ExternalStringResource is a wrapper around a two-byte string
* buffer that resides outside V8's heap. Implement an
* ExternalStringResource to manage the life cycle of the underlying
* buffer. Note that the string data must be immutable.
*/
class V8_EXPORT ExternalStringResource
: public ExternalStringResourceBase {
public:
/**
* Override the destructor to manage the life cycle of the underlying
* buffer.
*/
~ExternalStringResource() override = default;
/**
* The string data from the underlying buffer.
*/
virtual const uint16_t* data() const = 0;
/**
* The length of the string. That is, the number of two-byte characters.
*/
virtual size_t length() const = 0;
protected:
ExternalStringResource() = default;
};
/**
* An ExternalOneByteStringResource is a wrapper around an one-byte
* string buffer that resides outside V8's heap. Implement an
* ExternalOneByteStringResource to manage the life cycle of the
* underlying buffer. Note that the string data must be immutable
* and that the data must be Latin-1 and not UTF-8, which would require
* special treatment internally in the engine and do not allow efficient
* indexing. Use String::New or convert to 16 bit data for non-Latin1.
*/
class V8_EXPORT ExternalOneByteStringResource
: public ExternalStringResourceBase {
public:
/**
* Override the destructor to manage the life cycle of the underlying
* buffer.
*/
~ExternalOneByteStringResource() override = default;
/** The string data from the underlying buffer.*/
virtual const char* data() const = 0;
/** The number of Latin-1 characters in the string.*/
virtual size_t length() const = 0;
protected:
ExternalOneByteStringResource() = default;
};
/**
* If the string is an external string, return the ExternalStringResourceBase
* regardless of the encoding, otherwise return NULL. The encoding of the
* string is returned in encoding_out.
*/
V8_INLINE ExternalStringResourceBase* GetExternalStringResourceBase(
Encoding* encoding_out) const;
/**
* Get the ExternalStringResource for an external string. Returns
* NULL if IsExternal() doesn't return true.
*/
V8_INLINE ExternalStringResource* GetExternalStringResource() const;
/**
* Get the ExternalOneByteStringResource for an external one-byte string.
* Returns NULL if IsExternalOneByte() doesn't return true.
*/
const ExternalOneByteStringResource* GetExternalOneByteStringResource() const;
V8_INLINE static String* Cast(v8::Value* obj);
/** Allocates a new string from UTF-8 data. Only returns an empty value when
* length > kMaxLength. **/
static V8_WARN_UNUSED_RESULT MaybeLocal<String> NewFromUtf8(
Isolate* isolate, const char* data,
NewStringType type = NewStringType::kNormal, int length = -1);
/** Allocates a new string from Latin-1 data. Only returns an empty value
* when length > kMaxLength. **/
static V8_WARN_UNUSED_RESULT MaybeLocal<String> NewFromOneByte(
Isolate* isolate, const uint8_t* data,
NewStringType type = NewStringType::kNormal, int length = -1);
/** Allocates a new string from UTF-16 data. Only returns an empty value when
* length > kMaxLength. **/
static V8_WARN_UNUSED_RESULT MaybeLocal<String> NewFromTwoByte(
Isolate* isolate, const uint16_t* data,
NewStringType type = NewStringType::kNormal, int length = -1);
/**
* Creates a new string by concatenating the left and the right strings
* passed in as parameters.
*/
static Local<String> Concat(Isolate* isolate, Local<String> left,
Local<String> right);
/**
* Creates a new external string using the data defined in the given
* resource. When the external string is no longer live on V8's heap the
* resource will be disposed by calling its Dispose method. The caller of
* this function should not otherwise delete or modify the resource. Neither
* should the underlying buffer be deallocated or modified except through the
* destructor of the external string resource.
*/
static V8_WARN_UNUSED_RESULT MaybeLocal<String> NewExternalTwoByte(
Isolate* isolate, ExternalStringResource* resource);
/**
* Associate an external string resource with this string by transforming it
* in place so that existing references to this string in the JavaScript heap
* will use the external string resource. The external string resource's
* character contents need to be equivalent to this string.
* Returns true if the string has been changed to be an external string.
* The string is not modified if the operation fails. See NewExternal for
* information on the lifetime of the resource.
*/
bool MakeExternal(ExternalStringResource* resource);
/**
* Creates a new external string using the one-byte data defined in the given
* resource. When the external string is no longer live on V8's heap the
* resource will be disposed by calling its Dispose method. The caller of
* this function should not otherwise delete or modify the resource. Neither
* should the underlying buffer be deallocated or modified except through the
* destructor of the external string resource.
*/
static V8_WARN_UNUSED_RESULT MaybeLocal<String> NewExternalOneByte(
Isolate* isolate, ExternalOneByteStringResource* resource);
/**
* Associate an external string resource with this string by transforming it
* in place so that existing references to this string in the JavaScript heap
* will use the external string resource. The external string resource's
* character contents need to be equivalent to this string.
* Returns true if the string has been changed to be an external string.
* The string is not modified if the operation fails. See NewExternal for
* information on the lifetime of the resource.
*/
bool MakeExternal(ExternalOneByteStringResource* resource);
/**
* Returns true if this string can be made external.
*/
bool CanMakeExternal();
/**
* Returns true if the strings values are equal. Same as JS ==/===.
*/
bool StringEquals(Local<String> str);
/**
* Converts an object to a UTF-8-encoded character array. Useful if
* you want to print the object. If conversion to a string fails
* (e.g. due to an exception in the toString() method of the object)
* then the length() method returns 0 and the * operator returns
* NULL.
*/
class V8_EXPORT Utf8Value {
public:
Utf8Value(Isolate* isolate, Local<v8::Value> obj);
~Utf8Value();
char* operator*() { return str_; }
const char* operator*() const { return str_; }
int length() const { return length_; }
// Disallow copying and assigning.
Utf8Value(const Utf8Value&) = delete;
void operator=(const Utf8Value&) = delete;
private:
char* str_;
int length_;
};
/**
* Converts an object to a two-byte (UTF-16-encoded) string.
* If conversion to a string fails (eg. due to an exception in the toString()
* method of the object) then the length() method returns 0 and the * operator
* returns NULL.
*/
class V8_EXPORT Value {
public:
Value(Isolate* isolate, Local<v8::Value> obj);
~Value();
uint16_t* operator*() { return str_; }
const uint16_t* operator*() const { return str_; }
int length() const { return length_; }
// Disallow copying and assigning.
Value(const Value&) = delete;
void operator=(const Value&) = delete;
private:
uint16_t* str_;
int length_;
};
private:
void VerifyExternalStringResourceBase(ExternalStringResourceBase* v,
Encoding encoding) const;
void VerifyExternalStringResource(ExternalStringResource* val) const;
ExternalStringResource* GetExternalStringResourceSlow() const;
ExternalStringResourceBase* GetExternalStringResourceBaseSlow(
String::Encoding* encoding_out) const;
static void CheckCast(v8::Value* obj);
};
/**
* A JavaScript symbol (ECMA-262 edition 6)
*/
class V8_EXPORT Symbol : public Name {
public:
/**
* Returns the print name string of the symbol, or undefined if none.
*/
Local<Value> Name() const;
/**
* Create a symbol. If name is not empty, it will be used as the description.
*/
static Local<Symbol> New(Isolate* isolate,
Local<String> name = Local<String>());
/**
* Access global symbol registry.
* Note that 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.
*/
static Local<Symbol> For(Isolate *isolate, Local<String> name);
/**
* Retrieve a global symbol. Similar to |For|, but using a separate
* registry that is not accessible by (and cannot clash with) JavaScript code.
*/
static Local<Symbol> ForApi(Isolate *isolate, Local<String> name);
// Well-known symbols
static Local<Symbol> GetAsyncIterator(Isolate* isolate);
static Local<Symbol> GetHasInstance(Isolate* isolate);
static Local<Symbol> GetIsConcatSpreadable(Isolate* isolate);
static Local<Symbol> GetIterator(Isolate* isolate);
static Local<Symbol> GetMatch(Isolate* isolate);
static Local<Symbol> GetReplace(Isolate* isolate);
static Local<Symbol> GetSearch(Isolate* isolate);
static Local<Symbol> GetSplit(Isolate* isolate);
static Local<Symbol> GetToPrimitive(Isolate* isolate);
static Local<Symbol> GetToStringTag(Isolate* isolate);
static Local<Symbol> GetUnscopables(Isolate* isolate);
V8_INLINE static Symbol* Cast(Value* obj);
private:
Symbol();
static void CheckCast(Value* obj);
};
/**
* 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<Value> Name() const;
/**
* Create a private symbol. If name is not empty, it will be the description.
*/
static Local<Private> New(Isolate* isolate,
Local<String> name = Local<String>());
/**
* 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<Private> ForApi(Isolate* isolate, Local<String> name);
V8_INLINE static Private* Cast(Data* data);
private:
Private();
static void CheckCast(Data* that);
};
/**
* A JavaScript number value (ECMA-262, 4.3.20)
*/
class V8_EXPORT Number : public Primitive {
public:
double Value() const;
static Local<Number> New(Isolate* isolate, double value);
V8_INLINE static Number* Cast(v8::Value* obj);
private:
Number();
static void CheckCast(v8::Value* obj);
};
/**
* A JavaScript value representing a signed integer.
*/
class V8_EXPORT Integer : public Number {
public:
static Local<Integer> New(Isolate* isolate, int32_t value);
static Local<Integer> NewFromUnsigned(Isolate* isolate, uint32_t value);
int64_t Value() const;
V8_INLINE static Integer* Cast(v8::Value* obj);
private:
Integer();
static void CheckCast(v8::Value* obj);
};
/**
* A JavaScript value representing a 32-bit signed integer.
*/
class V8_EXPORT Int32 : public Integer {
public:
int32_t Value() const;
V8_INLINE static Int32* Cast(v8::Value* obj);
private:
Int32();
static void CheckCast(v8::Value* obj);
};
/**
* A JavaScript value representing a 32-bit unsigned integer.
*/
class V8_EXPORT Uint32 : public Integer {
public:
uint32_t Value() const;
V8_INLINE static Uint32* Cast(v8::Value* obj);
private:
Uint32();
static void CheckCast(v8::Value* obj);
};
/**
* A JavaScript BigInt value (https://tc39.github.io/proposal-bigint)
*/
class V8_EXPORT BigInt : public Primitive {
public:
static Local<BigInt> New(Isolate* isolate, int64_t value);
static Local<BigInt> NewFromUnsigned(Isolate* isolate, uint64_t value);
/**
* Creates a new BigInt object using a specified sign bit and a
* specified list of digits/words.
* The resulting number is calculated as:
*
* (-1)^sign_bit * (words[0] * (2^64)^0 + words[1] * (2^64)^1 + ...)
*/
static MaybeLocal<BigInt> NewFromWords(Local<Context> context, int sign_bit,
int word_count, const uint64_t* words);
/**
* Returns the value of this BigInt as an unsigned 64-bit integer.
* If `lossless` is provided, it will reflect whether the return value was
* truncated or wrapped around. In particular, it is set to `false` if this
* BigInt is negative.
*/
uint64_t Uint64Value(bool* lossless = nullptr) const;
/**
* Returns the value of this BigInt as a signed 64-bit integer.
* If `lossless` is provided, it will reflect whether this BigInt was
* truncated or not.
*/
int64_t Int64Value(bool* lossless = nullptr) const;
/**
* Returns the number of 64-bit words needed to store the result of
* ToWordsArray().
*/
int WordCount() const;
/**
* Writes the contents of this BigInt to a specified memory location.
* `sign_bit` must be provided and will be set to 1 if this BigInt is
* negative.
* `*word_count` has to be initialized to the length of the `words` array.
* Upon return, it will be set to the actual number of words that would
* be needed to store this BigInt (i.e. the return value of `WordCount()`).
*/
void ToWordsArray(int* sign_bit, int* word_count, uint64_t* words) const;
V8_INLINE static BigInt* Cast(v8::Value* obj);
private:
BigInt();
static void CheckCast(v8::Value* obj);
};
/**
* 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 property. See Object and ObjectTemplate's
* method SetAccessor.
*/
typedef void (*AccessorGetterCallback)(
Local<String> property,
const PropertyCallbackInfo<Value>& info);
typedef void (*AccessorNameGetterCallback)(
Local<Name> property,
const PropertyCallbackInfo<Value>& info);
typedef void (*AccessorSetterCallback)(
Local<String> property,
Local<Value> value,
const PropertyCallbackInfo<void>& info);
typedef void (*AccessorNameSetterCallback)(
Local<Name> property,
Local<Value> value,
const PropertyCallbackInfo<void>& 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.
*
* TODO(dcarney): Remove PROHIBITS_OVERWRITING as it is now unused.
*/
enum AccessControl {
DEFAULT = 0,
ALL_CAN_READ = 1,
ALL_CAN_WRITE = 1 << 1,
PROHIBITS_OVERWRITING = 1 << 2
};
/**
* Property filter bits. They can be or'ed to build a composite filter.
*/
enum PropertyFilter {
ALL_PROPERTIES = 0,
ONLY_WRITABLE =