In case of a boxed vector, `wasm_$name_vec_delete` now checks that the
vec is correctly initialized (by checking the first item only) because
transmuting `Vec<*mut T>` to `Vec<Box<T>>`, otherwise it will crash.
In `wasm.h`, `wasm_frame_t` is implemented with `WASM_DECLARE_TYPE`,
so with `WASM_DECLARE_VEC(frame, *)`. This `*` means the C struct for
the vector is defined:
```c
struct wasm_frame_vec_t {
size_t size;
wasm_frame_t** data;
}
```
The way we implement `wasm_frame_vec_t` in Rust is with the
`wasm_declare_vec!` macro. And it is wrong. We must use
`wasm_declared_boxed_vec!`.
In `wasm.h`, `wasm_tabletype_t` is implemented with
`WASM_DECLARE_TYPE`, so with `WASM_DECLARE_VEC(tabletype, *)`. This
`*` means the C struct for the vector is defined:
```c
struct wasm_tabletype_vec_t {
size_t size;
wasm_tabletype_t** data;
}
```
The way we implement `wasm_tabletype_vec_t` in Rust is with the
`wasm_declare_vec!` macro. And it is wrong. We must use
`wasm_declared_boxed_vec!`.
In `wasm.h`, `wasm_memorytype_t` is implemented with
`WASM_DECLARE_TYPE`, so with `WASM_DECLARE_VEC(memorytype, *)`. This
`*` means the C struct for the vector is defined:
```c
struct wasm_memorytype_vec_t {
size_t size;
wasm_memorytype_t** data;
}
```
The way we implement `wasm_memorytype_vec_t` in Rust is with the
`wasm_declare_vec!` macro. And it is wrong. We must use
`wasm_declared_boxed_vec!`.
In `wasm.h`, `wasm_globaltype_t` is implemented with
`WASM_DECLARE_TYPE`, so with `WASM_DECLARE_VEC(globaltype, *)`. This
`*` means the C struct for the vector is defined:
```c
struct wasm_globaltype_vec_t {
size_t size;
wasm_globaltype_t** data;
}
```
The way we implement `wasm_globaltype_vec_t` in Rust is with the
`wasm_declare_vec!` macro. And it is wrong. We must use
`wasm_declared_boxed_vec!`.
In `wasm.h`, `wasm_functype_t` is implemented with
`WASM_DECLARE_TYPE`, so with `WASM_DECLARE_VEC(functype, *)`. This `*`
means the C struct for the vector is defined:
```c
struct wasm_functype_vec_t {
size_t size;
wasm_functype_t** data;
}
```
The way we implement `wasm_functype_vec_t` in Rust is with the
`wasm_declare_vec!` macro. And it is wrong. We must use
`wasm_declared_boxed_vec!`.
1865: Fix memory leak in host function envs r=MarkMcCaskey a=MarkMcCaskey
TODO: link to issue
This PR contains a number of changes:
1. Make `WasmerEnv: Clone`
2. Store a pointer to the `clone` function when creating a host function (Notably this is a feature that wouldn't work even if we _could_ use a proper trait object because you can't have a `Sized` trait object and `Clone: Sized`).
3. Store a pointer to the `drop` function when creating a host function.
4. Clone the env via pointer every time an `Instance` is made. Therefore each `Instance` gets its own, unique `Env` per host function with `Env`.
5. Add reference counting and drop logic to a sub-field of `wasmer_export::ExportFunction` which frees the original version of the `Env` (the thing that gets cloned each time an `Instance` is made) with the `drop` function pointer.
6. Change some logic in `vm::Instance` from SoA (struct of arrays) to AoS (array of structs): this uses more memory but is a bit less error prone and can be easily changed later.
7. Add logic on this new struct (`vm::ImportEnv`) that contains the function pointers for each import in `Instance` to drop (with the `drop` fn pointer) when the `vm::Instance` is being dropped. This fixes the original memory leak.
8. Add wrapper functions inside the host function creation functions which makes the layout of the user supplied env-pointer the responsibility of each function. Thus, rather than `drop` being `Env::drop`, it's a function which frees all wrapper types, traverses indirections and frees the internal `Env` with `Env::drop`. This simplifies code at the cost of making the `host_env` pointer (`vmctx`) not consistent in terms of what it actually points to. This change fixes another memory leak related to the creation of host functions.
tl;dr: we're leaning into manually doing virtual method dispatch on `WasmerEnv`s and it actually works great! The biggest issue I have with the PR as-is is that the code isn't as clean/readable/robust as I'd ideally like it to be.
Edit (by @Hywan): This PR fixes#1584, #1714, #1865, #1667.
# Review
- [ ] Add a short description of the the change to the CHANGELOG.md file
Co-authored-by: Mark McCaskey <mark@wasmer.io>
Co-authored-by: Mark McCaskey <5770194+MarkMcCaskey@users.noreply.github.com>
1930: test+doc(c-api) Improve test coverage and documentation of the C API r=Hywan a=Hywan
# Description
This PR improves the test coverage by adding more test cases of the C API. It also largely improve the documentation of the C API by writing more documentation, adding more cross-links, improving navigation and the user-experience.
# Review
- [ ] Add a short description of the the change to the CHANGELOG.md file
Co-authored-by: Ivan Enderlin <ivan@mnt.io>
1911: Add support for const function signatures r=MarkMcCaskey a=webmaster128
# Description
`FunctionType` contains variable length vectors and I'm sure there is a good reason for this design. However, it makes creating them a bit annoying since it connot be done in constants. With this PR I propose a representation that uses a tuple of arrays, which can be converted into `FunctionType` on demand. This allows developers to use constant signatures and push them to a better place in their code.
In https://github.com/CosmWasm/cosmwasm/pull/659/files you see a demonstration of how this deduplicates code and pushes the definitions out of my way.
Since the conversion `&FunctionType` to `FunctionType` is implemented here, this should no be breaking anyone's code. In cases where you can pass an owned `FunctionType` instead of `&FunctionType` you save one clone.
# Review
- [x] Add a short description of the the change to the CHANGELOG.md file
Co-authored-by: Simon Warta <simon@warta.it>