From c5926e30e360735c63619e4d360c2f96897556c7 Mon Sep 17 00:00:00 2001 From: canine Date: Fri, 4 Apr 2025 23:52:16 -0400 Subject: [PATCH] (embind) fix misindexed template parameters --- system/include/emscripten/bind.h | 30 +++++++++++++++--------------- test/embind/embind.test.js | 8 ++++++++ test/embind/embind_test.cpp | 10 ++++++++++ 3 files changed, 33 insertions(+), 15 deletions(-) diff --git a/system/include/emscripten/bind.h b/system/include/emscripten/bind.h index 0d086b701c927..89da9e31f1e16 100644 --- a/system/include/emscripten/bind.h +++ b/system/include/emscripten/bind.h @@ -820,8 +820,8 @@ inline T* getContext(const T& t) { return ret; } -template -struct PropertyTag {}; +template +struct FunctionTag {}; template struct GetterPolicy; @@ -887,7 +887,7 @@ struct GetterPolicy> { }; template -struct GetterPolicy> { +struct GetterPolicy> { typedef GetterReturnType ReturnType; typedef Getter Context; @@ -968,7 +968,7 @@ struct SetterPolicy -struct SetterPolicy> { +struct SetterPolicy> { typedef SetterArgumentType ArgumentType; typedef Setter Context; @@ -1497,9 +1497,9 @@ struct RegisterClassConstructor> { } }; -template -struct RegisterClassConstructor { - template +template +struct RegisterClassConstructor> { + template static void invoke(Callable& factory) { typename WithPolicies::template ArgTypeList args; using ReturnPolicy = rvp::take_ownership; @@ -1633,10 +1633,10 @@ struct RegisterClassMethod> { } }; -template -struct RegisterClassMethod { +template +struct RegisterClassMethod> { - template + template static void invoke(const char* methodName, Callable& callable) { typename WithPolicies::template ArgTypeList args; @@ -1739,7 +1739,7 @@ class class_ { using invoker = internal::RegisterClassConstructor< typename std::conditional::value, Callable, - Signature>::type>; + internal::FunctionTag>::type>; invoker::template invoke(callable); return *this; @@ -1819,7 +1819,7 @@ class class_ { using invoker = internal::RegisterClassMethod< typename std::conditional::value, Callable, - Signature>::type>; + internal::FunctionTag>::type>; invoker::template invoke(methodName, callable); return *this; @@ -1896,7 +1896,7 @@ class class_ { typedef GetterPolicy< typename std::conditional::value, Getter, - PropertyTag>::type> GP; + FunctionTag>::type> GP; using ReturnPolicy = GetReturnValuePolicy::tag; auto gter = &GP::template get; typename WithPolicies::template ArgTypeList returnType; @@ -1930,11 +1930,11 @@ class class_ { typedef GetterPolicy< typename std::conditional::value, Getter, - PropertyTag>::type> GP; + FunctionTag>::type> GP; typedef SetterPolicy< typename std::conditional::value, Setter, - PropertyTag>::type> SP; + FunctionTag>::type> SP; auto gter = &GP::template get; diff --git a/test/embind/embind.test.js b/test/embind/embind.test.js index a010f6b88e264..a6c4040139fb5 100644 --- a/test/embind/embind.test.js +++ b/test/embind/embind.test.js @@ -1461,6 +1461,9 @@ module({ assert.equal("foo", b.getValFunction()); b.setValFunction("bar"); + // get & set with templated signature + assert.equal("bar", b.getThisPointer().getVal()); + // get & set via 'callable' assert.equal("bar", b.getValFunctor()); b.setValFunctor("baz"); @@ -1834,6 +1837,11 @@ module({ assert.equal("AbstractClass has no accessible constructor", e.message); }); + test("can construct class with external constructor with custom signature", function() { + const valHolder = new cm.ValHolder(1,2); + assert.equal(valHolder.getVal(), 3); + }); + test("can construct class with external constructor", function() { var e = new cm.HasExternalConstructor("foo"); assert.instanceof(e, cm.HasExternalConstructor); diff --git a/test/embind/embind_test.cpp b/test/embind/embind_test.cpp index c77a09c33364d..bc018ee579de2 100644 --- a/test/embind/embind_test.cpp +++ b/test/embind/embind_test.cpp @@ -327,10 +327,18 @@ ValHolder emval_test_return_ValHolder() { return val::object(); } +ValHolder valholder_from_sum(int x, int y) { + return val(x+y); +} + val valholder_get_value_mixin(const ValHolder& target) { return target.getVal(); } +ValHolder* valholder_get_this_ptr(ValHolder& target) { + return ⌖ +} + void valholder_set_value_mixin(ValHolder& target, const val& value) { target.setVal(value); } @@ -2005,6 +2013,7 @@ EMSCRIPTEN_BINDINGS(tests) { class_("ValHolder") .smart_ptr>("std::shared_ptr") .constructor() + .constructor(&valholder_from_sum, allow_raw_pointers()) // custom signature with policy .function("getVal", &ValHolder::getVal) .function("getValNonConst", &ValHolder::getValNonConst) .function("getConstVal", &ValHolder::getConstVal) @@ -2012,6 +2021,7 @@ EMSCRIPTEN_BINDINGS(tests) { .function("setVal", &ValHolder::setVal) .function("getValFunction", std::function(&valholder_get_value_mixin)) .function("setValFunction", std::function(&valholder_set_value_mixin)) + .function("getThisPointer", std::function(&valholder_get_this_ptr), allow_raw_pointer()) .function("getValFunctor", std::bind(&valholder_get_value_mixin, _1)) .function("setValFunctor", std::bind(&valholder_set_value_mixin, _1, _2)) .property("val", &ValHolder::getVal, &ValHolder::setVal)