// Copyright 2012 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following // disclaimer in the documentation and/or other materials provided // with the distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /** \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 "v8stdint.h" #ifdef _WIN32 // 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 V8EXPORT __declspec(dllexport) #elif USING_V8_SHARED #define V8EXPORT __declspec(dllimport) #else #define V8EXPORT #endif // BUILDING_V8_SHARED #else // _WIN32 // Setup for Linux shared library export. #if defined(__GNUC__) && ((__GNUC__ >= 4) || \ (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && defined(V8_SHARED) #ifdef BUILDING_V8_SHARED #define V8EXPORT __attribute__ ((visibility("default"))) #else #define V8EXPORT #endif #else #define V8EXPORT #endif #endif // _WIN32 #if defined(__GNUC__) && !defined(DEBUG) #define V8_INLINE(declarator) inline __attribute__((always_inline)) declarator #elif defined(_MSC_VER) && !defined(DEBUG) #define V8_INLINE(declarator) __forceinline declarator #else #define V8_INLINE(declarator) inline declarator #endif #if defined(__GNUC__) && !V8_DISABLE_DEPRECATIONS #define V8_DEPRECATED(declarator) declarator __attribute__ ((deprecated)) #elif defined(_MSC_VER) && !V8_DISABLE_DEPRECATIONS #define V8_DEPRECATED(declarator) __declspec(deprecated) declarator #else #define V8_DEPRECATED(declarator) declarator #endif #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)) #define V8_UNLIKELY(condition) __builtin_expect((condition), 0) #define V8_LIKELY(condition) __builtin_expect((condition), 1) #else #define V8_UNLIKELY(condition) (condition) #define V8_LIKELY(condition) (condition) #endif /** * The v8 JavaScript engine. */ namespace v8 { class AccessorInfo; 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 LocalContext; class Number; class NumberObject; class Object; class ObjectOperationDescriptor; class ObjectTemplate; class Primitive; class RawOperationDescriptor; class Signature; class StackFrame; class StackTrace; class String; class StringObject; class Symbol; class SymbolObject; class Uint32; class Utils; class Value; template class Handle; template class Local; template class Persistent; class FunctionTemplate; class ObjectTemplate; class Data; class AccessorInfo; template class PropertyCallbackInfo; class StackTrace; class StackFrame; class Isolate; class DeclaredAccessorDescriptor; class ObjectOperationDescriptor; class RawOperationDescriptor; namespace internal { class Arguments; class Heap; class HeapObject; class Isolate; class Object; template class CustomArguments; class PropertyCallbackArguments; class FunctionCallbackArguments; } /** * 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_; }; // --- Weak Handles --- /** * A weak reference callback function. * * This callback should either explicitly invoke Dispose on |object| if * V8 wrapper is not needed anymore, or 'revive' it by invocation of MakeWeak. * * \param object the weak global object to be reclaimed by the garbage collector * \param parameter the value passed in when making the weak global object */ template class WeakReferenceCallbacks { public: typedef void (*Revivable)(Isolate* isolate, Persistent* object, P* parameter); }; // --- Handles --- #define TYPE_CHECK(T, S) \ while (false) { \ *(static_cast(0)) = static_cast(0); \ } #define V8_USE_UNSAFE_HANDLES #define V8_USE_OLD_STYLE_PERSISTENT_HANDLE_VISITORS /** * 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) {} #ifdef V8_USE_UNSAFE_HANDLES /** * Creates a new handle for the specified value. */ V8_INLINE(explicit Handle(T* val)) : val_(val) {} #endif /** * 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); internal::Object** b = reinterpret_cast(*that); if (a == 0) return b == 0; if (b == 0) return false; return *a == *b; } #ifndef V8_USE_UNSAFE_HANDLES template V8_INLINE( bool operator==(const Persistent& that) const) { internal::Object** a = reinterpret_cast(**this); internal::Object** b = reinterpret_cast(*that); if (a == 0) return b == 0; if (b == 0) return false; return *a == *b; } #endif /** * 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!=(Handle 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); } #ifndef V8_USE_UNSAFE_HANDLES V8_INLINE(static Handle New(Isolate* isolate, Handle that)) { return New(isolate, that.val_); } // TODO(dcarney): remove before cutover V8_INLINE(static Handle New(Isolate* isolate, const Persistent& that)) { return New(isolate, that.val_); } #ifndef V8_ALLOW_ACCESS_TO_RAW_HANDLE_CONSTRUCTOR private: #endif /** * Creates a new handle for the specified value. */ V8_INLINE(explicit Handle(T* val)) : val_(val) {} #endif private: template friend class Persistent; template friend class Local; friend class Arguments; template friend class FunctionCallbackInfo; template friend class PropertyCallbackInfo; friend class String; friend class Object; friend class AccessorInfo; 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 InternalHandleHelper; friend class LocalContext; friend class HandleScope; #ifndef V8_USE_UNSAFE_HANDLES V8_INLINE(static Handle New(Isolate* isolate, T* that)); #endif 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. */ // TODO(dcarney): deprecate entire class 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); } #ifdef V8_USE_UNSAFE_HANDLES template V8_INLINE(Local(S* that) : Handle(that)) { } #endif 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)); } #ifndef V8_USE_UNSAFE_HANDLES template V8_INLINE(Local(Handle that)) : Handle(reinterpret_cast(*that)) { TYPE_CHECK(T, S); } #endif 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(Handle that)); V8_INLINE(static Local New(Isolate* isolate, Handle that)); #ifndef V8_USE_UNSAFE_HANDLES // TODO(dcarney): remove before cutover V8_INLINE(static Local New(Isolate* isolate, const Persistent& that)); #ifndef V8_ALLOW_ACCESS_TO_RAW_HANDLE_CONSTRUCTOR private: #endif template V8_INLINE(Local(S* that) : Handle(that)) { } #endif private: template friend class Persistent; template friend class Handle; friend class Arguments; template friend class FunctionCallbackInfo; template friend class PropertyCallbackInfo; friend class String; friend class Object; friend class AccessorInfo; friend class Context; friend class InternalHandleHelper; friend class LocalContext; friend class HandleScope; V8_INLINE(static Local New(Isolate* isolate, T* that)); }; /** * 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 Persistent 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 Persistent::New and existing handles can * be disposed using Persistent::Dispose. Since persistent handles * are passed by value you may have many persistent handle objects * that point to the same storage cell. For instance, if you pass a * persistent handle as an argument to a function you will not get two * different storage cells but rather two references to the same * storage cell. */ template class Persistent // NOLINT #ifdef V8_USE_UNSAFE_HANDLES : public Handle { #else { // NOLINT #endif public: #ifndef V8_USE_UNSAFE_HANDLES V8_INLINE(Persistent()) : val_(0) { } V8_INLINE(~Persistent()) { // TODO(dcarney): add this back before cutover. // Dispose(); } V8_INLINE(bool IsEmpty() const) { return val_ == 0; } // TODO(dcarney): remove somehow before cutover // The handle should either be 0, or a pointer to a live cell. V8_INLINE(void Clear()) { val_ = 0; } /** * A constructor that creates a new global cell pointing to that. In contrast * to the copy constructor, this creates a new persistent handle which needs * to be separately disposed. */ template V8_INLINE(Persistent(Isolate* isolate, Handle that)) : val_(*New(isolate, that)) { } template V8_INLINE(Persistent(Isolate* isolate, Persistent& that)) // NOLINT : val_(*New(isolate, that)) { } #else /** * Creates an empty persistent handle that doesn't point to any * storage cell. */ V8_INLINE(Persistent()) : Handle() { } /** * Creates a persistent handle for the same storage cell as the * specified handle. This constructor allows you to pass persistent * handles as arguments by value and to assign between persistent * handles. However, attempting to assign between incompatible * persistent handles, for instance from a Persistent to a * Persistent will cause a compile-time error. Assigning * between compatible persistent handles, for instance assigning a * Persistent to a variable declared as Persistent, * is allowed as String is a subclass of Value. */ template V8_INLINE(Persistent(Persistent 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(Persistent(S* that)) : Handle(that) { } /** * A constructor that creates a new global cell pointing to that. In contrast * to the copy constructor, this creates a new persistent handle which needs * to be separately disposed. */ template V8_INLINE(Persistent(Isolate* isolate, Handle that)) : Handle(New(isolate, that)) { } /** * "Casts" a plain handle which is known to be a persistent handle * to a persistent handle. */ template explicit V8_INLINE(Persistent(Handle that)) : Handle(*that) { } #endif #ifdef V8_USE_UNSAFE_HANDLES template V8_INLINE(static Persistent Cast(Persistent 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 Persistent(); #endif return Persistent(T::Cast(*that)); } template V8_INLINE(Persistent As()) { return Persistent::Cast(*this); } #else 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); } template V8_INLINE(Persistent& As()) { // NOLINT return Persistent::Cast(*this); } #endif V8_DEPRECATED(static Persistent New(Handle that)); /** * Creates a new persistent handle for an existing local or persistent handle. */ // TODO(dcarney): remove before cutover V8_INLINE(static Persistent New(Isolate* isolate, Handle that)); #ifndef V8_USE_UNSAFE_HANDLES // TODO(dcarney): remove before cutover V8_INLINE(static Persistent New(Isolate* isolate, Persistent that)); #endif #ifndef V8_USE_UNSAFE_HANDLES template V8_INLINE( bool operator==(const Persistent& that) const) { internal::Object** a = reinterpret_cast(**this); internal::Object** b = reinterpret_cast(*that); 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); internal::Object** b = reinterpret_cast(*that); if (a == 0) return b == 0; if (b == 0) return false; return *a == *b; } #endif V8_INLINE(void Dispose()); /** * Releases the storage cell referenced by this persistent handle. * Does not remove the reference to the cell from any handles. * This handle's reference, and any other references to the storage * cell remain and IsEmpty will still return false. */ // TODO(dcarney): deprecate V8_INLINE(void Dispose(Isolate* isolate)) { Dispose(); } /** * Make the reference to this object weak. When only weak handles * refer to the object, the garbage collector will perform a * callback to the given V8::NearDeathCallback function, passing * it the object reference and the given parameters. */ template V8_INLINE(void MakeWeak( P* parameters, typename WeakReferenceCallbacks::Revivable callback)); template V8_INLINE(void MakeWeak( P* parameters, typename WeakReferenceCallbacks::Revivable callback)); // TODO(dcarney): deprecate template V8_INLINE(void MakeWeak( Isolate* isolate, P* parameters, typename WeakReferenceCallbacks::Revivable callback)) { MakeWeak(parameters, callback); } // TODO(dcarney): deprecate template V8_INLINE(void MakeWeak( Isolate* isolate, P* parameters, typename WeakReferenceCallbacks::Revivable callback)) { MakeWeak

