// Copyright 2007-2008 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 #ifdef _WIN32 typedef int int32_t; typedef unsigned int uint32_t; typedef unsigned short uint16_t; // NOLINT typedef long long int64_t; // NOLINT // 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. // The reason for having both EXPORT and EXPORT_INLINE is that classes which // have their code inside this header file needs to have __declspec(dllexport) // when building the DLL but cannot have __declspec(dllimport) when building // a program which uses the DLL. #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 EXPORT __declspec(dllexport) #define EXPORT_INLINE __declspec(dllexport) #elif USING_V8_SHARED #define EXPORT __declspec(dllimport) #define EXPORT_INLINE #else #define EXPORT #define EXPORT_INLINE #endif // BUILDING_V8_SHARED #else // _WIN32 #include // Setup for Linux shared library export. There is no need to destinguish // neither between building or using the V8 shared library nor between using // the shared or static V8 library as there is on Windows. Therefore there is // no checking of BUILDING_V8_SHARED and USING_V8_SHARED. #if defined(__GNUC__) && (__GNUC__ >= 4) #define EXPORT __attribute__ ((visibility("default"))) #define EXPORT_INLINE __attribute__ ((visibility("default"))) #else // defined(__GNUC__) && (__GNUC__ >= 4) #define EXPORT #define EXPORT_INLINE #endif // defined(__GNUC__) && (__GNUC__ >= 4) #endif // _WIN32 /** * The v8 JavaScript engine. */ namespace v8 { class Context; class String; class Value; class Utils; class Number; class Object; class Array; class Int32; class Uint32; class External; class Primitive; class Boolean; class Integer; class Function; class Date; class ImplementationUtilities; class Signature; template class Handle; template class Local; template class Persistent; class FunctionTemplate; class ObjectTemplate; class Data; // --- W e a k H a n d l e s /** * A weak reference callback function. * * \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); // --- H a n d l e s --- #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 * an 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 EXPORT_INLINE Handle { public: /** * Creates an empty handle. */ Handle(); /** * Creates a new handle for the specified value. */ 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 compiletime 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. */ bool IsEmpty() const { return val_ == 0; } T* operator->() const; T* operator*() const; /** * Sets the handle to be empty. IsEmpty() will then return true. */ void Clear() { this->val_ = 0; } /** * 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 bool operator==(Handle that) const { void** a = reinterpret_cast(**this); void** 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 bool operator!=(Handle that) const { return !operator==(that); } template static inline Handle Cast(Handle that) { if (that.IsEmpty()) return Handle(); return Handle(T::Cast(*that)); } 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 EXPORT_INLINE Local : public Handle { public: 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) { if (that.IsEmpty()) return Local(); return Local(T::Cast(*that)); } /** 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. */ 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 EXPORT_INLINE Persistent : public Handle { public: /** * Creates an empty persistent handle that doesn't point to any * storage cell. */ 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 compiletime 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) { if (that.IsEmpty()) return Persistent(); return Persistent(T::Cast(*that)); } /** * Creates a new persistent handle for an existing local or * persistent handle. */ 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 any other references to the storage * cell remain and IsEmpty will still return false. */ 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. */ void MakeWeak(void* parameters, WeakReferenceCallback callback); /** Clears the weak reference to this object.*/ void ClearWeak(); /** *Checks if the handle holds the only reference to an object. */ bool IsNearDeath() const; /** * Returns true if the handle's reference is weak. */ bool IsWeak() 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 EXPORT 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 void** CreateHandle(void* 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 through a typedef in the // ImplementationUtilities class. class EXPORT Data { public: int extensions; void** next; void** limit; inline void Initialize() { extensions = -1; next = limit = NULL; } }; Data previous_; // 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_; void** RawClose(void** value); friend class ImplementationUtilities; }; // --- S p e c i a l o b j e c t s --- /** * The superclass of values and API object templates. */ class EXPORT 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 EXPORT ScriptData { // NOLINT public: virtual ~ScriptData() { } static ScriptData* PreCompile(const char* input, int length); static ScriptData* New(unsigned* data, int length); virtual int Length() = 0; virtual unsigned* Data() = 0; }; /** * The origin, within a file, of a script. */ class EXPORT ScriptOrigin { public: 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 EXPORT Script { public: /** * Compiles the specified script. The ScriptOrigin* and ScriptData* * parameters are owned by the caller of Script::Compile. No * references to these objects are kept after compilation finishes. */ static Local