Add a wasmtime_linker_define_func C API function (#3122)

This exposes the functionality of the `Linker` type where a
store-independent function can be created and inserted, allowing a
linker's functions to be used across many stores (instead of requiring
one linker-per-store).

Closes #3110
This commit is contained in:
Alex Crichton
2021-07-27 18:56:52 -05:00
committed by GitHub
parent 9b088756b3
commit 65378422bf
3 changed files with 82 additions and 15 deletions

View File

@@ -9,7 +9,7 @@ use std::mem::MaybeUninit;
use std::panic::{self, AssertUnwindSafe};
use std::ptr;
use std::str;
use wasmtime::{AsContextMut, Caller, Extern, Func, Trap};
use wasmtime::{AsContextMut, Caller, Extern, Func, Trap, Val};
#[derive(Clone)]
#[repr(transparent)]
@@ -187,25 +187,37 @@ pub struct wasmtime_caller_t<'a> {
caller: Caller<'a, crate::StoreData>,
}
pub type wasmtime_func_callback_t = extern "C" fn(
*mut c_void,
*mut wasmtime_caller_t,
*const wasmtime_val_t,
usize,
*mut wasmtime_val_t,
usize,
) -> Option<Box<wasm_trap_t>>;
#[no_mangle]
pub unsafe extern "C" fn wasmtime_func_new(
store: CStoreContextMut<'_>,
ty: &wasm_functype_t,
callback: extern "C" fn(
*mut c_void,
*mut wasmtime_caller_t,
*const wasmtime_val_t,
usize,
*mut wasmtime_val_t,
usize,
) -> Option<Box<wasm_trap_t>>,
callback: wasmtime_func_callback_t,
data: *mut c_void,
finalizer: Option<extern "C" fn(*mut std::ffi::c_void)>,
func: &mut Func,
) {
let foreign = crate::ForeignData { data, finalizer };
let ty = ty.ty().ty.clone();
let f = Func::new(store, ty, move |caller, params, results| {
let cb = c_callback_to_rust_fn(callback, data, finalizer);
let f = Func::new(store, ty, cb);
*func = f;
}
pub(crate) unsafe fn c_callback_to_rust_fn(
callback: wasmtime_func_callback_t,
data: *mut c_void,
finalizer: Option<extern "C" fn(*mut std::ffi::c_void)>,
) -> impl Fn(Caller<'_, crate::StoreData>, &[Val], &mut [Val]) -> Result<(), Trap> {
let foreign = crate::ForeignData { data, finalizer };
move |caller, params, results| {
let params = params
.iter()
.cloned()
@@ -234,8 +246,7 @@ pub unsafe extern "C" fn wasmtime_func_new(
results[i] = unsafe { result.to_val() };
}
Ok(())
});
*func = f;
}
}
#[no_mangle]

View File

@@ -1,7 +1,9 @@
use crate::func::c_callback_to_rust_fn;
use crate::{
bad_utf8, handle_result, wasm_engine_t, wasm_trap_t, wasmtime_error_t, wasmtime_extern_t,
wasmtime_module_t, CStoreContextMut,
bad_utf8, handle_result, wasm_engine_t, wasm_functype_t, wasm_trap_t, wasmtime_error_t,
wasmtime_extern_t, wasmtime_func_callback_t, wasmtime_module_t, CStoreContextMut,
};
use std::ffi::c_void;
use std::mem::MaybeUninit;
use std::str;
use wasmtime::{Func, Instance, Linker};
@@ -54,6 +56,25 @@ pub unsafe extern "C" fn wasmtime_linker_define(
handle_result(linker.define(module, name, item), |_linker| ())
}
#[no_mangle]
pub unsafe extern "C" fn wasmtime_linker_define_func(
linker: &mut wasmtime_linker_t,
module: *const u8,
module_len: usize,
name: *const u8,
name_len: usize,
ty: &wasm_functype_t,
callback: wasmtime_func_callback_t,
data: *mut c_void,
finalizer: Option<extern "C" fn(*mut std::ffi::c_void)>,
) -> Option<Box<wasmtime_error_t>> {
let ty = ty.ty().ty.clone();
let module = to_str!(module, module_len);
let name = to_str!(name, name_len);
let cb = c_callback_to_rust_fn(callback, data, finalizer);
handle_result(linker.linker.func_new(module, name, ty, cb), |_linker| ())
}
#[cfg(feature = "wasi")]
#[no_mangle]
pub extern "C" fn wasmtime_linker_define_wasi(