aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChad Austin <chad@imvu.com>2014-05-08 23:05:56 -0700
committerBruce Mitchener <bruce.mitchener@gmail.com>2014-05-21 22:59:08 +0700
commite25a0f0af05a12705bacf35e4d94bcdc9cd334e9 (patch)
tree22ecb898b8e056b33259cb991c8d05d1858b04b9
parent3147a2175cc90c1ceca368979bad72870b02561b (diff)
Make returning JavaScript instances work in the presence of base class pointer fixups.
-rw-r--r--src/embind/embind.js29
-rw-r--r--tests/embind/embind_test.cpp6
2 files changed, 25 insertions, 10 deletions
diff --git a/src/embind/embind.js b/src/embind/embind.js
index 27fa87b8..27dfa928 100644
--- a/src/embind/embind.js
+++ b/src/embind/embind.js
@@ -156,7 +156,16 @@ function _embind_repr(v) {
// raw pointer -> instance
var registeredInstances = {};
-function registerInheritedInstance(ptr, instance) {
+function getBasestPointer(class_, ptr) {
+ while (class_.baseClass) {
+ ptr = class_.upcast(ptr);
+ class_ = class_.baseClass;
+ }
+ return ptr;
+}
+
+function registerInheritedInstance(class_, ptr, instance) {
+ ptr = getBasestPointer(class_, ptr);
if (registeredInstances.hasOwnProperty(ptr)) {
throwBindingError('Tried to register registered instance: ' + ptr);
} else {
@@ -164,7 +173,8 @@ function registerInheritedInstance(ptr, instance) {
}
}
-function unregisterInheritedInstance(ptr) {
+function unregisterInheritedInstance(class_, ptr) {
+ ptr = getBasestPointer(class_, ptr);
if (registeredInstances.hasOwnProperty(ptr)) {
delete registeredInstances[ptr];
} else {
@@ -172,6 +182,11 @@ function unregisterInheritedInstance(ptr) {
}
}
+function getInheritedInstance(class_, ptr) {
+ ptr = getBasestPointer(class_, ptr);
+ return registeredInstances[ptr];
+}
+
function getInheritedInstanceCount() {
return Object.keys(registeredInstances).length;
}
@@ -1176,7 +1191,7 @@ RegisteredPointer.prototype['fromWireType'] = function fromWireType(ptr) {
return null;
}
- var registeredInstance = registeredInstances[rawPointer];
+ var registeredInstance = getInheritedInstance(this.registeredClass, rawPointer);
if (undefined !== registeredInstance) {
var rv = registeredInstance['clone']();
this.destructor(ptr);
@@ -1626,7 +1641,7 @@ function __embind_register_class_function(
var humanName = classType.name + '.' + methodName;
if (isPureVirtual) {
- classType.registeredClass.pureVirtualFunctions.push(methodName)
+ classType.registeredClass.pureVirtualFunctions.push(methodName);
}
function unboundTypesHandler() {
@@ -1751,7 +1766,7 @@ function __embind_register_class_class_function(
function unboundTypesHandler() {
throwUnboundTypeError('Cannot call ' + humanName + ' due to unbound types', rawArgTypes);
- };
+ }
var proto = classType.registeredClass.constructor;
if (undefined === proto[methodName]) {
@@ -1816,11 +1831,11 @@ function __embind_create_inheriting_constructor(constructorName, wrapperType, pr
Object.defineProperty(this, '$$', {
value: $$
});
- registerInheritedInstance($$.ptr, this);
+ registerInheritedInstance(registeredClass, $$.ptr, this);
};
wrapperPrototype.__destruct = function __destruct() {
- unregisterInheritedInstance(this.$$.ptr);
+ unregisterInheritedInstance(registeredClass, this.$$.ptr);
};
ctor.prototype = Object.create(wrapperPrototype);
diff --git a/tests/embind/embind_test.cpp b/tests/embind/embind_test.cpp
index d7999b6f..c387781e 100644
--- a/tests/embind/embind_test.cpp
+++ b/tests/embind/embind_test.cpp
@@ -1181,7 +1181,7 @@ std::string callAbstractMethod2(AbstractClassWithConstructor& ac) {
return ac.abstractMethod();
}
-struct HeldAbstractClass {
+struct HeldAbstractClass : public PolyBase, public PolySecondBase {
virtual void method() = 0;
};
struct HeldAbstractClassWrapper : wrapper<HeldAbstractClass> {
@@ -1192,7 +1192,7 @@ struct HeldAbstractClassWrapper : wrapper<HeldAbstractClass> {
}
};
-std::shared_ptr<HeldAbstractClass> passHeldAbstractClass(std::shared_ptr<HeldAbstractClass> p) {
+std::shared_ptr<PolySecondBase> passHeldAbstractClass(std::shared_ptr<HeldAbstractClass> p) {
return p;
}
@@ -1224,7 +1224,7 @@ EMSCRIPTEN_BINDINGS(interface_tests) {
;
function("callAbstractMethod2", &callAbstractMethod2);
- class_<HeldAbstractClass>("HeldAbstractClass")
+ class_<HeldAbstractClass, base<PolySecondBase>>("HeldAbstractClass")
.smart_ptr<std::shared_ptr<HeldAbstractClass>>("shared_ptr<HeldAbstractClass>")
.allow_subclass<HeldAbstractClassWrapper, std::shared_ptr<HeldAbstractClassWrapper>>("HeldAbstractClassWrapper")
.function("method", &HeldAbstractClass::method, pure_virtual())