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
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to