diff --git a/crates/c-api/src/ref.rs b/crates/c-api/src/ref.rs index 524d398447..5b48776ced 100644 --- a/crates/c-api/src/ref.rs +++ b/crates/c-api/src/ref.rs @@ -7,7 +7,7 @@ use wasmtime::{ExternRef, Func, 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 /// and `externref`s, a `*mut wasm_ref_t` is morally a -/// `Option, Option>>>`. +/// `Option>>`. /// /// A null `*mut wasm_ref_t` is either a null `funcref` or a null `externref` /// depending on context (e.g. the table's element type that it is going into or @@ -23,8 +23,8 @@ pub struct wasm_ref_t { #[derive(Clone)] pub(crate) enum WasmRefInner { - ExternRef(Option), - FuncRef(Option), + ExternRef(ExternRef), + FuncRef(Func), } wasmtime_c_api_macros::declare_own!(wasm_ref_t); @@ -35,40 +35,40 @@ pub(crate) fn ref_into_val(r: Option>) -> Option { let r = r?; Some(match r.r { - WasmRefInner::ExternRef(x) => Val::ExternRef(x), - WasmRefInner::FuncRef(x) => Val::FuncRef(x), + WasmRefInner::ExternRef(x) => Val::ExternRef(Some(x)), + WasmRefInner::FuncRef(f) => Val::FuncRef(Some(f)), }) } pub(crate) fn ref_to_val(r: &wasm_ref_t) -> Val { match &r.r { - WasmRefInner::ExternRef(x) => Val::ExternRef(x.clone()), - WasmRefInner::FuncRef(x) => Val::FuncRef(x.clone()), + WasmRefInner::ExternRef(x) => Val::ExternRef(Some(x.clone())), + WasmRefInner::FuncRef(f) => Val::FuncRef(Some(f.clone())), } } pub(crate) fn val_into_ref(val: Val) -> Option> { match val { - Val::ExternRef(x) => Some(Box::new(wasm_ref_t { + Val::ExternRef(Some(x)) => Some(Box::new(wasm_ref_t { r: WasmRefInner::ExternRef(x), })), - Val::FuncRef(x) => Some(Box::new(wasm_ref_t { - r: WasmRefInner::FuncRef(x), + Val::FuncRef(Some(f)) => Some(Box::new(wasm_ref_t { + r: WasmRefInner::FuncRef(f), })), _ => None, } } #[no_mangle] -pub extern "C" fn wasm_ref_copy(r: &wasm_ref_t) -> Box { - Box::new(r.clone()) +pub extern "C" fn wasm_ref_copy(r: Option<&wasm_ref_t>) -> Option> { + r.map(|r| Box::new(r.clone())) } #[no_mangle] -pub extern "C" fn wasm_ref_same(a: &wasm_ref_t, b: &wasm_ref_t) -> bool { - match (&a.r, &b.r) { - (WasmRefInner::ExternRef(Some(a)), WasmRefInner::ExternRef(Some(b))) => a.ptr_eq(b), - (WasmRefInner::ExternRef(None), WasmRefInner::ExternRef(None)) => true, +pub extern "C" fn wasm_ref_same(a: Option<&wasm_ref_t>, b: Option<&wasm_ref_t>) -> bool { + match (a.map(|a| &a.r), b.map(|b| &b.r)) { + (Some(WasmRefInner::ExternRef(a)), Some(WasmRefInner::ExternRef(b))) => a.ptr_eq(b), + (None, None) => true, // Note: we don't support equality for `Func`, so we always return // `false` for `funcref`s. _ => false, @@ -76,19 +76,19 @@ pub extern "C" fn wasm_ref_same(a: &wasm_ref_t, b: &wasm_ref_t) -> bool { } #[no_mangle] -pub extern "C" fn wasm_ref_get_host_info(_ref: &wasm_ref_t) -> *mut c_void { +pub extern "C" fn wasm_ref_get_host_info(_ref: Option<&wasm_ref_t>) -> *mut c_void { std::ptr::null_mut() } #[no_mangle] -pub extern "C" fn wasm_ref_set_host_info(_ref: &wasm_ref_t, _info: *mut c_void) { +pub extern "C" fn wasm_ref_set_host_info(_ref: Option<&wasm_ref_t>, _info: *mut c_void) { eprintln!("`wasm_ref_set_host_info` is not implemented"); std::process::abort(); } #[no_mangle] pub extern "C" fn wasm_ref_set_host_info_with_finalizer( - _ref: &wasm_ref_t, + _ref: Option<&wasm_ref_t>, _info: *mut c_void, _finalizer: Option, ) { diff --git a/crates/c-api/src/val.rs b/crates/c-api/src/val.rs index 7d567bc993..026356347c 100644 --- a/crates/c-api/src/val.rs +++ b/crates/c-api/src/val.rs @@ -78,7 +78,13 @@ impl wasm_val_t { kind: from_valtype(&ValType::F64), of: wasm_val_union { u64: f }, }, - Val::ExternRef(r) => wasm_val_t { + Val::ExternRef(None) => wasm_val_t { + kind: from_valtype(&ValType::ExternRef), + of: wasm_val_union { + ref_: ptr::null_mut(), + }, + }, + Val::ExternRef(Some(r)) => wasm_val_t { kind: from_valtype(&ValType::ExternRef), of: wasm_val_union { ref_: Box::into_raw(Box::new(wasm_ref_t { @@ -86,7 +92,13 @@ impl wasm_val_t { })), }, }, - Val::FuncRef(f) => wasm_val_t { + Val::FuncRef(None) => wasm_val_t { + kind: from_valtype(&ValType::FuncRef), + of: wasm_val_union { + ref_: ptr::null_mut(), + }, + }, + Val::FuncRef(Some(f)) => wasm_val_t { kind: from_valtype(&ValType::FuncRef), of: wasm_val_union { ref_: Box::into_raw(Box::new(wasm_ref_t {