diff --git a/lib/c-api/src/wasm_c_api/externals/mod.rs b/lib/c-api/src/wasm_c_api/externals/mod.rs index aae406712ab..05fc8043543 100644 --- a/lib/c-api/src/wasm_c_api/externals/mod.rs +++ b/lib/c-api/src/wasm_c_api/externals/mod.rs @@ -11,6 +11,7 @@ pub use table::*; use wasmer::{Extern, Instance}; #[allow(non_camel_case_types)] +#[derive(Clone)] pub struct wasm_extern_t { // this is how we ensure the instance stays alive pub(crate) instance: Option>, diff --git a/lib/c-api/src/wasm_c_api/macros.rs b/lib/c-api/src/wasm_c_api/macros.rs index 51b6d301745..c1e8955e036 100644 --- a/lib/c-api/src/wasm_c_api/macros.rs +++ b/lib/c-api/src/wasm_c_api/macros.rs @@ -80,6 +80,33 @@ int main() { pub data: *mut [], } + impl Clone for [] { + fn clone(&self) -> Self { + if self.data.is_null() { + return Self { + size: self.size, + data: ::std::ptr::null_mut(), + }; + } + let data = + unsafe { + let vec = Vec::from_raw_parts(self.data, self.size, self.size); + let mut vec_copy = vec.clone().into_boxed_slice(); + let new_ptr = vec_copy.as_mut_ptr(); + + ::std::mem::forget(vec); + ::std::mem::forget(vec_copy); + + new_ptr + }; + + Self { + size: self.size, + data, + } + } + } + impl<'a> From]>> for [] { fn from(mut vec: Vec<[]>) -> Self { vec.shrink_to_fit(); @@ -195,6 +222,15 @@ int main() { ::std::mem::forget(bytes); } + #[doc = "Performs a deep copy of a vector of [`wasm_" $name "_t`]."] + #[no_mangle] + pub unsafe extern "C" fn []( + out_ptr: &mut [], + in_ptr: & []) + { + *out_ptr = in_ptr.clone(); + } + #[doc = "Deletes a vector of [`wasm_" $name "_t`]. # Example @@ -231,6 +267,34 @@ Read the documentation of [`wasm_" $name "_t`] to see more concrete examples."] pub data: *mut *mut [], } + impl Clone for [] { + fn clone(&self) -> Self { + if self.data.is_null() { + return Self { + size: self.size, + data: ::std::ptr::null_mut(), + }; + } + let data = + unsafe { + let data: *mut Option]>> = self.data as _; + let vec = Vec::from_raw_parts(data, self.size, self.size); + let mut vec_copy = vec.clone().into_boxed_slice(); + let new_ptr = vec_copy.as_mut_ptr() as *mut *mut []; + + ::std::mem::forget(vec); + ::std::mem::forget(vec_copy); + + new_ptr + }; + + Self { + size: self.size, + data, + } + } + } + impl<'a> From]>>> for [] { fn from(other: Vec]>>) -> Self { let boxed_slice: Box<[Box<[]>]> = other.into_boxed_slice(); @@ -290,13 +354,13 @@ Read the documentation of [`wasm_" $name "_t`] to see more concrete examples."] bytes.push(*init.add(i)); } - let pointer = bytes.as_mut_ptr(); - debug_assert!(bytes.len() == bytes.capacity()); + let mut boxed_vec = bytes.into_boxed_slice(); + let pointer = boxed_vec.as_mut_ptr(); (*out).data = pointer; (*out).size = length; - ::std::mem::forget(bytes); + ::std::mem::forget(boxed_vec); } #[doc = "Creates a new uninitialized vector of [`wasm_" $name "_t`]. @@ -335,6 +399,15 @@ int main() { ::std::mem::forget(bytes); } + #[doc = "Performs a deep copy of a vector of [`wasm_" $name "_t`]."] + #[no_mangle] + pub unsafe extern "C" fn []( + out_ptr: &mut [], + in_ptr: & []) + { + *out_ptr = in_ptr.clone(); + } + #[doc = "Deletes a vector of [`wasm_" $name "_t`]. # Example @@ -342,7 +415,7 @@ int main() { See the [`wasm_" $name "_vec_t`] type to get an example."] #[no_mangle] pub unsafe extern "C" fn [](ptr: Option<&mut []>) { - if let Some(vec) = ptr { + if let Some(vec) = ptr { if !vec.data.is_null() { let data = vec.data as *mut Option]>>; let _data: Vec]>>> = Vec::from_raw_parts(data, vec.size, vec.size); diff --git a/lib/c-api/src/wasm_c_api/types/export.rs b/lib/c-api/src/wasm_c_api/types/export.rs index 26c6a5bb36f..1654de8193e 100644 --- a/lib/c-api/src/wasm_c_api/types/export.rs +++ b/lib/c-api/src/wasm_c_api/types/export.rs @@ -2,6 +2,7 @@ use super::{wasm_externtype_t, wasm_name_t}; use wasmer::ExportType; #[allow(non_camel_case_types)] +#[derive(Clone)] pub struct wasm_exporttype_t { name: Box, extern_type: Box, diff --git a/lib/c-api/src/wasm_c_api/types/function.rs b/lib/c-api/src/wasm_c_api/types/function.rs index a5318dbef45..131a79461ef 100644 --- a/lib/c-api/src/wasm_c_api/types/function.rs +++ b/lib/c-api/src/wasm_c_api/types/function.rs @@ -28,7 +28,7 @@ impl Clone for WasmFunctionType { } #[allow(non_camel_case_types)] -#[derive(Debug)] +#[derive(Debug, Clone)] #[repr(transparent)] pub struct wasm_functype_t { pub(crate) extern_type: wasm_externtype_t, @@ -90,9 +90,7 @@ pub unsafe extern "C" fn wasm_functype_copy( ) -> Option> { let function_type = function_type?; - Some(Box::new(wasm_functype_t::new( - function_type.inner().function_type.clone(), - ))) + Some(Box::new(function_type.clone())) } #[no_mangle] diff --git a/lib/c-api/src/wasm_c_api/types/global.rs b/lib/c-api/src/wasm_c_api/types/global.rs index 1b202ad8473..769002802d4 100644 --- a/lib/c-api/src/wasm_c_api/types/global.rs +++ b/lib/c-api/src/wasm_c_api/types/global.rs @@ -23,7 +23,7 @@ impl WasmGlobalType { } #[allow(non_camel_case_types)] -#[derive(Debug)] +#[derive(Debug, Clone)] #[repr(transparent)] pub struct wasm_globaltype_t { pub(crate) extern_type: wasm_externtype_t, diff --git a/lib/c-api/src/wasm_c_api/types/import.rs b/lib/c-api/src/wasm_c_api/types/import.rs index 4d3b2fe7244..a1f94f800a3 100644 --- a/lib/c-api/src/wasm_c_api/types/import.rs +++ b/lib/c-api/src/wasm_c_api/types/import.rs @@ -2,6 +2,7 @@ use super::{wasm_externtype_t, wasm_name_t}; use wasmer::ImportType; #[allow(non_camel_case_types)] +#[derive(Clone)] pub struct wasm_importtype_t { module: Box, name: Box, diff --git a/lib/c-api/src/wasm_c_api/types/memory.rs b/lib/c-api/src/wasm_c_api/types/memory.rs index 948ff6cf1ec..6565fbe69b5 100644 --- a/lib/c-api/src/wasm_c_api/types/memory.rs +++ b/lib/c-api/src/wasm_c_api/types/memory.rs @@ -25,7 +25,7 @@ impl WasmMemoryType { } #[allow(non_camel_case_types)] -#[derive(Debug)] +#[derive(Debug, Clone)] #[repr(transparent)] pub struct wasm_memorytype_t { pub(crate) extern_type: wasm_externtype_t, diff --git a/lib/c-api/src/wasm_c_api/types/table.rs b/lib/c-api/src/wasm_c_api/types/table.rs index 1f30ad17981..40ea3003779 100644 --- a/lib/c-api/src/wasm_c_api/types/table.rs +++ b/lib/c-api/src/wasm_c_api/types/table.rs @@ -32,7 +32,7 @@ impl WasmTableType { } #[allow(non_camel_case_types)] -#[derive(Debug)] +#[derive(Debug, Clone)] #[repr(transparent)] pub struct wasm_tabletype_t { pub(crate) extern_type: wasm_externtype_t, diff --git a/lib/c-api/src/wasm_c_api/value.rs b/lib/c-api/src/wasm_c_api/value.rs index 7449918bf9e..2415f3bea35 100644 --- a/lib/c-api/src/wasm_c_api/value.rs +++ b/lib/c-api/src/wasm_c_api/value.rs @@ -77,6 +77,39 @@ pub struct wasm_val_t { pub of: wasm_val_inner, } +impl std::fmt::Debug for wasm_val_t { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + let mut ds = f.debug_struct("wasm_val_t"); + ds.field("kind", &self.kind); + + match self.kind.try_into() { + Ok(wasm_valkind_enum::WASM_I32) => { + ds.field("i32", &unsafe { self.of.int32_t }); + } + Ok(wasm_valkind_enum::WASM_I64) => { + ds.field("i64", &unsafe { self.of.int64_t }); + } + Ok(wasm_valkind_enum::WASM_F32) => { + ds.field("f32", &unsafe { self.of.float32_t }); + } + Ok(wasm_valkind_enum::WASM_F64) => { + ds.field("f64", &unsafe { self.of.float64_t }); + } + Ok(wasm_valkind_enum::WASM_ANYREF) => { + ds.field("anyref", &unsafe { self.of.wref }); + } + + Ok(wasm_valkind_enum::WASM_FUNCREF) => { + ds.field("funcref", &unsafe { self.of.wref }); + } + Err(_) => { + ds.field("value", &"Invalid value type"); + } + } + ds.finish() + } +} + wasm_declare_vec!(val); impl Clone for wasm_val_t { diff --git a/lib/c-api/tests/Makefile b/lib/c-api/tests/Makefile index 1b44e95faad..42b95bb6628 100644 --- a/lib/c-api/tests/Makefile +++ b/lib/c-api/tests/Makefile @@ -20,10 +20,10 @@ CAPI_WASMER_TESTS = \ CAPI_BASE_TESTS = \ wasm-c-api/example/callback wasm-c-api/example/global wasm-c-api/example/hello \ wasm-c-api/example/memory wasm-c-api/example/reflect wasm-c-api/example/serialize \ - wasm-c-api/example/start wasm-c-api/example/trap + wasm-c-api/example/start wasm-c-api/example/trap wasm-c-api/example/multi CAPI_BASE_TESTS_NOT_WORKING = \ - wasm-c-api/example/finalize wasm-c-api/example/hostref wasm-c-api/example/multi \ + wasm-c-api/example/finalize wasm-c-api/example/hostref \ wasm-c-api/example/table wasm-c-api/example/threads DEPRECATED_TESTS = \ diff --git a/lib/c-api/tests/wasm-c-api/example/multi.c b/lib/c-api/tests/wasm-c-api/example/multi.c index 846c6ec92af..4a31e7e4da5 100644 --- a/lib/c-api/tests/wasm-c-api/example/multi.c +++ b/lib/c-api/tests/wasm-c-api/example/multi.c @@ -121,7 +121,7 @@ int main(int argc, const char* argv[]) { // Call. printf("Calling export...\n"); wasm_val_t vals[4] = { - WASM_I32_VAL(1), WASM_I32_VAL(2), WASM_I32_VAL(3), WASM_I32_VAL(4) + WASM_I32_VAL(1), WASM_I64_VAL(2), WASM_I64_VAL(3), WASM_I32_VAL(4) }; wasm_val_t res[4] = { WASM_INIT_VAL, WASM_INIT_VAL, WASM_INIT_VAL, WASM_INIT_VAL