WASM Support: Enhance `@extern` for Module-Qualified Imports
This issue proposes an enhancement to the C3 compiler's @extern directive to support importing functions from WebAssembly (WASM) frameworks like WASI, which use module-namespace qualified import symbols.
Currently, C3 effectively treats the module namespace as hard-coded to "env". While this allows for @extern("fd_write") to become env => fd_write, it doesn't support importing functions like wasi_snapshot_preview1 => fd_write.
Proposed Solution:
Extend the @extern directive to accept a module name along with the function name. Two potential approaches are:
-
Encoded String: Keeping with C3's existing aesthetic, the
@externdirective could accept an encoded string containing both parts. For example,@extern("wasi_snapshot_preview1%fd_write")would map towasi_snapshot_preview1 => fd_writeduring the LLVM processing stage. The%character would trigger the separation of the string into module and function names. -
Separate Arguments: Alternatively, the directive could accept separate arguments for the module and function names. This approach might be more explicit:
@extern("wasi_snapshot_preview1", "fd_write").
Collaboration:
This issue aims to gather feedback and discuss potential implementation strategies. If others become interested in this feature, I'd be happy to collaborate on a pull request (PR) to implement the chosen solution.
References:
- Godbolt Example demonstrating Clang C/C++
__attribute__((import_module("ns")))behavior:- https://godbolt.org/z/aY41Wq8n8
- Potential LLVM Integration Point:
- https://github.com/c3lang/c3c/blob/620c67b04e9784b66c96aecbc352bc8e2e1e89ec/src/compiler/llvm_codegen.c#L1174-L1178
Separate arguments is a good idea, since it could just default to "env" for the 1 argument version.
Would you like to try contributing this?
Ping @humbletim
Would you like to try contributing this?
Thanks for the ping! I'm definitely interested in contributing to a solution. I believe I have a good grasp of where the c3 code could be modified to accommodate the new llvm attribute. However, I'll need to do some more digging to fully understand the extern directive and potential code generation changes.
If you've already outlined a solution, I'm happy to help test it out as well.
My main question is whether to retain the @wasm tag and just make it work like @export but also take this second parameter. Or use @export for it, even though it doesn't make sense for other targets (I think?)
Ping!