[clang] [lld] [llvm] [WebAssembly][Clang] Add support for pointer to externref (PR #163610)

Hood Chatham via cfe-commits cfe-commits at lists.llvm.org
Fri Jan 30 08:57:14 PST 2026


hoodmane wrote:

My goal is to have an ABI for "function that returns multiple externrefs" in C. For typical types this looks like:
```C
int f(void** ret1, void** ret2, ... other arguments);

// call site
void* ret1;
void* ret2;
int status = f(&ret1, &ret2, ...);
```
Two problems happen with `externref_t`:
1. You need to put them into a table. Which table? If the caller puts them into one table and the callee reads them from a different table, it won't work.
2. Once we have a designated table, we have the problem that we need to explicitly allocate and deallocate slots in it, whereas with `&ret1` the compiler deals with that. Maybe we make `__builtin_wasm_externref_stack_alloc()` and it can automatically restore the externref stack in the epilogue and in a cleanuppad.
3. Supposing we have these things, maybe the call site looks like this:
   ```C
   int refaddr_ret1 = __builtin_wasm_externref_stack_alloc();
   int refaddr_ret2 = __builtin_wasm_externref_stack_alloc();
   int status = f(refaddr_ret1, refaddr_ret2, ...);
   externref_t ret1 = __builtin_wasm_table_get(__externref_stack_table, refaddr_ret1)
   externref_t ret2 = __builtin_wasm_table_get(__externref_stack_table, refaddr_ret2)
   ```
   This isn't particularly ergonomic and there is no type safety. It requires the user to know to write different code when the type is a `externref` then what they would do for any other C type. But it does solve the ABI problem -- one library can define a function of this type and another can call it without any additional coordination.

Perhaps I should try to make something like 3. above first. WDYT?

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


More information about the cfe-commits mailing list