diff options
author | Chad Austin <chad@imvu.com> | 2014-05-08 23:05:56 -0700 |
---|---|---|
committer | Bruce Mitchener <bruce.mitchener@gmail.com> | 2014-05-21 22:59:08 +0700 |
commit | e25a0f0af05a12705bacf35e4d94bcdc9cd334e9 (patch) | |
tree | 22ecb898b8e056b33259cb991c8d05d1858b04b9 | |
parent | 3147a2175cc90c1ceca368979bad72870b02561b (diff) |
Make returning JavaScript instances work in the presence of base class pointer fixups.
-rw-r--r-- | src/embind/embind.js | 29 | ||||
-rw-r--r-- | tests/embind/embind_test.cpp | 6 |
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()) |