diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/embind/embind.test.js | 47 | ||||
-rw-r--r-- | tests/embind/embind_test.cpp | 31 |
2 files changed, 78 insertions, 0 deletions
diff --git a/tests/embind/embind.test.js b/tests/embind/embind.test.js index ae421f27..a6b2e98c 100644 --- a/tests/embind/embind.test.js +++ b/tests/embind/embind.test.js @@ -1953,6 +1953,53 @@ module({ rv.delete(); cm.flushPendingDeletes(); }); + + test("method arguments with pointer ownership semantics are cleaned up after call", function() { + var parent = cm.AbstractClass; + var C = parent.extend("C", { + abstractMethod: function() { + }, + }); + var impl = new C; + cm.passShared(impl); + impl.delete(); + }); + + test("method arguments with pointer ownership semantics can be cloned", function() { + var parent = cm.AbstractClass; + var owned; + var C = parent.extend("C", { + abstractMethod: function() { + }, + passShared: function(p) { + owned = p.clone(); + } + }); + var impl = new C; + cm.passShared(impl); + impl.delete(); + + assert.equal("Derived", owned.getClassName()); + owned.delete(); + }); + + test("emscripten::val method arguments don't leak", function() { + var parent = cm.AbstractClass; + var got; + var C = parent.extend("C", { + abstractMethod: function() { + }, + passVal: function(g) { + got = g; + } + }); + var impl = new C; + var v = {}; + cm.passVal(impl, v); + impl.delete(); + + assert.equal(v, got); + }); }); BaseFixture.extend("registration order", function() { diff --git a/tests/embind/embind_test.cpp b/tests/embind/embind_test.cpp index eb534134..a0cb858d 100644 --- a/tests/embind/embind_test.cpp +++ b/tests/embind/embind_test.cpp @@ -1094,6 +1094,12 @@ public: std::string concreteMethod() const { return "concrete"; } + + virtual void passShared(const std::shared_ptr<Derived>&) { + } + + virtual void passVal(const val& v) { + } }; EMSCRIPTEN_SYMBOL(optionalMethod); @@ -1120,6 +1126,14 @@ public: void differentArguments(int i, double d, unsigned char f, double q, std::string s) { return call<void>("differentArguments", i, d, f, q, s); } + + virtual void passShared(const std::shared_ptr<Derived>& p) override { + return call<void>("passShared", p); + } + + virtual void passVal(const val& v) override { + return call<void>("passVal", v); + } }; class ConcreteClass : public AbstractClass { @@ -1196,6 +1210,15 @@ std::shared_ptr<PolySecondBase> passHeldAbstractClass(std::shared_ptr<HeldAbstra return p; } +void passShared(AbstractClass& ac) { + auto p = std::make_shared<Derived>(); + ac.passShared(p); +} + +void passVal(AbstractClass& ac, val v) { + return ac.passVal(v); +} + EMSCRIPTEN_BINDINGS(interface_tests) { class_<AbstractClass>("AbstractClass") .smart_ptr<std::shared_ptr<AbstractClass>>("shared_ptr<AbstractClass>") @@ -1209,6 +1232,12 @@ EMSCRIPTEN_BINDINGS(interface_tests) { } )) .function("concreteMethod", &AbstractClass::concreteMethod) + .function("passShared", select_overload<void(AbstractClass&, const std::shared_ptr<Derived>&)>([](AbstractClass& self, const std::shared_ptr<Derived>& derived) { + self.AbstractClass::passShared(derived); + })) + .function("passVal", select_overload<void(AbstractClass&, const val&)>([](AbstractClass& self, const val& v) { + self.AbstractClass::passVal(v); + })) ; function("getAbstractClass", &getAbstractClass); @@ -1216,6 +1245,8 @@ EMSCRIPTEN_BINDINGS(interface_tests) { function("callOptionalMethod", &callOptionalMethod); function("callReturnsSharedPtrMethod", &callReturnsSharedPtrMethod); function("callDifferentArguments", &callDifferentArguments); + function("passShared", &passShared); + function("passVal", &passVal); class_<AbstractClassWithConstructor>("AbstractClassWithConstructor") .allow_subclass<AbstractClassWithConstructorWrapper>("AbstractClassWithConstructorWrapper", constructor<std::string>()) |