mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-07 13:18:20 +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-engine-object-file = { version = "1.0.1", path = "../engine-object-file", optional = true }
|
||||||
wasmer-wasi = { version = "1.0.1", path = "../wasi", optional = true }
|
wasmer-wasi = { version = "1.0.1", path = "../wasi", optional = true }
|
||||||
wasmer-types = { version = "1.0.1", path = "../wasmer-types" }
|
wasmer-types = { version = "1.0.1", path = "../wasmer-types" }
|
||||||
|
enumset = "1.0"
|
||||||
cfg-if = "1.0"
|
cfg-if = "1.0"
|
||||||
lazy_static = "1.4"
|
lazy_static = "1.4"
|
||||||
libc = { version = "^0.2", default-features = false }
|
libc = { version = "^0.2", default-features = false }
|
||||||
|
|||||||
@@ -256,7 +256,7 @@ pub struct wasm_engine_t {
|
|||||||
#[cfg(feature = "compiler")]
|
#[cfg(feature = "compiler")]
|
||||||
use wasmer_compiler::CompilerConfig;
|
use wasmer_compiler::CompilerConfig;
|
||||||
#[cfg(feature = "compiler")]
|
#[cfg(feature = "compiler")]
|
||||||
fn get_default_compiler_config() -> Box<dyn CompilerConfig> {
|
pub(crate) fn get_default_compiler_config() -> Box<dyn CompilerConfig> {
|
||||||
cfg_if! {
|
cfg_if! {
|
||||||
if #[cfg(feature = "cranelift")] {
|
if #[cfg(feature = "cranelift")] {
|
||||||
Box::new(wasmer_compiler_cranelift::Cranelift::default())
|
Box::new(wasmer_compiler_cranelift::Cranelift::default())
|
||||||
|
|||||||
@@ -467,16 +467,19 @@ macro_rules! wasm_declare_own {
|
|||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! c_try {
|
macro_rules! c_try {
|
||||||
($expr:expr) => {{
|
($expr:expr; otherwise $return:expr) => {{
|
||||||
let res: Result<_, _> = $expr;
|
let res: Result<_, _> = $expr;
|
||||||
match res {
|
match res {
|
||||||
Ok(val) => val,
|
Ok(val) => val,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
crate::error::update_last_error(err);
|
crate::error::update_last_error(err);
|
||||||
return None;
|
return $return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
($expr:expr) => {{
|
||||||
|
c_try!($expr; otherwise None)
|
||||||
|
}};
|
||||||
($expr:expr, $e:expr) => {{
|
($expr:expr, $e:expr) => {{
|
||||||
let opt: Option<_> = $expr;
|
let opt: Option<_> = $expr;
|
||||||
c_try!(opt.ok_or_else(|| $e))
|
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 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;
|
typedef struct wasi_env_t wasi_env_t;
|
||||||
#endif
|
#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
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif // __cplusplus
|
#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);
|
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
|
* Unstable non-standard Wasmer-specific API to get the module's
|
||||||
* name, otherwise `out->size` is set to `0` and `out->data` to
|
* 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);
|
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.
|
* Gets the length in bytes of the last error if any, zero otherwise.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user