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 | |||