// 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 /** * The v8 JavaScript engine. */ namespace v8 { class Context; class String; class StringObject; class Value; class Utils; class Number; class NumberObject; class Object; class Array; class Int32; class Uint32; class External; class Primitive; class Boolean; class BooleanObject; class Integer; class Function; class Date; class ImplementationUtilities; class Signature; class AccessorSignature; template class Handle; template class Local; template class Persistent; class FunctionTemplate; class ObjectTemplate; class Data; class AccessorInfo; class StackTrace; class StackFrame; class Isolate; namespace internal { class Arguments; class Object; class Heap; class HeapObject; class Isolate; } // --- 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 */ typedef void (*WeakReferenceCallback)(Persistent object, void* parameter); // --- 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. */ inline Handle() : val_(0) {} /** * Creates a new handle for the specified value. */ inline explicit Handle(T* val) : val_(val) {} /** * 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 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. */ inline bool IsEmpty() const { return val_ == 0; } /** * Sets the handle to be empty. IsEmpty() will then return true. */ inline void Clear() { val_ = 0; } inline T* operator->() const { return val_; } 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 inline bool operator==(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; } /** * 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 inline bool operator!=(Handle that) const { return !operator==(that); } template static inline 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 inline Handle As() { return Handle::Cast(*this); } private: 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: inline Local(); template 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 inline Local(S* that) : Handle(that) { } template static inline 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 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. */ inline static Local New(Handle 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 : public Handle { public: /** * Creates an empty persistent handle that doesn't point to any * storage cell. */ inline Persistent(); /** * 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 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 inline Persistent(S* that) : Handle(that) { } /** * "Casts" a plain handle which is known to be a persistent handle * to a persistent handle. */ template explicit inline Persistent(Handle that) : Handle(*that) { } template static inline 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 inline Persistent As() { return Persistent::Cast(*this); } /** * Creates a new persistent handle for an existing local or * persistent handle. */ inline static Persistent New(Handle that); /** * 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. */ inline void 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::WeakReferenceCallback function, passing * it the object reference and the given parameters. */ inline void MakeWeak(void* parameters, WeakReferenceCallback callback); /** Clears the weak reference to this object. */ inline void 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. */ inline void MarkIndependent(); /** Returns true if this handle was previously marked as independent. */ inline bool IsIndependent() const; /** Checks if the handle holds the only reference to an object. */ inline bool IsNearDeath() const; /** Returns true if the handle's reference is weak. */ inline bool IsWeak() const; /** * Assigns a wrapper class ID to the handle. See RetainedObjectInfo * interface description in v8-profiler.h for details. */ 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. */ inline uint16_t WrapperClassId() const; private: friend class ImplementationUtilities; friend class ObjectTemplate; }; /** * 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: HandleScope(); ~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); // Faster version, uses HeapObject to obtain the current Isolate. static internal::Object** CreateHandle(internal::HeapObject* value); private: // Make it impossible 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; inline void Initialize() { next = limit = NULL; level = 0; } }; 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: 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) { } inline Handle ResourceName() const; inline Handle ResourceLineOffset() const; 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