Add IsDestroyed method for Wrappable

This commit is contained in:
Cheng Zhao 2015-07-06 18:16:57 +08:00
parent cc4e2fcd94
commit 7b9926807d
4 changed files with 95 additions and 4 deletions

View file

@ -12,8 +12,7 @@
#include "base/callback.h"
#include "base/logging.h"
#include "native_mate/arguments.h"
#include "native_mate/compat.h"
#include "native_mate/converter.h"
#include "native_mate/wrappable.h"
#include "v8/include/v8.h"
namespace mate {
@ -26,6 +25,25 @@ enum CreateFunctionTemplateFlags {
namespace internal {
// Check if the class has been destroyed.
template<typename T, typename Enable = void>
struct DestroyedChecker {
static bool IsDestroyed(Arguments* args) {
return false;
}
};
template<typename T>
struct DestroyedChecker<T*, typename enable_if<
is_convertible<T*, Wrappable*>::value>::type> {
static bool IsDestroyed(Arguments* args) {
T* object;
if (args->GetHolder(&object))
return static_cast<Wrappable*>(object)->IsDestroyed();
else
return false;
}
};
template<typename T>
struct CallbackParamTraits {
typedef T LocalType;
@ -358,6 +376,12 @@ struct Dispatcher<R(P1)> {
HolderT* holder = static_cast<HolderT*>(holder_base);
typename CallbackParamTraits<P1>::LocalType a1;
if ((holder->flags & HolderIsFirstArgument) &&
DestroyedChecker<typename
CallbackParamTraits<P1>::LocalType>::IsDestroyed(&args)) {
args.ThrowError("Object has been destroyed");
MATE_METHOD_RETURN_UNDEFINED();
}
if (!GetNextArgument(&args, holder->flags, true, &a1)) {
args.ThrowError();
MATE_METHOD_RETURN_UNDEFINED();
@ -381,6 +405,12 @@ struct Dispatcher<R(P1, P2)> {
typename CallbackParamTraits<P1>::LocalType a1;
typename CallbackParamTraits<P2>::LocalType a2;
if ((holder->flags & HolderIsFirstArgument) &&
DestroyedChecker<typename
CallbackParamTraits<P1>::LocalType>::IsDestroyed(&args)) {
args.ThrowError("Object has been destroyed");
MATE_METHOD_RETURN_UNDEFINED();
}
if (!GetNextArgument(&args, holder->flags, true, &a1) ||
!GetNextArgument(&args, holder->flags, false, &a2)) {
args.ThrowError();
@ -406,6 +436,12 @@ struct Dispatcher<R(P1, P2, P3)> {
typename CallbackParamTraits<P1>::LocalType a1;
typename CallbackParamTraits<P2>::LocalType a2;
typename CallbackParamTraits<P3>::LocalType a3;
if ((holder->flags & HolderIsFirstArgument) &&
DestroyedChecker<typename
CallbackParamTraits<P1>::LocalType>::IsDestroyed(&args)) {
args.ThrowError("Object has been destroyed");
MATE_METHOD_RETURN_UNDEFINED();
}
if (!GetNextArgument(&args, holder->flags, true, &a1) ||
!GetNextArgument(&args, holder->flags, false, &a2) ||
!GetNextArgument(&args, holder->flags, false, &a3)) {
@ -433,6 +469,12 @@ struct Dispatcher<R(P1, P2, P3, P4)> {
typename CallbackParamTraits<P2>::LocalType a2;
typename CallbackParamTraits<P3>::LocalType a3;
typename CallbackParamTraits<P4>::LocalType a4;
if ((holder->flags & HolderIsFirstArgument) &&
DestroyedChecker<typename
CallbackParamTraits<P1>::LocalType>::IsDestroyed(&args)) {
args.ThrowError("Object has been destroyed");
MATE_METHOD_RETURN_UNDEFINED();
}
if (!GetNextArgument(&args, holder->flags, true, &a1) ||
!GetNextArgument(&args, holder->flags, false, &a2) ||
!GetNextArgument(&args, holder->flags, false, &a3) ||
@ -464,6 +506,12 @@ struct Dispatcher<R(P1, P2, P3, P4, P5)> {
typename CallbackParamTraits<P3>::LocalType a3;
typename CallbackParamTraits<P4>::LocalType a4;
typename CallbackParamTraits<P5>::LocalType a5;
if ((holder->flags & HolderIsFirstArgument) &&
DestroyedChecker<typename
CallbackParamTraits<P1>::LocalType>::IsDestroyed(&args)) {
args.ThrowError("Object has been destroyed");
MATE_METHOD_RETURN_UNDEFINED();
}
if (!GetNextArgument(&args, holder->flags, true, &a1) ||
!GetNextArgument(&args, holder->flags, false, &a2) ||
!GetNextArgument(&args, holder->flags, false, &a3) ||
@ -497,6 +545,12 @@ struct Dispatcher<R(P1, P2, P3, P4, P5, P6)> {
typename CallbackParamTraits<P4>::LocalType a4;
typename CallbackParamTraits<P5>::LocalType a5;
typename CallbackParamTraits<P6>::LocalType a6;
if ((holder->flags & HolderIsFirstArgument) &&
DestroyedChecker<typename
CallbackParamTraits<P1>::LocalType>::IsDestroyed(&args)) {
args.ThrowError("Object has been destroyed");
MATE_METHOD_RETURN_UNDEFINED();
}
if (!GetNextArgument(&args, holder->flags, true, &a1) ||
!GetNextArgument(&args, holder->flags, false, &a2) ||
!GetNextArgument(&args, holder->flags, false, &a3) ||
@ -532,6 +586,12 @@ struct Dispatcher<R(P1, P2, P3, P4, P5, P6, P7)> {
typename CallbackParamTraits<P5>::LocalType a5;
typename CallbackParamTraits<P6>::LocalType a6;
typename CallbackParamTraits<P7>::LocalType a7;
if ((holder->flags & HolderIsFirstArgument) &&
DestroyedChecker<typename
CallbackParamTraits<P1>::LocalType>::IsDestroyed(&args)) {
args.ThrowError("Object has been destroyed");
MATE_METHOD_RETURN_UNDEFINED();
}
if (!GetNextArgument(&args, holder->flags, true, &a1) ||
!GetNextArgument(&args, holder->flags, false, &a2) ||
!GetNextArgument(&args, holder->flags, false, &a3) ||

View file

@ -15,8 +15,7 @@ $var MAX_ARITY = 7
#include "base/callback.h"
#include "base/logging.h"
#include "native_mate/arguments.h"
#include "native_mate/compat.h"
#include "native_mate/converter.h"
#include "native_mate/wrappable.h"
#include "v8/include/v8.h"
namespace mate {
@ -29,6 +28,25 @@ enum CreateFunctionTemplateFlags {
namespace internal {
// Check if the class has been destroyed.
template<typename T, typename Enable = void>
struct DestroyedChecker {
static bool IsDestroyed(Arguments* args) {
return false;
}
};
template<typename T>
struct DestroyedChecker<T*, typename enable_if<
is_convertible<T*, Wrappable*>::value>::type> {
static bool IsDestroyed(Arguments* args) {
T* object;
if (args->GetHolder(&object))
return static_cast<Wrappable*>(object)->IsDestroyed();
else
return false;
}
};
template<typename T>
struct CallbackParamTraits {
typedef T LocalType;
@ -183,6 +201,11 @@ $if ARITY != 0 [[
$for ARG [[ typename CallbackParamTraits<P$(ARG)>::LocalType a$(ARG);
]]
if ((holder->flags & HolderIsFirstArgument) &&
DestroyedChecker<typename CallbackParamTraits<P1>::LocalType>::IsDestroyed(&args)) {
args.ThrowError("Object has been destroyed");
MATE_METHOD_RETURN_UNDEFINED();
}
if ($for ARG ||
[[!GetNextArgument(&args, holder->flags, $if ARG == 1 [[true]] $else [[false]], &a$(ARG))]]) {
args.ThrowError();

View file

@ -64,6 +64,10 @@ v8::Local<v8::Object> Wrappable::GetWrapper(v8::Isolate* isolate) {
return wrapper;
}
bool Wrappable::IsDestroyed() const {
return false;
}
namespace internal {
void* FromV8Impl(v8::Isolate* isolate, v8::Local<v8::Value> val) {

View file

@ -54,6 +54,10 @@ class Wrappable {
// object constructed by GetObjectTemplateBuilder.
v8::Local<v8::Object> GetWrapper(v8::Isolate* isolate);
// Returns whether this class has been destroyed, users should override this
// method to indicate the native type's state.
virtual bool IsDestroyed() const;
// Returns the Isolate this object is created in.
v8::Isolate* isolate() const { return isolate_; }