Allow specify methods that can be called after object is destroyed

This commit is contained in:
Cheng Zhao 2015-07-06 21:25:55 +08:00
Родитель 7b9926807d
Коммит 41cd6d13c9
3 изменённых файлов: 41 добавлений и 16 удалений

Просмотреть файл

@ -21,6 +21,7 @@ class PerIsolateData;
enum CreateFunctionTemplateFlags {
HolderIsFirstArgument = 1 << 0,
SafeAfterDestroyed = 1 << 1,
};
namespace internal {
@ -377,6 +378,7 @@ struct Dispatcher<R(P1)> {
typename CallbackParamTraits<P1>::LocalType a1;
if ((holder->flags & HolderIsFirstArgument) &&
!(holder->flags & SafeAfterDestroyed) &&
DestroyedChecker<typename
CallbackParamTraits<P1>::LocalType>::IsDestroyed(&args)) {
args.ThrowError("Object has been destroyed");
@ -406,6 +408,7 @@ struct Dispatcher<R(P1, P2)> {
typename CallbackParamTraits<P1>::LocalType a1;
typename CallbackParamTraits<P2>::LocalType a2;
if ((holder->flags & HolderIsFirstArgument) &&
!(holder->flags & SafeAfterDestroyed) &&
DestroyedChecker<typename
CallbackParamTraits<P1>::LocalType>::IsDestroyed(&args)) {
args.ThrowError("Object has been destroyed");
@ -437,6 +440,7 @@ struct Dispatcher<R(P1, P2, P3)> {
typename CallbackParamTraits<P2>::LocalType a2;
typename CallbackParamTraits<P3>::LocalType a3;
if ((holder->flags & HolderIsFirstArgument) &&
!(holder->flags & SafeAfterDestroyed) &&
DestroyedChecker<typename
CallbackParamTraits<P1>::LocalType>::IsDestroyed(&args)) {
args.ThrowError("Object has been destroyed");
@ -470,6 +474,7 @@ struct Dispatcher<R(P1, P2, P3, P4)> {
typename CallbackParamTraits<P3>::LocalType a3;
typename CallbackParamTraits<P4>::LocalType a4;
if ((holder->flags & HolderIsFirstArgument) &&
!(holder->flags & SafeAfterDestroyed) &&
DestroyedChecker<typename
CallbackParamTraits<P1>::LocalType>::IsDestroyed(&args)) {
args.ThrowError("Object has been destroyed");
@ -507,6 +512,7 @@ struct Dispatcher<R(P1, P2, P3, P4, P5)> {
typename CallbackParamTraits<P4>::LocalType a4;
typename CallbackParamTraits<P5>::LocalType a5;
if ((holder->flags & HolderIsFirstArgument) &&
!(holder->flags & SafeAfterDestroyed) &&
DestroyedChecker<typename
CallbackParamTraits<P1>::LocalType>::IsDestroyed(&args)) {
args.ThrowError("Object has been destroyed");
@ -546,6 +552,7 @@ struct Dispatcher<R(P1, P2, P3, P4, P5, P6)> {
typename CallbackParamTraits<P5>::LocalType a5;
typename CallbackParamTraits<P6>::LocalType a6;
if ((holder->flags & HolderIsFirstArgument) &&
!(holder->flags & SafeAfterDestroyed) &&
DestroyedChecker<typename
CallbackParamTraits<P1>::LocalType>::IsDestroyed(&args)) {
args.ThrowError("Object has been destroyed");
@ -587,6 +594,7 @@ struct Dispatcher<R(P1, P2, P3, P4, P5, P6, P7)> {
typename CallbackParamTraits<P6>::LocalType a6;
typename CallbackParamTraits<P7>::LocalType a7;
if ((holder->flags & HolderIsFirstArgument) &&
!(holder->flags & SafeAfterDestroyed) &&
DestroyedChecker<typename
CallbackParamTraits<P1>::LocalType>::IsDestroyed(&args)) {
args.ThrowError("Object has been destroyed");

Просмотреть файл

@ -24,6 +24,7 @@ class PerIsolateData;
enum CreateFunctionTemplateFlags {
HolderIsFirstArgument = 1 << 0,
SafeAfterDestroyed = 1 << 1,
};
namespace internal {
@ -202,6 +203,7 @@ $for ARG [[ typename CallbackParamTraits<P$(ARG)>::LocalType a$(ARG);
]]
if ((holder->flags & HolderIsFirstArgument) &&
!(holder->flags & SafeAfterDestroyed) &&
DestroyedChecker<typename CallbackParamTraits<P1>::LocalType>::IsDestroyed(&args)) {
args.ThrowError("Object has been destroyed");
MATE_METHOD_RETURN_UNDEFINED();

Просмотреть файл

@ -23,7 +23,8 @@ namespace {
template<typename T, typename Enable = void>
struct CallbackTraits {
static v8::Local<v8::FunctionTemplate> CreateTemplate(v8::Isolate* isolate,
T callback) {
T callback,
bool = true) {
return CreateFunctionTemplate(isolate, base::Bind(callback));
}
};
@ -32,7 +33,7 @@ struct CallbackTraits {
template<typename T>
struct CallbackTraits<base::Callback<T> > {
static v8::Local<v8::FunctionTemplate> CreateTemplate(
v8::Isolate* isolate, const base::Callback<T>& callback) {
v8::Isolate* isolate, const base::Callback<T>& callback, bool = true) {
return CreateFunctionTemplate(isolate, callback);
}
};
@ -44,10 +45,12 @@ struct CallbackTraits<base::Callback<T> > {
template<typename T>
struct CallbackTraits<T, typename enable_if<
is_member_function_pointer<T>::value>::type> {
static v8::Local<v8::FunctionTemplate> CreateTemplate(v8::Isolate* isolate,
T callback) {
return CreateFunctionTemplate(isolate, base::Bind(callback),
HolderIsFirstArgument);
static v8::Local<v8::FunctionTemplate> CreateTemplate(
v8::Isolate* isolate, T callback, bool safe_after_destroyed = false) {
int flags = HolderIsFirstArgument;
if (safe_after_destroyed)
flags |= SafeAfterDestroyed;
return CreateFunctionTemplate(isolate, base::Bind(callback), flags);
}
};
@ -87,22 +90,34 @@ class ObjectTemplateBuilder {
// for creating raw function templates.
template<typename T>
ObjectTemplateBuilder& SetMethod(const base::StringPiece& name,
const T& callback) {
return SetImpl(name, CallbackTraits<T>::CreateTemplate(isolate_, callback));
const T& callback,
bool safe_after_destroyed = false) {
return SetImpl(name,
CallbackTraits<T>::CreateTemplate(isolate_,
callback,
safe_after_destroyed));
}
template<typename T>
ObjectTemplateBuilder& SetProperty(const base::StringPiece& name,
const T& getter) {
return SetPropertyImpl(name,
CallbackTraits<T>::CreateTemplate(isolate_, getter),
v8::Local<v8::FunctionTemplate>());
const T& getter,
bool safe_after_destroyed = false) {
return SetPropertyImpl(
name,
CallbackTraits<T>::CreateTemplate(isolate_, getter,
safe_after_destroyed),
v8::Local<v8::FunctionTemplate>());
}
template<typename T, typename U>
ObjectTemplateBuilder& SetProperty(const base::StringPiece& name,
const T& getter, const U& setter) {
return SetPropertyImpl(name,
CallbackTraits<T>::CreateTemplate(isolate_, getter),
CallbackTraits<U>::CreateTemplate(isolate_, setter));
const T& getter,
const U& setter,
bool safe_after_destroyed = false) {
return SetPropertyImpl(
name,
CallbackTraits<T>::CreateTemplate(isolate_, getter,
safe_after_destroyed),
CallbackTraits<U>::CreateTemplate(isolate_, setter,
safe_after_destroyed));
}
v8::Local<v8::ObjectTemplate> Build();