Skip to content

Commit

Permalink
Update embind nortti test and documentation. NFC
Browse files Browse the repository at this point in the history
Automatic downcasting of polymorphic types in embind has been broken
without rtti since emscripten-core#10914 landed.

This test update confirms this brokenness rather than fixing it since
this has been the behavior since 2020.

Fixes: emscripten-core#21619
  • Loading branch information
sbc100 committed Mar 27, 2024
1 parent d72d722 commit 6cb709b
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,8 @@ are available.
.. note:: *Embind* must understand the fully-derived type for automatic
downcasting to work.

.. note:: *Embind* does not support this unless RTTI is enabled.


Overloaded functions
====================
Expand Down
37 changes: 33 additions & 4 deletions test/core/test_embind_polymorphic_class_no_rtti.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,35 +9,64 @@
#include <stdio.h>

EM_JS(void, calltest, (), {
var foo = new Module["Foo"]();
var foo = new Module.Foo();
var fooRaw = Module.FooRaw();
console.log("foo.test() returned: " + foo.test());
console.log("foo.getClassName() -> " + foo.getClassName());
console.log("fooRaw.getClassName() -> " + fooRaw.getClassName());
#if __has_feature(cxx_rtti)
// When RTTI is available we do automatic downcasting
assert(foo.getClassName() == "Bar");
assert(fooRaw.getClassName() == "Bar");
#else
// When RTTI is not available we cannot do automatic downcasting
assert(foo.getClassName() == "Foo");
assert(fooRaw.getClassName() == "Foo");
#endif
foo.delete();
});

class Foo {
public:
virtual ~Foo() = default;
virtual int test() = 0;
std::string getClassName() {
return "Foo";
}
};

class Bar : public Foo {
public:
int test() override { return 42; }
std::string getClassName() {
return "Bar";
}
};

int main(int argc, char** argv){
printf("Hello, world.\n");
printf("in main\n");
calltest();
printf("calltest done\n");
return 0;
}

std::shared_ptr<Foo> MakeFoo() {
Foo* makeFooRaw() {
return new Bar();
}

std::shared_ptr<Foo> makeFoo() {
return std::make_shared<Bar>();
}

using namespace emscripten;

EMSCRIPTEN_BINDINGS(my_module) {
function("FooRaw", &makeFooRaw, allow_raw_pointers());
emscripten::class_<Foo>("Foo")
.smart_ptr_constructor("Foo", &MakeFoo)
.smart_ptr_constructor("Foo", &makeFoo)
.function("test", &Foo::test)
.function("getClassName", &Foo::getClassName)
;
class_<Bar, base<Foo>>("Bar")
.function("getClassName", &Bar::getClassName);
};
2 changes: 1 addition & 1 deletion test/core/test_embind_polymorphic_class_no_rtti.out
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
Hello, world.
in main
foo.test() returned: 42
10 changes: 7 additions & 3 deletions test/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -7580,9 +7580,13 @@ def test_embind_no_rtti(self):
self.emcc_args += ['-lembind', '-fno-rtti', '-DEMSCRIPTEN_HAS_UNBOUND_TYPE_NAMES=0']
self.do_runf('main.cpp', '418\ndotest returned: 42\n')

def test_embind_polymorphic_class_no_rtti(self):
self.emcc_args += ['-lembind', '-fno-rtti', '-DEMSCRIPTEN_HAS_UNBOUND_TYPE_NAMES=0']
self.do_core_test('test_embind_polymorphic_class_no_rtti.cpp')
@no_2gb('https://github.com/emscripten-core/emscripten/issues/21633')
@parameterized({
'': ([],),
'no_rtti': (['-fno-rtti', '-DEMSCRIPTEN_HAS_UNBOUND_TYPE_NAMES=0'],),
})
def test_embind_polymorphic_class(self, args):
self.do_core_test('test_embind_polymorphic_class_no_rtti.cpp', emcc_args=args + ['-lembind'])

def test_embind_no_rtti_followed_by_rtti(self):
src = r'''
Expand Down

0 comments on commit 6cb709b

Please sign in to comment.