A function environment `WrapperEnv` can be cloned. In case the
original and the cloned environments are being dropped, the
`self.finalizer` function —if any— is called twice. That's a bug. It
must be called only once.
This patch updates the code to apply the finalizer only once by taking
it —if any— the first time it's called.
We have known memory leaks with extern types. The idea is to change
the code so that extern types can hold/own data. This patch does that.
A `wasm_externtype_t` holds a `WasmExternType` enum. This enum owns
sibling types such as `WasmFunctionType`, `WasmGlobalType`,
`WasmTableType` and `WasmMemoryType`. It is those structures that ows
the extern types data, like `params` and `results` as
`wasm_valtype_vec_t` for `WasmFunctionType`. That way, for example,
`wasm_functype_t` can return a pointer to these vec which it owns.
A `wasm_externtype_t` continues to be transmuted to `wasm_functype_t`
etc. Nothing changes on that side.
Our implementation of `wasm_func_call` was correct for C code as
follows:
```c
wasm_val_vec_t arguments = WASM_EMPTY_VEC;
wasm_val_vec_t results = WASM_EMPTY_VEC;
wasm_func_call(func, &arguments, &results);
```
However, for a C code such as:
```c
wasm_val_t vals[1];
wasm_val_vec_t arguments = WASM_EMPTY_VEC;
wasm_val_vec_t results = WASM_ARRAY_VEC(vals);
wasm_func_call(func, &arguments, &results);
```
the `vals` array were kept empty/unchanged. Why?
Because `wasm_func_call` was replacing the value of `results` by a new
`wasm_val_vec_t`. It is correct when `results` is an empty vector, but
it is incorrect when `results` is initialized with empty values.
This patch tries to detect this pattern: If `results.data` is `null`,
it means the vector is empty/uninitialized, and we can set a new
`wasm_val_vec_t`, otherwise it means the vector is initialized with
empty values, and we need to update each item individually.
The implementation of “trap” in `wasm_func_new` was “incorrect”. It's
more idiomatic to return a `RuntimeError` than raising it in this
case, so that we don't duplicate locations where runtime errors are
raised.
The implementation of “trap” in `wasm_func_new_with_env` was
missing. This patch implements a similar strategy than the sibling
function.
This patch creates a `wasm_functype_t::new` constructor, that is used
by the new `wasm_func_type` function, and the existing
`wasm_functype_new_inner` function.
`wasm_$name_vec_t.into_slice` returns `None` if the vec is empty. So
an empty vec of `wasm_extern_t` given to `wasm_func_call` was raising
an error. This patch fixes this.
`wasm_store_t` is now a proper struct (rather than an opaque type) of
kind:
```rs
struct wasm_store_t {
inner: Store
}
```
The rest of the patch updates the code accordingly.