Reimplement the C# API.

This commit reimplements the C# API in terms of a Wasmtime linker.

It removes the custom binding implementation that was based on reflection in
favor of the linker's implementation.

This should make the C# API a little closer to the Rust API.

The `Engine` and `Store` types have been hidden behind the `Host` type which is
responsible for hosting WebAssembly module instances.

Documentation and tests have been updated.
This commit is contained in:
Peter Huene
2020-03-24 18:20:22 -07:00
parent 0d5d63fdb1
commit cf1d9ee857
38 changed files with 2149 additions and 2213 deletions

View File

@@ -109,7 +109,6 @@ pub unsafe extern "C" fn wasmtime_config_profiler_set(
#[no_mangle]
pub unsafe extern "C" fn wasmtime_wat2wasm(
_engine: *mut wasm_engine_t,
wat: *const wasm_byte_vec_t,
ret: *mut wasm_byte_vec_t,
error: *mut wasm_byte_vec_t,
@@ -143,10 +142,13 @@ pub struct wasmtime_linker_t {
}
#[no_mangle]
pub unsafe extern "C" fn wasmtime_linker_new(store: *mut wasm_store_t) -> *mut wasmtime_linker_t {
Box::into_raw(Box::new(wasmtime_linker_t {
linker: Linker::new(&(*store).store.borrow()),
}))
pub unsafe extern "C" fn wasmtime_linker_new(
store: *mut wasm_store_t,
allow_shadowing: bool,
) -> *mut wasmtime_linker_t {
let mut linker = Linker::new(&(*store).store.borrow());
linker.allow_shadowing(allow_shadowing);
Box::into_raw(Box::new(wasmtime_linker_t { linker }))
}
#[no_mangle]
@@ -213,3 +215,70 @@ pub unsafe extern "C" fn wasmtime_linker_instantiate(
let linker = &(*linker).linker;
handle_instantiate(linker.instantiate(&(*module).module.borrow()), trap)
}
pub type wasmtime_func_callback_t = std::option::Option<
unsafe extern "C" fn(
caller: *const wasmtime_caller_t,
args: *const wasm_val_t,
results: *mut wasm_val_t,
) -> *mut wasm_trap_t,
>;
#[repr(C)]
pub struct wasmtime_caller_t<'a> {
inner: wasmtime::Caller<'a>,
}
#[no_mangle]
pub unsafe extern "C" fn wasmtime_func_new(
store: *mut wasm_store_t,
ty: *const wasm_functype_t,
callback: wasmtime_func_callback_t,
) -> *mut wasm_func_t {
let store = &(*store).store.borrow();
let ty = (*ty).functype.clone();
let func = Func::new(store, ty, move |caller, params, results| {
let params = params
.iter()
.map(|p| wasm_val_t::from_val(p))
.collect::<Vec<_>>();
let mut out_results = vec![wasm_val_t::default(); results.len()];
let func = callback.expect("wasm_func_callback_t fn");
let caller = wasmtime_caller_t { inner: caller };
let out = func(&caller, params.as_ptr(), out_results.as_mut_ptr());
if !out.is_null() {
let trap: Box<wasm_trap_t> = Box::from_raw(out);
return Err(trap.trap.borrow().clone());
}
for i in 0..results.len() {
results[i] = out_results[i].val();
}
Ok(())
});
let func = Box::new(wasm_func_t {
ext: wasm_extern_t {
which: ExternHost::Func(HostRef::new(func)),
},
});
Box::into_raw(func)
}
#[no_mangle]
pub unsafe extern "C" fn wasmtime_caller_export_get(
caller: *const wasmtime_caller_t,
name: *const wasm_name_t,
) -> *mut wasm_extern_t {
let name = match str::from_utf8((*name).as_slice()) {
Ok(s) => s,
Err(_) => return std::ptr::null_mut(),
};
match (*caller).inner.get_export(name).map(|e| match e {
Extern::Func(f) => ExternHost::Func(HostRef::new(f.clone())),
Extern::Global(g) => ExternHost::Global(HostRef::new(g.clone())),
Extern::Memory(m) => ExternHost::Memory(HostRef::new(m.clone())),
Extern::Table(t) => ExternHost::Table(HostRef::new(t.clone())),
}) {
Some(export) => Box::into_raw(Box::new(wasm_extern_t { which: export })),
None => std::ptr::null_mut(),
}
}