I was having problems running some legacy C code with function pointer casting and it seems like this is a known issue. I read this article to get me up to speed a bit https://blog.pyodide.org/posts/function-pointer-cast-handling/
It seems like emscripten has compilation options to fix this, albeit extremely inefficiently. I'm wondering if there's anything that handles this better with wasmtime.
Thanks!
Clang has some builtin logic where, if it sees a function address being directly casted, it'll insert a shim to make it work. But if the place where the address is taken is different from the place where the address is casted, it doesn't work.
That's all I'm aware of.
According to that blog post, EMULATE_FUNCTION_POINTER_CASTS
is a Binaryen pass. It appears to be wasm-opt --fpcast-emu
. I haven't used that myself, but it's something one could try.
It's worth noting that nowadays with the wasm-gc instructions you can actually test if a functions pointer has a given type with: table.get $func_table ref.test $type
. Using this, you can make a helper function that calls a function pointer, dropping or adding arguments as needed to fix up the signature. Of course you can only handle a fixed list of signatures this way but presumably your codebase only has a fixed set of types you need to handle.
After saying this, I realized that doing this would be an improvement for Pyodide since the JS trampoline approach doesn't work with JSPI / stack switching. So if you want to see a full example, I made one here:
https://github.com/pyodide/pyodide/blob/32a99ccba3d08d601d2925140c61f50756d5b240/cpython/patches/0005-Use-wasm-gc-based-call-adaptor-if-available.patch#L114
There is quite limited toolchain support for wasm-gc instructions, so it is a bit of an adventure to use ref.test
at all.
Last updated: Jan 24 2025 at 00:11 UTC