(parameters, callback); } V8_INLINE(void ClearWeak()); // TODO(dcarney): deprecate V8_INLINE(void ClearWeak(Isolate* isolate)) { 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()); // TODO(dcarney): deprecate V8_INLINE(void MarkIndependent(Isolate* isolate)) { 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()); // TODO(dcarney): deprecate V8_INLINE(void MarkPartiallyDependent(Isolate* isolate)) { MarkPartiallyDependent(); } V8_INLINE(bool IsIndependent() const); // TODO(dcarney): deprecate V8_INLINE(bool IsIndependent(Isolate* isolate) const) { return IsIndependent(); } /** Checks if the handle holds the only reference to an object. */ V8_INLINE(bool IsNearDeath() const); // TODO(dcarney): deprecate V8_INLINE(bool IsNearDeath(Isolate* isolate) const) { return IsNearDeath(); } /** Returns true if the handle's reference is weak. */ V8_INLINE(bool IsWeak() const); // TODO(dcarney): deprecate V8_INLINE(bool IsWeak(Isolate* isolate) const) { return IsWeak(); } /** * 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)); // TODO(dcarney): deprecate V8_INLINE(void SetWrapperClassId(Isolate* isolate, uint16_t class_id)) { SetWrapperClassId(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); // TODO(dcarney): deprecate V8_INLINE(uint16_t WrapperClassId(Isolate* isolate) const) { return WrapperClassId(); } /** * Disposes the current contents of the handle and replaces it. */ V8_INLINE(void Reset(Isolate* isolate, const Handle& other)); #ifndef V8_USE_UNSAFE_HANDLES V8_INLINE(void Reset(Isolate* isolate, const Persistent& other)); #endif /** * Returns the underlying raw pointer and clears the handle. The caller is * responsible of eventually destroying the underlying object (by creating a * Persistent handle which points to it and Disposing it). In the future, * destructing a Persistent will also Dispose it. With this function, the * embedder can let the Persistent go out of scope without it getting * disposed. */ V8_INLINE(T* ClearAndLeak()); #ifndef V8_USE_UNSAFE_HANDLES #ifndef V8_ALLOW_ACCESS_TO_PERSISTENT_IMPLICIT private: #endif // TODO(dcarney): make unlinkable before cutover V8_INLINE(Persistent(const Persistent& that)) : val_(that.val_) {} // TODO(dcarney): make unlinkable before cutover V8_INLINE(Persistent& operator=(const Persistent& that)) { // NOLINT this->val_ = that.val_; return *this; } public: #ifndef V8_ALLOW_ACCESS_TO_RAW_HANDLE_CONSTRUCTOR private: #endif // TODO(dcarney): remove before cutover template V8_INLINE(Persistent(S* that)) : val_(that) { } // TODO(dcarney): remove before cutover template V8_INLINE(Persistent(Persistent that)) : val_(*that) { TYPE_CHECK(T, S); } // TODO(dcarney): remove before cutover V8_INLINE(T* operator*() const) { return val_; } public: #ifndef V8_ALLOW_ACCESS_TO_PERSISTENT_ARROW private: #endif // TODO(dcarney): remove before cutover V8_INLINE(T* operator->() const) { return val_; } public: #endif private: template friend class Handle; template friend class Local; friend class ImplementationUtilities; friend class ObjectTemplate; friend class Context; friend class InternalHandleHelper; friend class LocalContext; V8_INLINE(static Persistent New(Isolate* isolate, T* that)); #ifndef V8_USE_UNSAFE_HANDLES T* val_; #endif }; /** * 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 V8EXPORT HandleScope { public: // TODO(svenpanne) Deprecate me when Chrome is fixed! HandleScope(); HandleScope(Isolate* isolate); ~HandleScope(); /** * Closes the handle scope and returns the value as a handle in the * previous scope, which is the new current scope after the call. */ template Local Close(Handle value); /** * Counts the number of allocated handles. */ static int NumberOfHandles(); /** * Creates a new handle with the given value. */ static internal::Object** CreateHandle(internal::Object* value); static internal::Object** CreateHandle(internal::Isolate* isolate, internal::Object* value); // Faster version, uses HeapObject to obtain the current Isolate. static internal::Object** CreateHandle(internal::HeapObject* value); private: // 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); // This Data class is accessible internally as HandleScopeData through a // typedef in the ImplementationUtilities class. class V8EXPORT Data { public: internal::Object** next; internal::Object** limit; int level; V8_INLINE(void Initialize()) { next = limit = NULL; level = 0; } }; void Initialize(Isolate* isolate); void Leave(); internal::Isolate* isolate_; internal::Object** prev_next_; internal::Object** prev_limit_; // Allow for the active closing of HandleScopes which allows to pass a handle // from the HandleScope being closed to the next top most HandleScope. bool is_closed_; internal::Object** RawClose(internal::Object** value); friend class ImplementationUtilities; }; // --- Special objects --- /** * The superclass of values and API object templates. */ class V8EXPORT Data { private: Data(); }; /** * Pre-compilation data that can be associated with a script. This * data can be calculated for a script in advance of actually * compiling it, and can be stored between compilations. When script * data is given to the compile method compilation will be faster. */ class V8EXPORT ScriptData { // NOLINT public: virtual ~ScriptData() { } /** * Pre-compiles the specified script (context-independent). * * \param input Pointer to UTF-8 script source code. * \param length Length of UTF-8 script source code. */ static ScriptData* PreCompile(const char* input, int length); /** * Pre-compiles the specified script (context-independent). * * NOTE: Pre-compilation using this method cannot happen on another thread * without using Lockers. * * \param source Script source code. */ static ScriptData* PreCompile(Handle source); /** * Load previous pre-compilation data. * * \param data Pointer to data returned by a call to Data() of a previous * ScriptData. Ownership is not transferred. * \param length Length of data. */ static ScriptData* New(const char* data, int length); /** * Returns the length of Data(). */ virtual int Length() = 0; /** * Returns a serialized representation of this ScriptData that can later be * passed to New(). NOTE: Serialized data is platform-dependent. */ virtual const char* Data() = 0; /** * Returns true if the source code could not be parsed. */ virtual bool HasError() = 0; }; /** * 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())) : resource_name_(resource_name), resource_line_offset_(resource_line_offset), resource_column_offset_(resource_column_offset) { } V8_INLINE(Handle ResourceName() const); V8_INLINE(Handle ResourceLineOffset() const); V8_INLINE(Handle ResourceColumnOffset() const); private: Handle resource_name_; Handle resource_line_offset_; Handle resource_column_offset_; }; /** * A compiled JavaScript script. */ class V8EXPORT Script { public: /** * Compiles the specified script (context-independent). * * \param source Script source code. * \param origin Script origin, owned by caller, no references are kept * when New() returns * \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 New() returns. * \param script_data Arbitrary data associated with script. Using * this has same effect as calling SetData(), but allows data to be * available to compile event handlers. * \return Compiled script object (context independent; when run it * will use the currently entered context). */ static Local