Add wasmtime_func_new_with_env.
This commit adds the `wasmtime_func_new_with_env` C API function and refactors the implementation to share the implementation between the C API and Wasmtime extension variants.
This commit is contained in:
@@ -103,9 +103,18 @@ WASM_API_EXTERN wasm_instance_t* wasmtime_linker_instantiate(
|
|||||||
typedef struct wasmtime_caller_t wasmtime_caller_t;
|
typedef struct wasmtime_caller_t wasmtime_caller_t;
|
||||||
|
|
||||||
typedef own wasm_trap_t* (*wasmtime_func_callback_t)(const wasmtime_caller_t* caller, const wasm_val_t args[], wasm_val_t results[]);
|
typedef own wasm_trap_t* (*wasmtime_func_callback_t)(const wasmtime_caller_t* caller, const wasm_val_t args[], wasm_val_t results[]);
|
||||||
|
typedef own wasm_trap_t* (*wasmtime_func_callback_with_env_t)(const wasmtime_caller_t* caller, void* env, const wasm_val_t args[], wasm_val_t results[]);
|
||||||
|
|
||||||
WASM_API_EXTERN own wasm_func_t* wasmtime_func_new(wasm_store_t*, const wasm_functype_t*, wasmtime_func_callback_t callback);
|
WASM_API_EXTERN own wasm_func_t* wasmtime_func_new(wasm_store_t*, const wasm_functype_t*, wasmtime_func_callback_t callback);
|
||||||
|
|
||||||
|
WASM_API_EXTERN own wasm_func_t* wasmtime_func_new_with_env(
|
||||||
|
wasm_store_t* store,
|
||||||
|
const wasm_functype_t* type,
|
||||||
|
wasmtime_func_callback_with_env_t callback,
|
||||||
|
void* env,
|
||||||
|
void (*finalizer)(void*)
|
||||||
|
);
|
||||||
|
|
||||||
WASM_API_EXTERN own wasm_extern_t* wasmtime_caller_export_get(const wasmtime_caller_t* caller, const wasm_name_t* name);
|
WASM_API_EXTERN own wasm_extern_t* wasmtime_caller_export_get(const wasmtime_caller_t* caller, const wasm_name_t* name);
|
||||||
|
|
||||||
#undef own
|
#undef own
|
||||||
|
|||||||
@@ -221,17 +221,22 @@ pub unsafe extern "C" fn wasmtime_linker_instantiate(
|
|||||||
handle_instantiate(linker.instantiate(&(*module).module.borrow()), trap)
|
handle_instantiate(linker.instantiate(&(*module).module.borrow()), trap)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type wasmtime_func_callback_t = std::option::Option<
|
pub type wasmtime_func_callback_t = unsafe extern "C" fn(
|
||||||
unsafe extern "C" fn(
|
caller: *const wasmtime_caller_t,
|
||||||
caller: *const wasmtime_caller_t,
|
args: *const wasm_val_t,
|
||||||
args: *const wasm_val_t,
|
results: *mut wasm_val_t,
|
||||||
results: *mut wasm_val_t,
|
) -> *mut wasm_trap_t;
|
||||||
) -> *mut wasm_trap_t,
|
|
||||||
>;
|
pub type wasmtime_func_callback_with_env_t = unsafe extern "C" fn(
|
||||||
|
caller: *const wasmtime_caller_t,
|
||||||
|
env: *mut std::ffi::c_void,
|
||||||
|
args: *const wasm_val_t,
|
||||||
|
results: *mut wasm_val_t,
|
||||||
|
) -> *mut wasm_trap_t;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct wasmtime_caller_t<'a> {
|
pub struct wasmtime_caller_t<'a> {
|
||||||
inner: wasmtime::Caller<'a>,
|
pub inner: wasmtime::Caller<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@@ -240,32 +245,24 @@ pub unsafe extern "C" fn wasmtime_func_new(
|
|||||||
ty: *const wasm_functype_t,
|
ty: *const wasm_functype_t,
|
||||||
callback: wasmtime_func_callback_t,
|
callback: wasmtime_func_callback_t,
|
||||||
) -> *mut wasm_func_t {
|
) -> *mut wasm_func_t {
|
||||||
let store = &(*store).store.borrow();
|
crate::create_function(store, ty, crate::Callback::Wasmtime(callback))
|
||||||
let ty = (*ty).functype.clone();
|
}
|
||||||
let func = Func::new(store, ty, move |caller, params, results| {
|
|
||||||
let params = params
|
#[no_mangle]
|
||||||
.iter()
|
pub unsafe extern "C" fn wasmtime_func_new_with_env(
|
||||||
.map(|p| wasm_val_t::from_val(p))
|
store: *mut wasm_store_t,
|
||||||
.collect::<Vec<_>>();
|
ty: *const wasm_functype_t,
|
||||||
let mut out_results = vec![wasm_val_t::default(); results.len()];
|
callback: wasmtime_func_callback_with_env_t,
|
||||||
let func = callback.expect("wasm_func_callback_t fn");
|
env: *mut std::ffi::c_void,
|
||||||
let caller = wasmtime_caller_t { inner: caller };
|
finalizer: Option<unsafe extern "C" fn(arg1: *mut std::ffi::c_void)>,
|
||||||
let out = func(&caller, params.as_ptr(), out_results.as_mut_ptr());
|
) -> *mut wasm_func_t {
|
||||||
if !out.is_null() {
|
crate::create_function_with_env(
|
||||||
let trap: Box<wasm_trap_t> = Box::from_raw(out);
|
store,
|
||||||
return Err(trap.trap.borrow().clone());
|
ty,
|
||||||
}
|
crate::CallbackWithEnv::Wasmtime(callback),
|
||||||
for i in 0..results.len() {
|
env,
|
||||||
results[i] = out_results[i].val();
|
finalizer,
|
||||||
}
|
)
|
||||||
Ok(())
|
|
||||||
});
|
|
||||||
let func = Box::new(wasm_func_t {
|
|
||||||
ext: wasm_extern_t {
|
|
||||||
which: ExternHost::Func(HostRef::new(func)),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
Box::into_raw(func)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
|||||||
@@ -368,16 +368,14 @@ impl wasm_func_t {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type wasm_func_callback_t = std::option::Option<
|
pub type wasm_func_callback_t =
|
||||||
unsafe extern "C" fn(args: *const wasm_val_t, results: *mut wasm_val_t) -> *mut wasm_trap_t,
|
unsafe extern "C" fn(args: *const wasm_val_t, results: *mut wasm_val_t) -> *mut wasm_trap_t;
|
||||||
>;
|
|
||||||
pub type wasm_func_callback_with_env_t = std::option::Option<
|
pub type wasm_func_callback_with_env_t = unsafe extern "C" fn(
|
||||||
unsafe extern "C" fn(
|
env: *mut std::ffi::c_void,
|
||||||
env: *mut std::ffi::c_void,
|
args: *const wasm_val_t,
|
||||||
args: *const wasm_val_t,
|
results: *mut wasm_val_t,
|
||||||
results: *mut wasm_val_t,
|
) -> *mut wasm_trap_t;
|
||||||
) -> *mut wasm_trap_t,
|
|
||||||
>;
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
@@ -622,22 +620,36 @@ impl wasm_val_t {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
enum Callback {
|
||||||
pub unsafe extern "C" fn wasm_func_new(
|
Wasm(wasm_func_callback_t),
|
||||||
|
Wasmtime(crate::ext::wasmtime_func_callback_t),
|
||||||
|
}
|
||||||
|
|
||||||
|
enum CallbackWithEnv {
|
||||||
|
Wasm(wasm_func_callback_with_env_t),
|
||||||
|
Wasmtime(crate::ext::wasmtime_func_callback_with_env_t),
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn create_function(
|
||||||
store: *mut wasm_store_t,
|
store: *mut wasm_store_t,
|
||||||
ty: *const wasm_functype_t,
|
ty: *const wasm_functype_t,
|
||||||
callback: wasm_func_callback_t,
|
callback: Callback,
|
||||||
) -> *mut wasm_func_t {
|
) -> *mut wasm_func_t {
|
||||||
let store = &(*store).store.borrow();
|
let store = &(*store).store.borrow();
|
||||||
let ty = (*ty).functype.clone();
|
let ty = (*ty).functype.clone();
|
||||||
let func = Func::new(store, ty, move |_, params, results| {
|
let func = Func::new(store, ty, move |caller, params, results| {
|
||||||
let params = params
|
let params = params
|
||||||
.iter()
|
.iter()
|
||||||
.map(|p| wasm_val_t::from_val(p))
|
.map(|p| wasm_val_t::from_val(p))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let mut out_results = vec![wasm_val_t::default(); results.len()];
|
let mut out_results = vec![wasm_val_t::default(); results.len()];
|
||||||
let func = callback.expect("wasm_func_callback_t fn");
|
let out = match callback {
|
||||||
let out = func(params.as_ptr(), out_results.as_mut_ptr());
|
Callback::Wasm(callback) => callback(params.as_ptr(), out_results.as_mut_ptr()),
|
||||||
|
Callback::Wasmtime(callback) => {
|
||||||
|
let caller = crate::ext::wasmtime_caller_t { inner: caller };
|
||||||
|
callback(&caller, params.as_ptr(), out_results.as_mut_ptr())
|
||||||
|
}
|
||||||
|
};
|
||||||
if !out.is_null() {
|
if !out.is_null() {
|
||||||
let trap: Box<wasm_trap_t> = Box::from_raw(out);
|
let trap: Box<wasm_trap_t> = Box::from_raw(out);
|
||||||
return Err(trap.trap.borrow().clone());
|
return Err(trap.trap.borrow().clone());
|
||||||
@@ -655,6 +667,74 @@ pub unsafe extern "C" fn wasm_func_new(
|
|||||||
Box::into_raw(func)
|
Box::into_raw(func)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe fn create_function_with_env(
|
||||||
|
store: *mut wasm_store_t,
|
||||||
|
ty: *const wasm_functype_t,
|
||||||
|
callback: CallbackWithEnv,
|
||||||
|
env: *mut std::ffi::c_void,
|
||||||
|
finalizer: Option<unsafe extern "C" fn(arg1: *mut std::ffi::c_void)>,
|
||||||
|
) -> *mut wasm_func_t {
|
||||||
|
let store = &(*store).store.borrow();
|
||||||
|
let ty = (*ty).functype.clone();
|
||||||
|
|
||||||
|
// Create a small object which will run the finalizer when it's dropped, and
|
||||||
|
// then we move this `run_finalizer` object into the closure below (via the
|
||||||
|
// `drop(&run_finalizer)` statement so it's all dropped when the closure is
|
||||||
|
// dropped.
|
||||||
|
struct RunOnDrop<F: FnMut()>(F);
|
||||||
|
impl<F: FnMut()> Drop for RunOnDrop<F> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
(self.0)();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let run_finalizer = RunOnDrop(move || {
|
||||||
|
if let Some(finalizer) = finalizer {
|
||||||
|
finalizer(env);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let func = Func::new(store, ty, move |caller, params, results| {
|
||||||
|
drop(&run_finalizer);
|
||||||
|
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 out = match callback {
|
||||||
|
CallbackWithEnv::Wasm(callback) => {
|
||||||
|
callback(env, params.as_ptr(), out_results.as_mut_ptr())
|
||||||
|
}
|
||||||
|
CallbackWithEnv::Wasmtime(callback) => {
|
||||||
|
let caller = crate::ext::wasmtime_caller_t { inner: caller };
|
||||||
|
callback(&caller, env, 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 wasm_func_new(
|
||||||
|
store: *mut wasm_store_t,
|
||||||
|
ty: *const wasm_functype_t,
|
||||||
|
callback: wasm_func_callback_t,
|
||||||
|
) -> *mut wasm_func_t {
|
||||||
|
create_function(store, ty, Callback::Wasm(callback))
|
||||||
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn wasm_func_delete(f: *mut wasm_func_t) {
|
pub unsafe extern "C" fn wasm_func_delete(f: *mut wasm_func_t) {
|
||||||
let _ = Box::from_raw(f);
|
let _ = Box::from_raw(f);
|
||||||
@@ -896,49 +976,7 @@ pub unsafe extern "C" fn wasm_func_new_with_env(
|
|||||||
env: *mut std::ffi::c_void,
|
env: *mut std::ffi::c_void,
|
||||||
finalizer: Option<unsafe extern "C" fn(arg1: *mut std::ffi::c_void)>,
|
finalizer: Option<unsafe extern "C" fn(arg1: *mut std::ffi::c_void)>,
|
||||||
) -> *mut wasm_func_t {
|
) -> *mut wasm_func_t {
|
||||||
let store = &(*store).store.borrow();
|
create_function_with_env(store, ty, CallbackWithEnv::Wasm(callback), env, finalizer)
|
||||||
let ty = (*ty).functype.clone();
|
|
||||||
|
|
||||||
// Create a small object which will run the finalizer when it's dropped, and
|
|
||||||
// then we move this `run_finalizer` object into the closure below (via the
|
|
||||||
// `drop(&run_finalizer)` statement so it's all dropped when the closure is
|
|
||||||
// dropped.
|
|
||||||
struct RunOnDrop<F: FnMut()>(F);
|
|
||||||
impl<F: FnMut()> Drop for RunOnDrop<F> {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
(self.0)();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let run_finalizer = RunOnDrop(move || {
|
|
||||||
if let Some(finalizer) = finalizer {
|
|
||||||
finalizer(env);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let func = Func::new(store, ty, move |_, params, results| {
|
|
||||||
drop(&run_finalizer);
|
|
||||||
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_with_env_t fn");
|
|
||||||
let out = func(env, 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]
|
#[no_mangle]
|
||||||
|
|||||||
Reference in New Issue
Block a user