// 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 V8_H_ #define V8_H_ #include #include #include #include "v8config.h" // We reserve the V8_* prefix for macros defined in V8 public API and // assume there are no name conflicts with the embedder's code. #ifdef V8_OS_WIN // Setup for Windows DLL export/import. When building the V8 DLL the // BUILDING_V8_SHARED needs to be defined. When building a program which uses // the V8 DLL USING_V8_SHARED needs to be defined. When either building the V8 // static library or building a program which uses the V8 static library neither // BUILDING_V8_SHARED nor USING_V8_SHARED should be defined. #if defined(BUILDING_V8_SHARED) && defined(USING_V8_SHARED) #error both BUILDING_V8_SHARED and USING_V8_SHARED are set - please check the\ build configuration to ensure that at most one of these is set #endif #ifdef BUILDING_V8_SHARED # define V8_EXPORT __declspec(dllexport) #elif USING_V8_SHARED # define V8_EXPORT __declspec(dllimport) #else # define V8_EXPORT #endif // BUILDING_V8_SHARED #else // V8_OS_WIN // Setup for Linux shared library export. #if V8_HAS_ATTRIBUTE_VISIBILITY && defined(V8_SHARED) # ifdef BUILDING_V8_SHARED # define V8_EXPORT __attribute__ ((visibility("default"))) # else # define V8_EXPORT # endif #else # define V8_EXPORT #endif #endif // V8_OS_WIN /** * The v8 JavaScript engine. */ namespace v8 { class AccessorSignature; class Array; class Boolean; class BooleanObject; class Context; class CpuProfiler; class Data; class Date; class DeclaredAccessorDescriptor; class External; class Function; class FunctionTemplate; class HeapProfiler; class ImplementationUtilities; class Int32; class Integer; class Isolate; class Name; class Number; class NumberObject; class Object; class ObjectOperationDescriptor; class ObjectTemplate; class Platform; class Primitive; class Promise; class RawOperationDescriptor; class Script; class Signature; class StackFrame; class StackTrace; class String; class StringObject; class Symbol; class SymbolObject; class Private; class Uint32; class Utils; class Value; template class Handle; template class Local; template class Eternal; template class NonCopyablePersistentTraits; template class PersistentBase; template > class Persistent; template class UniquePersistent; template class PersistentValueMap; template class PersistentValueVector; template class WeakCallbackObject; class FunctionTemplate; class ObjectTemplate; class Data; template class FunctionCallbackInfo; template class PropertyCallbackInfo; class StackTrace; class StackFrame; class Isolate; class DeclaredAccessorDescriptor; class ObjectOperationDescriptor; class RawOperationDescriptor; class CallHandlerHelper; class EscapableHandleScope; template class ReturnValue; namespace internal { class Arguments; class Heap; class HeapObject; class Isolate; class Object; struct StreamedSource; template class CustomArguments; class PropertyCallbackArguments; class FunctionCallbackArguments; class GlobalHandles; } /** * General purpose unique identifier. */ class UniqueId { public: explicit UniqueId(intptr_t data) : data_(data) {} bool operator==(const UniqueId& other) const { return data_ == other.data_; } bool operator!=(const UniqueId& other) const { return data_ != other.data_; } bool operator<(const UniqueId& other) const { return data_ < other.data_; } private: intptr_t data_; }; // --- Handles --- #define TYPE_CHECK(T, S) \ while (false) { \ *(static_cast(0)) = static_cast(0); \ } /** * An object reference managed by the v8 garbage collector. * * All objects returned from v8 have to be tracked by the garbage * collector so that it knows that the objects are still alive. Also, * because the garbage collector may move objects, it is unsafe to * point directly to an object. Instead, all objects are stored in * handles which are known by the garbage collector and updated * whenever an object moves. Handles should always be passed by value * (except in cases like out-parameters) and they should never be * allocated on the heap. * * There are two types of handles: local and persistent handles. * Local handles are light-weight and transient and typically used in * local operations. They are managed by HandleScopes. 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 Handle); 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 Handle { public: /** * Creates an empty handle. */ V8_INLINE Handle() : val_(0) {} /** * Creates a handle for the contents of the specified handle. This * constructor allows you to pass handles as arguments by value and * to assign between handles. However, if you try to assign between * incompatible handles, for instance from a Handle to a * Handle it will cause a compile-time error. Assigning * between compatible handles, for instance assigning a * Handle to a variable declared as Handle, is legal * because String is a subclass of Value. */ template V8_INLINE Handle(Handle that) : val_(reinterpret_cast(*that)) { /** * This check fails when trying to convert between incompatible * handles. For example, converting from a Handle to a * Handle. */ TYPE_CHECK(T, S); } /** * Returns true if the handle is empty. */ V8_INLINE bool IsEmpty() const { return val_ == 0; } /** * Sets the handle to be empty. IsEmpty() will then return true. */ V8_INLINE void Clear() { val_ = 0; } V8_INLINE T* operator->() const { return val_; } V8_INLINE T* operator*() const { return val_; } /** * Checks whether two handles are the same. * Returns true if both are empty, or if the objects * to which they refer are identical. * The handles' references are not checked. */ template V8_INLINE bool operator==(const Handle& that) const { internal::Object** a = reinterpret_cast(this->val_); internal::Object** b = reinterpret_cast(that.val_); if (a == 0) return b == 0; if (b == 0) return false; return *a == *b; } template V8_INLINE bool operator==( const PersistentBase& that) const { internal::Object** a = reinterpret_cast(this->val_); internal::Object** b = reinterpret_cast(that.val_); if (a == 0) return b == 0; if (b == 0) return false; return *a == *b; } /** * Checks whether two handles are different. * Returns true if only one of the handles is empty, or if * the objects to which they refer are different. * The handles' references are not checked. */ template V8_INLINE bool operator!=(const Handle& that) const { return !operator==(that); } template V8_INLINE bool operator!=( const Persistent& that) const { return !operator==(that); } template V8_INLINE static Handle Cast(Handle 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 Handle(); #endif return Handle(T::Cast(*that)); } template V8_INLINE Handle As() { return Handle::Cast(*this); } V8_INLINE static Handle New(Isolate* isolate, Handle that) { return New(isolate, that.val_); } V8_INLINE static Handle New(Isolate* isolate, const PersistentBase& that) { return New(isolate, that.val_); } private: friend class Utils; template friend class Persistent; template friend class PersistentBase; template friend class Handle; template friend class Local; template friend class FunctionCallbackInfo; template friend class PropertyCallbackInfo; template friend class internal::CustomArguments; friend Handle Undefined(Isolate* isolate); friend Handle Null(Isolate* isolate); friend Handle True(Isolate* isolate); friend Handle False(Isolate* isolate); friend class Context; friend class HandleScope; friend class Object; friend class Private; /** * Creates a new handle for the specified value. */ V8_INLINE explicit Handle(T* val) : val_(val) {} V8_INLINE static Handle New(Isolate* isolate, T* that); T* val_; }; /** * A light-weight stack-allocated object handle. All operations * that return objects from within v8 return them in local handles. They * are created within HandleScopes, and all local handles allocated within a * handle scope are destroyed when the handle scope is destroyed. Hence it * is not necessary to explicitly deallocate local handles. */ template class Local : public Handle { public: V8_INLINE Local(); template V8_INLINE Local(Local that) : Handle(reinterpret_cast(*that)) { /** * This check fails when trying to convert between incompatible * handles. For example, converting from a Handle to a * Handle. */ TYPE_CHECK(T, S); } template V8_INLINE static Local Cast(Local that) { #ifdef V8_ENABLE_CHECKS // If we're going to perform the type check then we have to check // that the handle isn't empty before doing the checked cast. if (that.IsEmpty()) return Local(); #endif return Local(T::Cast(*that)); } template V8_INLINE Local(Handle that) : Handle(reinterpret_cast(*that)) { TYPE_CHECK(T, S); } template V8_INLINE Local As() { return Local::Cast(*this); } /** * Create a local handle for the content of another handle. * The referee is kept alive by the local handle even when * the original handle is destroyed/disposed. */ V8_INLINE static Local New(Isolate* isolate, Handle that); V8_INLINE static Local New(Isolate* isolate, const PersistentBase& that); private: friend class Utils; template friend class Eternal; template friend class PersistentBase; template friend class Persistent; template friend class Handle; template friend class Local; template friend class FunctionCallbackInfo; template friend class PropertyCallbackInfo; friend class String; friend class Object; friend class Context; template friend class internal::CustomArguments; friend class HandleScope; friend class EscapableHandleScope; template friend class PersistentValueMap; template friend class PersistentValueVector; template V8_INLINE Local(S* that) : Handle(that) { } V8_INLINE static Local New(Isolate* isolate, T* that); }; // Eternal handles are set-once handles that live for the life of the isolate. template class Eternal { public: V8_INLINE Eternal() : index_(kInitialValue) { } template V8_INLINE Eternal(Isolate* isolate, Local handle) : index_(kInitialValue) { Set(isolate, handle); } // Can only be safely called if already set. V8_INLINE Local Get(Isolate* isolate); V8_INLINE bool IsEmpty() { return index_ == kInitialValue; } template V8_INLINE void Set(Isolate* isolate, Local handle); private: static const int kInitialValue = -1; int index_; }; template class WeakCallbackData { public: typedef void (*Callback)(const WeakCallbackData& data); V8_INLINE Isolate* GetIsolate() const { return isolate_; } V8_INLINE Local GetValue() const { return handle_; } V8_INLINE P* GetParameter() const { return parameter_; } private: friend class internal::GlobalHandles; WeakCallbackData(Isolate* isolate, Local handle, P* parameter) : isolate_(isolate), handle_(handle), parameter_(parameter) { } Isolate* isolate_; Local handle_; P* parameter_; }; /** * 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. * * A persistent handle contains a reference to a storage cell within * the v8 engine which holds an object value and which is updated by * the garbage collector whenever the object is moved. A new storage * cell can be created using the constructor or PersistentBase::Reset and * existing handles can be disposed using PersistentBase::Reset. * */ template class PersistentBase { public: /** * If non-empty, destroy the underlying storage cell * IsEmpty() will return true after this call. */ V8_INLINE void Reset(); /** * If non-empty, destroy the underlying storage cell * and create a new one with the contents of other if other is non empty */ template V8_INLINE void Reset(Isolate* isolate, const Handle& other); /** * If non-empty, destroy the underlying storage cell * and create a new one with the contents of other if other is non empty */ template V8_INLINE void Reset(Isolate* isolate, const PersistentBase& other); V8_INLINE bool IsEmpty() const { return val_ == 0; } template V8_INLINE bool operator==(const PersistentBase& that) const { internal::Object** a = reinterpret_cast(this->val_); internal::Object** b = reinterpret_cast(that.val_); if (a == 0) return b == 0; if (b == 0) return false; return *a == *b; } template V8_INLINE bool operator==(const Handle& that) const { internal::Object** a = reinterpret_cast(this->val_); internal::Object** b = reinterpret_cast(that.val_); if (a == 0) return b == 0; if (b == 0) return false; return *a == *b; } template V8_INLINE bool operator!=(const PersistentBase& that) const { return !operator==(that); } template V8_INLINE bool operator!=(const Handle& that) const { return !operator==(that); } /** * Install a finalization callback on this object. * NOTE: There is no guarantee as to *when* or even *if* the callback is * invoked. The invocation is performed solely on a best effort basis. * As always, GC-based finalization should *not* be relied upon for any * critical form of resource management! */ template V8_INLINE void SetWeak( P* parameter, typename WeakCallbackData::Callback callback); template V8_INLINE void SetWeak( P* parameter, typename WeakCallbackData::Callback callback); template V8_INLINE P* ClearWeak(); // TODO(dcarney): remove this. V8_INLINE void ClearWeak() { ClearWeak(); } /** * Marks the reference to this object independent. Garbage collector is free * to ignore any object groups containing this object. Weak callback for an * independent handle should not assume that it will be preceded by a global * GC prologue callback or followed by a global GC epilogue callback. */ V8_INLINE void MarkIndependent(); /** * Marks the reference to this object partially dependent. Partially dependent * handles only depend on other partially dependent handles and these * dependencies are provided through object groups. It provides a way to build * smaller object groups for young objects that represent only a subset of all * external dependencies. This mark is automatically cleared after each * garbage collection. */ V8_INLINE void MarkPartiallyDependent(); V8_INLINE bool IsIndependent() const; /** Checks if the handle holds the only reference to an object. */ V8_INLINE bool IsNearDeath() const; /** Returns true if the handle's reference is weak. */ V8_INLINE bool IsWeak() const; /** * Assigns a wrapper class ID to the handle. See RetainedObjectInfo interface * description in v8-profiler.h for details. */ 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; private: friend class Isolate; friend class Utils; template friend class Handle; template friend class Local; template friend class Persistent; template friend class UniquePersistent; template friend class PersistentBase; template friend class ReturnValue; template friend class PersistentValueMap; template friend class PersistentValueVector; friend class Object; explicit V8_INLINE PersistentBase(T* val) : val_(val) {} PersistentBase(PersistentBase& other); // NOLINT void operator=(PersistentBase&); V8_INLINE static T* New(Isolate* isolate, T* that); T* val_; }; /** * Default traits for Persistent. This class does not allow * use of the copy constructor or assignment operator. * At present kResetInDestructor is not set, but that will change in a future * version. */ template class NonCopyablePersistentTraits { public: typedef Persistent > NonCopyablePersistent; static const bool kResetInDestructor = false; template V8_INLINE static void Copy(const Persistent& source, NonCopyablePersistent* dest) { Uncompilable(); } // TODO(dcarney): come up with a good compile error here. template V8_INLINE static void Uncompilable() { TYPE_CHECK(O, Primitive); } }; /** * Helper class traits to allow copying and assignment of Persistent. * This will clone the contents of storage cell, but not any of the flags, etc. */ template struct CopyablePersistentTraits { typedef Persistent > CopyablePersistent; static const bool kResetInDestructor = true; template static V8_INLINE void Copy(const Persistent& source, CopyablePersistent* dest) { // do nothing, just allow copy } }; /** * A PersistentBase which allows copy and assignment. * * Copy, assignment and destructor bevavior is controlled by the traits * class M. * * Note: Persistent class hierarchy is subject to future changes. */ template class Persistent : public PersistentBase { public: /** * A Persistent with no storage cell. */ V8_INLINE Persistent() : PersistentBase(0) { } /** * Construct a Persistent from a Handle. * When the Handle is non-empty, a new storage cell is created * pointing to the same object, and no flags are set. */ template V8_INLINE Persistent(Isolate* isolate, Handle that) : PersistentBase(PersistentBase::New(isolate, *that)) { TYPE_CHECK(T, S); } /** * Construct a Persistent from a Persistent. * When the Persistent is non-empty, a new storage cell is created * pointing to the same object, and no flags are set. */ template V8_INLINE Persistent(Isolate* isolate, const Persistent& that) : PersistentBase(PersistentBase::New(isolate, *that)) { TYPE_CHECK(T, S); } /** * The copy constructors and assignment operator create a Persistent * exactly as the Persistent constructor, but the Copy function from the * traits class is called, allowing the setting of flags based on the * copied Persistent. */ V8_INLINE Persistent(const Persistent& that) : PersistentBase(0) { Copy(that); } template V8_INLINE Persistent(const Persistent& that) : PersistentBase(0) { Copy(that); } V8_INLINE Persistent& operator=(const Persistent& that) { // NOLINT Copy(that); return *this; } template V8_INLINE Persistent& operator=(const Persistent& that) { // NOLINT Copy(that); return *this; } /** * The destructor will dispose the Persistent based on the * kResetInDestructor flags in the traits class. Since not calling dispose * can result in a memory leak, it is recommended to always set this flag. */ V8_INLINE ~Persistent() { if (M::kResetInDestructor) this->Reset(); } // TODO(dcarney): this is pretty useless, fix or remove template V8_INLINE static Persistent& Cast(Persistent& that) { // NOLINT #ifdef V8_ENABLE_CHECKS // If we're going to perform the type check then we have to check // that the handle isn't empty before doing the checked cast. if (!that.IsEmpty()) T::Cast(*that); #endif return reinterpret_cast&>(that); } // TODO(dcarney): this is pretty useless, fix or remove template V8_INLINE Persistent& As() { // NOLINT return Persistent::Cast(*this); } private: friend class Isolate; friend class Utils; template friend class Handle; template friend class Local; template friend class Persistent; template friend class ReturnValue; template V8_INLINE Persistent(S* that) : PersistentBase(that) { } V8_INLINE T* operator*() const { return this->val_; } template V8_INLINE void Copy(const Persistent& that); }; /** * A PersistentBase which has move semantics. * * Note: Persistent class hierarchy is subject to future changes. */ template class UniquePersistent : public PersistentBase { struct RValue { V8_INLINE explicit RValue(UniquePersistent* obj) : object(obj) {} UniquePersistent* object; }; public: /** * A UniquePersistent with no storage cell. */ V8_INLINE UniquePersistent() : PersistentBase(0) { } /** * Construct a UniquePersistent from a Handle. * When the Handle is non-empty, a new storage cell is created * pointing to the same object, and no flags are set. */ template V8_INLINE UniquePersistent(Isolate* isolate, Handle that) : PersistentBase(PersistentBase::New(isolate, *that)) { TYPE_CHECK(T, S); } /** * Construct a UniquePersistent from a PersistentBase. * When the Persistent is non-empty, a new storage cell is created * pointing to the same object, and no flags are set. */ template V8_INLINE UniquePersistent(Isolate* isolate, const PersistentBase& that) : PersistentBase(PersistentBase::New(isolate, that.val_)) { TYPE_CHECK(T, S); } /** * Move constructor. */ V8_INLINE UniquePersistent(RValue rvalue) : PersistentBase(rvalue.object->val_) { rvalue.object->val_ = 0; } V8_INLINE ~UniquePersistent() { this->Reset(); } /** * Move via assignment. */ template V8_INLINE UniquePersistent& operator=(UniquePersistent rhs) { TYPE_CHECK(T, S); this->Reset(); this->val_ = rhs.val_; rhs.val_ = 0; return *this; } /** * Cast operator for moves. */ V8_INLINE operator RValue() { return RValue(this); } /** * Pass allows returning uniques from functions, etc. */ UniquePersistent Pass() { return UniquePersistent(RValue(this)); } private: UniquePersistent(UniquePersistent&); void operator=(UniquePersistent&); }; /** * 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: HandleScope(Isolate* isolate); ~HandleScope(); /** * Counts the number of allocated handles. */ static int NumberOfHandles(Isolate* isolate); V8_INLINE Isolate* GetIsolate() const { return reinterpret_cast(isolate_); } protected: V8_INLINE HandleScope() {} void Initialize(Isolate* isolate); static internal::Object** CreateHandle(internal::Isolate* isolate, internal::Object* value); private: // Uses heap_object to obtain the current Isolate. static internal::Object** CreateHandle(internal::HeapObject* heap_object, internal::Object* value); // Make it hard to create heap-allocated or illegal handle scopes by // disallowing certain operations. HandleScope(const HandleScope&); void operator=(const HandleScope&); void* operator new(size_t size); void operator delete(void*, size_t); internal::Isolate* isolate_; internal::Object** prev_next_; internal::Object** prev_limit_; // Local::New uses CreateHandle with an Isolate* parameter. template friend class Local; // Object::GetInternalField and Context::GetEmbedderData use CreateHandle with // a HeapObject* in their shortcuts. friend class Object; friend class Context; }; /** * A HandleScope which first allocates a handle in the current scope * which will be later filled with the escape value. */ class V8_EXPORT EscapableHandleScope : public HandleScope { public: EscapableHandleScope(Isolate* isolate); V8_INLINE ~EscapableHandleScope() {} /** * Pushes the value into the previous scope and returns a handle to it. * Cannot be called twice. */ template V8_INLINE Local Escape(Local value) { internal::Object** slot = Escape(reinterpret_cast(*value)); return Local(reinterpret_cast(slot)); } private: internal::Object** Escape(internal::Object** escape_value); // Make it hard to create heap-allocated or illegal handle scopes by // disallowing certain operations. EscapableHandleScope(const EscapableHandleScope&); void operator=(const EscapableHandleScope&); void* operator new(size_t size); void operator delete(void*, size_t); internal::Object** escape_slot_; }; /** * A simple Maybe type, representing an object which may or may not have a * value. */ template struct Maybe { Maybe() : has_value(false) {} explicit Maybe(T t) : has_value(true), value(t) {} Maybe(bool has, T t) : has_value(has), value(t) {} bool has_value; T value; }; // Convenience wrapper. template inline Maybe maybe(T t) { return Maybe(t); } // --- Special objects --- /** * The superclass of values and API object templates. */ class V8_EXPORT Data { private: Data(); }; /** * The origin, within a file, of a script. */ class ScriptOrigin { public: V8_INLINE ScriptOrigin( Handle resource_name, Handle resource_line_offset = Handle(), Handle resource_column_offset = Handle(), Handle resource_is_shared_cross_origin = Handle(), Handle script_id = Handle()) : resource_name_(resource_name), resource_line_offset_(resource_line_offset), resource_column_offset_(resource_column_offset), resource_is_shared_cross_origin_(resource_is_shared_cross_origin), script_id_(script_id) { } V8_INLINE Handle ResourceName() const; V8_INLINE Handle ResourceLineOffset() const; V8_INLINE Handle ResourceColumnOffset() const; V8_INLINE Handle ResourceIsSharedCrossOrigin() const; V8_INLINE Handle ScriptID() const; private: Handle resource_name_; Handle resource_line_offset_; Handle resource_column_offset_; Handle resource_is_shared_cross_origin_; Handle script_id_; }; /** * A compiled JavaScript script, not yet tied to a Context. */ class V8_EXPORT UnboundScript { public: /** * Binds the script to the currently entered context. */ Local