v8.h   v8.h 
skipping to change at line 123 skipping to change at line 123
class String; class String;
class StringObject; class StringObject;
class Symbol; class Symbol;
class SymbolObject; class SymbolObject;
class Uint32; class Uint32;
class Utils; class Utils;
class Value; class Value;
template <class T> class Handle; template <class T> class Handle;
template <class T> class Local; template <class T> class Local;
template <class T> class Eternal; template <class T> class Eternal;
template <class T> class Persistent; template<class T> class NonCopyablePersistentTraits;
template<class T,
class M = NonCopyablePersistentTraits<T> > class Persistent;
template<class T, class P> class WeakCallbackObject;
class FunctionTemplate; class FunctionTemplate;
class ObjectTemplate; class ObjectTemplate;
class Data; class Data;
template<typename T> class PropertyCallbackInfo; template<typename T> class PropertyCallbackInfo;
class StackTrace; class StackTrace;
class StackFrame; class StackFrame;
class Isolate; class Isolate;
class DeclaredAccessorDescriptor; class DeclaredAccessorDescriptor;
class ObjectOperationDescriptor; class ObjectOperationDescriptor;
class RawOperationDescriptor; class RawOperationDescriptor;
skipping to change at line 145 skipping to change at line 148
namespace internal { namespace internal {
class Arguments; class Arguments;
class Heap; class Heap;
class HeapObject; class HeapObject;
class Isolate; class Isolate;
class Object; class Object;
template<typename T> class CustomArguments; template<typename T> class CustomArguments;
class PropertyCallbackArguments; class PropertyCallbackArguments;
class FunctionCallbackArguments; class FunctionCallbackArguments;
class GlobalHandles;
} }
/** /**
* General purpose unique identifier. * General purpose unique identifier.
*/ */
class UniqueId { class UniqueId {
public: public:
explicit UniqueId(intptr_t data) explicit UniqueId(intptr_t data)
: data_(data) {} : data_(data) {}
skipping to change at line 171 skipping to change at line 175
} }
bool operator<(const UniqueId& other) const { bool operator<(const UniqueId& other) const {
return data_ < other.data_; return data_ < other.data_;
} }
private: private:
intptr_t data_; 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 MakeWe
ak.
*
* \param object the weak global object to be reclaimed by the garbage coll
ector
* \param parameter the value passed in when making the weak global object
*/
template<typename T, typename P>
class WeakReferenceCallbacks {
public:
typedef void (*Revivable)(Isolate* isolate,
Persistent<T>* object,
P* parameter);
};
// --- Handles --- // --- Handles ---
#define TYPE_CHECK(T, S) \ #define TYPE_CHECK(T, S) \
while (false) { \ while (false) { \
*(static_cast<T* volatile*>(0)) = static_cast<S*>(0); \ *(static_cast<T* volatile*>(0)) = static_cast<S*>(0); \
} }
/** /**
* An object reference managed by the v8 garbage collector. * An object reference managed by the v8 garbage collector.
* *
skipping to change at line 229 skipping to change at line 214
* behind the scenes and the same rules apply to these values as to * behind the scenes and the same rules apply to these values as to
* their handles. * their handles.
*/ */
template <class T> class Handle { template <class T> class Handle {
public: public:
/** /**
* Creates an empty handle. * Creates an empty handle.
*/ */
V8_INLINE(Handle()) : val_(0) {} 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 * Creates a handle for the contents of the specified handle. This
* constructor allows you to pass handles as arguments by value and * constructor allows you to pass handles as arguments by value and
* to assign between handles. However, if you try to assign between * to assign between handles. However, if you try to assign between
* incompatible handles, for instance from a Handle<String> to a * incompatible handles, for instance from a Handle<String> to a
* Handle<Number> it will cause a compile-time error. Assigning * Handle<Number> it will cause a compile-time error. Assigning
* between compatible handles, for instance assigning a * between compatible handles, for instance assigning a
* Handle<String> to a variable declared as Handle<Value>, is legal * Handle<String> to a variable declared as Handle<Value>, is legal
* because String is a subclass of Value. * because String is a subclass of Value.
*/ */
skipping to change at line 284 skipping to change at line 262
* The handles' references are not checked. * The handles' references are not checked.
*/ */
template <class S> V8_INLINE(bool operator==(const Handle<S>& that) const ) { template <class S> V8_INLINE(bool operator==(const Handle<S>& that) const ) {
internal::Object** a = reinterpret_cast<internal::Object**>(**this); internal::Object** a = reinterpret_cast<internal::Object**>(**this);
internal::Object** b = reinterpret_cast<internal::Object**>(*that); internal::Object** b = reinterpret_cast<internal::Object**>(*that);
if (a == 0) return b == 0; if (a == 0) return b == 0;
if (b == 0) return false; if (b == 0) return false;
return *a == *b; return *a == *b;
} }
#ifndef V8_USE_UNSAFE_HANDLES
template <class S> V8_INLINE( template <class S> V8_INLINE(
bool operator==(const Persistent<S>& that) const) { bool operator==(const Persistent<S>& that) const) {
internal::Object** a = reinterpret_cast<internal::Object**>(**this); internal::Object** a = reinterpret_cast<internal::Object**>(**this);
internal::Object** b = reinterpret_cast<internal::Object**>(*that); internal::Object** b = reinterpret_cast<internal::Object**>(*that);
if (a == 0) return b == 0; if (a == 0) return b == 0;
if (b == 0) return false; if (b == 0) return false;
return *a == *b; return *a == *b;
} }
#endif
/** /**
* Checks whether two handles are different. * Checks whether two handles are different.
* Returns true if only one of the handles is empty, or if * Returns true if only one of the handles is empty, or if
* the objects to which they refer are different. * the objects to which they refer are different.
* The handles' references are not checked. * The handles' references are not checked.
*/ */
template <class S> V8_INLINE(bool operator!=(const Handle<S>& that) const ) { template <class S> V8_INLINE(bool operator!=(const Handle<S>& that) const ) {
return !operator==(that); return !operator==(that);
} }
#ifndef V8_USE_UNSAFE_HANDLES
template <class S> V8_INLINE( template <class S> V8_INLINE(
bool operator!=(const Persistent<S>& that) const) { bool operator!=(const Persistent<S>& that) const) {
return !operator==(that); return !operator==(that);
} }
#endif
template <class S> V8_INLINE(static Handle<T> Cast(Handle<S> that)) { template <class S> V8_INLINE(static Handle<T> Cast(Handle<S> that)) {
#ifdef V8_ENABLE_CHECKS #ifdef V8_ENABLE_CHECKS
// If we're going to perform the type check then we have to check // 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. // that the handle isn't empty before doing the checked cast.
if (that.IsEmpty()) return Handle<T>(); if (that.IsEmpty()) return Handle<T>();
#endif #endif
return Handle<T>(T::Cast(*that)); return Handle<T>(T::Cast(*that));
} }
template <class S> V8_INLINE(Handle<S> As()) { template <class S> V8_INLINE(Handle<S> As()) {
return Handle<S>::Cast(*this); return Handle<S>::Cast(*this);
} }
#ifndef V8_USE_UNSAFE_HANDLES
V8_INLINE(static Handle<T> New(Isolate* isolate, Handle<T> that)) { V8_INLINE(static Handle<T> New(Isolate* isolate, Handle<T> that)) {
return New(isolate, that.val_); return New(isolate, that.val_);
} }
// TODO(dcarney): remove before cutover
V8_INLINE(static Handle<T> New(Isolate* isolate, const Persistent<T>& tha t)) { V8_INLINE(static Handle<T> New(Isolate* isolate, const Persistent<T>& tha t)) {
return New(isolate, that.val_); return New(isolate, that.val_);
} }
#ifndef V8_ALLOW_ACCESS_TO_RAW_HANDLE_CONSTRUCTOR #ifndef V8_ALLOW_ACCESS_TO_RAW_HANDLE_CONSTRUCTOR
private: private:
#endif #endif
/** /**
* Creates a new handle for the specified value. * Creates a new handle for the specified value.
*/ */
V8_INLINE(explicit Handle(T* val)) : val_(val) {} V8_INLINE(explicit Handle(T* val)) : val_(val) {}
#endif
private: private:
friend class Utils; friend class Utils;
template<class F> friend class Persistent; template<class F, class M> friend class Persistent;
template<class F> friend class Local; template<class F> friend class Local;
template<class F> friend class FunctionCallbackInfo; template<class F> friend class FunctionCallbackInfo;
template<class F> friend class PropertyCallbackInfo; template<class F> friend class PropertyCallbackInfo;
template<class F> friend class internal::CustomArguments; template<class F> friend class internal::CustomArguments;
friend Handle<Primitive> Undefined(Isolate* isolate); friend Handle<Primitive> Undefined(Isolate* isolate);
friend Handle<Primitive> Null(Isolate* isolate); friend Handle<Primitive> Null(Isolate* isolate);
friend Handle<Boolean> True(Isolate* isolate); friend Handle<Boolean> True(Isolate* isolate);
friend Handle<Boolean> False(Isolate* isolate); friend Handle<Boolean> False(Isolate* isolate);
friend class Context; friend class Context;
friend class HandleScope; friend class HandleScope;
#ifndef V8_USE_UNSAFE_HANDLES
V8_INLINE(static Handle<T> New(Isolate* isolate, T* that)); V8_INLINE(static Handle<T> New(Isolate* isolate, T* that));
#endif
T* val_; T* val_;
}; };
/** /**
* A light-weight stack-allocated object handle. All operations * A light-weight stack-allocated object handle. All operations
* that return objects from within v8 return them in local handles. They * that return objects from within v8 return them in local handles. They
* are created within HandleScopes, and all local handles allocated within a * are created within HandleScopes, and all local handles allocated within a
* handle scope are destroyed when the handle scope is destroyed. Hence it * handle scope are destroyed when the handle scope is destroyed. Hence it
* is not necessary to explicitly deallocate local handles. * is not necessary to explicitly deallocate local handles.
*/ */
// TODO(dcarney): deprecate entire class
template <class T> class Local : public Handle<T> { template <class T> class Local : public Handle<T> {
public: public:
V8_INLINE(Local()); V8_INLINE(Local());
template <class S> V8_INLINE(Local(Local<S> that)) template <class S> V8_INLINE(Local(Local<S> that))
: Handle<T>(reinterpret_cast<T*>(*that)) { : Handle<T>(reinterpret_cast<T*>(*that)) {
/** /**
* This check fails when trying to convert between incompatible * This check fails when trying to convert between incompatible
* handles. For example, converting from a Handle<String> to a * handles. For example, converting from a Handle<String> to a
* Handle<Number>. * Handle<Number>.
*/ */
TYPE_CHECK(T, S); TYPE_CHECK(T, S);
} }
#ifdef V8_USE_UNSAFE_HANDLES
template <class S> V8_INLINE(Local(S* that) : Handle<T>(that)) { }
#endif
template <class S> V8_INLINE(static Local<T> Cast(Local<S> that)) { template <class S> V8_INLINE(static Local<T> Cast(Local<S> that)) {
#ifdef V8_ENABLE_CHECKS #ifdef V8_ENABLE_CHECKS
// If we're going to perform the type check then we have to check // 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. // that the handle isn't empty before doing the checked cast.
if (that.IsEmpty()) return Local<T>(); if (that.IsEmpty()) return Local<T>();
#endif #endif
return Local<T>(T::Cast(*that)); return Local<T>(T::Cast(*that));
} }
#ifndef V8_USE_UNSAFE_HANDLES
template <class S> V8_INLINE(Local(Handle<S> that)) template <class S> V8_INLINE(Local(Handle<S> that))
: Handle<T>(reinterpret_cast<T*>(*that)) { : Handle<T>(reinterpret_cast<T*>(*that)) {
TYPE_CHECK(T, S); TYPE_CHECK(T, S);
} }
#endif
template <class S> V8_INLINE(Local<S> As()) { template <class S> V8_INLINE(Local<S> As()) {
return Local<S>::Cast(*this); return Local<S>::Cast(*this);
} }
/** /**
* Create a local handle for the content of another handle. * Create a local handle for the content of another handle.
* The referee is kept alive by the local handle even when * The referee is kept alive by the local handle even when
* the original handle is destroyed/disposed. * the original handle is destroyed/disposed.
*/ */
V8_INLINE(static Local<T> New(Handle<T> that)); V8_INLINE(static Local<T> New(Handle<T> that));
V8_INLINE(static Local<T> New(Isolate* isolate, Handle<T> that)); V8_INLINE(static Local<T> New(Isolate* isolate, Handle<T> that));
#ifndef V8_USE_UNSAFE_HANDLES template<class M>
// TODO(dcarney): remove before cutover V8_INLINE(static Local<T> New(Isolate* isolate,
V8_INLINE(static Local<T> New(Isolate* isolate, const Persistent<T>& that const Persistent<T, M>& that));
));
#ifndef V8_ALLOW_ACCESS_TO_RAW_HANDLE_CONSTRUCTOR #ifndef V8_ALLOW_ACCESS_TO_RAW_HANDLE_CONSTRUCTOR
private: private:
#endif #endif
template <class S> V8_INLINE(Local(S* that) : Handle<T>(that)) { } template <class S> V8_INLINE(Local(S* that) : Handle<T>(that)) { }
#endif
private: private:
friend class Utils; friend class Utils;
template<class F> friend class Eternal; template<class F> friend class Eternal;
template<class F> friend class Persistent; template<class F, class M> friend class Persistent;
template<class F> friend class Handle; template<class F> friend class Handle;
template<class F> friend class FunctionCallbackInfo; template<class F> friend class FunctionCallbackInfo;
template<class F> friend class PropertyCallbackInfo; template<class F> friend class PropertyCallbackInfo;
friend class String; friend class String;
friend class Object; friend class Object;
friend class Context; friend class Context;
template<class F> friend class internal::CustomArguments; template<class F> friend class internal::CustomArguments;
friend class HandleScope; friend class HandleScope;
V8_INLINE(static Local<T> New(Isolate* isolate, T* that)); V8_INLINE(static Local<T> New(Isolate* isolate, T* that));
skipping to change at line 463 skipping to change at line 424
V8_INLINE(Local<T> Get(Isolate* isolate)); V8_INLINE(Local<T> Get(Isolate* isolate));
V8_INLINE(bool IsEmpty()) { return index_ == kInitialValue; } V8_INLINE(bool IsEmpty()) { return index_ == kInitialValue; }
template<class S> template<class S>
V8_INLINE(void Set(Isolate* isolate, Local<S> handle)); V8_INLINE(void Set(Isolate* isolate, Local<S> handle));
private: private:
static const int kInitialValue = -1; static const int kInitialValue = -1;
int index_; int index_;
}; };
template<class T, class P>
class WeakCallbackData {
public:
typedef void (*Callback)(const WeakCallbackData<T, P>& data);
V8_INLINE(Isolate* GetIsolate()) const { return isolate_; }
V8_INLINE(Local<T> GetValue()) const { return handle_; }
V8_INLINE(P* GetParameter()) const { return parameter_; }
private:
friend class internal::GlobalHandles;
WeakCallbackData(Isolate* isolate, Local<T> handle, P* parameter)
: isolate_(isolate), handle_(handle), parameter_(parameter) { }
Isolate* isolate_;
Local<T> handle_;
P* parameter_;
};
// TODO(dcarney): Remove this class.
template<typename T,
typename P,
typename M = NonCopyablePersistentTraits<T> >
class WeakReferenceCallbacks {
public:
typedef void (*Revivable)(Isolate* isolate,
Persistent<T, M>* object,
P* parameter);
};
/**
* 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 futu
re
* version.
*/
template<class T>
class NonCopyablePersistentTraits {
public:
typedef Persistent<T, NonCopyablePersistentTraits<T> > NonCopyablePersist
ent;
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);
}
};
/** /**
* An object reference that is independent of any handle scope. Where * 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 * a Local handle only lives as long as the HandleScope in which it was
* allocated, a Persistent handle remains valid until it is explicitly * allocated, a Persistent handle remains valid until it is explicitly
* disposed. * disposed.
* *
* A persistent handle contains a reference to a storage cell within * 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 v8 engine which holds an object value and which is updated by
* the garbage collector whenever the object is moved. A new storage * the garbage collector whenever the object is moved. A new storage
* cell can be created using Persistent::New and existing handles can * cell can be created using the constructor or Persistent::Reset and
* be disposed using Persistent::Dispose. Since persistent handles * existing handles can be disposed using Persistent::Reset.
* are passed by value you may have many persistent handle objects *
* that point to the same storage cell. For instance, if you pass a * Copy, assignment and destructor bevavior is controlled by the traits
* persistent handle as an argument to a function you will not get two * class M.
* different storage cells but rather two references to the same */
* storage cell. template <class T, class M> class Persistent {
*/
template <class T> class Persistent // NOLINT
#ifdef V8_USE_UNSAFE_HANDLES
: public Handle<T> {
#else
{ // NOLINT
#endif
public: public:
#ifndef V8_USE_UNSAFE_HANDLES
V8_INLINE(Persistent()) : val_(0) { }
// TODO(dcarney): add this back before cutover.
// V8_INLINE(~Persistent()) {
// 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 cont * A Persistent with no storage cell.
rast
* to the copy constructor, this creates a new persistent handle which ne
eds
* to be separately disposed.
*/ */
template <class S> V8_INLINE(Persistent(Isolate* isolate, Handle<S> that) V8_INLINE(Persistent()) : val_(0) { }
)
: val_(New(isolate, *that)) { }
template <class S> V8_INLINE(Persistent(Isolate* isolate,
const Persistent<S>& that)) // NO
LINT
: val_(New(isolate, *that)) { }
#else
/** /**
* Creates an empty persistent handle that doesn't point to any * Construct a Persistent from a Handle.
* storage cell. * When the Handle is non-empty, a new storage cell is created
* pointing to the same object, and no flags are set.
*/ */
V8_INLINE(Persistent()) : Handle<T>() { } template <class S> V8_INLINE(Persistent(Isolate* isolate, Handle<S> that)
)
: val_(New(isolate, *that)) {
TYPE_CHECK(T, S);
}
/** /**
* Creates a persistent handle for the same storage cell as the * Construct a Persistent from a Persistent.
* specified handle. This constructor allows you to pass persistent * When the Persistent is non-empty, a new storage cell is created
* handles as arguments by value and to assign between persistent * pointing to the same object, and no flags are set.
* handles. However, attempting to assign between incompatible */
* persistent handles, for instance from a Persistent<String> to a template <class S, class M2>
* Persistent<Number> will cause a compile-time error. Assigning V8_INLINE(Persistent(Isolate* isolate, const Persistent<S, M2>& that))
* between compatible persistent handles, for instance assigning a : val_(New(isolate, *that)) {
* Persistent<String> to a variable declared as Persistent<Value>,
* is allowed as String is a subclass of Value.
*/
template <class S> V8_INLINE(Persistent(Persistent<S> that))
: Handle<T>(reinterpret_cast<T*>(*that)) {
/**
* This check fails when trying to convert between incompatible
* handles. For example, converting from a Handle<String> to a
* Handle<Number>.
*/
TYPE_CHECK(T, S); TYPE_CHECK(T, S);
} }
/**
template <class S> V8_INLINE(Persistent(S* that)) : Handle<T>(that) { } * 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)) : val_(0) {
Copy(that);
}
template <class S, class M2>
V8_INLINE(Persistent(const Persistent<S, M2>& that)) : val_(0) {
Copy(that);
}
V8_INLINE(Persistent& operator=(const Persistent& that)) { // NOLINT
Copy(that);
return *this;
}
template <class S, class M2>
V8_INLINE(Persistent& operator=(const Persistent<S, M2>& that)) { // NOLI
NT
Copy(that);
return *this;
}
/** /**
* A constructor that creates a new global cell pointing to that. In cont * If non-empty, destroy the underlying storage cell
rast * IsEmpty() will return true after this call.
* to the copy constructor, this creates a new persistent handle which ne
eds
* to be separately disposed.
*/ */
template <class S> V8_INLINE(Persistent(Isolate* isolate, Handle<S> that) V8_INLINE(void Reset());
) template <class S>
: Handle<T>(New(isolate, that)) { }
/** /**
* "Casts" a plain handle which is known to be a persistent handle * If non-empty, destroy the underlying storage cell
* to a persistent handle. * and create a new one with the contents of other if other is non empty
*/ */
template <class S> explicit V8_INLINE(Persistent(Handle<S> that)) V8_INLINE(void Reset(Isolate* isolate, const Handle<S>& other));
: Handle<T>(*that) { } /**
* If non-empty, destroy the underlying storage cell
#endif * and create a new one with the contents of other if other is non empty
*/
#ifdef V8_USE_UNSAFE_HANDLES template <class S, class M2>
template <class S> V8_INLINE(static Persistent<T> Cast(Persistent<S> that V8_INLINE(void Reset(Isolate* isolate, const Persistent<S, M2>& other));
)) { // TODO(dcarney): deprecate
#ifdef V8_ENABLE_CHECKS V8_INLINE(void Dispose()) { Reset(); }
// If we're going to perform the type check then we have to check V8_DEPRECATED(V8_INLINE(void Dispose(Isolate* isolate))) { Reset(); }
// that the handle isn't empty before doing the checked cast.
if (that.IsEmpty()) return Persistent<T>();
#endif
return Persistent<T>(T::Cast(*that));
}
template <class S> V8_INLINE(Persistent<S> As()) { V8_INLINE(bool IsEmpty() const) { return val_ == 0; }
return Persistent<S>::Cast(*this);
}
#else // TODO(dcarney): this is pretty useless, fix or remove
template <class S> template <class S>
V8_INLINE(static Persistent<T>& Cast(Persistent<S>& that)) { // NOLINT V8_INLINE(static Persistent<T>& Cast(Persistent<S>& that)) { // NOLINT
#ifdef V8_ENABLE_CHECKS #ifdef V8_ENABLE_CHECKS
// If we're going to perform the type check then we have to check // 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. // that the handle isn't empty before doing the checked cast.
if (!that.IsEmpty()) T::Cast(*that); if (!that.IsEmpty()) T::Cast(*that);
#endif #endif
return reinterpret_cast<Persistent<T>&>(that); return reinterpret_cast<Persistent<T>&>(that);
} }
// TODO(dcarney): this is pretty useless, fix or remove
template <class S> V8_INLINE(Persistent<S>& As()) { // NOLINT template <class S> V8_INLINE(Persistent<S>& As()) { // NOLINT
return Persistent<S>::Cast(*this); return Persistent<S>::Cast(*this);
} }
#endif
#ifdef V8_USE_UNSAFE_HANDLES
V8_DEPRECATED(static Persistent<T> New(Handle<T> that));
V8_INLINE(static Persistent<T> New(Isolate* isolate, Handle<T> that));
V8_INLINE(static Persistent<T> New(Isolate* isolate, Persistent<T> that))
;
#endif
#ifndef V8_USE_UNSAFE_HANDLES template <class S, class M2> V8_INLINE(
template <class S> V8_INLINE( bool operator==(const Persistent<S, M2>& that) const) {
bool operator==(const Persistent<S>& that) const) {
internal::Object** a = reinterpret_cast<internal::Object**>(**this); internal::Object** a = reinterpret_cast<internal::Object**>(**this);
internal::Object** b = reinterpret_cast<internal::Object**>(*that); internal::Object** b = reinterpret_cast<internal::Object**>(*that);
if (a == 0) return b == 0; if (a == 0) return b == 0;
if (b == 0) return false; if (b == 0) return false;
return *a == *b; return *a == *b;
} }
template <class S> V8_INLINE(bool operator==(const Handle<S>& that) const ) { template <class S> V8_INLINE(bool operator==(const Handle<S>& that) const ) {
internal::Object** a = reinterpret_cast<internal::Object**>(**this); internal::Object** a = reinterpret_cast<internal::Object**>(**this);
internal::Object** b = reinterpret_cast<internal::Object**>(*that); internal::Object** b = reinterpret_cast<internal::Object**>(*that);
if (a == 0) return b == 0; if (a == 0) return b == 0;
if (b == 0) return false; if (b == 0) return false;
return *a == *b; return *a == *b;
} }
template <class S> V8_INLINE( template <class S, class M2> V8_INLINE(
bool operator!=(const Persistent<S>& that) const) { bool operator!=(const Persistent<S, M2>& that) const) {
return !operator==(that); return !operator==(that);
} }
template <class S> V8_INLINE(bool operator!=(const Handle<S>& that) const ) { template <class S> V8_INLINE(bool operator!=(const Handle<S>& that) const ) {
return !operator==(that); return !operator==(that);
} }
#endif
V8_INLINE(void Dispose()); template<typename P>
V8_INLINE(void SetWeak(
P* parameter,
typename WeakCallbackData<T, P>::Callback callback));
/** template<typename S, typename P>
* Releases the storage cell referenced by this persistent handle. V8_INLINE(void SetWeak(
* Does not remove the reference to the cell from any handles. P* parameter,
* This handle's reference, and any other references to the storage typename WeakCallbackData<S, P>::Callback callback));
* cell remain and IsEmpty will still return false.
*/
V8_DEPRECATED(V8_INLINE(void Dispose(Isolate* isolate))) { Dispose(); }
/** // TODO(dcarney): deprecate
* 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<typename S, typename P> template<typename S, typename P>
V8_INLINE(void MakeWeak( V8_INLINE(void MakeWeak(
P* parameters, P* parameter,
typename WeakReferenceCallbacks<S, P>::Revivable callback)); typename WeakReferenceCallbacks<S, P>::Revivable callback));
// TODO(dcarney): deprecate
template<typename P> template<typename P>
V8_INLINE(void MakeWeak( V8_INLINE(void MakeWeak(
P* parameters, P* parameter,
typename WeakReferenceCallbacks<T, P>::Revivable callback));
template<typename S, typename P>
V8_DEPRECATED(void MakeWeak(
Isolate* isolate,
P* parameters,
typename WeakReferenceCallbacks<S, P>::Revivable callback));
template<typename P>
V8_DEPRECATED(void MakeWeak(
Isolate* isolate,
P* parameters,
typename WeakReferenceCallbacks<T, P>::Revivable callback)); typename WeakReferenceCallbacks<T, P>::Revivable callback));
V8_INLINE(void ClearWeak()); V8_INLINE(void ClearWeak());
V8_DEPRECATED(V8_INLINE(void ClearWeak(Isolate* isolate))) { ClearWeak(); } V8_DEPRECATED(V8_INLINE(void ClearWeak(Isolate* isolate))) { ClearWeak(); }
/** /**
* Marks the reference to this object independent. Garbage collector is f ree * Marks the reference to this object independent. Garbage collector is f ree
* to ignore any object groups containing this object. Weak callback for an * to ignore any object groups containing this object. Weak callback for an
* independent handle should not assume that it will be preceded by a glo bal * independent handle should not assume that it will be preceded by a glo bal
skipping to change at line 730 skipping to change at line 697
/** /**
* Returns the class ID previously assigned to this handle or 0 if no cla ss ID * Returns the class ID previously assigned to this handle or 0 if no cla ss ID
* was previously assigned. * was previously assigned.
*/ */
V8_INLINE(uint16_t WrapperClassId() const); V8_INLINE(uint16_t WrapperClassId() const);
V8_DEPRECATED(V8_INLINE(uint16_t WrapperClassId(Isolate* isolate)) const) { V8_DEPRECATED(V8_INLINE(uint16_t WrapperClassId(Isolate* isolate)) const) {
return WrapperClassId(); return WrapperClassId();
} }
/** // TODO(dcarney): remove
* Disposes the current contents of the handle and replaces it.
*/
V8_INLINE(void Reset(Isolate* isolate, const Handle<T>& other));
#ifndef V8_USE_UNSAFE_HANDLES
V8_INLINE(void Reset(Isolate* isolate, const Persistent<T>& other));
#endif
/**
* Returns the underlying raw pointer and clears the handle. The caller i
s
* responsible of eventually destroying the underlying object (by creatin
g 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()); V8_INLINE(T* ClearAndLeak());
#ifndef V8_USE_UNSAFE_HANDLES // TODO(dcarney): remove
V8_INLINE(void Clear()) { val_ = 0; }
private:
// 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: // TODO(dcarney): remove
#ifndef V8_ALLOW_ACCESS_TO_RAW_HANDLE_CONSTRUCTOR #ifndef V8_ALLOW_ACCESS_TO_RAW_HANDLE_CONSTRUCTOR
private: private:
#endif #endif
// TODO(dcarney): remove before cutover
template <class S> V8_INLINE(Persistent(S* that)) : val_(that) { } template <class S> V8_INLINE(Persistent(S* that)) : val_(that) { }
// TODO(dcarney): remove before cutover
V8_INLINE(T* operator*() const) { return val_; } V8_INLINE(T* operator*() const) { return val_; }
private: private:
// TODO(dcarney): remove before cutover
V8_INLINE(T* operator->() const) { return val_; }
public:
#endif
private:
friend class Utils; friend class Utils;
template<class F> friend class Handle; template<class F> friend class Handle;
template<class F> friend class Local; template<class F> friend class Local;
template<class F> friend class Persistent; template<class F1, class F2> friend class Persistent;
template<class F> friend class ReturnValue; template<class F> friend class ReturnValue;
V8_INLINE(static T* New(Isolate* isolate, T* that)); V8_INLINE(static T* New(Isolate* isolate, T* that));
template<class S, class M2>
V8_INLINE(void Copy(const Persistent<S, M2>& that));
#ifndef V8_USE_UNSAFE_HANDLES
T* val_; T* val_;
#endif
}; };
/** /**
* A stack-allocated class that governs a number of local handles. * A stack-allocated class that governs a number of local handles.
* After a handle scope has been created, all local handles will be * After a handle scope has been created, all local handles will be
* allocated within that handle scope until either the handle scope is * allocated within that handle scope until either the handle scope is
* deleted or another handle scope is created. If there is already a * deleted or another handle scope is created. If there is already a
* handle scope and a new one is created, all allocations will take * handle scope and a new one is created, all allocations will take
* place in the new handle scope until it is deleted. After that, * place in the new handle scope until it is deleted. After that,
* new handles will again be allocated in the original handle scope. * new handles will again be allocated in the original handle scope.
skipping to change at line 2329 skipping to change at line 2264
* is negative the returned array will have length 0. * is negative the returned array will have length 0.
*/ */
static Local<Array> New(int length = 0); static Local<Array> New(int length = 0);
V8_INLINE(static Array* Cast(Value* obj)); V8_INLINE(static Array* Cast(Value* obj));
private: private:
Array(); Array();
static void CheckCast(Value* obj); static void CheckCast(Value* obj);
}; };
template<typename T>
class ReturnValue {
public:
template <class S> V8_INLINE(ReturnValue(const ReturnValue<S>& that))
: value_(that.value_) {
TYPE_CHECK(T, S);
}
// Handle setters
template <typename S> V8_INLINE(void Set(const Persistent<S>& handle));
template <typename S> V8_INLINE(void Set(const Handle<S> handle));
// Fast primitive setters
V8_INLINE(void Set(bool value));
V8_INLINE(void Set(double i));
V8_INLINE(void Set(int32_t i));
V8_INLINE(void Set(uint32_t i));
// Fast JS primitive setters
V8_INLINE(void SetNull());
V8_INLINE(void SetUndefined());
V8_INLINE(void SetEmptyString());
// Convenience getter for Isolate
V8_INLINE(Isolate* GetIsolate());
private:
template<class F> friend class ReturnValue;
template<class F> friend class FunctionCallbackInfo;
template<class F> friend class PropertyCallbackInfo;
V8_INLINE(internal::Object* GetDefaultValue());
V8_INLINE(explicit ReturnValue(internal::Object** slot));
internal::Object** value_;
};
/**
* The argument information given to function call callbacks. This
* class provides access to information about the context of the call,
* including the receiver, the number and values of arguments, and
* the holder of the function.
*/
template<typename T>
class FunctionCallbackInfo {
public:
V8_INLINE(int Length() const);
V8_INLINE(Local<Value> operator[](int i) const);
V8_INLINE(Local<Function> Callee() const);
V8_INLINE(Local<Object> This() const);
V8_INLINE(Local<Object> Holder() const);
V8_INLINE(bool IsConstructCall() const);
V8_INLINE(Local<Value> Data() const);
V8_INLINE(Isolate* GetIsolate() const);
V8_INLINE(ReturnValue<T> GetReturnValue() const);
// This shouldn't be public, but the arm compiler needs it.
static const int kArgsLength = 6;
protected:
friend class internal::FunctionCallbackArguments;
friend class internal::CustomArguments<FunctionCallbackInfo>;
static const int kReturnValueIndex = 0;
static const int kReturnValueDefaultValueIndex = -1;
static const int kIsolateIndex = -2;
static const int kDataIndex = -3;
static const int kCalleeIndex = -4;
static const int kHolderIndex = -5;
V8_INLINE(FunctionCallbackInfo(internal::Object** implicit_args,
internal::Object** values,
int length,
bool is_construct_call));
internal::Object** implicit_args_;
internal::Object** values_;
int length_;
bool is_construct_call_;
};
/**
* The information passed to a property callback about the context
* of the property access.
*/
template<typename T>
class PropertyCallbackInfo {
public:
V8_INLINE(Isolate* GetIsolate() const);
V8_INLINE(Local<Value> Data() const);
V8_INLINE(Local<Object> This() const);
V8_INLINE(Local<Object> Holder() const);
V8_INLINE(ReturnValue<T> GetReturnValue() const);
// This shouldn't be public, but the arm compiler needs it.
static const int kArgsLength = 6;
protected:
friend class MacroAssembler;
friend class internal::PropertyCallbackArguments;
friend class internal::CustomArguments<PropertyCallbackInfo>;
static const int kThisIndex = 0;
static const int kHolderIndex = -1;
static const int kDataIndex = -2;
static const int kReturnValueIndex = -3;
static const int kReturnValueDefaultValueIndex = -4;
static const int kIsolateIndex = -5;
V8_INLINE(PropertyCallbackInfo(internal::Object** args))
: args_(args) { }
internal::Object** args_;
};
typedef void (*FunctionCallback)(const FunctionCallbackInfo<Value>& info);
/** /**
* A JavaScript function object (ECMA-262, 15.3). * A JavaScript function object (ECMA-262, 15.3).
*/ */
class V8_EXPORT Function : public Object { class V8_EXPORT Function : public Object {
public: public:
/**
* Create a function in the current execution context
* for a given FunctionCallback.
*/
static Local<Function> New(Isolate* isolate,
FunctionCallback callback,
Local<Value> data = Local<Value>(),
int length = 0);
Local<Object> NewInstance() const; Local<Object> NewInstance() const;
Local<Object> NewInstance(int argc, Handle<Value> argv[]) const; Local<Object> NewInstance(int argc, Handle<Value> argv[]) const;
Local<Value> Call(Handle<Object> recv, int argc, Handle<Value> argv[]); Local<Value> Call(Handle<Object> recv, int argc, Handle<Value> argv[]);
void SetName(Handle<String> name); void SetName(Handle<String> name);
Handle<Value> GetName() const; Handle<Value> GetName() const;
/** /**
* Name inferred from variable or property assignment of this function. * Name inferred from variable or property assignment of this function.
* Used to facilitate debugging and profiling of JavaScript code written * Used to facilitate debugging and profiling of JavaScript code written
* in an OO style, where many functions are anonymous but are assigned * in an OO style, where many functions are anonymous but are assigned
skipping to change at line 2979 skipping to change at line 3028
Local<AccessorSignature>(), Local<AccessorSignature>(),
AccessControl settings = DEFAULT); AccessControl settings = DEFAULT);
private: private:
Template(); Template();
friend class ObjectTemplate; friend class ObjectTemplate;
friend class FunctionTemplate; friend class FunctionTemplate;
}; };
template<typename T>
class ReturnValue {
public:
template <class S> V8_INLINE(ReturnValue(const ReturnValue<S>& that))
: value_(that.value_) {
TYPE_CHECK(T, S);
}
// Handle setters
template <typename S> V8_INLINE(void Set(const Persistent<S>& handle));
template <typename S> V8_INLINE(void Set(const Handle<S> handle));
// Fast primitive setters
V8_INLINE(void Set(bool value));
V8_INLINE(void Set(double i));
V8_INLINE(void Set(int32_t i));
V8_INLINE(void Set(uint32_t i));
// Fast JS primitive setters
V8_INLINE(void SetNull());
V8_INLINE(void SetUndefined());
V8_INLINE(void SetEmptyString());
// Convenience getter for Isolate
V8_INLINE(Isolate* GetIsolate());
private:
template<class F> friend class ReturnValue;
template<class F> friend class FunctionCallbackInfo;
template<class F> friend class PropertyCallbackInfo;
V8_INLINE(internal::Object* GetDefaultValue());
V8_INLINE(explicit ReturnValue(internal::Object** slot));
internal::Object** value_;
};
/**
* The argument information given to function call callbacks. This
* class provides access to information about the context of the call,
* including the receiver, the number and values of arguments, and
* the holder of the function.
*/
template<typename T>
class FunctionCallbackInfo {
public:
V8_INLINE(int Length() const);
V8_INLINE(Local<Value> operator[](int i) const);
V8_INLINE(Local<Function> Callee() const);
V8_INLINE(Local<Object> This() const);
V8_INLINE(Local<Object> Holder() const);
V8_INLINE(bool IsConstructCall() const);
V8_INLINE(Local<Value> Data() const);
V8_INLINE(Isolate* GetIsolate() const);
V8_INLINE(ReturnValue<T> GetReturnValue() const);
// This shouldn't be public, but the arm compiler needs it.
static const int kArgsLength = 6;
protected:
friend class internal::FunctionCallbackArguments;
friend class internal::CustomArguments<FunctionCallbackInfo>;
static const int kReturnValueIndex = 0;
static const int kReturnValueDefaultValueIndex = -1;
static const int kIsolateIndex = -2;
static const int kDataIndex = -3;
static const int kCalleeIndex = -4;
static const int kHolderIndex = -5;
V8_INLINE(FunctionCallbackInfo(internal::Object** implicit_args,
internal::Object** values,
int length,
bool is_construct_call));
internal::Object** implicit_args_;
internal::Object** values_;
int length_;
bool is_construct_call_;
};
/**
* The information passed to a property callback about the context
* of the property access.
*/
template<typename T>
class PropertyCallbackInfo {
public:
V8_INLINE(Isolate* GetIsolate() const);
V8_INLINE(Local<Value> Data() const);
V8_INLINE(Local<Object> This() const);
V8_INLINE(Local<Object> Holder() const);
V8_INLINE(ReturnValue<T> GetReturnValue() const);
// This shouldn't be public, but the arm compiler needs it.
static const int kArgsLength = 6;
protected:
friend class MacroAssembler;
friend class internal::PropertyCallbackArguments;
friend class internal::CustomArguments<PropertyCallbackInfo>;
static const int kThisIndex = 0;
static const int kHolderIndex = -1;
static const int kDataIndex = -2;
static const int kReturnValueIndex = -3;
static const int kReturnValueDefaultValueIndex = -4;
static const int kIsolateIndex = -5;
V8_INLINE(PropertyCallbackInfo(internal::Object** args))
: args_(args) { }
internal::Object** args_;
};
typedef void (*FunctionCallback)(const FunctionCallbackInfo<Value>& info);
/** /**
* NamedProperty[Getter|Setter] are used as interceptors on object. * NamedProperty[Getter|Setter] are used as interceptors on object.
* See ObjectTemplate::SetNamedPropertyHandler. * See ObjectTemplate::SetNamedPropertyHandler.
*/ */
typedef void (*NamedPropertyGetterCallback)( typedef void (*NamedPropertyGetterCallback)(
Local<String> property, Local<String> property,
const PropertyCallbackInfo<Value>& info); const PropertyCallbackInfo<Value>& info);
/** /**
* Returns the value if the setter intercepts the request. * Returns the value if the setter intercepts the request.
skipping to change at line 4488 skipping to change at line 4432
*/ */
static void SetJitCodeEventHandler(JitCodeEventOptions options, static void SetJitCodeEventHandler(JitCodeEventOptions options,
JitCodeEventHandler event_handler); JitCodeEventHandler event_handler);
// TODO(svenpanne) Really deprecate me when Chrome is fixed. // TODO(svenpanne) Really deprecate me when Chrome is fixed.
/** Deprecated. Use Isolate::AdjustAmountOfExternalAllocatedMemory instea d. */ /** Deprecated. Use Isolate::AdjustAmountOfExternalAllocatedMemory instea d. */
static intptr_t AdjustAmountOfExternalAllocatedMemory( static intptr_t AdjustAmountOfExternalAllocatedMemory(
intptr_t change_in_bytes); intptr_t change_in_bytes);
/** /**
* Retrieve the V8 thread id of the calling thread.
*
* The thread id for a thread should only be retrieved after the V8
* lock has been acquired with a Locker object with that thread.
*/
static int GetCurrentThreadId();
/**
* Forcefully terminate execution of a JavaScript thread. This can
* be used to terminate long-running scripts.
*
* TerminateExecution should only be called when then V8 lock has
* been acquired with a Locker object. Therefore, in order to be
* able to terminate long-running threads, preemption must be
* enabled to allow the user of TerminateExecution to acquire the
* lock.
*
* The termination is achieved by throwing an exception that is
* uncatchable by JavaScript exception handlers. Termination
* exceptions act as if they were caught by a C++ TryCatch exception
* handler. If forceful termination is used, any C++ TryCatch
* exception handler that catches an exception should check if that
* exception is a termination exception and immediately return if
* that is the case. Returning immediately in that case will
* continue the propagation of the termination exception if needed.
*
* The thread id passed to TerminateExecution must have been
* obtained by calling GetCurrentThreadId on the thread in question.
*
* \param thread_id The thread id of the thread to terminate.
*/
static void TerminateExecution(int thread_id);
/**
* Forcefully terminate the current thread of JavaScript execution * Forcefully terminate the current thread of JavaScript execution
* in the given isolate. If no isolate is provided, the default * in the given isolate. If no isolate is provided, the default
* isolate is used. * isolate is used.
* *
* This method can be used by any thread even if that thread has not * This method can be used by any thread even if that thread has not
* acquired the V8 lock with a Locker object. * acquired the V8 lock with a Locker object.
* *
* \param isolate The isolate in which to terminate the current JS execut ion. * \param isolate The isolate in which to terminate the current JS execut ion.
*/ */
static void TerminateExecution(Isolate* isolate = NULL); static void TerminateExecution(Isolate* isolate = NULL);
skipping to change at line 4639 skipping to change at line 4549
* Initialize the ICU library bundled with V8. The embedder should only * Initialize the ICU library bundled with V8. The embedder should only
* invoke this method when using the bundled ICU. Returns true on success . * invoke this method when using the bundled ICU. Returns true on success .
*/ */
static bool InitializeICU(); static bool InitializeICU();
private: private:
V8(); V8();
static internal::Object** GlobalizeReference(internal::Isolate* isolate, static internal::Object** GlobalizeReference(internal::Isolate* isolate,
internal::Object** handle); internal::Object** handle);
static internal::Object** CopyPersistent(internal::Object** handle);
static void DisposeGlobal(internal::Object** global_handle); static void DisposeGlobal(internal::Object** global_handle);
typedef WeakReferenceCallbacks<Value, void>::Revivable RevivableCallback; typedef WeakReferenceCallbacks<Value, void>::Revivable RevivableCallback;
typedef WeakCallbackData<Value, void>::Callback WeakCallback;
static void MakeWeak(internal::Object** global_handle, static void MakeWeak(internal::Object** global_handle,
void* data, void* data,
WeakCallback weak_callback,
RevivableCallback weak_reference_callback); RevivableCallback weak_reference_callback);
static void ClearWeak(internal::Object** global_handle); static void ClearWeak(internal::Object** global_handle);
static void Eternalize(Isolate* isolate, static void Eternalize(Isolate* isolate,
Value* handle, Value* handle,
int* index); int* index);
static Local<Value> GetEternal(Isolate* isolate, int index); static Local<Value> GetEternal(Isolate* isolate, int index);
template <class T> friend class Handle; template <class T> friend class Handle;
template <class T> friend class Local; template <class T> friend class Local;
template <class T> friend class Eternal; template <class T> friend class Eternal;
template <class T> friend class Persistent; template <class T, class M> friend class Persistent;
friend class Context; friend class Context;
}; };
/** /**
* An external exception handler. * An external exception handler.
*/ */
class V8_EXPORT TryCatch { class V8_EXPORT TryCatch {
public: public:
/** /**
* Creates a new try/catch block and registers it with v8. Note that * Creates a new try/catch block and registers it with v8. Note that
skipping to change at line 4990 skipping to change at line 4903
* Stack-allocated class which sets the execution context for all * Stack-allocated class which sets the execution context for all
* operations executed within a local scope. * operations executed within a local scope.
*/ */
class Scope { class Scope {
public: public:
explicit V8_INLINE(Scope(Handle<Context> context)) : context_(context) { explicit V8_INLINE(Scope(Handle<Context> context)) : context_(context) {
context_->Enter(); context_->Enter();
} }
// TODO(dcarney): deprecate // TODO(dcarney): deprecate
V8_INLINE(Scope(Isolate* isolate, Persistent<Context>& context)) // NOL INT V8_INLINE(Scope(Isolate* isolate, Persistent<Context>& context)) // NOL INT
#ifndef V8_USE_UNSAFE_HANDLES
: context_(Handle<Context>::New(isolate, context)) { : context_(Handle<Context>::New(isolate, context)) {
#else
: context_(Local<Context>::New(isolate, context)) {
#endif
context_->Enter(); context_->Enter();
} }
V8_INLINE(~Scope()) { context_->Exit(); } V8_INLINE(~Scope()) { context_->Exit(); }
private: private:
Handle<Context> context_; Handle<Context> context_;
}; };
private: private:
friend class Value; friend class Value;
skipping to change at line 5474 skipping to change at line 5383
reinterpret_cast<internal::HeapObject*>(*p)))); reinterpret_cast<internal::HeapObject*>(*p))));
} }
return Local<T>(reinterpret_cast<T*>(HandleScope::CreateHandle(*p))); return Local<T>(reinterpret_cast<T*>(HandleScope::CreateHandle(*p)));
} }
template <class T> template <class T>
Local<T> Local<T>::New(Isolate* isolate, Handle<T> that) { Local<T> Local<T>::New(Isolate* isolate, Handle<T> that) {
return New(isolate, that.val_); return New(isolate, that.val_);
} }
#ifndef V8_USE_UNSAFE_HANDLES
template <class T> template <class T>
Local<T> Local<T>::New(Isolate* isolate, const Persistent<T>& that) { template <class M>
Local<T> Local<T>::New(Isolate* isolate, const Persistent<T, M>& that) {
return New(isolate, that.val_); return New(isolate, that.val_);
} }
template <class T> template <class T>
Handle<T> Handle<T>::New(Isolate* isolate, T* that) { Handle<T> Handle<T>::New(Isolate* isolate, T* that) {
if (that == NULL) return Handle<T>(); if (that == NULL) return Handle<T>();
T* that_ptr = that; T* that_ptr = that;
internal::Object** p = reinterpret_cast<internal::Object**>(that_ptr); internal::Object** p = reinterpret_cast<internal::Object**>(that_ptr);
return Handle<T>(reinterpret_cast<T*>(HandleScope::CreateHandle( return Handle<T>(reinterpret_cast<T*>(HandleScope::CreateHandle(
reinterpret_cast<internal::Isolate*>(isolate), *p))); reinterpret_cast<internal::Isolate*>(isolate), *p)));
} }
#endif
template <class T> template <class T>
Local<T> Local<T>::New(Isolate* isolate, T* that) { Local<T> Local<T>::New(Isolate* isolate, T* that) {
if (that == NULL) return Local<T>(); if (that == NULL) return Local<T>();
T* that_ptr = that; T* that_ptr = that;
internal::Object** p = reinterpret_cast<internal::Object**>(that_ptr); internal::Object** p = reinterpret_cast<internal::Object**>(that_ptr);
return Local<T>(reinterpret_cast<T*>(HandleScope::CreateHandle( return Local<T>(reinterpret_cast<T*>(HandleScope::CreateHandle(
reinterpret_cast<internal::Isolate*>(isolate), *p))); reinterpret_cast<internal::Isolate*>(isolate), *p)));
} }
skipping to change at line 5511 skipping to change at line 5419
void Eternal<T>::Set(Isolate* isolate, Local<S> handle) { void Eternal<T>::Set(Isolate* isolate, Local<S> handle) {
TYPE_CHECK(T, S); TYPE_CHECK(T, S);
V8::Eternalize(isolate, reinterpret_cast<Value*>(*handle), &this->index_) ; V8::Eternalize(isolate, reinterpret_cast<Value*>(*handle), &this->index_) ;
} }
template<class T> template<class T>
Local<T> Eternal<T>::Get(Isolate* isolate) { Local<T> Eternal<T>::Get(Isolate* isolate) {
return Local<T>(reinterpret_cast<T*>(*V8::GetEternal(isolate, index_))); return Local<T>(reinterpret_cast<T*>(*V8::GetEternal(isolate, index_)));
} }
#ifdef V8_USE_UNSAFE_HANDLES template <class T, class M>
template <class T> T* Persistent<T, M>::New(Isolate* isolate, T* that) {
Persistent<T> Persistent<T>::New(Handle<T> that) {
return New(Isolate::GetCurrent(), that.val_);
}
template <class T>
Persistent<T> Persistent<T>::New(Isolate* isolate, Handle<T> that) {
return New(Isolate::GetCurrent(), that.val_);
}
template <class T>
Persistent<T> Persistent<T>::New(Isolate* isolate, Persistent<T> that) {
return New(Isolate::GetCurrent(), that.val_);
}
#endif
template <class T>
T* Persistent<T>::New(Isolate* isolate, T* that) {
if (that == NULL) return NULL; if (that == NULL) return NULL;
internal::Object** p = reinterpret_cast<internal::Object**>(that); internal::Object** p = reinterpret_cast<internal::Object**>(that);
return reinterpret_cast<T*>( return reinterpret_cast<T*>(
V8::GlobalizeReference(reinterpret_cast<internal::Isolate*>(isolate), V8::GlobalizeReference(reinterpret_cast<internal::Isolate*>(isolate),
p)); p));
} }
template <class T> template <class T, class M>
bool Persistent<T>::IsIndependent() const { template <class S, class M2>
void Persistent<T, M>::Copy(const Persistent<S, M2>& that) {
TYPE_CHECK(T, S);
Reset();
if (that.IsEmpty()) return;
internal::Object** p = reinterpret_cast<internal::Object**>(that.val_);
this->val_ = reinterpret_cast<T*>(V8::CopyPersistent(p));
M::Copy(that, this);
}
template <class T, class M>
bool Persistent<T, M>::IsIndependent() const {
typedef internal::Internals I; typedef internal::Internals I;
if (this->IsEmpty()) return false; if (this->IsEmpty()) return false;
return I::GetNodeFlag(reinterpret_cast<internal::Object**>(this->val_), return I::GetNodeFlag(reinterpret_cast<internal::Object**>(this->val_),
I::kNodeIsIndependentShift); I::kNodeIsIndependentShift);
} }
template <class T> template <class T, class M>
bool Persistent<T>::IsNearDeath() const { bool Persistent<T, M>::IsNearDeath() const {
typedef internal::Internals I; typedef internal::Internals I;
if (this->IsEmpty()) return false; if (this->IsEmpty()) return false;
uint8_t node_state = uint8_t node_state =
I::GetNodeState(reinterpret_cast<internal::Object**>(this->val_)); I::GetNodeState(reinterpret_cast<internal::Object**>(this->val_));
return node_state == I::kNodeStateIsNearDeathValue || return node_state == I::kNodeStateIsNearDeathValue ||
node_state == I::kNodeStateIsPendingValue; node_state == I::kNodeStateIsPendingValue;
} }
template <class T> template <class T, class M>
bool Persistent<T>::IsWeak() const { bool Persistent<T, M>::IsWeak() const {
typedef internal::Internals I; typedef internal::Internals I;
if (this->IsEmpty()) return false; if (this->IsEmpty()) return false;
return I::GetNodeState(reinterpret_cast<internal::Object**>(this->val_)) == return I::GetNodeState(reinterpret_cast<internal::Object**>(this->val_)) ==
I::kNodeStateIsWeakValue; I::kNodeStateIsWeakValue;
} }
template <class T> template <class T, class M>
void Persistent<T>::Dispose() { void Persistent<T, M>::Reset() {
if (this->IsEmpty()) return; if (this->IsEmpty()) return;
V8::DisposeGlobal(reinterpret_cast<internal::Object**>(this->val_)); V8::DisposeGlobal(reinterpret_cast<internal::Object**>(this->val_));
#ifndef V8_USE_UNSAFE_HANDLES
val_ = 0; val_ = 0;
#endif
} }
template <class T> template <class T, class M>
template <class S>
void Persistent<T, M>::Reset(Isolate* isolate, const Handle<S>& other) {
TYPE_CHECK(T, S);
Reset();
if (other.IsEmpty()) return;
this->val_ = New(isolate, other.val_);
}
template <class T, class M>
template <class S, class M2>
void Persistent<T, M>::Reset(Isolate* isolate,
const Persistent<S, M2>& other) {
TYPE_CHECK(T, S);
Reset();
if (other.IsEmpty()) return;
this->val_ = New(isolate, other.val_);
}
template <class T, class M>
template <typename S, typename P> template <typename S, typename P>
void Persistent<T>::MakeWeak( void Persistent<T, M>::SetWeak(
P* parameters, P* parameter,
typename WeakReferenceCallbacks<S, P>::Revivable callback) { typename WeakCallbackData<S, P>::Callback callback) {
TYPE_CHECK(S, T); TYPE_CHECK(S, T);
typedef typename WeakReferenceCallbacks<Value, void>::Revivable Revivable ; typedef typename WeakCallbackData<Value, void>::Callback Callback;
V8::MakeWeak(reinterpret_cast<internal::Object**>(this->val_), V8::MakeWeak(reinterpret_cast<internal::Object**>(this->val_),
parameters, parameter,
reinterpret_cast<Revivable>(callback)); reinterpret_cast<Callback>(callback),
NULL);
} }
template <class T> template <class T, class M>
template <typename P> template <typename P>
void Persistent<T>::MakeWeak( void Persistent<T, M>::SetWeak(
P* parameters, P* parameter,
typename WeakReferenceCallbacks<T, P>::Revivable callback) { typename WeakCallbackData<T, P>::Callback callback) {
MakeWeak<T, P>(parameters, callback); SetWeak<T, P>(parameter, callback);
} }
template <class T> template <class T, class M>
template <typename S, typename P> template <typename S, typename P>
void Persistent<T>::MakeWeak( void Persistent<T, M>::MakeWeak(
Isolate* isolate,
P* parameters, P* parameters,
typename WeakReferenceCallbacks<S, P>::Revivable callback) { typename WeakReferenceCallbacks<S, P>::Revivable callback) {
MakeWeak<S, P>(parameters, callback); TYPE_CHECK(S, T);
typedef typename WeakReferenceCallbacks<Value, void>::Revivable Revivable
;
V8::MakeWeak(reinterpret_cast<internal::Object**>(this->val_),
parameters,
NULL,
reinterpret_cast<Revivable>(callback));
} }
template <class T> template <class T, class M>
template<typename P> template <typename P>
void Persistent<T>::MakeWeak( void Persistent<T, M>::MakeWeak(
Isolate* isolate,
P* parameters, P* parameters,
typename WeakReferenceCallbacks<T, P>::Revivable callback) { typename WeakReferenceCallbacks<T, P>::Revivable callback) {
MakeWeak<P>(parameters, callback); MakeWeak<T, P>(parameters, callback);
} }
template <class T> template <class T, class M>
void Persistent<T>::ClearWeak() { void Persistent<T, M>::ClearWeak() {
V8::ClearWeak(reinterpret_cast<internal::Object**>(this->val_)); V8::ClearWeak(reinterpret_cast<internal::Object**>(this->val_));
} }
template <class T> template <class T, class M>
void Persistent<T>::MarkIndependent() { void Persistent<T, M>::MarkIndependent() {
typedef internal::Internals I; typedef internal::Internals I;
if (this->IsEmpty()) return; if (this->IsEmpty()) return;
I::UpdateNodeFlag(reinterpret_cast<internal::Object**>(this->val_), I::UpdateNodeFlag(reinterpret_cast<internal::Object**>(this->val_),
true, true,
I::kNodeIsIndependentShift); I::kNodeIsIndependentShift);
} }
template <class T> template <class T, class M>
void Persistent<T>::MarkPartiallyDependent() { void Persistent<T, M>::MarkPartiallyDependent() {
typedef internal::Internals I; typedef internal::Internals I;
if (this->IsEmpty()) return; if (this->IsEmpty()) return;
I::UpdateNodeFlag(reinterpret_cast<internal::Object**>(this->val_), I::UpdateNodeFlag(reinterpret_cast<internal::Object**>(this->val_),
true, true,
I::kNodeIsPartiallyDependentShift); I::kNodeIsPartiallyDependentShift);
} }
template <class T> template <class T, class M>
void Persistent<T>::Reset(Isolate* isolate, const Handle<T>& other) { T* Persistent<T, M>::ClearAndLeak() {
Dispose();
#ifdef V8_USE_UNSAFE_HANDLES
*this = *New(isolate, other);
#else
if (other.IsEmpty()) {
this->val_ = NULL;
return;
}
internal::Object** p = reinterpret_cast<internal::Object**>(other.val_);
this->val_ = reinterpret_cast<T*>(
V8::GlobalizeReference(reinterpret_cast<internal::Isolate*>(isolate),
p));
#endif
}
#ifndef V8_USE_UNSAFE_HANDLES
template <class T>
void Persistent<T>::Reset(Isolate* isolate, const Persistent<T>& other) {
Dispose();
if (other.IsEmpty()) {
this->val_ = NULL;
return;
}
internal::Object** p = reinterpret_cast<internal::Object**>(other.val_);
this->val_ = reinterpret_cast<T*>(
V8::GlobalizeReference(reinterpret_cast<internal::Isolate*>(isolate),
p));
}
#endif
template <class T>
T* Persistent<T>::ClearAndLeak() {
T* old; T* old;
#ifdef V8_USE_UNSAFE_HANDLES
old = **this;
*this = Persistent<T>();
#else
old = val_; old = val_;
val_ = NULL; val_ = NULL;
#endif
return old; return old;
} }
template <class T> template <class T, class M>
void Persistent<T>::SetWrapperClassId(uint16_t class_id) { void Persistent<T, M>::SetWrapperClassId(uint16_t class_id) {
typedef internal::Internals I; typedef internal::Internals I;
if (this->IsEmpty()) return; if (this->IsEmpty()) return;
internal::Object** obj = reinterpret_cast<internal::Object**>(this->val_) ; internal::Object** obj = reinterpret_cast<internal::Object**>(this->val_) ;
uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset; uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset;
*reinterpret_cast<uint16_t*>(addr) = class_id; *reinterpret_cast<uint16_t*>(addr) = class_id;
} }
template <class T> template <class T, class M>
uint16_t Persistent<T>::WrapperClassId() const { uint16_t Persistent<T, M>::WrapperClassId() const {
typedef internal::Internals I; typedef internal::Internals I;
if (this->IsEmpty()) return 0; if (this->IsEmpty()) return 0;
internal::Object** obj = reinterpret_cast<internal::Object**>(this->val_) ; internal::Object** obj = reinterpret_cast<internal::Object**>(this->val_) ;
uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset; uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset;
return *reinterpret_cast<uint16_t*>(addr); return *reinterpret_cast<uint16_t*>(addr);
} }
template<typename T> template<typename T>
ReturnValue<T>::ReturnValue(internal::Object** slot) : value_(slot) {} ReturnValue<T>::ReturnValue(internal::Object** slot) : value_(slot) {}
 End of changes. 96 change blocks. 
474 lines changed or deleted 351 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/