The `wasm.h` file defines `wasm_importtype_new` to take ownership of
the module, the name, and the extern type. This patch thus changes
`NonNull` to `Box` for those types.
`wasm_importtype_new` also handles null pointer with `Option<Box<T>>`
and returns an `Option<Box<T>>`.
The rest of the code is simplified. The patch fixes also some typos in
variable namings.
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.
`assert.h` does nothing when the code is compiled in release
mode. That's not what we want :-). Let's reimplement `assert` as
`wasmer_assert`, which is close to the original `assert` function.
There is no memory leaks with those functions as far as I understand this code.
Check the following code as a fun playground, which reproduces a
typical use of `wasm_functype_params` or `_results` that both return a
`wasm_valtype_vec_t`:
```rust
struct wasm_valtype_t { x: u8 }
impl Drop for wasm_valtype_t {
fn drop(&mut self) {
println!("wasm_valtype_t {{ {} }} dropped!", self.x)
}
}
struct wasm_valtype_vec_t {
size: usize,
data: *mut *mut wasm_valtype_t,
}
unsafe fn wasm_valtype_vec_delete(ptr: *mut wasm_valtype_vec_t) {
let vec = &mut *ptr;
if !vec.data.is_null() {
let data: Vec<*mut wasm_valtype_t> = Vec::from_raw_parts(vec.data, vec.size, vec.size);
let _data: Vec<Box<wasm_valtype_t>> = ::std::mem::transmute(data);
vec.data = ::std::ptr::null_mut();
vec.size = 0;
}
}
fn main() {
let x = Box::into_raw(Box::new(wasm_valtype_t { x: 1 }));
let y = Box::into_raw(Box::new(wasm_valtype_t { x: 2 }));
let z = Box::into_raw(Box::new(wasm_valtype_t { x: 3 }));
let mut valtypes: Vec<*mut wasm_valtype_t> = vec![x, y, z];
let vec = Box::into_raw(Box::new(wasm_valtype_vec_t {
size: valtypes.len(),
data: valtypes.as_mut_ptr(),
}));
::std::mem::forget(valtypes);
unsafe { wasm_valtype_vec_delete(vec as *mut _); }
}
```
It prints:
```
wasm_valtype_t { 1 } dropped!
wasm_valtype_t { 2 } dropped!
wasm_valtype_t { 3 } dropped!
```
All `wasm_valtype_t` are dropped correctly. Since they contain an
owned value, there is no leaks here.