diff --git a/v8pp/class.hpp b/v8pp/class.hpp index 9eb707d7..737be3e6 100644 --- a/v8pp/class.hpp +++ b/v8pp/class.hpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -82,8 +83,7 @@ class object_registry final : public class_info // each JavaScript instance has 3 internal fields: // 0 - pointer to a wrapped C++ object // 1 - pointer to this object_registry - // 2 - pointer to the object destructor - func->InstanceTemplate()->SetInternalFieldCount(3); + func->InstanceTemplate()->SetInternalFieldCount(2); func->Inherit(js_func); } @@ -93,6 +93,7 @@ class object_registry final : public class_info , bases_(std::move(src.bases_)) , derivatives_(std::move(src.derivatives_)) , objects_(std::move(src.objects_)) + , unowned_objects_(std::move(src.unowned_objects_)) , isolate_(std::move(src.isolate_)) , func_(std::move(src.func_)) , js_func_(std::move(src.js_func_)) @@ -238,7 +239,9 @@ class object_registry final : public class_info obj->SetAlignedPointerInInternalField(0, Traits::pointer_id(object)); obj->SetAlignedPointerInInternalField(1, this); - obj->SetAlignedPointerInInternalField(2, call_dtor? /*dtor_*/this : nullptr); + if (!call_dtor) { + unowned_objects_.emplace(object); + } v8::Global pobj(isolate_, obj); pobj.SetWeak(this, [](v8::WeakCallbackInfo const& data) @@ -269,7 +272,7 @@ class object_registry final : public class_info while (value->IsObject()) { v8::Local obj = value.As(); - if (obj->InternalFieldCount() == 3) + if (obj->InternalFieldCount() == 2) { object_id id = obj->GetAlignedPointerFromInternalField(0); if (id) @@ -294,22 +297,24 @@ class object_registry final : public class_info private: void reset_object(std::pair>& object) { - bool call_dtor = true; if (!object.second.IsNearDeath()) { v8::Local obj = to_local(isolate_, object.second); - assert(obj->InternalFieldCount() == 3); + assert(obj->InternalFieldCount() == 2); assert(obj->GetAlignedPointerFromInternalField(0) == Traits::pointer_id(object.first)); assert(obj->GetAlignedPointerFromInternalField(1) == this); - call_dtor = (obj->GetAlignedPointerFromInternalField(2) != nullptr); // remove internal fields to disable unwrapping for this V8 Object obj->SetAlignedPointerInInternalField(0, nullptr); obj->SetAlignedPointerInInternalField(1, nullptr); - obj->SetAlignedPointerInInternalField(2, nullptr); } - if (call_dtor) + auto it = unowned_objects_.find(object.first); + if (it == unowned_objects_.end()) { dtor_(isolate_, object.first); + } + else + { + unowned_objects_.erase(it); } object.second.Reset(); } @@ -330,6 +335,7 @@ class object_registry final : public class_info std::vector derivatives_; std::unordered_map> objects_; + std::unordered_set unowned_objects_; v8::Isolate* isolate_; v8::Global func_;