-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WebAssembly externalref and tables #61
Comments
I've done a bit more research on funcref tables and have found how they are intended to be supported. Some documentation seems to imply that it already is, however I get llvm bugs whenever I try to duplicate their syntax. The issue here mentions adding a type called __funcref that will make a function pointer as a funcref. However, when I try to make a table with it (in place of __externref_t), it just gives me errors. Or, in the few cases where it doesn't, I can't use the table functions since it gives errors saying it's not a WebAssembly table. This is in spite of this documentation using it as an example: typedef void (*__funcref funcref_t)();
static __funcref table[0];
size_t getSize() {
return __builtin_wasm_table_size(table);
} I don't think it has anything to do with the version of clang since I have tested it with both clang version 17.0.6 and 19.1.5. |
I still haven't been able to find anything conclusive on importing/exporting custom tables directly through clang. I've found this discussion where they say:
Which makes it sound like there's support for importing/exporting, but everything else seems to imply it only applies to the __indirect_function_table. So, for now, I'm just going to conclude that clang can't handle the importing/exporting of tables outside of the __indirect_function_table. |
After discovering webassembly tables after looking into more methods to use for #30 , I discovered some more features that might be useful for this project. For starters, I mentioned how it could allow callbacks to be almost directly passed to JS here: #55 . Additionally, it can be used to store and pass around what WebAssembly calls externrefs. These, in conjunction with tables, allow a WASM module to interact with JS objects to some level. However, there are some limitations and workarounds needed for both.
Tables
The basic WebAssembly documentation that started this off is here. However, I found it somewhat lacking and had to search through multiple sources to find everything I needed. Here's a general overview:
While WASM can do all of the above things, the current implementation in C through clang is a bit more limited. For reference, the list below was mostly derived from this.
__indirect_function_table.get(functionID)(..args)
static __externref_t ext[0];
However, there are some stipulations:ref __builtin_wasm_table_get(table, idx)
void __builtin_wasm_table_set(table, idx, ref)
uint __builtin_wasm_table_size(table)
uint __builtin_wasm_table_grow(table, ref, uint)
void __builtin_wasm_table_fill(table, idx, ref, uint)
void __builtin_wasm_table_copy(table, table, uint, uint, uint)
wasm_table_one_set(idx, ref) { __builtin_wasm_table_set(table_one, id, ref); }
externref
I couldn't find a lot of documentation around this either, but it was mentioned near the bottom here and the C/clang implementation here. The closest description I can get is that it's a pointer for JS objects. The main usages and limitations are as follows:
Uses
So, between WASM tables and externrefs there's a lot of limitations to keep in mind. However, I think it would make several things easier if they were to be integrated into the code base.
Examples
Here's some example/prototype code for using WASM tables.
The following is a malloc like implementation. In a real implementation, malloc_ref and free_ref should fill in empty/freed spaces before growing the table. The main disadvantage to something like this is you would have to convert __externref_t to externref_pntr if you wanted to store a value and then later convert it back to object_ref via get_ref to return it back to JS.
Example code for using the indirect_function_table can be found here
Importing/Exporting tables
As I said above, I couldn't find a way to get clang to export/import tables outside of __indirect_function_table, however, it can be done directly through WASM. So if desired, one could import a WASM module written in something like WAT that imports/exports custom tables and use it in the main library.
For example, the following code is what defines and exports a WASM table:
The above code was generated using clang, but it could, potentially, be written to create a secondary funcref table with exported functions for adding and removing items from it. It could also be used to export/import secondary WASM tables so that both JS and C could access them.
I think the code also demonstrates some of the limitations of tables in how they can't be passed around. Mainly that it seems to take a set number, not a variable, for referencing the table and therefor the table number must be known at compile time.
The text was updated successfully, but these errors were encountered: