Do not manually destroy native resources
This commit is contained in:
parent
9398494100
commit
e859228db1
6 changed files with 37 additions and 47 deletions
|
@ -20,6 +20,10 @@ class Arguments {
|
|||
explicit Arguments(const MATE_METHOD_ARGS_TYPE& info);
|
||||
~Arguments();
|
||||
|
||||
v8::Local<v8::Object> GetHolder() const {
|
||||
return info_->Holder();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool GetHolder(T* out) {
|
||||
return ConvertFromV8(isolate_, info_->Holder(), out);
|
||||
|
|
|
@ -15,27 +15,20 @@ namespace mate {
|
|||
|
||||
enum CreateFunctionTemplateFlags {
|
||||
HolderIsFirstArgument = 1 << 0,
|
||||
SafeAfterDestroyed = 1 << 1,
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Check if the class has been destroyed.
|
||||
template<typename T, typename Enable = void>
|
||||
struct DestroyedChecker {
|
||||
static bool IsDestroyed(Arguments* args) {
|
||||
return false;
|
||||
struct Destroyable {
|
||||
static void Destroy(Arguments* args) {
|
||||
v8::Local<v8::Object> holder = args->GetHolder();
|
||||
delete static_cast<Wrappable*>(holder->GetAlignedPointerFromInternalField(0));
|
||||
holder->SetAlignedPointerInInternalField(0, nullptr);
|
||||
}
|
||||
};
|
||||
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;
|
||||
v8::Local<v8::Object> holder = args->GetHolder();
|
||||
return holder->InternalFieldCount() == 0 ||
|
||||
holder->GetAlignedPointerFromInternalField(0) == nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -149,8 +142,7 @@ struct ArgumentHolder {
|
|||
: ok(false) {
|
||||
if (index == 0 &&
|
||||
(create_flags & HolderIsFirstArgument) &&
|
||||
!(create_flags & SafeAfterDestroyed) &&
|
||||
DestroyedChecker<ArgLocalType>::IsDestroyed(args)) {
|
||||
Destroyable::IsDestroyed(args)) {
|
||||
args->ThrowError("Object has been destroyed");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,12 @@ ObjectTemplateBuilder& ObjectTemplateBuilder::SetPropertyImpl(
|
|||
return *this;
|
||||
}
|
||||
|
||||
ObjectTemplateBuilder& ObjectTemplateBuilder::MakeDestroyable() {
|
||||
SetMethod("destroy", base::Bind(internal::Destroyable::Destroy));
|
||||
SetMethod("isDestroy", base::Bind(internal::Destroyable::IsDestroyed));
|
||||
return *this;
|
||||
}
|
||||
|
||||
v8::Local<v8::ObjectTemplate> ObjectTemplateBuilder::Build() {
|
||||
v8::Local<v8::ObjectTemplate> result = template_;
|
||||
template_.Clear();
|
||||
|
|
|
@ -22,9 +22,8 @@ namespace {
|
|||
// because of base::Bind().
|
||||
template<typename T, typename Enable = void>
|
||||
struct CallbackTraits {
|
||||
static v8::Local<v8::FunctionTemplate> CreateTemplate(v8::Isolate* isolate,
|
||||
T callback,
|
||||
bool = true) {
|
||||
static v8::Local<v8::FunctionTemplate> CreateTemplate(
|
||||
v8::Isolate* isolate, T callback) {
|
||||
return CreateFunctionTemplate(isolate, base::Bind(callback));
|
||||
}
|
||||
};
|
||||
|
@ -33,7 +32,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, bool = true) {
|
||||
v8::Isolate* isolate, const base::Callback<T>& callback) {
|
||||
return CreateFunctionTemplate(isolate, callback);
|
||||
}
|
||||
};
|
||||
|
@ -46,10 +45,8 @@ 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, bool safe_after_destroyed = false) {
|
||||
v8::Isolate* isolate, T callback) {
|
||||
int flags = HolderIsFirstArgument;
|
||||
if (safe_after_destroyed)
|
||||
flags |= SafeAfterDestroyed;
|
||||
return CreateFunctionTemplate(isolate, base::Bind(callback), flags);
|
||||
}
|
||||
};
|
||||
|
@ -90,36 +87,31 @@ class ObjectTemplateBuilder {
|
|||
// for creating raw function templates.
|
||||
template<typename T>
|
||||
ObjectTemplateBuilder& SetMethod(const base::StringPiece& name,
|
||||
T callback,
|
||||
bool safe_after_destroyed = false) {
|
||||
T callback) {
|
||||
return SetImpl(name,
|
||||
CallbackTraits<T>::CreateTemplate(isolate_,
|
||||
callback,
|
||||
safe_after_destroyed));
|
||||
CallbackTraits<T>::CreateTemplate(isolate_, callback));
|
||||
}
|
||||
template<typename T>
|
||||
ObjectTemplateBuilder& SetProperty(const base::StringPiece& name,
|
||||
T getter,
|
||||
bool safe_after_destroyed = false) {
|
||||
T getter) {
|
||||
return SetPropertyImpl(
|
||||
name,
|
||||
CallbackTraits<T>::CreateTemplate(isolate_, getter,
|
||||
safe_after_destroyed),
|
||||
CallbackTraits<T>::CreateTemplate(isolate_, getter),
|
||||
v8::Local<v8::FunctionTemplate>());
|
||||
}
|
||||
template<typename T, typename U>
|
||||
ObjectTemplateBuilder& SetProperty(const base::StringPiece& name,
|
||||
T getter,
|
||||
U setter,
|
||||
bool safe_after_destroyed = false) {
|
||||
U setter) {
|
||||
return SetPropertyImpl(
|
||||
name,
|
||||
CallbackTraits<T>::CreateTemplate(isolate_, getter,
|
||||
safe_after_destroyed),
|
||||
CallbackTraits<U>::CreateTemplate(isolate_, setter,
|
||||
safe_after_destroyed));
|
||||
CallbackTraits<T>::CreateTemplate(isolate_, getter),
|
||||
CallbackTraits<U>::CreateTemplate(isolate_, setter));
|
||||
}
|
||||
|
||||
// Add "destroy" and "isDestroyed" methods.
|
||||
ObjectTemplateBuilder& MakeDestroyable();
|
||||
|
||||
v8::Local<v8::ObjectTemplate> Build();
|
||||
|
||||
private:
|
||||
|
|
|
@ -78,10 +78,6 @@ 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) {
|
||||
|
|
|
@ -13,6 +13,8 @@ namespace mate {
|
|||
|
||||
namespace internal {
|
||||
|
||||
struct Destroyable;
|
||||
|
||||
void* FromV8Impl(v8::Isolate* isolate, v8::Local<v8::Value> val);
|
||||
|
||||
} // namespace internal
|
||||
|
@ -54,10 +56,6 @@ 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_; }
|
||||
|
||||
|
@ -79,6 +77,8 @@ class Wrappable {
|
|||
virtual void AfterInit(v8::Isolate* isolate) {}
|
||||
|
||||
private:
|
||||
friend struct internal::Destroyable;
|
||||
|
||||
static void FirstWeakCallback(const v8::WeakCallbackInfo<Wrappable>& data);
|
||||
static void SecondWeakCallback(const v8::WeakCallbackInfo<Wrappable>& data);
|
||||
|
||||
|
|
Loading…
Reference in a new issue