diff --git a/crates/c-api/src/async.rs b/crates/c-api/src/async.rs index a5952297e4d1..5518cca39319 100644 --- a/crates/c-api/src/async.rs +++ b/crates/c-api/src/async.rs @@ -15,7 +15,7 @@ use wasmtime::{ use crate::{ bad_utf8, handle_result, to_str, translate_args, wasm_config_t, wasm_functype_t, wasm_trap_t, wasmtime_caller_t, wasmtime_error_t, wasmtime_instance_pre_t, wasmtime_linker_t, - wasmtime_module_t, wasmtime_val_t, wasmtime_val_union, CStoreContextMut, WASMTIME_I32, + wasmtime_module_t, wasmtime_val_t, wasmtime_val_union, WasmtimeStoreContextMut, WASMTIME_I32, }; #[no_mangle] @@ -30,7 +30,7 @@ pub extern "C" fn wasmtime_config_async_stack_size_set(c: &mut wasm_config_t, si #[no_mangle] pub extern "C" fn wasmtime_context_epoch_deadline_async_yield_and_update( - mut store: CStoreContextMut<'_>, + mut store: WasmtimeStoreContextMut<'_>, delta: u64, ) { store.epoch_deadline_async_yield_and_update(delta); @@ -38,7 +38,7 @@ pub extern "C" fn wasmtime_context_epoch_deadline_async_yield_and_update( #[no_mangle] pub extern "C" fn wasmtime_context_fuel_async_yield_interval( - mut store: CStoreContextMut<'_>, + mut store: WasmtimeStoreContextMut<'_>, interval: Option, ) -> Option> { handle_result( @@ -103,7 +103,7 @@ pub type wasmtime_func_async_continuation_callback_t = extern "C" fn(*mut c_void async fn invoke_c_async_callback<'a>( cb: wasmtime_func_async_callback_t, data: CallbackDataPtr, - mut caller: Caller<'a, crate::StoreData>, + mut caller: Caller<'a, crate::WasmtimeStoreData>, params: &'a [Val], results: &'a mut [Val], ) -> Result<()> { @@ -172,7 +172,7 @@ unsafe fn c_async_callback_to_rust_fn( data: *mut c_void, finalizer: Option, ) -> impl for<'a> Fn( - Caller<'a, crate::StoreData>, + Caller<'a, crate::WasmtimeStoreData>, &'a [Val], &'a mut [Val], ) -> Box> + Send + 'a> @@ -219,7 +219,7 @@ fn handle_call_error( } async fn do_func_call_async( - mut store: CStoreContextMut<'_>, + mut store: WasmtimeStoreContextMut<'_>, func: &Func, args: impl ExactSizeIterator, results: &mut [MaybeUninit], @@ -245,7 +245,7 @@ async fn do_func_call_async( #[no_mangle] pub unsafe extern "C" fn wasmtime_func_call_async<'a>( - mut store: CStoreContextMut<'a>, + mut store: WasmtimeStoreContextMut<'a>, func: &'a Func, args: *const wasmtime_val_t, nargs: usize, @@ -295,7 +295,7 @@ pub unsafe extern "C" fn wasmtime_linker_define_async_func( async fn do_linker_instantiate_async( linker: &wasmtime_linker_t, - store: CStoreContextMut<'_>, + store: WasmtimeStoreContextMut<'_>, module: &wasmtime_module_t, instance_ptr: &mut Instance, trap_ret: &mut *mut wasm_trap_t, @@ -311,7 +311,7 @@ async fn do_linker_instantiate_async( #[no_mangle] pub extern "C" fn wasmtime_linker_instantiate_async<'a>( linker: &'a wasmtime_linker_t, - store: CStoreContextMut<'a>, + store: WasmtimeStoreContextMut<'a>, module: &'a wasmtime_module_t, instance_ptr: &'a mut Instance, trap_ret: &'a mut *mut wasm_trap_t, @@ -330,7 +330,7 @@ pub extern "C" fn wasmtime_linker_instantiate_async<'a>( async fn do_instance_pre_instantiate_async( instance_pre: &wasmtime_instance_pre_t, - store: CStoreContextMut<'_>, + store: WasmtimeStoreContextMut<'_>, instance_ptr: &mut Instance, trap_ret: &mut *mut wasm_trap_t, err_ret: &mut *mut wasmtime_error_t, @@ -345,7 +345,7 @@ async fn do_instance_pre_instantiate_async( #[no_mangle] pub extern "C" fn wasmtime_instance_pre_instantiate_async<'a>( instance_pre: &'a wasmtime_instance_pre_t, - store: CStoreContextMut<'a>, + store: WasmtimeStoreContextMut<'a>, instance_ptr: &'a mut Instance, trap_ret: &'a mut *mut wasm_trap_t, err_ret: &'a mut *mut wasmtime_error_t, diff --git a/crates/c-api/src/extern.rs b/crates/c-api/src/extern.rs index 3fbf1d0cdf3f..a915973df05b 100644 --- a/crates/c-api/src/extern.rs +++ b/crates/c-api/src/extern.rs @@ -1,6 +1,6 @@ use crate::{ wasm_externkind_t, wasm_externtype_t, wasm_func_t, wasm_global_t, wasm_memory_t, wasm_table_t, - CStoreContext, StoreRef, + WasmtimeStoreContext, StoreRef, }; use std::mem::ManuallyDrop; use wasmtime::{Extern, Func, Global, Memory, SharedMemory, Table}; @@ -152,7 +152,7 @@ pub unsafe extern "C" fn wasmtime_extern_delete(e: &mut ManuallyDrop, + store: WasmtimeStoreContext<'_>, e: &wasmtime_extern_t, ) -> Box { Box::new(wasm_externtype_t::from_extern_type(e.to_extern().ty(store))) diff --git a/crates/c-api/src/func.rs b/crates/c-api/src/func.rs index 52d6c526abcf..649cd2c4b275 100644 --- a/crates/c-api/src/func.rs +++ b/crates/c-api/src/func.rs @@ -1,7 +1,8 @@ use crate::wasm_trap_t; use crate::{ wasm_extern_t, wasm_functype_t, wasm_store_t, wasm_val_t, wasm_val_vec_t, wasmtime_error_t, - wasmtime_extern_t, wasmtime_val_t, wasmtime_val_union, CStoreContext, CStoreContextMut, + wasmtime_extern_t, wasmtime_val_t, wasmtime_val_union, WasmtimeStoreContext, + WasmtimeStoreContextMut, }; use anyhow::{Error, Result}; use std::any::Any; @@ -59,11 +60,11 @@ unsafe fn create_function( let func = Func::new( store.store.context_mut(), ty, - move |_caller, params, results| { + move |mut caller, params, results| { let params: wasm_val_vec_t = params .iter() .cloned() - .map(|p| wasm_val_t::from_val(p)) + .map(|p| wasm_val_t::from_val(&mut caller.as_context_mut(), p)) .collect::>() .into(); let mut out_results: wasm_val_vec_t = vec![wasm_val_t::default(); results.len()].into(); @@ -72,7 +73,7 @@ unsafe fn create_function( return Err(trap.error); } - let out_results = out_results.as_slice(); + let out_results = out_results.as_slice_mut(); for i in 0..results.len() { results[i] = out_results[i].val(); } @@ -150,7 +151,10 @@ pub unsafe extern "C" fn wasm_func_call( match result { Ok(Ok(())) => { for (slot, val) in results.iter_mut().zip(wt_results.iter().cloned()) { - crate::initialize(slot, wasm_val_t::from_val(val)); + crate::initialize( + slot, + wasm_val_t::from_val(&mut func.ext.store.context_mut(), val), + ); } ptr::null_mut() } @@ -200,7 +204,7 @@ pub extern "C" fn wasm_func_as_extern_const(f: &wasm_func_t) -> &wasm_extern_t { #[repr(C)] pub struct wasmtime_caller_t<'a> { - pub(crate) caller: Caller<'a, crate::StoreData>, + pub(crate) caller: Caller<'a, crate::WasmtimeStoreData>, } pub type wasmtime_func_callback_t = extern "C" fn( @@ -221,7 +225,7 @@ pub type wasmtime_func_unchecked_callback_t = extern "C" fn( #[no_mangle] pub unsafe extern "C" fn wasmtime_func_new( - store: CStoreContextMut<'_>, + store: WasmtimeStoreContextMut<'_>, ty: &wasm_functype_t, callback: wasmtime_func_callback_t, data: *mut c_void, @@ -238,7 +242,7 @@ pub(crate) unsafe fn c_callback_to_rust_fn( callback: wasmtime_func_callback_t, data: *mut c_void, finalizer: Option, -) -> impl Fn(Caller<'_, crate::StoreData>, &[Val], &mut [Val]) -> Result<()> { +) -> impl Fn(Caller<'_, crate::WasmtimeStoreData>, &[Val], &mut [Val]) -> Result<()> { let foreign = crate::ForeignData { data, finalizer }; move |mut caller, params, results| { let _ = &foreign; // move entire foreign into this closure @@ -291,7 +295,7 @@ pub(crate) unsafe fn c_callback_to_rust_fn( #[no_mangle] pub unsafe extern "C" fn wasmtime_func_new_unchecked( - store: CStoreContextMut<'_>, + store: WasmtimeStoreContextMut<'_>, ty: &wasm_functype_t, callback: wasmtime_func_unchecked_callback_t, data: *mut c_void, @@ -307,7 +311,7 @@ pub(crate) unsafe fn c_unchecked_callback_to_rust_fn( callback: wasmtime_func_unchecked_callback_t, data: *mut c_void, finalizer: Option, -) -> impl Fn(Caller<'_, crate::StoreData>, &mut [ValRaw]) -> Result<()> { +) -> impl Fn(Caller<'_, crate::WasmtimeStoreData>, &mut [ValRaw]) -> Result<()> { let foreign = crate::ForeignData { data, finalizer }; move |caller, values| { let _ = &foreign; // move entire foreign into this closure @@ -321,7 +325,7 @@ pub(crate) unsafe fn c_unchecked_callback_to_rust_fn( #[no_mangle] pub unsafe extern "C" fn wasmtime_func_call( - mut store: CStoreContextMut<'_>, + mut store: WasmtimeStoreContextMut<'_>, func: &Func, args: *const wasmtime_val_t, nargs: usize, @@ -367,7 +371,7 @@ pub unsafe extern "C" fn wasmtime_func_call( #[no_mangle] pub unsafe extern "C" fn wasmtime_func_call_unchecked( - store: CStoreContextMut<'_>, + store: WasmtimeStoreContextMut<'_>, func: &Func, args_and_results: *mut ValRaw, args_and_results_len: usize, @@ -390,7 +394,7 @@ fn store_err(err: Error, trap_ret: &mut *mut wasm_trap_t) -> Option, + store: WasmtimeStoreContext<'_>, func: &Func, ) -> Box { Box::new(wasm_functype_t::new(func.ty(store))) @@ -399,7 +403,7 @@ pub extern "C" fn wasmtime_func_type( #[no_mangle] pub extern "C" fn wasmtime_caller_context<'a>( caller: &'a mut wasmtime_caller_t, -) -> CStoreContextMut<'a> { +) -> WasmtimeStoreContextMut<'a> { caller.caller.as_context_mut() } @@ -424,7 +428,7 @@ pub unsafe extern "C" fn wasmtime_caller_export_get( #[no_mangle] pub unsafe extern "C" fn wasmtime_func_from_raw( - store: CStoreContextMut<'_>, + store: WasmtimeStoreContextMut<'_>, raw: *mut c_void, func: &mut Func, ) { @@ -433,7 +437,7 @@ pub unsafe extern "C" fn wasmtime_func_from_raw( #[no_mangle] pub unsafe extern "C" fn wasmtime_func_to_raw( - store: CStoreContextMut<'_>, + store: WasmtimeStoreContextMut<'_>, func: &Func, ) -> *mut c_void { func.to_raw(store) diff --git a/crates/c-api/src/global.rs b/crates/c-api/src/global.rs index 8fcc392e2170..0ed8e43aa25a 100644 --- a/crates/c-api/src/global.rs +++ b/crates/c-api/src/global.rs @@ -1,6 +1,6 @@ use crate::{ handle_result, wasm_extern_t, wasm_globaltype_t, wasm_store_t, wasm_val_t, wasmtime_error_t, - wasmtime_val_t, CStoreContext, CStoreContextMut, + wasmtime_val_t, WasmtimeStoreContext, WasmtimeStoreContextMut, }; use std::mem::MaybeUninit; use wasmtime::{Extern, Global}; @@ -65,10 +65,9 @@ pub unsafe extern "C" fn wasm_global_type(g: &wasm_global_t) -> Box) { let global = g.global(); - crate::initialize( - out, - wasm_val_t::from_val(global.get(g.ext.store.context_mut())), - ); + let mut ctx = g.ext.store.context_mut(); + let val = global.get(&mut ctx); + crate::initialize(out, wasm_val_t::from_val(&mut ctx, val)); } #[no_mangle] @@ -79,7 +78,7 @@ pub unsafe extern "C" fn wasm_global_set(g: &mut wasm_global_t, val: &wasm_val_t #[no_mangle] pub unsafe extern "C" fn wasmtime_global_new( - mut store: CStoreContextMut<'_>, + mut store: WasmtimeStoreContextMut<'_>, gt: &wasm_globaltype_t, val: &wasmtime_val_t, ret: &mut Global, @@ -93,7 +92,7 @@ pub unsafe extern "C" fn wasmtime_global_new( #[no_mangle] pub extern "C" fn wasmtime_global_type( - store: CStoreContext<'_>, + store: WasmtimeStoreContext<'_>, global: &Global, ) -> Box { Box::new(wasm_globaltype_t::new(global.ty(store))) @@ -101,7 +100,7 @@ pub extern "C" fn wasmtime_global_type( #[no_mangle] pub extern "C" fn wasmtime_global_get( - mut store: CStoreContextMut<'_>, + mut store: WasmtimeStoreContextMut<'_>, global: &Global, val: &mut MaybeUninit, ) { @@ -111,7 +110,7 @@ pub extern "C" fn wasmtime_global_get( #[no_mangle] pub unsafe extern "C" fn wasmtime_global_set( - mut store: CStoreContextMut<'_>, + mut store: WasmtimeStoreContextMut<'_>, global: &Global, val: &wasmtime_val_t, ) -> Option> { diff --git a/crates/c-api/src/instance.rs b/crates/c-api/src/instance.rs index 6a6e71196915..826ec5c034b3 100644 --- a/crates/c-api/src/instance.rs +++ b/crates/c-api/src/instance.rs @@ -1,6 +1,6 @@ use crate::{ wasm_extern_t, wasm_extern_vec_t, wasm_module_t, wasm_store_t, wasm_trap_t, wasmtime_error_t, - wasmtime_extern_t, wasmtime_module_t, CStoreContextMut, StoreData, StoreRef, + wasmtime_extern_t, wasmtime_module_t, WasmtimeStoreContextMut, WasmtimeStoreData, StoreRef, }; use std::mem::MaybeUninit; use wasmtime::{Instance, InstancePre, Trap}; @@ -70,7 +70,7 @@ pub unsafe extern "C" fn wasm_instance_exports( #[no_mangle] pub unsafe extern "C" fn wasmtime_instance_new( - store: CStoreContextMut<'_>, + store: WasmtimeStoreContextMut<'_>, module: &wasmtime_module_t, imports: *const wasmtime_extern_t, nimports: usize, @@ -111,7 +111,7 @@ pub(crate) fn handle_instantiate( #[no_mangle] pub unsafe extern "C" fn wasmtime_instance_export_get( - store: CStoreContextMut<'_>, + store: WasmtimeStoreContextMut<'_>, instance: &Instance, name: *const u8, name_len: usize, @@ -133,7 +133,7 @@ pub unsafe extern "C" fn wasmtime_instance_export_get( #[no_mangle] pub unsafe extern "C" fn wasmtime_instance_export_nth( - store: CStoreContextMut<'_>, + store: WasmtimeStoreContextMut<'_>, instance: &Instance, index: usize, name_ptr: &mut *const u8, @@ -153,7 +153,7 @@ pub unsafe extern "C" fn wasmtime_instance_export_nth( #[repr(transparent)] pub struct wasmtime_instance_pre_t { - pub(crate) underlying: InstancePre, + pub(crate) underlying: InstancePre, } #[no_mangle] @@ -163,7 +163,7 @@ pub unsafe extern "C" fn wasmtime_instance_pre_delete(_instance_pre: Box, + store: WasmtimeStoreContextMut<'_>, instance_ptr: &mut Instance, trap_ptr: &mut *mut wasm_trap_t, ) -> Option> { diff --git a/crates/c-api/src/linker.rs b/crates/c-api/src/linker.rs index 0c2fd8a6149e..7accd3466dcc 100644 --- a/crates/c-api/src/linker.rs +++ b/crates/c-api/src/linker.rs @@ -1,6 +1,6 @@ use crate::{ bad_utf8, handle_result, wasm_engine_t, wasm_functype_t, wasm_trap_t, wasmtime_error_t, - wasmtime_extern_t, wasmtime_instance_pre_t, wasmtime_module_t, CStoreContext, CStoreContextMut, + wasmtime_extern_t, wasmtime_instance_pre_t, wasmtime_module_t, WasmtimeStoreContext, WasmtimeStoreContextMut, }; use std::ffi::c_void; use std::mem::MaybeUninit; @@ -9,7 +9,7 @@ use wasmtime::{Func, Instance, Linker}; #[repr(C)] pub struct wasmtime_linker_t { - pub(crate) linker: Linker, + pub(crate) linker: Linker, } wasmtime_c_api_macros::declare_own!(wasmtime_linker_t); @@ -50,7 +50,7 @@ pub(crate) use to_str; #[no_mangle] pub unsafe extern "C" fn wasmtime_linker_define( linker: &mut wasmtime_linker_t, - store: CStoreContext<'_>, + store: WasmtimeStoreContext<'_>, module: *const u8, module_len: usize, name: *const u8, @@ -123,7 +123,7 @@ pub extern "C" fn wasmtime_linker_define_wasi( #[no_mangle] pub unsafe extern "C" fn wasmtime_linker_define_instance( linker: &mut wasmtime_linker_t, - store: CStoreContextMut<'_>, + store: WasmtimeStoreContextMut<'_>, name: *const u8, name_len: usize, instance: &Instance, @@ -136,7 +136,7 @@ pub unsafe extern "C" fn wasmtime_linker_define_instance( #[no_mangle] pub extern "C" fn wasmtime_linker_instantiate( linker: &wasmtime_linker_t, - store: CStoreContextMut<'_>, + store: WasmtimeStoreContextMut<'_>, module: &wasmtime_module_t, instance_ptr: &mut Instance, trap_ptr: &mut *mut wasm_trap_t, @@ -161,7 +161,7 @@ pub unsafe extern "C" fn wasmtime_linker_instantiate_pre( #[no_mangle] pub unsafe extern "C" fn wasmtime_linker_module( linker: &mut wasmtime_linker_t, - store: CStoreContextMut<'_>, + store: WasmtimeStoreContextMut<'_>, name: *const u8, name_len: usize, module: &wasmtime_module_t, @@ -174,7 +174,7 @@ pub unsafe extern "C" fn wasmtime_linker_module( #[no_mangle] pub unsafe extern "C" fn wasmtime_linker_get_default( linker: &wasmtime_linker_t, - store: CStoreContextMut<'_>, + store: WasmtimeStoreContextMut<'_>, name: *const u8, name_len: usize, func: &mut Func, @@ -187,7 +187,7 @@ pub unsafe extern "C" fn wasmtime_linker_get_default( #[no_mangle] pub unsafe extern "C" fn wasmtime_linker_get( linker: &wasmtime_linker_t, - store: CStoreContextMut<'_>, + store: WasmtimeStoreContextMut<'_>, module: *const u8, module_len: usize, name: *const u8, diff --git a/crates/c-api/src/memory.rs b/crates/c-api/src/memory.rs index 299dbae7bb68..5b081918482a 100644 --- a/crates/c-api/src/memory.rs +++ b/crates/c-api/src/memory.rs @@ -1,6 +1,6 @@ use crate::{ - handle_result, wasm_extern_t, wasm_memorytype_t, wasm_store_t, wasmtime_error_t, CStoreContext, - CStoreContextMut, + handle_result, wasm_extern_t, wasm_memorytype_t, wasm_store_t, wasmtime_error_t, WasmtimeStoreContext, + WasmtimeStoreContextMut, }; use std::convert::TryFrom; use wasmtime::{Extern, Memory}; @@ -88,7 +88,7 @@ pub unsafe extern "C" fn wasm_memory_grow( #[no_mangle] pub extern "C" fn wasmtime_memory_new( - store: CStoreContextMut<'_>, + store: WasmtimeStoreContextMut<'_>, ty: &wasm_memorytype_t, ret: &mut Memory, ) -> Option> { @@ -97,30 +97,30 @@ pub extern "C" fn wasmtime_memory_new( #[no_mangle] pub extern "C" fn wasmtime_memory_type( - store: CStoreContext<'_>, + store: WasmtimeStoreContext<'_>, mem: &Memory, ) -> Box { Box::new(wasm_memorytype_t::new(mem.ty(store))) } #[no_mangle] -pub extern "C" fn wasmtime_memory_data(store: CStoreContext<'_>, mem: &Memory) -> *const u8 { +pub extern "C" fn wasmtime_memory_data(store: WasmtimeStoreContext<'_>, mem: &Memory) -> *const u8 { mem.data(store).as_ptr() } #[no_mangle] -pub extern "C" fn wasmtime_memory_data_size(store: CStoreContext<'_>, mem: &Memory) -> usize { +pub extern "C" fn wasmtime_memory_data_size(store: WasmtimeStoreContext<'_>, mem: &Memory) -> usize { mem.data(store).len() } #[no_mangle] -pub extern "C" fn wasmtime_memory_size(store: CStoreContext<'_>, mem: &Memory) -> u64 { +pub extern "C" fn wasmtime_memory_size(store: WasmtimeStoreContext<'_>, mem: &Memory) -> u64 { mem.size(store) } #[no_mangle] pub extern "C" fn wasmtime_memory_grow( - store: CStoreContextMut<'_>, + store: WasmtimeStoreContextMut<'_>, mem: &Memory, delta: u64, prev_size: &mut u64, diff --git a/crates/c-api/src/ref.rs b/crates/c-api/src/ref.rs index 19085ae4b58e..48ccd121f378 100644 --- a/crates/c-api/src/ref.rs +++ b/crates/c-api/src/ref.rs @@ -1,6 +1,6 @@ -use crate::abort; +use crate::{abort, StoreRef}; use std::os::raw::c_void; -use wasmtime::{Ref, Val}; +use wasmtime::{AnyRef, ExternRef, Func, ManuallyRooted, Ref, Val}; /// `*mut wasm_ref_t` is a reference type (`externref` or `funcref`), as seen by /// the C API. Because we do not have a uniform representation for `funcref`s @@ -14,25 +14,88 @@ use wasmtime::{Ref, Val}; /// Note: this is not `#[repr(C)]` because it is an opaque type in the header, /// and only ever referenced as `*mut wasm_ref_t`. This also lets us use a /// regular, non-`repr(C)` `enum` to define `WasmRefInner`. -#[derive(Clone)] pub struct wasm_ref_t { - pub(crate) r: Ref, + pub(crate) store: StoreRef, + pub(crate) r: ManuallyRootedRef, +} + +pub(crate) enum ManuallyRootedRef { + Any(Option>), + Extern(Option>), + Func(Func), +} + +impl Clone for wasm_ref_t { + fn clone(&self) -> wasm_ref_t { + let ctx = unsafe { self.store.context_mut() }; + let r = match &self.r { + ManuallyRootedRef::Any(a) => ManuallyRootedRef::Any(a.as_ref().map(|a| a.clone(ctx))), + ManuallyRootedRef::Extern(e) => { + ManuallyRootedRef::Extern(e.as_ref().map(|e| e.clone(ctx))) + } + ManuallyRootedRef::Func(f) => ManuallyRootedRef::Func(f.clone()), + }; + wasm_ref_t { + store: self.store.clone(), + r, + } + } +} + +impl Drop for wasm_ref_t { + fn drop(&mut self) { + let ctx = unsafe { self.store.context_mut() }; + match &mut self.r { + ManuallyRootedRef::Any(a) => { + a.take().map(|a| a.unroot(ctx)); + } + ManuallyRootedRef::Extern(e) => { + e.take().map(|e| e.unroot(ctx)); + } + ManuallyRootedRef::Func(_) => {} + } + } } wasmtime_c_api_macros::declare_own!(wasm_ref_t); impl wasm_ref_t { - pub(crate) fn new(r: Ref) -> Option> { - if r.is_null() { - None - } else { - Some(Box::new(wasm_ref_t { r })) + pub(crate) unsafe fn new(store: StoreRef, r: Ref) -> Option> { + match r { + Ref::Any(None) | Ref::Extern(None) | Ref::Func(None) => None, + Ref::Any(Some(a)) => { + let r = ManuallyRootedRef::Any(Some( + a.to_manually_rooted(unsafe { store.context_mut() }).ok()?, + )); + Some(Box::new(wasm_ref_t { store, r })) + } + Ref::Extern(Some(e)) => { + let r = ManuallyRootedRef::Extern(Some( + e.to_manually_rooted(unsafe { store.context_mut() }).ok()?, + )); + Some(Box::new(wasm_ref_t { store, r })) + } + Ref::Func(Some(f)) => Some(Box::new(wasm_ref_t { + store, + r: ManuallyRootedRef::Func(f), + })), } } } -pub(crate) fn ref_to_val(r: &wasm_ref_t) -> Val { - Val::from(r.r.clone()) +impl wasm_ref_t { + pub(crate) unsafe fn to_ref(&self) -> Ref { + let ctx = self.store.context_mut(); + match &self.r { + ManuallyRootedRef::Any(a) => Ref::Any(a.as_ref().map(|a| a.to_rooted(ctx))), + ManuallyRootedRef::Extern(e) => Ref::Extern(e.as_ref().map(|e| e.to_rooted(ctx))), + ManuallyRootedRef::Func(f) => Ref::Func(Some(f.clone())), + } + } +} + +pub(crate) unsafe fn ref_to_val(r: &wasm_ref_t) -> Val { + r.to_ref().into() } #[no_mangle] @@ -41,9 +104,46 @@ pub extern "C" fn wasm_ref_copy(r: Option<&wasm_ref_t>) -> Option, _b: Option<&wasm_ref_t>) -> bool { - // We need a store to determine whether these are the same reference or not. - abort("wasm_ref_same") +pub unsafe extern "C" fn wasm_ref_same(a: Option<&wasm_ref_t>, b: Option<&wasm_ref_t>) -> bool { + match (a, b) { + (None, None) => true, + + // Can't compare functions for equality. + ( + Some(wasm_ref_t { + store: _, + r: ManuallyRootedRef::Func(_), + }), + Some(wasm_ref_t { + store: _, + r: ManuallyRootedRef::Func(_), + }), + ) => false, + + ( + Some(wasm_ref_t { + store, + r: ManuallyRootedRef::Any(Some(a)), + }), + Some(wasm_ref_t { + store: _, + r: ManuallyRootedRef::Any(Some(b)), + }), + ) => ManuallyRooted::ref_eq(store.context(), a, b).unwrap_or_default(), + + ( + Some(wasm_ref_t { + store, + r: ManuallyRootedRef::Extern(Some(a)), + }), + Some(wasm_ref_t { + store: _, + r: ManuallyRootedRef::Extern(Some(b)), + }), + ) => ManuallyRooted::ref_eq(store.context(), a, b).unwrap_or_default(), + + _ => false, + } } #[no_mangle] diff --git a/crates/c-api/src/store.rs b/crates/c-api/src/store.rs index 32ff1a3d8f26..1908419be8fb 100644 --- a/crates/c-api/src/store.rs +++ b/crates/c-api/src/store.rs @@ -7,6 +7,11 @@ use wasmtime::{ UpdateDeadline, Val, }; +pub type WasmStoreData = Option; +pub type WasmStore = Store; +pub type WasmStoreContext<'a> = StoreContext<'a, WasmStoreData>; +pub type WasmStoreContextMut<'a> = StoreContextMut<'a, WasmStoreData>; + /// This representation of a `Store` is used to implement the `wasm.h` API. /// /// This is stored alongside `Func` and such for `wasm.h` so each object is @@ -19,17 +24,25 @@ use wasmtime::{ /// least Wasmtime's implementation). #[derive(Clone)] pub struct StoreRef { - store: Arc>>, + store: Arc>, } impl StoreRef { - pub unsafe fn context(&self) -> StoreContext<'_, ()> { + pub unsafe fn context(&self) -> WasmStoreContext<'_> { (*self.store.get()).as_context() } - pub unsafe fn context_mut(&mut self) -> StoreContextMut<'_, ()> { + pub unsafe fn context_mut(&self) -> WasmStoreContextMut<'_> { (*self.store.get()).as_context_mut() } + + pub fn from_context(ctx: impl AsContext) -> Self { + ctx.as_context() + .data() + .as_ref() + .expect("a WasmStore's inner value is always Some") + .clone() + } } #[repr(C)] @@ -43,12 +56,15 @@ wasmtime_c_api_macros::declare_own!(wasm_store_t); #[no_mangle] pub extern "C" fn wasm_store_new(engine: &wasm_engine_t) -> Box { let engine = &engine.engine; - let store = Store::new(engine, ()); - Box::new(wasm_store_t { - store: StoreRef { - store: Arc::new(UnsafeCell::new(store)), - }, - }) + let store = Store::new(engine, None); + let store = StoreRef { + store: Arc::new(UnsafeCell::new(store)), + }; + let store2 = store.clone(); + unsafe { + *(*store.store.get()).data_mut() = Some(store2); + } + Box::new(wasm_store_t { store }) } /// Representation of a `Store` for `wasmtime.h` This notably tries to move more @@ -60,16 +76,17 @@ pub extern "C" fn wasm_store_new(engine: &wasm_engine_t) -> Box { /// foreign data and configuring WASI as well. #[repr(C)] pub struct wasmtime_store_t { - pub(crate) store: Store, + pub(crate) store: Store, } wasmtime_c_api_macros::declare_own!(wasmtime_store_t); -pub type CStoreContext<'a> = StoreContext<'a, StoreData>; -pub type CStoreContextMut<'a> = StoreContextMut<'a, StoreData>; +pub type WasmtimeStoreContext<'a> = StoreContext<'a, WasmtimeStoreData>; +pub type WasmtimeStoreContextMut<'a> = StoreContextMut<'a, WasmtimeStoreData>; -pub struct StoreData { +pub struct WasmtimeStoreData { foreign: crate::ForeignData, + #[cfg(feature = "wasi")] pub(crate) wasi: Option, @@ -94,7 +111,7 @@ pub extern "C" fn wasmtime_store_new( Box::new(wasmtime_store_t { store: Store::new( &engine.engine, - StoreData { + WasmtimeStoreData { foreign: ForeignData { data, finalizer }, #[cfg(feature = "wasi")] wasi: None, @@ -114,7 +131,7 @@ pub const WASMTIME_UPDATE_DEADLINE_YIELD: wasmtime_update_deadline_kind_t = 1; pub extern "C" fn wasmtime_store_epoch_deadline_callback( store: &mut wasmtime_store_t, func: extern "C" fn( - CStoreContextMut<'_>, + WasmtimeStoreContextMut<'_>, *mut c_void, *mut u64, *mut wasmtime_update_deadline_kind_t, @@ -148,7 +165,9 @@ pub extern "C" fn wasmtime_store_epoch_deadline_callback( } #[no_mangle] -pub extern "C" fn wasmtime_store_context(store: &mut wasmtime_store_t) -> CStoreContextMut<'_> { +pub extern "C" fn wasmtime_store_context( + store: &mut wasmtime_store_t, +) -> WasmtimeStoreContextMut<'_> { store.store.as_context_mut() } @@ -182,19 +201,22 @@ pub extern "C" fn wasmtime_store_limiter( } #[no_mangle] -pub extern "C" fn wasmtime_context_get_data(store: CStoreContext<'_>) -> *mut c_void { +pub extern "C" fn wasmtime_context_get_data(store: WasmtimeStoreContext<'_>) -> *mut c_void { store.data().foreign.data } #[no_mangle] -pub extern "C" fn wasmtime_context_set_data(mut store: CStoreContextMut<'_>, data: *mut c_void) { +pub extern "C" fn wasmtime_context_set_data( + mut store: WasmtimeStoreContextMut<'_>, + data: *mut c_void, +) { store.data_mut().foreign.data = data; } #[cfg(feature = "wasi")] #[no_mangle] pub extern "C" fn wasmtime_context_set_wasi( - mut context: CStoreContextMut<'_>, + mut context: WasmtimeStoreContextMut<'_>, wasi: Box, ) -> Option> { crate::handle_result(wasi.into_wasi_ctx(), |wasi| { @@ -203,13 +225,13 @@ pub extern "C" fn wasmtime_context_set_wasi( } #[no_mangle] -pub extern "C" fn wasmtime_context_gc(mut context: CStoreContextMut<'_>) { +pub extern "C" fn wasmtime_context_gc(mut context: WasmtimeStoreContextMut<'_>) { context.gc(); } #[no_mangle] pub extern "C" fn wasmtime_context_set_fuel( - mut store: CStoreContextMut<'_>, + mut store: WasmtimeStoreContextMut<'_>, fuel: u64, ) -> Option> { crate::handle_result(store.set_fuel(fuel), |()| {}) @@ -217,7 +239,7 @@ pub extern "C" fn wasmtime_context_set_fuel( #[no_mangle] pub extern "C" fn wasmtime_context_get_fuel( - store: CStoreContext<'_>, + store: WasmtimeStoreContext<'_>, fuel: &mut u64, ) -> Option> { crate::handle_result(store.get_fuel(), |amt| { @@ -227,7 +249,7 @@ pub extern "C" fn wasmtime_context_get_fuel( #[no_mangle] pub extern "C" fn wasmtime_context_set_epoch_deadline( - mut store: CStoreContextMut<'_>, + mut store: WasmtimeStoreContextMut<'_>, ticks_beyond_current: u64, ) { store.set_epoch_deadline(ticks_beyond_current); diff --git a/crates/c-api/src/table.rs b/crates/c-api/src/table.rs index 36e888e24d07..7dcb3f5e0d62 100644 --- a/crates/c-api/src/table.rs +++ b/crates/c-api/src/table.rs @@ -1,6 +1,6 @@ use crate::{ handle_result, wasm_extern_t, wasm_ref_t, wasm_store_t, wasm_tabletype_t, wasmtime_error_t, - wasmtime_val_t, CStoreContext, CStoreContextMut, + wasmtime_val_t, WasmtimeStoreContext, WasmtimeStoreContextMut, }; use anyhow::anyhow; use std::mem::MaybeUninit; @@ -32,12 +32,12 @@ impl wasm_table_t { } } -fn option_wasm_ref_t_to_ref(r: Option<&wasm_ref_t>, table_ty: &TableType) -> Ref { - match (r.map(|r| r.r.clone()), table_ty.element().heap_type()) { +unsafe fn option_wasm_ref_t_to_ref(r: Option<&wasm_ref_t>, table_ty: &TableType) -> Ref { + match (r, table_ty.element().heap_type()) { (None, HeapType::NoFunc | HeapType::Func | HeapType::Concrete(_)) => Ref::Func(None), (None, HeapType::Extern) => Ref::Extern(None), (None, HeapType::Any | HeapType::I31 | HeapType::None) => Ref::Any(None), - (Some(r), _) => r, + (Some(r), _) => r.to_ref(), } } @@ -72,7 +72,7 @@ pub unsafe extern "C" fn wasm_table_get( ) -> Option> { let table = t.table(); let r = table.get(t.ext.store.context_mut(), index)?; - wasm_ref_t::new(r) + wasm_ref_t::new(t.ext.store.clone(), r) } #[no_mangle] @@ -116,7 +116,7 @@ pub extern "C" fn wasm_table_as_extern_const(t: &wasm_table_t) -> &wasm_extern_t #[no_mangle] pub unsafe extern "C" fn wasmtime_table_new( - mut store: CStoreContextMut<'_>, + mut store: WasmtimeStoreContextMut<'_>, tt: &wasm_tabletype_t, init: &wasmtime_val_t, out: &mut Table, @@ -132,7 +132,7 @@ pub unsafe extern "C" fn wasmtime_table_new( #[no_mangle] pub unsafe extern "C" fn wasmtime_table_type( - store: CStoreContext<'_>, + store: WasmtimeStoreContext<'_>, table: &Table, ) -> Box { Box::new(wasm_tabletype_t::new(table.ty(store))) @@ -140,7 +140,7 @@ pub unsafe extern "C" fn wasmtime_table_type( #[no_mangle] pub extern "C" fn wasmtime_table_get( - mut store: CStoreContextMut<'_>, + mut store: WasmtimeStoreContextMut<'_>, table: &Table, index: u32, ret: &mut MaybeUninit, @@ -156,7 +156,7 @@ pub extern "C" fn wasmtime_table_get( #[no_mangle] pub unsafe extern "C" fn wasmtime_table_set( - mut store: CStoreContextMut<'_>, + mut store: WasmtimeStoreContextMut<'_>, table: &Table, index: u32, val: &wasmtime_val_t, @@ -171,13 +171,13 @@ pub unsafe extern "C" fn wasmtime_table_set( } #[no_mangle] -pub extern "C" fn wasmtime_table_size(store: CStoreContext<'_>, table: &Table) -> u32 { +pub extern "C" fn wasmtime_table_size(store: WasmtimeStoreContext<'_>, table: &Table) -> u32 { table.size(store) } #[no_mangle] pub unsafe extern "C" fn wasmtime_table_grow( - mut store: CStoreContextMut<'_>, + mut store: WasmtimeStoreContextMut<'_>, table: &Table, delta: u32, val: &wasmtime_val_t, diff --git a/crates/c-api/src/val.rs b/crates/c-api/src/val.rs index 633201712cc1..b1b08a6d1109 100644 --- a/crates/c-api/src/val.rs +++ b/crates/c-api/src/val.rs @@ -1,11 +1,11 @@ use crate::r#ref::ref_to_val; use crate::{ - from_valtype, into_valtype, wasm_ref_t, wasm_valkind_t, wasmtime_valkind_t, CStoreContextMut, - WASM_I32, + from_valtype, into_valtype, wasm_ref_t, wasm_valkind_t, wasmtime_valkind_t, StoreRef, + WasmStoreData, WasmtimeStoreContextMut, WASM_I32, }; use std::mem::{self, ManuallyDrop, MaybeUninit}; use std::ptr; -use wasmtime::{AsContextMut, Func, HeapType, Ref, Val, ValType}; +use wasmtime::{AsContext, AsContextMut, Func, HeapType, Ref, Val, ValType}; #[repr(C)] pub struct wasm_val_t { @@ -52,7 +52,7 @@ impl Clone for wasm_val_t { _ => {} } } - return ret; + ret } } @@ -66,7 +66,7 @@ impl Default for wasm_val_t { } impl wasm_val_t { - pub fn from_val(val: Val) -> wasm_val_t { + pub unsafe fn from_val(store: impl AsContext, val: Val) -> wasm_val_t { match val { Val::I32(i) => wasm_val_t { kind: from_valtype(&ValType::I32), @@ -84,18 +84,28 @@ impl wasm_val_t { kind: from_valtype(&ValType::F64), of: wasm_val_union { u64: f }, }, - Val::ExternRef(_) => crate::abort("externref"), + Val::AnyRef(a) => wasm_val_t { + kind: from_valtype(&ValType::ANYREF), + of: wasm_val_union { + ref_: wasm_ref_t::new(StoreRef::from_context(store), Ref::Any(a)) + .map_or(ptr::null_mut(), Box::into_raw), + }, + }, + Val::ExternRef(e) => wasm_val_t { + kind: from_valtype(&ValType::EXTERNREF), + of: wasm_val_union { + ref_: wasm_ref_t::new(StoreRef::from_context(store), Ref::Extern(e)) + .map_or(ptr::null_mut(), Box::into_raw), + }, + }, Val::FuncRef(f) => wasm_val_t { kind: from_valtype(&ValType::FUNCREF), of: wasm_val_union { - ref_: f.map_or(ptr::null_mut(), |f| { - Box::into_raw(Box::new(wasm_ref_t { - r: Ref::Func(Some(f)), - })) - }), + ref_: wasm_ref_t::new(StoreRef::from_context(store), Ref::Func(f)) + .map_or(ptr::null_mut(), Box::into_raw), }, }, - _ => unimplemented!("wasm_val_t::from_val {:?}", val), + Val::V128(_) => crate::abort("wasm_val_t from v128") } } @@ -237,7 +247,7 @@ impl Drop for wasmtime_val_t { #[no_mangle] pub unsafe extern "C" fn wasmtime_val_delete( - cx: CStoreContextMut<'_>, + cx: WasmtimeStoreContextMut<'_>, val: &mut ManuallyDrop, ) { // TODO: needed for when we re-add externref support. @@ -248,7 +258,7 @@ pub unsafe extern "C" fn wasmtime_val_delete( #[no_mangle] pub unsafe extern "C" fn wasmtime_val_copy( - mut cx: CStoreContextMut<'_>, + mut cx: WasmtimeStoreContextMut<'_>, dst: &mut MaybeUninit, src: &wasmtime_val_t, ) { diff --git a/crates/c-api/src/vec.rs b/crates/c-api/src/vec.rs index 7a5aae734ffa..3bf4e6ee014a 100644 --- a/crates/c-api/src/vec.rs +++ b/crates/c-api/src/vec.rs @@ -54,6 +54,16 @@ macro_rules! declare_vecs { } } + pub fn as_slice_mut(&mut self) -> &mut [$elem_ty] { + // Same as above: no null pointer. + if self.size == 0 { + &mut [] + } else { + assert!(!self.data.is_null()); + unsafe { slice::from_raw_parts_mut(self.data, self.size) } + } + } + pub fn as_uninit_slice(&mut self) -> &mut [MaybeUninit<$elem_ty>] { // Note that we're careful to not create a slice with a null // pointer as the data pointer, since that isn't defined