diff options
author | Chad Austin <chad@imvu.com> | 2014-05-09 17:53:18 -0700 |
---|---|---|
committer | Bruce Mitchener <bruce.mitchener@gmail.com> | 2014-05-21 23:04:10 +0700 |
commit | 22288a4229ccba67a4cf0cbe4730ddde9589f0f3 (patch) | |
tree | 14998b2397df4ff2ff9c642a8c756e8b89c20857 | |
parent | a8eda73be9b64636c82474a79742a578b3f2c425 (diff) |
Fix a bug where, when extending from a class held with intrusive pointers, the JavaScript object would be released when the last JS handle was destroyed, not when the object was.
-rw-r--r-- | src/embind/embind.js | 2 | ||||
-rw-r--r-- | tests/embind/embind.test.js | 10 | ||||
-rw-r--r-- | tests/embind/embind_test.cpp | 48 |
3 files changed, 35 insertions, 25 deletions
diff --git a/src/embind/embind.js b/src/embind/embind.js index 355f05f4..0e3dfab1 100644 --- a/src/embind/embind.js +++ b/src/embind/embind.js @@ -1349,7 +1349,7 @@ ClassHandle.prototype['delete'] = function ClassHandle_delete() { if (toDelete) { runDestructor(this); } - if (toDelete || !this.$$.preservePointerOnDelete) { + if (!this.$$.preservePointerOnDelete) { this.$$.smartPtr = undefined; this.$$.ptr = undefined; } diff --git a/tests/embind/embind.test.js b/tests/embind/embind.test.js index 5e56c114..b2c4c98b 100644 --- a/tests/embind/embind.test.js +++ b/tests/embind/embind.test.js @@ -2254,6 +2254,16 @@ module({ }); test("can extend from intrusive pointer class and still preserve reference in JavaScript", function() { + var C = cm.IntrusiveClass.extend("C", { + }); + var instance = new C; + var holder = new cm.IntrusiveClassHolder; + holder.set(instance); + instance.delete(); + + var back = holder.get(); + assert.equal(back, instance); + holder.delete(); }); }); diff --git a/tests/embind/embind_test.cpp b/tests/embind/embind_test.cpp index c7262b67..eb534134 100644 --- a/tests/embind/embind_test.cpp +++ b/tests/embind/embind_test.cpp @@ -2538,6 +2538,30 @@ private: friend class intrusive_ptr; }; +namespace emscripten { + template<typename T> + struct smart_ptr_trait<intrusive_ptr<T>> { + typedef intrusive_ptr<T> pointer_type; + typedef T element_type; + + static sharing_policy get_sharing_policy() { + return sharing_policy::INTRUSIVE; + } + + static T* get(const intrusive_ptr<T>& p) { + return p.get(); + } + + static intrusive_ptr<T> share(const intrusive_ptr<T>& r, T* ptr) { + return intrusive_ptr<T>(ptr); + } + + static pointer_type* construct_null() { + return new pointer_type; + } + }; +} + template<typename T> intrusive_ptr<T> make_intrusive_ptr() { return intrusive_ptr<T>(new T); @@ -2579,30 +2603,6 @@ EMSCRIPTEN_BINDINGS(intrusive_pointers) { function("passThroughIntrusiveClass", &passThrough<intrusive_ptr<IntrusiveClass>>); } - -/* -#define NORTHSTAR_IMPLEMENT_REFCOUNT(T) \ - template<> \ - NS_ALWAYS_INLINE void ::northstar::IntrusiveImplementation<T>::incRef(const T* ptr) { \ - ++ptr->referenceCount; \ - } \ - template<> \ - void ::northstar::IntrusiveImplementation<T>::decRef(const T* ptr) { \ - if (ptr && --ptr->referenceCount == 0) { \ - ptr->onStartDestruction(); \ - delete ptr; \ - } \ - } \ - template<> \ - NS_ALWAYS_INLINE const ::northstar::PointerTarget* ::northstar::IntrusiveImplementation<T>::toPointerTarget(const T* ptr) { \ - return ptr; \ - } \ - template<> \ - NS_ALWAYS_INLINE T* ::northstar::IntrusiveImplementation<T>::fromPointerTarget(const ::northstar::PointerTarget* t) { \ - return static_cast<T*>(const_cast<PointerTarget*>(t)); \ - } -*/ - std::string getTypeOfVal(const val& v) { return v.typeof().as<std::string>(); } |