From b201f124947079aa963a67d98e5616e463fae563 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Thu, 28 Jan 2021 17:26:15 +0100 Subject: [PATCH 01/14] feat(c-api) Start implementing `wasm_target_t`, `wasm_triple_t` and `wasm_cpu_features_t`. --- lib/c-api/Cargo.toml | 1 + lib/c-api/src/wasm_c_api/engine.rs | 2 +- lib/c-api/src/wasm_c_api/macros.rs | 7 +- lib/c-api/src/wasm_c_api/unstable/engine.rs | 69 ++++++++ lib/c-api/src/wasm_c_api/unstable/mod.rs | 2 + .../src/wasm_c_api/unstable/target_lexicon.rs | 155 ++++++++++++++++++ lib/c-api/wasmer_wasm.h | 41 +++++ 7 files changed, 274 insertions(+), 3 deletions(-) create mode 100644 lib/c-api/src/wasm_c_api/unstable/engine.rs create mode 100644 lib/c-api/src/wasm_c_api/unstable/target_lexicon.rs diff --git a/lib/c-api/Cargo.toml b/lib/c-api/Cargo.toml index 9a6e0fb1065..da37986cef1 100644 --- a/lib/c-api/Cargo.toml +++ b/lib/c-api/Cargo.toml @@ -27,6 +27,7 @@ wasmer-engine-native = { version = "1.0.1", path = "../engine-native", optional wasmer-engine-object-file = { version = "1.0.1", path = "../engine-object-file", optional = true } wasmer-wasi = { version = "1.0.1", path = "../wasi", optional = true } wasmer-types = { version = "1.0.1", path = "../wasmer-types" } +enumset = "1.0" cfg-if = "1.0" lazy_static = "1.4" libc = { version = "^0.2", default-features = false } diff --git a/lib/c-api/src/wasm_c_api/engine.rs b/lib/c-api/src/wasm_c_api/engine.rs index dd3b6fa416a..2724cc6ffef 100644 --- a/lib/c-api/src/wasm_c_api/engine.rs +++ b/lib/c-api/src/wasm_c_api/engine.rs @@ -256,7 +256,7 @@ pub struct wasm_engine_t { #[cfg(feature = "compiler")] use wasmer_compiler::CompilerConfig; #[cfg(feature = "compiler")] -fn get_default_compiler_config() -> Box { +pub(crate) fn get_default_compiler_config() -> Box { cfg_if! { if #[cfg(feature = "cranelift")] { Box::new(wasmer_compiler_cranelift::Cranelift::default()) diff --git a/lib/c-api/src/wasm_c_api/macros.rs b/lib/c-api/src/wasm_c_api/macros.rs index c1e8955e036..dc85f6a9662 100644 --- a/lib/c-api/src/wasm_c_api/macros.rs +++ b/lib/c-api/src/wasm_c_api/macros.rs @@ -467,16 +467,19 @@ macro_rules! wasm_declare_own { #[macro_export] macro_rules! c_try { - ($expr:expr) => {{ + ($expr:expr; otherwise $return:expr) => {{ let res: Result<_, _> = $expr; match res { Ok(val) => val, Err(err) => { crate::error::update_last_error(err); - return None; + return $return; } } }}; + ($expr:expr) => {{ + c_try!($expr; otherwise None) + }}; ($expr:expr, $e:expr) => {{ let opt: Option<_> = $expr; c_try!(opt.ok_or_else(|| $e)) diff --git a/lib/c-api/src/wasm_c_api/unstable/engine.rs b/lib/c-api/src/wasm_c_api/unstable/engine.rs new file mode 100644 index 00000000000..cdcdf83cf90 --- /dev/null +++ b/lib/c-api/src/wasm_c_api/unstable/engine.rs @@ -0,0 +1,69 @@ +#[cfg(feature = "compiler")] +use super::super::engine::get_default_compiler_config; +use super::super::engine::wasm_engine_t; +use super::target_lexicon::wasm_target_t; +use cfg_if::cfg_if; +use std::sync::Arc; +#[cfg(feature = "compiler")] +use wasmer_compiler::CompilerConfig; +use wasmer_engine::Engine; +#[cfg(feature = "jit")] +use wasmer_engine_jit::JIT; +#[cfg(feature = "native")] +use wasmer_engine_native::Native; +#[cfg(feature = "object-file")] +use wasmer_engine_object_file::ObjectFile; + +cfg_if! { + if #[cfg(all(feature = "jit", feature = "compiler"))] { + #[no_mangle] + pub extern "C" fn wasm_new_engine_with_target(target: Option>) -> Option> { + let target = target?; + let compiler_config: Box = get_default_compiler_config(); + let engine: Arc = Arc::new(JIT::new(compiler_config).target(target.inner).engine()); + + Some(Box::new(wasm_engine_t { inner: engine })) + } + } else if #[cfg(feature = "jit")] { + #[no_mangle] + pub extern "C" fn wasm_new_engine_with_target(target: Option>) -> Option> { + let target = target?; + let engine: Arc = Arc::new(JIT::headless().target(target.inner).engine()); + + Some(Box::new(wasm_engine_t { inner: engine })) + } + } else if #[cfg(all(feature = "native", feature = "compiler"))] { + #[no_mangle] + pub extern "C" fn wasm_new_engine_with_target(target: Option>) -> Option> { + let target = target?; + let mut compiler_config: Box = get_default_compiler_config(); + let engine: Arc = Arc::new(Native::new(compiler_config).target(target.inner).engine()); + + Some(Box::new(wasm_engine_t { inner: engine })) + } + } else if #[cfg(feature = "native")] { + #[no_mangle] + pub extern "C" fn wasm_new_engine_with_target(target: Option>) -> Option>> { + let target = target?; + let engine: Arc = Arc::new(Native::headless().target(target.inner).engine()); + + Some(Box::new(wasm_engine_t { inner: engine })) + } + } + // There are currently no uses of the object-file engine + compiler from the C API. + // So if we get here, we default to headless mode regardless of if `compiler` is enabled. + else if #[cfg(feature = "object-file")] { + #[no_mangle] + pub extern "C" fn wasm_new_engine_with_target(target: Option>) -> Option> { + let target = target?; + let engine: Arc = Arc::new(ObjectFile::headless().target(target.inner).engine()); + + Some(Box::new(wasm_engine_t { inner: engine })) + } + } else { + #[no_mangle] + pub extern "C" fn wasm_new_engine_with_target(_target: Option>) -> Option> { + unimplemented!("No engine attached; You might want to recompile `wasmer_c_api` with for example `--feature jit`"); + } + } +} diff --git a/lib/c-api/src/wasm_c_api/unstable/mod.rs b/lib/c-api/src/wasm_c_api/unstable/mod.rs index cc57a848e88..5b673aec6ec 100644 --- a/lib/c-api/src/wasm_c_api/unstable/mod.rs +++ b/lib/c-api/src/wasm_c_api/unstable/mod.rs @@ -1 +1,3 @@ +pub mod engine; pub mod module; +pub mod target_lexicon; diff --git a/lib/c-api/src/wasm_c_api/unstable/target_lexicon.rs b/lib/c-api/src/wasm_c_api/unstable/target_lexicon.rs new file mode 100644 index 00000000000..9b6c858e1d4 --- /dev/null +++ b/lib/c-api/src/wasm_c_api/unstable/target_lexicon.rs @@ -0,0 +1,155 @@ +//! Contains everything to create a target with a triple and CPU featurres. +//! +//! # Example +//! +//! ```rust +//! # use inline_c::assert_c; +//! # fn main() { +//! # (assert_c! { +//! # #include "tests/wasmer_wasm.h" +//! # +//! int main() { +//! wasm_byte_vec_t triple_name; +//! wasmer_byte_vec_new_from_string(&triple_name, "x86_64-apple-darwin"); +//! +//! wasm_triple_t* triple = wasm_triple_new((wasm_name_t*) &triple_name); +//! assert(triple); +//! +//! wasm_byte_vec_t cpu_feature_name; +//! wasmer_byte_vec_new_from_string(&cpu_feature_name, "sse2"); +//! +//! wasm_cpu_features_t* cpu_features = wasm_cpu_features_new(); +//! wasm_cpu_features_add(cpu_features, (wasm_name_t*) &cpu_feature_name); +//! +//! wasm_target_t* target = wasm_target_new(triple, cpu_features); +//! assert(target); +//! +//! wasm_target_delete(target); +//! wasm_byte_vec_delete(&cpu_feature_name); +//! wasm_byte_vec_delete(&triple_name); +//! +//! return 0; +//! } +//! # }) +//! # .success(); +//! # } +//! ``` + +use super::super::types::wasm_name_t; +use crate::error::CApiError; +use enumset::EnumSet; +use std::ffi::CStr; +use std::slice; +use std::str::FromStr; +use wasmer_compiler::{CpuFeature, Target, Triple}; + +/// Represents a triple + CPU features pair. +#[allow(non_camel_case_types)] +pub struct wasm_target_t { + pub(crate) inner: Target, +} + +/// Createas a new `wasm_target_`. +/// +/// It takes ownership of `triple` and `cpu_features`. +/// +/// # Example +/// +/// See the module's documentation. +#[no_mangle] +pub unsafe extern "C" fn wasm_target_new( + triple: Option>, + cpu_features: Option>, +) -> Option> { + let triple = triple?; + let cpu_features = cpu_features?; + + Some(Box::new(wasm_target_t { + inner: Target::new(triple.inner.clone(), cpu_features.inner.clone()), + })) +} + +/// Delete a `wasm_target_t`. +/// +/// # Example +/// +/// See the module's documentation. +#[no_mangle] +pub unsafe extern "C" fn wasm_target_delete(_target: Option>) {} + +#[allow(non_camel_case_types)] +pub struct wasm_triple_t { + inner: Triple, +} + +#[no_mangle] +pub unsafe extern "C" fn wasm_triple_new( + triple: Option<&wasm_name_t>, +) -> Option> { + let triple = triple?; + let triple = c_try!(CStr::from_bytes_with_nul_unchecked(slice::from_raw_parts( + triple.data, + triple.size + 1 + )) + .to_str()); + + Some(Box::new(wasm_triple_t { + inner: c_try!(Triple::from_str(triple).map_err(|e| CApiError { msg: e.to_string() })), + })) +} + +#[no_mangle] +pub unsafe extern "C" fn wasm_triple_new_from_host() -> Box { + Box::new(wasm_triple_t { + inner: Triple::host(), + }) +} + +#[no_mangle] +pub unsafe extern "C" fn wasm_triple_delete(_triple: Option>) {} + +#[allow(non_camel_case_types)] +pub struct wasm_cpu_features_t { + inner: EnumSet, +} + +#[no_mangle] +pub unsafe extern "C" fn wasm_cpu_features_new() -> Box { + Box::new(wasm_cpu_features_t { + inner: CpuFeature::set(), + }) +} + +#[no_mangle] +pub unsafe extern "C" fn wasm_cpu_features_delete(_cpu_features: Option>) { +} + +#[no_mangle] +pub unsafe extern "C" fn wasm_cpu_features_add( + cpu_features: Option<&mut wasm_cpu_features_t>, + feature: Option<&wasm_name_t>, +) -> bool { + let cpu_features = match cpu_features { + Some(cpu_features) => cpu_features, + _ => return false, + }; + let feature = match feature { + Some(feature) => feature, + _ => return false, + }; + let feature = c_try!( + CStr::from_bytes_with_nul_unchecked(slice::from_raw_parts( + feature.data, + feature.size + 1, + )) + .to_str(); + otherwise false + ); + + cpu_features.inner.insert(c_try!( + CpuFeature::from_str(feature); + otherwise false + )); + + true +} diff --git a/lib/c-api/wasmer_wasm.h b/lib/c-api/wasmer_wasm.h index d3ae2b7636c..8b09b83d086 100644 --- a/lib/c-api/wasmer_wasm.h +++ b/lib/c-api/wasmer_wasm.h @@ -162,6 +162,15 @@ typedef struct wasi_config_t wasi_config_t; typedef struct wasi_env_t wasi_env_t; #endif +typedef struct wasm_cpu_features_t wasm_cpu_features_t; + +/** + * Represents a triple + CPU features pair. + */ +typedef struct wasm_target_t wasm_target_t; + +typedef struct wasm_triple_t wasm_triple_t; + #ifdef __cplusplus extern "C" { #endif // __cplusplus @@ -337,6 +346,12 @@ void wasm_config_set_compiler(wasm_config_t *config, wasmer_compiler_t compiler) */ void wasm_config_set_engine(wasm_config_t *config, wasmer_engine_t engine); +bool wasm_cpu_features_add(wasm_cpu_features_t *cpu_features, const wasm_name_t *feature); + +void wasm_cpu_features_delete(wasm_cpu_features_t *_cpu_features); + +wasm_cpu_features_t *wasm_cpu_features_new(void); + /** * Unstable non-standard Wasmer-specific API to get the module's * name, otherwise `out->size` is set to `0` and `out->data` to @@ -458,6 +473,32 @@ void wasm_module_name(const wasm_module_t *module, wasm_name_t *out); */ bool wasm_module_set_name(wasm_module_t *module, const wasm_name_t *name); +/** + * Delete a `wasm_target_t`. + * + * # Example + * + * See the module's documentation. + */ +void wasm_target_delete(wasm_target_t *_target); + +/** + * Createas a new `wasm_target_`. + * + * It takes ownership of `triple` and `cpu_features`. + * + * # Example + * + * See the module's documentation. + */ +wasm_target_t *wasm_target_new(wasm_triple_t *triple, wasm_cpu_features_t *cpu_features); + +void wasm_triple_delete(wasm_triple_t *_triple); + +wasm_triple_t *wasm_triple_new(const wasm_name_t *triple); + +wasm_triple_t *wasm_triple_new_from_host(void); + /** * Gets the length in bytes of the last error if any, zero otherwise. * From 169fe16f318bb8c21703226be5612687f789d3b7 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 29 Jan 2021 12:19:35 +0100 Subject: [PATCH 02/14] doc+test(c-api) Add more tests and more documentation. --- .../src/wasm_c_api/unstable/target_lexicon.rs | 182 ++++++++++++++++-- 1 file changed, 170 insertions(+), 12 deletions(-) diff --git a/lib/c-api/src/wasm_c_api/unstable/target_lexicon.rs b/lib/c-api/src/wasm_c_api/unstable/target_lexicon.rs index 9b6c858e1d4..d498ce5cc50 100644 --- a/lib/c-api/src/wasm_c_api/unstable/target_lexicon.rs +++ b/lib/c-api/src/wasm_c_api/unstable/target_lexicon.rs @@ -1,4 +1,6 @@ -//! Contains everything to create a target with a triple and CPU featurres. +//! Contains everything to create a target with a triple and CPU features. +//! +//! This is useful for cross-compilation. //! //! # Example //! @@ -9,24 +11,39 @@ //! # #include "tests/wasmer_wasm.h" //! # //! int main() { -//! wasm_byte_vec_t triple_name; -//! wasmer_byte_vec_new_from_string(&triple_name, "x86_64-apple-darwin"); +//! // Declare the target triple. +//! wasm_triple_t* triple; //! -//! wasm_triple_t* triple = wasm_triple_new((wasm_name_t*) &triple_name); -//! assert(triple); +//! { +//! wasm_byte_vec_t triple_name; +//! wasmer_byte_vec_new_from_string(&triple_name, "x86_64-apple-darwin"); //! -//! wasm_byte_vec_t cpu_feature_name; -//! wasmer_byte_vec_new_from_string(&cpu_feature_name, "sse2"); +//! triple = wasm_triple_new((wasm_name_t*) &triple_name); //! +//! wasm_byte_vec_delete(&triple_name); +//! } +//! +//! assert(triple); +//! +//! // Declare the target CPU features. //! wasm_cpu_features_t* cpu_features = wasm_cpu_features_new(); -//! wasm_cpu_features_add(cpu_features, (wasm_name_t*) &cpu_feature_name); //! +//! { +//! wasm_byte_vec_t cpu_feature_name; +//! wasmer_byte_vec_new_from_string(&cpu_feature_name, "sse2"); +//! +//! wasm_cpu_features_add(cpu_features, (wasm_name_t*) &cpu_feature_name); +//! +//! wasm_byte_vec_delete(&cpu_feature_name); +//! } +//! +//! assert(cpu_features); +//! +//! // Create the target! //! wasm_target_t* target = wasm_target_new(triple, cpu_features); //! assert(target); //! //! wasm_target_delete(target); -//! wasm_byte_vec_delete(&cpu_feature_name); -//! wasm_byte_vec_delete(&triple_name); //! //! return 0; //! } @@ -44,12 +61,16 @@ use std::str::FromStr; use wasmer_compiler::{CpuFeature, Target, Triple}; /// Represents a triple + CPU features pair. +/// +/// # Example +/// +/// See the module's documentation. #[allow(non_camel_case_types)] pub struct wasm_target_t { pub(crate) inner: Target, } -/// Createas a new `wasm_target_`. +/// Creates a new [`wasm_target_t`]. /// /// It takes ownership of `triple` and `cpu_features`. /// @@ -69,7 +90,7 @@ pub unsafe extern "C" fn wasm_target_new( })) } -/// Delete a `wasm_target_t`. +/// Delete a [`wasm_target_t`]. /// /// # Example /// @@ -77,11 +98,47 @@ pub unsafe extern "C" fn wasm_target_new( #[no_mangle] pub unsafe extern "C" fn wasm_target_delete(_target: Option>) {} +/// A target “triple”. +/// +/// Historically such things had three fields, though they have added +/// additional fields over time. +/// +/// # Example +/// +/// ```rust +/// # use inline_c::assert_c; +/// # fn main() { +/// # (assert_c! { +/// # #include "tests/wasmer_wasm.h" +/// # +/// int main() { +/// wasm_byte_vec_t triple_name; +/// wasmer_byte_vec_new_from_string(&triple_name, "x86_64-apple-darwin"); +/// +/// wasm_triple_t* triple = wasm_triple_new((wasm_name_t*) &triple_name); +/// assert(triple); +/// +/// wasm_triple_delete(triple); +/// wasm_byte_vec_delete(&triple_name); +/// +/// return 0; +/// } +/// # }) +/// # .success(); +/// # } +/// ``` +/// +/// See also [`wasm_triple_new_from_host`]. #[allow(non_camel_case_types)] pub struct wasm_triple_t { inner: Triple, } +/// Create a new [`wasm_triple_t`] based on a triple string. +/// +/// # Example +/// +/// See [`wasm_triple_t`] or [`wasm_triple_new_from_host`]. #[no_mangle] pub unsafe extern "C" fn wasm_triple_new( triple: Option<&wasm_name_t>, @@ -98,6 +155,30 @@ pub unsafe extern "C" fn wasm_triple_new( })) } +/// Create the [`wasm_triple_t`] for the current host. +/// +/// # Example +/// +/// ```rust +/// # use inline_c::assert_c; +/// # fn main() { +/// # (assert_c! { +/// # #include "tests/wasmer_wasm.h" +/// # +/// int main() { +/// wasm_triple_t* triple = wasm_triple_new_from_host(); +/// assert(triple); +/// +/// wasm_triple_delete(triple); +/// +/// return 0; +/// } +/// # }) +/// # .success(); +/// # } +/// ``` +/// +/// See also [`wasm_triple_new`]. #[no_mangle] pub unsafe extern "C" fn wasm_triple_new_from_host() -> Box { Box::new(wasm_triple_t { @@ -105,14 +186,80 @@ pub unsafe extern "C" fn wasm_triple_new_from_host() -> Box { }) } +/// Delete a [`wasm_triple_t`]. +/// +/// # Example +/// +/// See [`wasm_triple_t`]. #[no_mangle] pub unsafe extern "C" fn wasm_triple_delete(_triple: Option>) {} +/// Represents a set of CPU features. +/// +/// CPU features are identified by their stringified names. The +/// reference is the GCC options: +/// +/// * , +/// * , +/// * . +/// +/// At the time of writing this documentation (it might be outdated in +/// the future), the supported features are the following: +/// +/// * `sse2`, +/// * `sse3`, +/// * `ssse3`, +/// * `sse4.1`, +/// * `sse4.2`, +/// * `popcnt`, +/// * `avx`, +/// * `bmi`, +/// * `bmi2`, +/// * `avx2`, +/// * `avx512dq`, +/// * `avx512vl`, +/// * `lzcnt`. +/// +/// # Example +/// +/// ```rust +/// # use inline_c::assert_c; +/// # fn main() { +/// # (assert_c! { +/// # #include "tests/wasmer_wasm.h" +/// # +/// int main() { +/// // Create a new CPU feature set. +/// wasm_cpu_features_t* cpu_features = wasm_cpu_features_new(); +/// +/// // Create a new feature name, here `sse2`, and add it to the set. +/// { +/// wasm_byte_vec_t cpu_feature_name; +/// wasmer_byte_vec_new_from_string(&cpu_feature_name, "sse2"); +/// +/// wasm_cpu_features_add(cpu_features, (wasm_name_t*) &cpu_feature_name); +/// +/// wasm_byte_vec_delete(&cpu_feature_name); +/// } +/// +/// wasm_cpu_features_delete(cpu_features); +/// +/// return 0; +/// } +/// # }) +/// # .success(); +/// # } +/// ``` #[allow(non_camel_case_types)] pub struct wasm_cpu_features_t { inner: EnumSet, } +/// Create a new [`wasm_cpu_features_t`]. +/// +/// # Example +/// +/// See [`wasm_cpu_features_t`]. #[no_mangle] pub unsafe extern "C" fn wasm_cpu_features_new() -> Box { Box::new(wasm_cpu_features_t { @@ -120,10 +267,21 @@ pub unsafe extern "C" fn wasm_cpu_features_new() -> Box { }) } +/// Delete a [`wasm_cpu_features_t`]. +/// +/// # Example +/// +/// See [`wasm_cpu_features_t`]. #[no_mangle] pub unsafe extern "C" fn wasm_cpu_features_delete(_cpu_features: Option>) { } +/// Add a new CPU feature into the set represented by +/// [`wasm_cpu_features_t`]. +/// +/// # Example +/// +/// See [`wasm_cpu_features_t`]. #[no_mangle] pub unsafe extern "C" fn wasm_cpu_features_add( cpu_features: Option<&mut wasm_cpu_features_t>, From 1eec2585506ec7507098010872670550039875de Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 29 Jan 2021 14:25:47 +0100 Subject: [PATCH 03/14] chore(c-api) Remove warning. --- lib/c-api/src/wasm_c_api/externals/function.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/c-api/src/wasm_c_api/externals/function.rs b/lib/c-api/src/wasm_c_api/externals/function.rs index 8b5a1cc40c2..d7ae24181fd 100644 --- a/lib/c-api/src/wasm_c_api/externals/function.rs +++ b/lib/c-api/src/wasm_c_api/externals/function.rs @@ -106,7 +106,7 @@ pub unsafe extern "C" fn wasm_func_new_with_env( struct WrapperEnv { env: *mut c_void, finalizer: Option, - }; + } // Only relevant when using multiple threads in the C API; // Synchronization will be done via the C API / on the C side. From bc5bbfdeefc66367b83a283aa521e42cc33af0cd Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 29 Jan 2021 14:26:38 +0100 Subject: [PATCH 04/14] feat(c-api) Implement `Debug` for `wasm_target_t`. --- lib/c-api/src/wasm_c_api/unstable/target_lexicon.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/c-api/src/wasm_c_api/unstable/target_lexicon.rs b/lib/c-api/src/wasm_c_api/unstable/target_lexicon.rs index d498ce5cc50..e14ad39b2f6 100644 --- a/lib/c-api/src/wasm_c_api/unstable/target_lexicon.rs +++ b/lib/c-api/src/wasm_c_api/unstable/target_lexicon.rs @@ -65,6 +65,7 @@ use wasmer_compiler::{CpuFeature, Target, Triple}; /// # Example /// /// See the module's documentation. +#[derive(Debug)] #[allow(non_camel_case_types)] pub struct wasm_target_t { pub(crate) inner: Target, From 14b8fb0a9a2529fc7f109a26af83ff2fdb20d2b6 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 29 Jan 2021 14:26:52 +0100 Subject: [PATCH 05/14] feat(c-api) Implement `wasm_config_set_target`. --- lib/c-api/src/wasm_c_api/unstable/engine.rs | 108 ++++++++------------ 1 file changed, 42 insertions(+), 66 deletions(-) diff --git a/lib/c-api/src/wasm_c_api/unstable/engine.rs b/lib/c-api/src/wasm_c_api/unstable/engine.rs index cdcdf83cf90..d484d83dc90 100644 --- a/lib/c-api/src/wasm_c_api/unstable/engine.rs +++ b/lib/c-api/src/wasm_c_api/unstable/engine.rs @@ -1,69 +1,45 @@ -#[cfg(feature = "compiler")] -use super::super::engine::get_default_compiler_config; -use super::super::engine::wasm_engine_t; +use super::super::engine::wasm_config_t; use super::target_lexicon::wasm_target_t; -use cfg_if::cfg_if; -use std::sync::Arc; -#[cfg(feature = "compiler")] -use wasmer_compiler::CompilerConfig; -use wasmer_engine::Engine; -#[cfg(feature = "jit")] -use wasmer_engine_jit::JIT; -#[cfg(feature = "native")] -use wasmer_engine_native::Native; -#[cfg(feature = "object-file")] -use wasmer_engine_object_file::ObjectFile; -cfg_if! { - if #[cfg(all(feature = "jit", feature = "compiler"))] { - #[no_mangle] - pub extern "C" fn wasm_new_engine_with_target(target: Option>) -> Option> { - let target = target?; - let compiler_config: Box = get_default_compiler_config(); - let engine: Arc = Arc::new(JIT::new(compiler_config).target(target.inner).engine()); - - Some(Box::new(wasm_engine_t { inner: engine })) - } - } else if #[cfg(feature = "jit")] { - #[no_mangle] - pub extern "C" fn wasm_new_engine_with_target(target: Option>) -> Option> { - let target = target?; - let engine: Arc = Arc::new(JIT::headless().target(target.inner).engine()); - - Some(Box::new(wasm_engine_t { inner: engine })) - } - } else if #[cfg(all(feature = "native", feature = "compiler"))] { - #[no_mangle] - pub extern "C" fn wasm_new_engine_with_target(target: Option>) -> Option> { - let target = target?; - let mut compiler_config: Box = get_default_compiler_config(); - let engine: Arc = Arc::new(Native::new(compiler_config).target(target.inner).engine()); - - Some(Box::new(wasm_engine_t { inner: engine })) - } - } else if #[cfg(feature = "native")] { - #[no_mangle] - pub extern "C" fn wasm_new_engine_with_target(target: Option>) -> Option>> { - let target = target?; - let engine: Arc = Arc::new(Native::headless().target(target.inner).engine()); - - Some(Box::new(wasm_engine_t { inner: engine })) - } - } - // There are currently no uses of the object-file engine + compiler from the C API. - // So if we get here, we default to headless mode regardless of if `compiler` is enabled. - else if #[cfg(feature = "object-file")] { - #[no_mangle] - pub extern "C" fn wasm_new_engine_with_target(target: Option>) -> Option> { - let target = target?; - let engine: Arc = Arc::new(ObjectFile::headless().target(target.inner).engine()); - - Some(Box::new(wasm_engine_t { inner: engine })) - } - } else { - #[no_mangle] - pub extern "C" fn wasm_new_engine_with_target(_target: Option>) -> Option> { - unimplemented!("No engine attached; You might want to recompile `wasmer_c_api` with for example `--feature jit`"); - } - } +/// Updates the configuration to specify a particular target for the engine. +/// +/// # Example +/// +/// ```rust +/// # use inline_c::assert_c; +/// # fn main() { +/// # (assert_c! { +/// # #include "tests/wasmer_wasm.h" +/// # +/// int main() { +/// // Create the configuration. +/// wasm_config_t* config = wasm_config_new(); +/// +/// // Set the target. +/// { +/// wasm_triple_t* triple = wasm_triple_new_from_host(); +/// wasm_cpu_features_t* cpu_features = wasm_cpu_features_new(); +/// wasm_target_t* target = wasm_target_new(triple, cpu_features); +/// +/// wasm_config_set_target(config, target); +/// } +/// +/// // Create the engine. +/// wasm_engine_t* engine = wasm_engine_new_with_config(config); +/// +/// // Check we have an engine! +/// assert(engine); +/// +/// // Free everything. +/// wasm_engine_delete(engine); +/// +/// return 0; +/// } +/// # }) +/// # .success(); +/// # } +/// ``` +#[no_mangle] +pub extern "C" fn wasm_config_set_target(config: &mut wasm_config_t, target: Box) { + config.target = Some(target); } From 9fda912f31d933276fe257ccb38c0aa5effdc170 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 29 Jan 2021 14:27:07 +0100 Subject: [PATCH 06/14] feat(c-api) `wasm_config_t` and `wasm_engine_new_with_config` handle the target. --- lib/c-api/src/wasm_c_api/engine.rs | 57 +++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 8 deletions(-) diff --git a/lib/c-api/src/wasm_c_api/engine.rs b/lib/c-api/src/wasm_c_api/engine.rs index 2724cc6ffef..2e9e6b21e0a 100644 --- a/lib/c-api/src/wasm_c_api/engine.rs +++ b/lib/c-api/src/wasm_c_api/engine.rs @@ -1,3 +1,5 @@ +pub use super::unstable::engine::wasm_config_set_target; +use super::unstable::target_lexicon::wasm_target_t; use crate::error::{update_last_error, CApiError}; use cfg_if::cfg_if; use std::sync::Arc; @@ -93,6 +95,7 @@ pub struct wasm_config_t { engine: wasmer_engine_t, #[cfg(feature = "compiler")] compiler: wasmer_compiler_t, + pub(super) target: Option>, } /// Create a new default Wasmer configuration. @@ -396,7 +399,7 @@ pub unsafe extern "C" fn wasm_engine_delete(_engine: Option>) /// cbindgen:ignore #[no_mangle] pub extern "C" fn wasm_engine_new_with_config( - config: Box, + config: Option>, ) -> Option> { #[allow(dead_code)] fn return_with_error(msg: M) -> Option> @@ -408,7 +411,9 @@ pub extern "C" fn wasm_engine_new_with_config( }); return None; - }; + } + + let config = config?; cfg_if! { if #[cfg(feature = "compiler")] { @@ -447,7 +452,13 @@ pub extern "C" fn wasm_engine_new_with_config( wasmer_engine_t::JIT => { cfg_if! { if #[cfg(feature = "jit")] { - Arc::new(JIT::new(compiler_config).engine()) + let mut builder = JIT::new(compiler_config); + + if let Some(target) = config.target { + builder = builder.target(target.inner); + } + + Arc::new(builder.engine()) } else { return return_with_error("Wasmer has not been compiled with the `jit` feature."); } @@ -456,7 +467,13 @@ pub extern "C" fn wasm_engine_new_with_config( wasmer_engine_t::NATIVE => { cfg_if! { if #[cfg(feature = "native")] { - Arc::new(Native::new(compiler_config).engine()) + let mut builder = Native::new(compiler_config); + + if let Some(target) = config.target { + builder = builder.target(target.inner); + } + + Arc::new(builder.engine()) } else { return return_with_error("Wasmer has not been compiled with the `native` feature."); } @@ -467,7 +484,13 @@ pub extern "C" fn wasm_engine_new_with_config( // There are currently no uses of the object-file engine + compiler from the C API. // So we run in headless mode. if #[cfg(feature = "object-file")] { - Arc::new(ObjectFile::headless().engine()) + let mut builder = ObjectFile::headless(); + + if let Some(target) = config.target { + builder = builder.target(target.inner); + } + + Arc::new(builder.engine()) } else { return return_with_error("Wasmer has not been compiled with the `object-file` feature."); } @@ -480,7 +503,13 @@ pub extern "C" fn wasm_engine_new_with_config( wasmer_engine_t::JIT => { cfg_if! { if #[cfg(feature = "jit")] { - Arc::new(JIT::headless().engine()) + let mut builder = JIT::headless(); + + if let Some(target) = config.target { + builder = builder.target(target.inner); + } + + Arc::new(builder.engine()) } else { return return_with_error("Wasmer has not been compiled with the `jit` feature."); } @@ -489,7 +518,13 @@ pub extern "C" fn wasm_engine_new_with_config( wasmer_engine_t::NATIVE => { cfg_if! { if #[cfg(feature = "native")] { - Arc::new(Native::headless().engine()) + let mut builder = Native::headless(); + + if let Some(target) = config.target { + builder = builder.target(target.inner); + } + + Arc::new(builder.engine()) } else { return return_with_error("Wasmer has not been compiled with the `native` feature."); } @@ -498,7 +533,13 @@ pub extern "C" fn wasm_engine_new_with_config( wasmer_engine_t::OBJECT_FILE => { cfg_if! { if #[cfg(feature = "object-file")] { - Arc::new(ObjectFile::headless().engine()) + let mut builder = ObjectFile::headless(); + + if let Some(target) = config.target { + builder = builder.target(target.inner); + } + + Arc::new(builder.engine()) } else { return return_with_error("Wasmer has not been compiled with the `object-file` feature."); } From e4057469bc78388d93164d9177529e75d1bd5478 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 29 Jan 2021 14:29:50 +0100 Subject: [PATCH 07/14] chore(c-api) `get_default_compiler_config` can stay private. --- lib/c-api/src/wasm_c_api/engine.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/c-api/src/wasm_c_api/engine.rs b/lib/c-api/src/wasm_c_api/engine.rs index 2e9e6b21e0a..bfc3e4f09d7 100644 --- a/lib/c-api/src/wasm_c_api/engine.rs +++ b/lib/c-api/src/wasm_c_api/engine.rs @@ -259,7 +259,7 @@ pub struct wasm_engine_t { #[cfg(feature = "compiler")] use wasmer_compiler::CompilerConfig; #[cfg(feature = "compiler")] -pub(crate) fn get_default_compiler_config() -> Box { +fn get_default_compiler_config() -> Box { cfg_if! { if #[cfg(feature = "cranelift")] { Box::new(wasmer_compiler_cranelift::Cranelift::default()) From dc9f8fc82c27b95b64d54d0f81169d76fd82fe48 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 29 Jan 2021 14:34:59 +0100 Subject: [PATCH 08/14] chore(c-api) Update headers. --- lib/c-api/build.rs | 12 +++ lib/c-api/wasmer_wasm.h | 203 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 213 insertions(+), 2 deletions(-) diff --git a/lib/c-api/build.rs b/lib/c-api/build.rs index 6fcc41b6456..7181d1989dc 100644 --- a/lib/c-api/build.rs +++ b/lib/c-api/build.rs @@ -427,8 +427,20 @@ fn exclude_items_from_wasm_c_api(builder: Builder) -> Builder { .exclude_item("wasi_version_t") .exclude_item("wasm_config_set_compiler") .exclude_item("wasm_config_set_engine") + .exclude_item("wasm_config_set_target") + .exclude_item("wasm_cpu_features_add") + .exclude_item("wasm_cpu_features_delete") + .exclude_item("wasm_cpu_features_new") + .exclude_item("wasm_cpu_features_t") .exclude_item("wasm_module_name") .exclude_item("wasm_module_set_name") + .exclude_item("wasm_target_delete") + .exclude_item("wasm_target_new") + .exclude_item("wasm_target_t") + .exclude_item("wasm_triple_delete") + .exclude_item("wasm_triple_new") + .exclude_item("wasm_triple_new_from_host") + .exclude_item("wasm_triple_t") .exclude_item("wasmer_compiler_t") .exclude_item("wasmer_engine_t") .exclude_item("wat2wasm") diff --git a/lib/c-api/wasmer_wasm.h b/lib/c-api/wasmer_wasm.h index 8b09b83d086..db88c4e99e5 100644 --- a/lib/c-api/wasmer_wasm.h +++ b/lib/c-api/wasmer_wasm.h @@ -162,13 +162,108 @@ typedef struct wasi_config_t wasi_config_t; typedef struct wasi_env_t wasi_env_t; #endif +/** + * Represents a set of CPU features. + * + * CPU features are identified by their stringified names. The + * reference is the GCC options: + * + * * , + * * , + * * . + * + * At the time of writing this documentation (it might be outdated in + * the future), the supported features are the following: + * + * * `sse2`, + * * `sse3`, + * * `ssse3`, + * * `sse4.1`, + * * `sse4.2`, + * * `popcnt`, + * * `avx`, + * * `bmi`, + * * `bmi2`, + * * `avx2`, + * * `avx512dq`, + * * `avx512vl`, + * * `lzcnt`. + * + * # Example + * + * ```rust + * # use inline_c::assert_c; + * # fn main() { + * # (assert_c! { + * # #include "tests/wasmer_wasm.h" + * # + * int main() { + * // Create a new CPU feature set. + * wasm_cpu_features_t* cpu_features = wasm_cpu_features_new(); + * + * // Create a new feature name, here `sse2`, and add it to the set. + * { + * wasm_byte_vec_t cpu_feature_name; + * wasmer_byte_vec_new_from_string(&cpu_feature_name, "sse2"); + * + * wasm_cpu_features_add(cpu_features, (wasm_name_t*) &cpu_feature_name); + * + * wasm_byte_vec_delete(&cpu_feature_name); + * } + * + * wasm_cpu_features_delete(cpu_features); + * + * return 0; + * } + * # }) + * # .success(); + * # } + * ``` + */ typedef struct wasm_cpu_features_t wasm_cpu_features_t; /** * Represents a triple + CPU features pair. + * + * # Example + * + * See the module's documentation. */ typedef struct wasm_target_t wasm_target_t; +/** + * A target “triple”. + * + * Historically such things had three fields, though they have added + * additional fields over time. + * + * # Example + * + * ```rust + * # use inline_c::assert_c; + * # fn main() { + * # (assert_c! { + * # #include "tests/wasmer_wasm.h" + * # + * int main() { + * wasm_byte_vec_t triple_name; + * wasmer_byte_vec_new_from_string(&triple_name, "x86_64-apple-darwin"); + * + * wasm_triple_t* triple = wasm_triple_new((wasm_name_t*) &triple_name); + * assert(triple); + * + * wasm_triple_delete(triple); + * wasm_byte_vec_delete(&triple_name); + * + * return 0; + * } + * # }) + * # .success(); + * # } + * ``` + * + * See also [`wasm_triple_new_from_host`]. + */ typedef struct wasm_triple_t wasm_triple_t; #ifdef __cplusplus @@ -346,10 +441,74 @@ void wasm_config_set_compiler(wasm_config_t *config, wasmer_compiler_t compiler) */ void wasm_config_set_engine(wasm_config_t *config, wasmer_engine_t engine); +/** + * Updates the configuration to specify a particular target for the engine. + * + * # Example + * + * ```rust + * # use inline_c::assert_c; + * # fn main() { + * # (assert_c! { + * # #include "tests/wasmer_wasm.h" + * # + * int main() { + * // Create the configuration. + * wasm_config_t* config = wasm_config_new(); + * + * // Set the target. + * { + * wasm_triple_t* triple = wasm_triple_new_from_host(); + * wasm_cpu_features_t* cpu_features = wasm_cpu_features_new(); + * wasm_target_t* target = wasm_target_new(triple, cpu_features); + * + * wasm_config_set_target(config, target); + * } + * + * // Create the engine. + * wasm_engine_t* engine = wasm_engine_new_with_config(config); + * + * // Check we have an engine! + * assert(engine); + * + * // Free everything. + * wasm_engine_delete(engine); + * + * return 0; + * } + * # }) + * # .success(); + * # } + * ``` + */ +void wasm_config_set_target(wasm_config_t *config, wasm_target_t *target); + +/** + * Add a new CPU feature into the set represented by + * [`wasm_cpu_features_t`]. + * + * # Example + * + * See [`wasm_cpu_features_t`]. + */ bool wasm_cpu_features_add(wasm_cpu_features_t *cpu_features, const wasm_name_t *feature); +/** + * Delete a [`wasm_cpu_features_t`]. + * + * # Example + * + * See [`wasm_cpu_features_t`]. + */ void wasm_cpu_features_delete(wasm_cpu_features_t *_cpu_features); +/** + * Create a new [`wasm_cpu_features_t`]. + * + * # Example + * + * See [`wasm_cpu_features_t`]. + */ wasm_cpu_features_t *wasm_cpu_features_new(void); /** @@ -474,7 +633,7 @@ void wasm_module_name(const wasm_module_t *module, wasm_name_t *out); bool wasm_module_set_name(wasm_module_t *module, const wasm_name_t *name); /** - * Delete a `wasm_target_t`. + * Delete a [`wasm_target_t`]. * * # Example * @@ -483,7 +642,7 @@ bool wasm_module_set_name(wasm_module_t *module, const wasm_name_t *name); void wasm_target_delete(wasm_target_t *_target); /** - * Createas a new `wasm_target_`. + * Creates a new [`wasm_target_t`]. * * It takes ownership of `triple` and `cpu_features`. * @@ -493,10 +652,50 @@ void wasm_target_delete(wasm_target_t *_target); */ wasm_target_t *wasm_target_new(wasm_triple_t *triple, wasm_cpu_features_t *cpu_features); +/** + * Delete a [`wasm_triple_t`]. + * + * # Example + * + * See [`wasm_triple_t`]. + */ void wasm_triple_delete(wasm_triple_t *_triple); +/** + * Create a new [`wasm_triple_t`] based on a triple string. + * + * # Example + * + * See [`wasm_triple_t`] or [`wasm_triple_new_from_host`]. + */ wasm_triple_t *wasm_triple_new(const wasm_name_t *triple); +/** + * Create the [`wasm_triple_t`] for the current host. + * + * # Example + * + * ```rust + * # use inline_c::assert_c; + * # fn main() { + * # (assert_c! { + * # #include "tests/wasmer_wasm.h" + * # + * int main() { + * wasm_triple_t* triple = wasm_triple_new_from_host(); + * assert(triple); + * + * wasm_triple_delete(triple); + * + * return 0; + * } + * # }) + * # .success(); + * # } + * ``` + * + * See also [`wasm_triple_new`]. + */ wasm_triple_t *wasm_triple_new_from_host(void); /** From fd39a74c6f5e80cd145edd8803e2dc9f8dac5410 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 29 Jan 2021 14:36:41 +0100 Subject: [PATCH 09/14] doc(changelog) Add #2072. --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff38fecb0b9..ddede6f49a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ ## **[Unreleased]** ### Added +- [#2072](https://github.com/wasmerio/wasmer/pull/2072) Add `wasm_config_set_target`, along with `wasm_target_t`, `wasm_triple_t` and `wasm_cpu_features_t` in the unstable C API. - [#2059](https://github.com/wasmerio/wasmer/pull/2059) Ability to capture `stdout` and `stderr` with WASI in the C API. - [#2040](https://github.com/wasmerio/wasmer/pull/2040) Add `InstanceHandle::vmoffsets` to expose the offsets of the `vmctx` region. - [#2026](https://github.com/wasmerio/wasmer/pull/2010) Expose trap code of a `RuntimeError`, if it's a `Trap`. From 3c5692ca2ff5dbacaa1f7baa2258643829f77f96 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 29 Jan 2021 14:39:59 +0100 Subject: [PATCH 10/14] doc(c-api) Mark some types as unstable. --- lib/c-api/src/wasm_c_api/unstable/engine.rs | 3 ++- lib/c-api/src/wasm_c_api/unstable/target_lexicon.rs | 12 ++++++++---- lib/c-api/wasmer_wasm.h | 12 ++++++++---- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/lib/c-api/src/wasm_c_api/unstable/engine.rs b/lib/c-api/src/wasm_c_api/unstable/engine.rs index d484d83dc90..5fdd31428a5 100644 --- a/lib/c-api/src/wasm_c_api/unstable/engine.rs +++ b/lib/c-api/src/wasm_c_api/unstable/engine.rs @@ -1,7 +1,8 @@ use super::super::engine::wasm_config_t; use super::target_lexicon::wasm_target_t; -/// Updates the configuration to specify a particular target for the engine. +/// Unstable non-standard Wasmer-specific API to update the +/// configuration to specify a particular target for the engine. /// /// # Example /// diff --git a/lib/c-api/src/wasm_c_api/unstable/target_lexicon.rs b/lib/c-api/src/wasm_c_api/unstable/target_lexicon.rs index e14ad39b2f6..33c5f05af14 100644 --- a/lib/c-api/src/wasm_c_api/unstable/target_lexicon.rs +++ b/lib/c-api/src/wasm_c_api/unstable/target_lexicon.rs @@ -1,4 +1,5 @@ -//! Contains everything to create a target with a triple and CPU features. +//! Unstable non-standard Wasmer-specific API that contains everything +//! to create a target with a triple and CPU features. //! //! This is useful for cross-compilation. //! @@ -60,7 +61,8 @@ use std::slice; use std::str::FromStr; use wasmer_compiler::{CpuFeature, Target, Triple}; -/// Represents a triple + CPU features pair. +/// Unstable non-standard Wasmer-specific API to represent a triple + +/// CPU features pair. /// /// # Example /// @@ -99,7 +101,8 @@ pub unsafe extern "C" fn wasm_target_new( #[no_mangle] pub unsafe extern "C" fn wasm_target_delete(_target: Option>) {} -/// A target “triple”. +/// Unstable non-standard Wasmer-specific API to represent a target +/// “triple”. /// /// Historically such things had three fields, though they have added /// additional fields over time. @@ -195,7 +198,8 @@ pub unsafe extern "C" fn wasm_triple_new_from_host() -> Box { #[no_mangle] pub unsafe extern "C" fn wasm_triple_delete(_triple: Option>) {} -/// Represents a set of CPU features. +/// Unstable non-standard Wasmer-specific API to represent a set of +/// CPU features. /// /// CPU features are identified by their stringified names. The /// reference is the GCC options: diff --git a/lib/c-api/wasmer_wasm.h b/lib/c-api/wasmer_wasm.h index db88c4e99e5..a6438a042e8 100644 --- a/lib/c-api/wasmer_wasm.h +++ b/lib/c-api/wasmer_wasm.h @@ -163,7 +163,8 @@ typedef struct wasi_env_t wasi_env_t; #endif /** - * Represents a set of CPU features. + * Unstable non-standard Wasmer-specific API to represent a set of + * CPU features. * * CPU features are identified by their stringified names. The * reference is the GCC options: @@ -223,7 +224,8 @@ typedef struct wasi_env_t wasi_env_t; typedef struct wasm_cpu_features_t wasm_cpu_features_t; /** - * Represents a triple + CPU features pair. + * Unstable non-standard Wasmer-specific API to represent a triple + + * CPU features pair. * * # Example * @@ -232,7 +234,8 @@ typedef struct wasm_cpu_features_t wasm_cpu_features_t; typedef struct wasm_target_t wasm_target_t; /** - * A target “triple”. + * Unstable non-standard Wasmer-specific API to represent a target + * “triple”. * * Historically such things had three fields, though they have added * additional fields over time. @@ -442,7 +445,8 @@ void wasm_config_set_compiler(wasm_config_t *config, wasmer_compiler_t compiler) void wasm_config_set_engine(wasm_config_t *config, wasmer_engine_t engine); /** - * Updates the configuration to specify a particular target for the engine. + * Unstable non-standard Wasmer-specific API to update the + * configuration to specify a particular target for the engine. * * # Example * From 88e5e4985d35f8d334f5cfed49a488736de8e7b9 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 29 Jan 2021 14:40:26 +0100 Subject: [PATCH 11/14] chore(cargo) Update `Cargo.lock`. --- Cargo.lock | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.lock b/Cargo.lock index 164458639f0..a7da9c0dbcc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2321,6 +2321,7 @@ version = "1.0.1" dependencies = [ "cbindgen", "cfg-if 1.0.0", + "enumset", "inline-c", "lazy_static", "libc", From 9fb174e9612974c97c8082b688d482df120088b4 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 29 Jan 2021 14:41:41 +0100 Subject: [PATCH 12/14] doc(c-api) Add more documentation. --- lib/c-api/src/wasm_c_api/unstable/engine.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/c-api/src/wasm_c_api/unstable/engine.rs b/lib/c-api/src/wasm_c_api/unstable/engine.rs index 5fdd31428a5..92264a9a6e8 100644 --- a/lib/c-api/src/wasm_c_api/unstable/engine.rs +++ b/lib/c-api/src/wasm_c_api/unstable/engine.rs @@ -1,3 +1,6 @@ +//! Unstable non-standard Wasmer-specific types for the +//! `wasm_engine_t` and siblings. + use super::super::engine::wasm_config_t; use super::target_lexicon::wasm_target_t; From 7e757ded6b2a487b1ab0c37f7a6d72f888c610cf Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 29 Jan 2021 15:04:40 +0100 Subject: [PATCH 13/14] test(c-api) Simplify test by using `wasm_name_new_from_string`. --- .../src/wasm_c_api/unstable/target_lexicon.rs | 32 +++++++++---------- lib/c-api/wasmer_wasm.h | 16 +++++----- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/lib/c-api/src/wasm_c_api/unstable/target_lexicon.rs b/lib/c-api/src/wasm_c_api/unstable/target_lexicon.rs index 33c5f05af14..36541adeaa3 100644 --- a/lib/c-api/src/wasm_c_api/unstable/target_lexicon.rs +++ b/lib/c-api/src/wasm_c_api/unstable/target_lexicon.rs @@ -16,12 +16,12 @@ //! wasm_triple_t* triple; //! //! { -//! wasm_byte_vec_t triple_name; -//! wasmer_byte_vec_new_from_string(&triple_name, "x86_64-apple-darwin"); +//! wasm_name_t triple_name; +//! wasm_name_new_from_string(&triple_name, "x86_64-apple-darwin"); //! -//! triple = wasm_triple_new((wasm_name_t*) &triple_name); +//! triple = wasm_triple_new(&triple_name); //! -//! wasm_byte_vec_delete(&triple_name); +//! wasm_name_delete(&triple_name); //! } //! //! assert(triple); @@ -30,12 +30,12 @@ //! wasm_cpu_features_t* cpu_features = wasm_cpu_features_new(); //! //! { -//! wasm_byte_vec_t cpu_feature_name; -//! wasmer_byte_vec_new_from_string(&cpu_feature_name, "sse2"); +//! wasm_name_t cpu_feature_name; +//! wasm_name_new_from_string(&cpu_feature_name, "sse2"); //! -//! wasm_cpu_features_add(cpu_features, (wasm_name_t*) &cpu_feature_name); +//! wasm_cpu_features_add(cpu_features, &cpu_feature_name); //! -//! wasm_byte_vec_delete(&cpu_feature_name); +//! wasm_name_delete(&cpu_feature_name); //! } //! //! assert(cpu_features); @@ -116,14 +116,14 @@ pub unsafe extern "C" fn wasm_target_delete(_target: Option>) /// # #include "tests/wasmer_wasm.h" /// # /// int main() { -/// wasm_byte_vec_t triple_name; -/// wasmer_byte_vec_new_from_string(&triple_name, "x86_64-apple-darwin"); +/// wasm_name_t triple_name; +/// wasm_name_new_from_string(&triple_name, "x86_64-apple-darwin"); /// -/// wasm_triple_t* triple = wasm_triple_new((wasm_name_t*) &triple_name); +/// wasm_triple_t* triple = wasm_triple_new(&triple_name); /// assert(triple); /// /// wasm_triple_delete(triple); -/// wasm_byte_vec_delete(&triple_name); +/// wasm_name_delete(&triple_name); /// /// return 0; /// } @@ -239,12 +239,12 @@ pub unsafe extern "C" fn wasm_triple_delete(_triple: Option>) /// /// // Create a new feature name, here `sse2`, and add it to the set. /// { -/// wasm_byte_vec_t cpu_feature_name; -/// wasmer_byte_vec_new_from_string(&cpu_feature_name, "sse2"); +/// wasm_name_t cpu_feature_name; +/// wasm_name_new_from_string(&cpu_feature_name, "sse2"); /// -/// wasm_cpu_features_add(cpu_features, (wasm_name_t*) &cpu_feature_name); +/// wasm_cpu_features_add(cpu_features, &cpu_feature_name); /// -/// wasm_byte_vec_delete(&cpu_feature_name); +/// wasm_name_delete(&cpu_feature_name); /// } /// /// wasm_cpu_features_delete(cpu_features); diff --git a/lib/c-api/wasmer_wasm.h b/lib/c-api/wasmer_wasm.h index a6438a042e8..1bad0973a3e 100644 --- a/lib/c-api/wasmer_wasm.h +++ b/lib/c-api/wasmer_wasm.h @@ -204,12 +204,12 @@ typedef struct wasi_env_t wasi_env_t; * * // Create a new feature name, here `sse2`, and add it to the set. * { - * wasm_byte_vec_t cpu_feature_name; - * wasmer_byte_vec_new_from_string(&cpu_feature_name, "sse2"); + * wasm_name_t cpu_feature_name; + * wasm_name_new_from_string(&cpu_feature_name, "sse2"); * - * wasm_cpu_features_add(cpu_features, (wasm_name_t*) &cpu_feature_name); + * wasm_cpu_features_add(cpu_features, &cpu_feature_name); * - * wasm_byte_vec_delete(&cpu_feature_name); + * wasm_name_delete(&cpu_feature_name); * } * * wasm_cpu_features_delete(cpu_features); @@ -249,14 +249,14 @@ typedef struct wasm_target_t wasm_target_t; * # #include "tests/wasmer_wasm.h" * # * int main() { - * wasm_byte_vec_t triple_name; - * wasmer_byte_vec_new_from_string(&triple_name, "x86_64-apple-darwin"); + * wasm_name_t triple_name; + * wasm_name_new_from_string(&triple_name, "x86_64-apple-darwin"); * - * wasm_triple_t* triple = wasm_triple_new((wasm_name_t*) &triple_name); + * wasm_triple_t* triple = wasm_triple_new(&triple_name); * assert(triple); * * wasm_triple_delete(triple); - * wasm_byte_vec_delete(&triple_name); + * wasm_name_delete(&triple_name); * * return 0; * } From 7eb08399f28c0a0ed2fbffb19c532451d823ec33 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Tue, 2 Feb 2021 09:49:39 +0100 Subject: [PATCH 14/14] fix(c-api) Include feedbacks from @MarkMcCaskey! --- .../src/wasm_c_api/unstable/target_lexicon.rs | 28 ++++++++----------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/lib/c-api/src/wasm_c_api/unstable/target_lexicon.rs b/lib/c-api/src/wasm_c_api/unstable/target_lexicon.rs index 36541adeaa3..ccba407834c 100644 --- a/lib/c-api/src/wasm_c_api/unstable/target_lexicon.rs +++ b/lib/c-api/src/wasm_c_api/unstable/target_lexicon.rs @@ -56,9 +56,8 @@ use super::super::types::wasm_name_t; use crate::error::CApiError; use enumset::EnumSet; -use std::ffi::CStr; use std::slice; -use std::str::FromStr; +use std::str::{self, FromStr}; use wasmer_compiler::{CpuFeature, Target, Triple}; /// Unstable non-standard Wasmer-specific API to represent a triple + @@ -81,7 +80,7 @@ pub struct wasm_target_t { /// /// See the module's documentation. #[no_mangle] -pub unsafe extern "C" fn wasm_target_new( +pub extern "C" fn wasm_target_new( triple: Option>, cpu_features: Option>, ) -> Option> { @@ -99,7 +98,7 @@ pub unsafe extern "C" fn wasm_target_new( /// /// See the module's documentation. #[no_mangle] -pub unsafe extern "C" fn wasm_target_delete(_target: Option>) {} +pub extern "C" fn wasm_target_delete(_target: Option>) {} /// Unstable non-standard Wasmer-specific API to represent a target /// “triple”. @@ -148,11 +147,10 @@ pub unsafe extern "C" fn wasm_triple_new( triple: Option<&wasm_name_t>, ) -> Option> { let triple = triple?; - let triple = c_try!(CStr::from_bytes_with_nul_unchecked(slice::from_raw_parts( + let triple = c_try!(str::from_utf8(slice::from_raw_parts( triple.data, - triple.size + 1 - )) - .to_str()); + triple.size + ))); Some(Box::new(wasm_triple_t { inner: c_try!(Triple::from_str(triple).map_err(|e| CApiError { msg: e.to_string() })), @@ -184,7 +182,7 @@ pub unsafe extern "C" fn wasm_triple_new( /// /// See also [`wasm_triple_new`]. #[no_mangle] -pub unsafe extern "C" fn wasm_triple_new_from_host() -> Box { +pub extern "C" fn wasm_triple_new_from_host() -> Box { Box::new(wasm_triple_t { inner: Triple::host(), }) @@ -196,7 +194,7 @@ pub unsafe extern "C" fn wasm_triple_new_from_host() -> Box { /// /// See [`wasm_triple_t`]. #[no_mangle] -pub unsafe extern "C" fn wasm_triple_delete(_triple: Option>) {} +pub extern "C" fn wasm_triple_delete(_triple: Option>) {} /// Unstable non-standard Wasmer-specific API to represent a set of /// CPU features. @@ -266,7 +264,7 @@ pub struct wasm_cpu_features_t { /// /// See [`wasm_cpu_features_t`]. #[no_mangle] -pub unsafe extern "C" fn wasm_cpu_features_new() -> Box { +pub extern "C" fn wasm_cpu_features_new() -> Box { Box::new(wasm_cpu_features_t { inner: CpuFeature::set(), }) @@ -278,8 +276,7 @@ pub unsafe extern "C" fn wasm_cpu_features_new() -> Box { /// /// See [`wasm_cpu_features_t`]. #[no_mangle] -pub unsafe extern "C" fn wasm_cpu_features_delete(_cpu_features: Option>) { -} +pub extern "C" fn wasm_cpu_features_delete(_cpu_features: Option>) {} /// Add a new CPU feature into the set represented by /// [`wasm_cpu_features_t`]. @@ -301,11 +298,10 @@ pub unsafe extern "C" fn wasm_cpu_features_add( _ => return false, }; let feature = c_try!( - CStr::from_bytes_with_nul_unchecked(slice::from_raw_parts( + str::from_utf8(slice::from_raw_parts( feature.data, feature.size + 1, - )) - .to_str(); + )); otherwise false );