aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChad Austin <chad@imvu.com>2014-05-09 17:53:18 -0700
committerBruce Mitchener <bruce.mitchener@gmail.com>2014-05-21 23:04:10 +0700
commit22288a4229ccba67a4cf0cbe4730ddde9589f0f3 (patch)
tree14998b2397df4ff2ff9c642a8c756e8b89c20857
parenta8eda73be9b64636c82474a79742a578b3f2c425 (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.js2
-rw-r--r--tests/embind/embind.test.js10
-rw-r--r--tests/embind/embind_test.cpp48
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>();
}