-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Tracking issue for the reference types proposal #929
Labels
wasmtime
Issues about wasmtime that don't fall into another label
Comments
alexcrichton
added
the
wasmtime
Issues about wasmtime that don't fall into another label
label
Feb 27, 2020
Closed
fyi, enough to get an |
fitzgen
added a commit
to fitzgen/wasmtime
that referenced
this issue
Jun 5, 2020
For host VM code, we use plain reference counting, where cloning increments the reference count, and dropping decrements it. We can avoid many of the on-stack increment/decrement operations that typically plague the performance of reference counting via Rust's ownership and borrowing system. Moving a `VMExternRef` avoids mutating its reference count, and borrowing it either avoids the reference count increment or delays it until if/when the `VMExternRef` is cloned. When passing a `VMExternRef` into compiled Wasm code, we don't want to do reference count mutations for every compiled `local.{get,set}`, nor for every function call. Therefore, we use a variation of **deferred reference counting**, where we only mutate reference counts when storing `VMExternRef`s somewhere that outlives the activation: into a global or table. Simultaneously, we over-approximate the set of `VMExternRef`s that are inside Wasm function activations. Periodically, we walk the stack at GC safe points, and use stack map information to precisely identify the set of `VMExternRef`s inside Wasm activations. Then we take the difference between this precise set and our over-approximation, and decrement the reference count for each of the `VMExternRef`s that are in our over-approximation but not in the precise set. Finally, the over-approximation is replaced with the precise set. The `VMExternRefActivationsTable` implements the over-approximized set of `VMExternRef`s referenced by Wasm activations. Calling a Wasm function and passing it a `VMExternRef` moves the `VMExternRef` into the table, and the compiled Wasm function logically "borrows" the `VMExternRef` from the table. Similarly, `global.get` and `table.get` operations clone the gotten `VMExternRef` into the `VMExternRefActivationsTable` and then "borrow" the reference out of the table. When a `VMExternRef` is returned to host code from a Wasm function, the host increments the reference count (because the reference is logically "borrowed" from the `VMExternRefActivationsTable` and the reference count from the table will be dropped at the next GC). For more general information on deferred reference counting, see *An Examination of Deferred Reference Counting and Cycle Detection* by Quinane: https://openresearch-repository.anu.edu.au/bitstream/1885/42030/2/hon-thesis.pdf cc bytecodealliance#929 Fixes bytecodealliance#1804
fitzgen
added a commit
to fitzgen/wasmtime
that referenced
this issue
Jun 11, 2020
For host VM code, we use plain reference counting, where cloning increments the reference count, and dropping decrements it. We can avoid many of the on-stack increment/decrement operations that typically plague the performance of reference counting via Rust's ownership and borrowing system. Moving a `VMExternRef` avoids mutating its reference count, and borrowing it either avoids the reference count increment or delays it until if/when the `VMExternRef` is cloned. When passing a `VMExternRef` into compiled Wasm code, we don't want to do reference count mutations for every compiled `local.{get,set}`, nor for every function call. Therefore, we use a variation of **deferred reference counting**, where we only mutate reference counts when storing `VMExternRef`s somewhere that outlives the activation: into a global or table. Simultaneously, we over-approximate the set of `VMExternRef`s that are inside Wasm function activations. Periodically, we walk the stack at GC safe points, and use stack map information to precisely identify the set of `VMExternRef`s inside Wasm activations. Then we take the difference between this precise set and our over-approximation, and decrement the reference count for each of the `VMExternRef`s that are in our over-approximation but not in the precise set. Finally, the over-approximation is replaced with the precise set. The `VMExternRefActivationsTable` implements the over-approximized set of `VMExternRef`s referenced by Wasm activations. Calling a Wasm function and passing it a `VMExternRef` moves the `VMExternRef` into the table, and the compiled Wasm function logically "borrows" the `VMExternRef` from the table. Similarly, `global.get` and `table.get` operations clone the gotten `VMExternRef` into the `VMExternRefActivationsTable` and then "borrow" the reference out of the table. When a `VMExternRef` is returned to host code from a Wasm function, the host increments the reference count (because the reference is logically "borrowed" from the `VMExternRefActivationsTable` and the reference count from the table will be dropped at the next GC). For more general information on deferred reference counting, see *An Examination of Deferred Reference Counting and Cycle Detection* by Quinane: https://openresearch-repository.anu.edu.au/bitstream/1885/42030/2/hon-thesis.pdf cc bytecodealliance#929 Fixes bytecodealliance#1804
fitzgen
added a commit
to fitzgen/wasmtime
that referenced
this issue
Jun 11, 2020
For host VM code, we use plain reference counting, where cloning increments the reference count, and dropping decrements it. We can avoid many of the on-stack increment/decrement operations that typically plague the performance of reference counting via Rust's ownership and borrowing system. Moving a `VMExternRef` avoids mutating its reference count, and borrowing it either avoids the reference count increment or delays it until if/when the `VMExternRef` is cloned. When passing a `VMExternRef` into compiled Wasm code, we don't want to do reference count mutations for every compiled `local.{get,set}`, nor for every function call. Therefore, we use a variation of **deferred reference counting**, where we only mutate reference counts when storing `VMExternRef`s somewhere that outlives the activation: into a global or table. Simultaneously, we over-approximate the set of `VMExternRef`s that are inside Wasm function activations. Periodically, we walk the stack at GC safe points, and use stack map information to precisely identify the set of `VMExternRef`s inside Wasm activations. Then we take the difference between this precise set and our over-approximation, and decrement the reference count for each of the `VMExternRef`s that are in our over-approximation but not in the precise set. Finally, the over-approximation is replaced with the precise set. The `VMExternRefActivationsTable` implements the over-approximized set of `VMExternRef`s referenced by Wasm activations. Calling a Wasm function and passing it a `VMExternRef` moves the `VMExternRef` into the table, and the compiled Wasm function logically "borrows" the `VMExternRef` from the table. Similarly, `global.get` and `table.get` operations clone the gotten `VMExternRef` into the `VMExternRefActivationsTable` and then "borrow" the reference out of the table. When a `VMExternRef` is returned to host code from a Wasm function, the host increments the reference count (because the reference is logically "borrowed" from the `VMExternRefActivationsTable` and the reference count from the table will be dropped at the next GC). For more general information on deferred reference counting, see *An Examination of Deferred Reference Counting and Cycle Detection* by Quinane: https://openresearch-repository.anu.edu.au/bitstream/1885/42030/2/hon-thesis.pdf cc bytecodealliance#929 Fixes bytecodealliance#1804
fitzgen
added a commit
to fitzgen/wasmtime
that referenced
this issue
Jun 11, 2020
For host VM code, we use plain reference counting, where cloning increments the reference count, and dropping decrements it. We can avoid many of the on-stack increment/decrement operations that typically plague the performance of reference counting via Rust's ownership and borrowing system. Moving a `VMExternRef` avoids mutating its reference count, and borrowing it either avoids the reference count increment or delays it until if/when the `VMExternRef` is cloned. When passing a `VMExternRef` into compiled Wasm code, we don't want to do reference count mutations for every compiled `local.{get,set}`, nor for every function call. Therefore, we use a variation of **deferred reference counting**, where we only mutate reference counts when storing `VMExternRef`s somewhere that outlives the activation: into a global or table. Simultaneously, we over-approximate the set of `VMExternRef`s that are inside Wasm function activations. Periodically, we walk the stack at GC safe points, and use stack map information to precisely identify the set of `VMExternRef`s inside Wasm activations. Then we take the difference between this precise set and our over-approximation, and decrement the reference count for each of the `VMExternRef`s that are in our over-approximation but not in the precise set. Finally, the over-approximation is replaced with the precise set. The `VMExternRefActivationsTable` implements the over-approximized set of `VMExternRef`s referenced by Wasm activations. Calling a Wasm function and passing it a `VMExternRef` moves the `VMExternRef` into the table, and the compiled Wasm function logically "borrows" the `VMExternRef` from the table. Similarly, `global.get` and `table.get` operations clone the gotten `VMExternRef` into the `VMExternRefActivationsTable` and then "borrow" the reference out of the table. When a `VMExternRef` is returned to host code from a Wasm function, the host increments the reference count (because the reference is logically "borrowed" from the `VMExternRefActivationsTable` and the reference count from the table will be dropped at the next GC). For more general information on deferred reference counting, see *An Examination of Deferred Reference Counting and Cycle Detection* by Quinane: https://openresearch-repository.anu.edu.au/bitstream/1885/42030/2/hon-thesis.pdf cc bytecodealliance#929 Fixes bytecodealliance#1804
fitzgen
added a commit
to fitzgen/wasmtime
that referenced
this issue
Jun 11, 2020
For host VM code, we use plain reference counting, where cloning increments the reference count, and dropping decrements it. We can avoid many of the on-stack increment/decrement operations that typically plague the performance of reference counting via Rust's ownership and borrowing system. Moving a `VMExternRef` avoids mutating its reference count, and borrowing it either avoids the reference count increment or delays it until if/when the `VMExternRef` is cloned. When passing a `VMExternRef` into compiled Wasm code, we don't want to do reference count mutations for every compiled `local.{get,set}`, nor for every function call. Therefore, we use a variation of **deferred reference counting**, where we only mutate reference counts when storing `VMExternRef`s somewhere that outlives the activation: into a global or table. Simultaneously, we over-approximate the set of `VMExternRef`s that are inside Wasm function activations. Periodically, we walk the stack at GC safe points, and use stack map information to precisely identify the set of `VMExternRef`s inside Wasm activations. Then we take the difference between this precise set and our over-approximation, and decrement the reference count for each of the `VMExternRef`s that are in our over-approximation but not in the precise set. Finally, the over-approximation is replaced with the precise set. The `VMExternRefActivationsTable` implements the over-approximized set of `VMExternRef`s referenced by Wasm activations. Calling a Wasm function and passing it a `VMExternRef` moves the `VMExternRef` into the table, and the compiled Wasm function logically "borrows" the `VMExternRef` from the table. Similarly, `global.get` and `table.get` operations clone the gotten `VMExternRef` into the `VMExternRefActivationsTable` and then "borrow" the reference out of the table. When a `VMExternRef` is returned to host code from a Wasm function, the host increments the reference count (because the reference is logically "borrowed" from the `VMExternRefActivationsTable` and the reference count from the table will be dropped at the next GC). For more general information on deferred reference counting, see *An Examination of Deferred Reference Counting and Cycle Detection* by Quinane: https://openresearch-repository.anu.edu.au/bitstream/1885/42030/2/hon-thesis.pdf cc bytecodealliance#929 Fixes bytecodealliance#1804
fitzgen
added a commit
to fitzgen/wasmtime
that referenced
this issue
Jun 15, 2020
For host VM code, we use plain reference counting, where cloning increments the reference count, and dropping decrements it. We can avoid many of the on-stack increment/decrement operations that typically plague the performance of reference counting via Rust's ownership and borrowing system. Moving a `VMExternRef` avoids mutating its reference count, and borrowing it either avoids the reference count increment or delays it until if/when the `VMExternRef` is cloned. When passing a `VMExternRef` into compiled Wasm code, we don't want to do reference count mutations for every compiled `local.{get,set}`, nor for every function call. Therefore, we use a variation of **deferred reference counting**, where we only mutate reference counts when storing `VMExternRef`s somewhere that outlives the activation: into a global or table. Simultaneously, we over-approximate the set of `VMExternRef`s that are inside Wasm function activations. Periodically, we walk the stack at GC safe points, and use stack map information to precisely identify the set of `VMExternRef`s inside Wasm activations. Then we take the difference between this precise set and our over-approximation, and decrement the reference count for each of the `VMExternRef`s that are in our over-approximation but not in the precise set. Finally, the over-approximation is replaced with the precise set. The `VMExternRefActivationsTable` implements the over-approximized set of `VMExternRef`s referenced by Wasm activations. Calling a Wasm function and passing it a `VMExternRef` moves the `VMExternRef` into the table, and the compiled Wasm function logically "borrows" the `VMExternRef` from the table. Similarly, `global.get` and `table.get` operations clone the gotten `VMExternRef` into the `VMExternRefActivationsTable` and then "borrow" the reference out of the table. When a `VMExternRef` is returned to host code from a Wasm function, the host increments the reference count (because the reference is logically "borrowed" from the `VMExternRefActivationsTable` and the reference count from the table will be dropped at the next GC). For more general information on deferred reference counting, see *An Examination of Deferred Reference Counting and Cycle Detection* by Quinane: https://openresearch-repository.anu.edu.au/bitstream/1885/42030/2/hon-thesis.pdf cc bytecodealliance#929 Fixes bytecodealliance#1804
fitzgen
added a commit
to fitzgen/wasmtime
that referenced
this issue
Jun 17, 2020
fitzgen
added a commit
to fitzgen/wasmtime
that referenced
this issue
Jun 17, 2020
fitzgen
added a commit
to fitzgen/wasmtime
that referenced
this issue
Jun 17, 2020
fitzgen
added a commit
to fitzgen/wasmtime
that referenced
this issue
Jun 17, 2020
fitzgen
added a commit
to fitzgen/wasmtime
that referenced
this issue
Jun 17, 2020
alexcrichton
pushed a commit
that referenced
this issue
Jun 18, 2020
fitzgen
added a commit
to fitzgen/wasmtime
that referenced
this issue
Jun 18, 2020
fitzgen
added a commit
to fitzgen/wasmtime
that referenced
this issue
Jun 23, 2020
`funcref`s are implemented as `NonNull<VMCallerCheckedAnyfunc>`. This should be more efficient than using a `VMExternRef` that points at a `VMCallerCheckedAnyfunc` because it gets rid of an indirection, dynamic allocation, and some reference counting. Note that the null function reference is *NOT* a null pointer; it is a `VMCallerCheckedAnyfunc` that has a null `func_ptr` member. Part of bytecodealliance#929
fitzgen
added a commit
to fitzgen/wasmtime
that referenced
this issue
Jun 24, 2020
`funcref`s are implemented as `NonNull<VMCallerCheckedAnyfunc>`. This should be more efficient than using a `VMExternRef` that points at a `VMCallerCheckedAnyfunc` because it gets rid of an indirection, dynamic allocation, and some reference counting. Note that the null function reference is *NOT* a null pointer; it is a `VMCallerCheckedAnyfunc` that has a null `func_ptr` member. Part of bytecodealliance#929
fitzgen
added a commit
to fitzgen/wasmtime
that referenced
this issue
Jun 24, 2020
`funcref`s are implemented as `NonNull<VMCallerCheckedAnyfunc>`. This should be more efficient than using a `VMExternRef` that points at a `VMCallerCheckedAnyfunc` because it gets rid of an indirection, dynamic allocation, and some reference counting. Note that the null function reference is *NOT* a null pointer; it is a `VMCallerCheckedAnyfunc` that has a null `func_ptr` member. Part of bytecodealliance#929
fitzgen
added a commit
to fitzgen/wasmtime
that referenced
this issue
Jun 24, 2020
`funcref`s are implemented as `NonNull<VMCallerCheckedAnyfunc>`. This should be more efficient than using a `VMExternRef` that points at a `VMCallerCheckedAnyfunc` because it gets rid of an indirection, dynamic allocation, and some reference counting. Note that the null function reference is *NOT* a null pointer; it is a `VMCallerCheckedAnyfunc` that has a null `func_ptr` member. Part of bytecodealliance#929
fitzgen
added a commit
to fitzgen/wasmtime
that referenced
this issue
Jun 24, 2020
`funcref`s are implemented as `NonNull<VMCallerCheckedAnyfunc>`. This should be more efficient than using a `VMExternRef` that points at a `VMCallerCheckedAnyfunc` because it gets rid of an indirection, dynamic allocation, and some reference counting. Note that the null function reference is *NOT* a null pointer; it is a `VMCallerCheckedAnyfunc` that has a null `func_ptr` member. Part of bytecodealliance#929
fitzgen
added a commit
to fitzgen/wasmtime
that referenced
this issue
Jun 25, 2020
These instructions have fast, inline JIT paths for the common cases, and only call out to host VM functions for the slow paths. This required some changes to `cranelift-wasm`'s `FuncEnvironment`: instead of taking a `FuncCursor` to insert an instruction sequence within the current basic block, `FuncEnvironment::translate_table_{get,set}` now take a `&mut FunctionBuilder` so that they can create whole new basic blocks. This is necessary for implementing GC read/write barriers that involve branching (e.g. checking for null, or whether a store buffer is at capacity). Furthermore, it required that the `load`, `load_complex`, and `store` instructions handle loading and storing through an `r{32,64}` rather than just `i{32,64}` addresses. This involved making `r{32,64}` types acceptable instantiations of the `iAddr` type variable, plus a few new instruction encodings. Part of bytecodealliance#929
fitzgen
added a commit
to fitzgen/wasmtime
that referenced
this issue
Jun 25, 2020
These instructions have fast, inline JIT paths for the common cases, and only call out to host VM functions for the slow paths. This required some changes to `cranelift-wasm`'s `FuncEnvironment`: instead of taking a `FuncCursor` to insert an instruction sequence within the current basic block, `FuncEnvironment::translate_table_{get,set}` now take a `&mut FunctionBuilder` so that they can create whole new basic blocks. This is necessary for implementing GC read/write barriers that involve branching (e.g. checking for null, or whether a store buffer is at capacity). Furthermore, it required that the `load`, `load_complex`, and `store` instructions handle loading and storing through an `r{32,64}` rather than just `i{32,64}` addresses. This involved making `r{32,64}` types acceptable instantiations of the `iAddr` type variable, plus a few new instruction encodings. Part of bytecodealliance#929
fitzgen
added a commit
to fitzgen/wasmtime
that referenced
this issue
Jun 26, 2020
These instructions have fast, inline JIT paths for the common cases, and only call out to host VM functions for the slow paths. This required some changes to `cranelift-wasm`'s `FuncEnvironment`: instead of taking a `FuncCursor` to insert an instruction sequence within the current basic block, `FuncEnvironment::translate_table_{get,set}` now take a `&mut FunctionBuilder` so that they can create whole new basic blocks. This is necessary for implementing GC read/write barriers that involve branching (e.g. checking for null, or whether a store buffer is at capacity). Furthermore, it required that the `load`, `load_complex`, and `store` instructions handle loading and storing through an `r{32,64}` rather than just `i{32,64}` addresses. This involved making `r{32,64}` types acceptable instantiations of the `iAddr` type variable, plus a few new instruction encodings. Part of bytecodealliance#929
fitzgen
added a commit
to fitzgen/wasmtime
that referenced
this issue
Jun 26, 2020
These instructions have fast, inline JIT paths for the common cases, and only call out to host VM functions for the slow paths. This required some changes to `cranelift-wasm`'s `FuncEnvironment`: instead of taking a `FuncCursor` to insert an instruction sequence within the current basic block, `FuncEnvironment::translate_table_{get,set}` now take a `&mut FunctionBuilder` so that they can create whole new basic blocks. This is necessary for implementing GC read/write barriers that involve branching (e.g. checking for null, or whether a store buffer is at capacity). Furthermore, it required that the `load`, `load_complex`, and `store` instructions handle loading and storing through an `r{32,64}` rather than just `i{32,64}` addresses. This involved making `r{32,64}` types acceptable instantiations of the `iAddr` type variable, plus a few new instruction encodings. Part of bytecodealliance#929
fitzgen
added a commit
to fitzgen/wasmtime
that referenced
this issue
Jun 30, 2020
These instructions have fast, inline JIT paths for the common cases, and only call out to host VM functions for the slow paths. This required some changes to `cranelift-wasm`'s `FuncEnvironment`: instead of taking a `FuncCursor` to insert an instruction sequence within the current basic block, `FuncEnvironment::translate_table_{get,set}` now take a `&mut FunctionBuilder` so that they can create whole new basic blocks. This is necessary for implementing GC read/write barriers that involve branching (e.g. checking for null, or whether a store buffer is at capacity). Furthermore, it required that the `load`, `load_complex`, and `store` instructions handle loading and storing through an `r{32,64}` rather than just `i{32,64}` addresses. This involved making `r{32,64}` types acceptable instantiations of the `iAddr` type variable, plus a few new instruction encodings. Part of bytecodealliance#929
fitzgen
added a commit
to fitzgen/wasmtime
that referenced
this issue
Jul 2, 2020
We use libcalls to implement these -- unlike `table.{get,set}`, for which we create inline JIT fast paths -- because no known toolchain actually uses externref globals. Part of bytecodealliance#929
fitzgen
added a commit
to fitzgen/wasmtime
that referenced
this issue
Jul 2, 2020
We use libcalls to implement these -- unlike `table.{get,set}`, for which we create inline JIT fast paths -- because no known toolchain actually uses externref globals. Part of bytecodealliance#929
fitzgen
added a commit
to fitzgen/wasmtime
that referenced
this issue
Jul 2, 2020
We use libcalls to implement these -- unlike `table.{get,set}`, for which we create inline JIT fast paths -- because no known toolchain actually uses externref globals. Part of bytecodealliance#929
alexcrichton
pushed a commit
that referenced
this issue
Jul 2, 2020
* wasmtime: Implement `global.{get,set}` for externref globals We use libcalls to implement these -- unlike `table.{get,set}`, for which we create inline JIT fast paths -- because no known toolchain actually uses externref globals. Part of #929 * wasmtime: Enable `{extern,func}ref` globals in the API
fitzgen
added a commit
to fitzgen/wasmtime
that referenced
this issue
Jul 2, 2020
fitzgen
added a commit
to fitzgen/wasmtime
that referenced
this issue
Jul 3, 2020
fitzgen
added a commit
to fitzgen/wasmtime
that referenced
this issue
Jul 6, 2020
All spec tests are now passing on |
fitzgen
added a commit
to fitzgen/wasmtime
that referenced
this issue
Jul 6, 2020
This is a mix of exposing new things (e.g. a `Table::fill` method) and extending existing support to `externref`s (e.g. `Table::new`). Part of bytecodealliance#929
fitzgen
added a commit
to fitzgen/wasmtime
that referenced
this issue
Jul 8, 2020
This required that `wasm_val_t` have a `Drop` implementation, an explicit `Clone` implementation, and no longer be `Copy`, which rippled out through the crate a bit. Additionally, `wasm_func_call` and friends were creating references to uninitialized data for its out pointers and assigning to them. As soon as `wasm_val_t` gained a `Drop` impl and tried to drop the old value of the assignment (which is uninitialized data), then things blew up. The fix is to properly represent the out pointers with `MaybeUninit`, and use `ptr::write` to initialize them without dropping the old data. Part of bytecodealliance#929
fitzgen
added a commit
to fitzgen/wasmtime
that referenced
this issue
Jul 8, 2020
This required that `wasm_val_t` have a `Drop` implementation, an explicit `Clone` implementation, and no longer be `Copy`, which rippled out through the crate a bit. Additionally, `wasm_func_call` and friends were creating references to uninitialized data for its out pointers and assigning to them. As soon as `wasm_val_t` gained a `Drop` impl and tried to drop the old value of the assignment (which is uninitialized data), then things blew up. The fix is to properly represent the out pointers with `MaybeUninit`, and use `ptr::write` to initialize them without dropping the old data. Part of bytecodealliance#929
fitzgen
added a commit
to fitzgen/wasmtime
that referenced
this issue
Jul 10, 2020
This required that `wasm_val_t` have a `Drop` implementation, an explicit `Clone` implementation, and no longer be `Copy`, which rippled out through the crate a bit. Additionally, `wasm_func_call` and friends were creating references to uninitialized data for its out pointers and assigning to them. As soon as `wasm_val_t` gained a `Drop` impl and tried to drop the old value of the assignment (which is uninitialized data), then things blew up. The fix is to properly represent the out pointers with `MaybeUninit`, and use `ptr::write` to initialize them without dropping the old data. Part of bytecodealliance#929
fitzgen
added a commit
to fitzgen/wasmtime
that referenced
this issue
Jul 10, 2020
This required that `wasm_val_t` have a `Drop` implementation, an explicit `Clone` implementation, and no longer be `Copy`, which rippled out through the crate a bit. Additionally, `wasm_func_call` and friends were creating references to uninitialized data for its out pointers and assigning to them. As soon as `wasm_val_t` gained a `Drop` impl and tried to drop the old value of the assignment (which is uninitialized data), then things blew up. The fix is to properly represent the out pointers with `MaybeUninit`, and use `ptr::write` to initialize them without dropping the old data. Part of bytecodealliance#929
Reference types have been implemented and enabled for some time now, so closing. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is a tracking issue for the reference types proposal.
TODO
binary.wast
br_table.wast
exports.wast
globals.wast
imports.wast
linking.wast
memory_grow.wast
ref_func.wast
ref_is_null.wast
ref_null.wast
select.wast
table_fill.wast
table_get.wast
table_grow.wast
table_set.wast
table_size.wast
unreached_invalid.wast
externref
s passed into Wasm: Do not leakexternref
s passed into Wasm #1804Func::wrap
support for functions using reference types: EnableFunc::wrap
support for functions using reference types #1868Support Reference Types in Language Embedding APIs
The text was updated successfully, but these errors were encountered: