mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-07 05:08:19 +00:00
feat(c-api) Start implementing wasm_target_t, wasm_triple_t and wasm_cpu_features_t.
This commit is contained in:
@@ -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 }
|
||||
|
||||
@@ -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<dyn CompilerConfig> {
|
||||
pub(crate) fn get_default_compiler_config() -> Box<dyn CompilerConfig> {
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "cranelift")] {
|
||||
Box::new(wasmer_compiler_cranelift::Cranelift::default())
|
||||
|
||||
@@ -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))
|
||||
|
||||
69
lib/c-api/src/wasm_c_api/unstable/engine.rs
Normal file
69
lib/c-api/src/wasm_c_api/unstable/engine.rs
Normal file
@@ -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<Box<wasm_target_t>>) -> Option<Box<wasm_engine_t>> {
|
||||
let target = target?;
|
||||
let compiler_config: Box<dyn CompilerConfig> = get_default_compiler_config();
|
||||
let engine: Arc<dyn Engine + Send + Sync> = 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<Box<wasm_target_t>>) -> Option<Box<wasm_engine_t>> {
|
||||
let target = target?;
|
||||
let engine: Arc<dyn Engine + Send + Sync> = 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<Box<wasm_target_t>>) -> Option<Box<wasm_engine_t>> {
|
||||
let target = target?;
|
||||
let mut compiler_config: Box<dyn CompilerConfig> = get_default_compiler_config();
|
||||
let engine: Arc<dyn Engine + Send + Sync> = 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<Box<wasm_target_t>>) -> Option<Box<wasm_engine_t>>> {
|
||||
let target = target?;
|
||||
let engine: Arc<dyn Engine + Send + Sync> = 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<Box<wasm_target_t>>) -> Option<Box<wasm_engine_t>> {
|
||||
let target = target?;
|
||||
let engine: Arc<dyn Engine + Send + Sync> = 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<Box<wasm_target_t>>) -> Option<Box<wasm_engine_t>> {
|
||||
unimplemented!("No engine attached; You might want to recompile `wasmer_c_api` with for example `--feature jit`");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1 +1,3 @@
|
||||
pub mod engine;
|
||||
pub mod module;
|
||||
pub mod target_lexicon;
|
||||
|
||||
155
lib/c-api/src/wasm_c_api/unstable/target_lexicon.rs
Normal file
155
lib/c-api/src/wasm_c_api/unstable/target_lexicon.rs
Normal file
@@ -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<Box<wasm_triple_t>>,
|
||||
cpu_features: Option<Box<wasm_cpu_features_t>>,
|
||||
) -> Option<Box<wasm_target_t>> {
|
||||
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<Box<wasm_target_t>>) {}
|
||||
|
||||
#[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<Box<wasm_triple_t>> {
|
||||
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<wasm_triple_t> {
|
||||
Box::new(wasm_triple_t {
|
||||
inner: Triple::host(),
|
||||
})
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wasm_triple_delete(_triple: Option<Box<wasm_triple_t>>) {}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub struct wasm_cpu_features_t {
|
||||
inner: EnumSet<CpuFeature>,
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wasm_cpu_features_new() -> Box<wasm_cpu_features_t> {
|
||||
Box::new(wasm_cpu_features_t {
|
||||
inner: CpuFeature::set(),
|
||||
})
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wasm_cpu_features_delete(_cpu_features: Option<Box<wasm_cpu_features_t>>) {
|
||||
}
|
||||
|
||||
#[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
|
||||
}
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user