From 7b9926807d330ec173e912f28b86f843225a3286 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 6 Jul 2015 18:16:57 +0800 Subject: [PATCH] Add IsDestroyed method for Wrappable --- native_mate/function_template.h | 64 +++++++++++++++++++++++++++- native_mate/function_template.h.pump | 27 +++++++++++- native_mate/wrappable.cc | 4 ++ native_mate/wrappable.h | 4 ++ 4 files changed, 95 insertions(+), 4 deletions(-) diff --git a/native_mate/function_template.h b/native_mate/function_template.h index cb3c90d72d75..808d4b6deea9 100644 --- a/native_mate/function_template.h +++ b/native_mate/function_template.h @@ -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 +struct DestroyedChecker { + static bool IsDestroyed(Arguments* args) { + return false; + } +}; +template +struct DestroyedChecker::value>::type> { + static bool IsDestroyed(Arguments* args) { + T* object; + if (args->GetHolder(&object)) + return static_cast(object)->IsDestroyed(); + else + return false; + } +}; + template struct CallbackParamTraits { typedef T LocalType; @@ -358,6 +376,12 @@ struct Dispatcher { HolderT* holder = static_cast(holder_base); typename CallbackParamTraits::LocalType a1; + if ((holder->flags & HolderIsFirstArgument) && + DestroyedChecker::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 { typename CallbackParamTraits::LocalType a1; typename CallbackParamTraits::LocalType a2; + if ((holder->flags & HolderIsFirstArgument) && + DestroyedChecker::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 { typename CallbackParamTraits::LocalType a1; typename CallbackParamTraits::LocalType a2; typename CallbackParamTraits::LocalType a3; + if ((holder->flags & HolderIsFirstArgument) && + DestroyedChecker::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 { typename CallbackParamTraits::LocalType a2; typename CallbackParamTraits::LocalType a3; typename CallbackParamTraits::LocalType a4; + if ((holder->flags & HolderIsFirstArgument) && + DestroyedChecker::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 { typename CallbackParamTraits::LocalType a3; typename CallbackParamTraits::LocalType a4; typename CallbackParamTraits::LocalType a5; + if ((holder->flags & HolderIsFirstArgument) && + DestroyedChecker::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 { typename CallbackParamTraits::LocalType a4; typename CallbackParamTraits::LocalType a5; typename CallbackParamTraits::LocalType a6; + if ((holder->flags & HolderIsFirstArgument) && + DestroyedChecker::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 { typename CallbackParamTraits::LocalType a5; typename CallbackParamTraits::LocalType a6; typename CallbackParamTraits::LocalType a7; + if ((holder->flags & HolderIsFirstArgument) && + DestroyedChecker::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) || diff --git a/native_mate/function_template.h.pump b/native_mate/function_template.h.pump index e01bef42a17c..34033bc9d142 100644 --- a/native_mate/function_template.h.pump +++ b/native_mate/function_template.h.pump @@ -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 +struct DestroyedChecker { + static bool IsDestroyed(Arguments* args) { + return false; + } +}; +template +struct DestroyedChecker::value>::type> { + static bool IsDestroyed(Arguments* args) { + T* object; + if (args->GetHolder(&object)) + return static_cast(object)->IsDestroyed(); + else + return false; + } +}; + template struct CallbackParamTraits { typedef T LocalType; @@ -183,6 +201,11 @@ $if ARITY != 0 [[ $for ARG [[ typename CallbackParamTraits::LocalType a$(ARG); ]] + if ((holder->flags & HolderIsFirstArgument) && + DestroyedChecker::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(); diff --git a/native_mate/wrappable.cc b/native_mate/wrappable.cc index 7c00e350e888..94ec5365668e 100644 --- a/native_mate/wrappable.cc +++ b/native_mate/wrappable.cc @@ -64,6 +64,10 @@ v8::Local Wrappable::GetWrapper(v8::Isolate* isolate) { return wrapper; } +bool Wrappable::IsDestroyed() const { + return false; +} + namespace internal { void* FromV8Impl(v8::Isolate* isolate, v8::Local val) { diff --git a/native_mate/wrappable.h b/native_mate/wrappable.h index 6f027f2e417c..d55ce42cf7fb 100644 --- a/native_mate/wrappable.h +++ b/native_mate/wrappable.h @@ -54,6 +54,10 @@ class Wrappable { // object constructed by GetObjectTemplateBuilder. v8::Local 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_; }