[clang] [clang][WebAssembly] Handle casted function pointers with different number of arguments (PR #153168)

Jorge Zapata via cfe-commits cfe-commits at lists.llvm.org
Sat Oct 18 03:53:42 PDT 2025


turran wrote:

> I still have concerns about what exactly the semantics of this change is, and it's a problem that it's not really documented, there are only 2 tests
> 

I added the most common patterns found in GLib in those two examples. At least with that, GLib properly works. I guess there might be other use cases, but I haven't found them yet.

> 
> FuncCastEmulation doesn't actually operate on casts, it actually operates only at callsites. Function pointers always have their usual values no matter how they are generated, casted, or passed around; the transformation only happens at call time. This is why it works across modules despite being so simple. I just want to reiterate again how much simpler a solution that operates at the callsite is compared to trying to trace the origin of all the pointers and casts. Currently there are only 2 tests, but there would need to be a lot more to cover the various ways function pointers can be materialized and casted, including ones that have nothing to do with the GLib use case, because we need to make sure we can adequately describe the behavior of the language change. This is another simplicity advantage of solutions that work on the wasm level; the language is simpler, so the transformation is simpler and easier to understand, describe, and test, and there's less risk of issues when e.g. new frontend or C++ features (or LLVM features like ptr, for that matter) are added or changed.

I took a look again to `EMULATE_FUNCTION_POINTER_CASTS` and both examples work correctly. So something else is missing to be able to make GLib run properly. The examples are very narrow cases and don't expose the multi. c file problem, for example, but might be another thing

Checking the generated wasm/wat, IIUC their approach, it wraps every indirect call with another call with a maximum number of arguments of type i64 for later pushing them into the stack and calling the real indirect call afterwards. The real indirect call will just pop the desired arguments, and everything will simply work. It is fixing the problem with a hammer IMHO, making all indirect calls slower when they are not really needed. I understand the benefit, but the cost is very high.


https://github.com/llvm/llvm-project/pull/153168


More information about the cfe-commits mailing list