feat(c-api) Implement the traps argument of wasm_instance_new.

When running `Instance::new`, it can error with an
`InstantiationError`. There is 2 scenarii:

1. Either it's a `InstantiationError::Link`. In this case, the
   `wasm_instance_new` function must return `NULL` and register the
   error in the Wasmer error registry.

2. Either it's a `InstantiationError::Start`. In this case, the
   `wasm_instance_new` function must return `NULL` and the error must be
   converted into a `wasm_trap_t`, which is stored in the `wasm_trap_t**`
   array. This array is initialized by `wasm_instance_new` itself.
This commit is contained in:
Ivan Enderlin
2020-10-26 15:12:26 +01:00
parent 7eddb46cb0
commit a2d96d9ba7

View File

@@ -5,7 +5,7 @@ use super::trap::wasm_trap_t;
use crate::ordered_resolver::OrderedResolver;
use std::mem;
use std::sync::Arc;
use wasmer::{Extern, Instance};
use wasmer::{Extern, Instance, InstantiationError};
#[allow(non_camel_case_types)]
pub struct wasm_instance_t {
@@ -17,8 +17,7 @@ pub unsafe extern "C" fn wasm_instance_new(
_store: &wasm_store_t,
module: &wasm_module_t,
imports: &wasm_extern_vec_t,
// own
_traps: *mut *mut wasm_trap_t,
traps: *mut *mut wasm_trap_t,
) -> Option<Box<wasm_instance_t>> {
let wasm_module = &module.inner;
let module_imports = wasm_module.imports();
@@ -32,7 +31,35 @@ pub unsafe extern "C" fn wasm_instance_new(
.cloned()
.collect();
let instance = Arc::new(c_try!(Instance::new(wasm_module, &resolver)));
let instance = match Instance::new(wasm_module, &resolver) {
Ok(instance) => Arc::new(instance),
Err(InstantiationError::Link(link_error)) => {
crate::error::update_last_error(link_error);
return None;
}
Err(InstantiationError::Start(runtime_error)) => {
let pointer = {
let trap: Box<wasm_trap_t> = Box::new(runtime_error.into());
let mut traps: Vec<*mut wasm_trap_t> = Vec::with_capacity(1);
traps.push(Box::into_raw(trap));
debug_assert!(traps.len() == traps.capacity());
let pointer = traps.as_mut_ptr();
mem::forget(traps);
pointer
};
*traps = *pointer;
return None;
}
};
Some(Box::new(wasm_instance_t { inner: instance }))
}