mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-09 22:28:21 +00:00
chore(c-api) Formalize API prefixes.
The new rule is the following: * `wasm_` for the standard C API, * `wasmer_` or `wasi_` for the Wasmer non-standard C API. For all symbols inside the `unstable` module, the renaming `wasm_` to `wasmer_` is done without deprecations. It was clear that those API were unstable. For all the other symbols, symbols have been renamed to `wasmer_` but the old symbols have been kept with deprecation warnings. Special note: The `wasm_named_extern_t` type (and associated functions) was in `wasi` by mistake. Its place was in the `unstable` module. This patch also fixes that. The `wasm_declare_vec_*` macros have been updated to support a default prefix, or a user-defined prefix. It's now possible to write `wasm_declare_boxed_vec!(foo);` to get all the API prefixed by `wasm_` (as previously), or `wasm_declare_boxed_vec!(foo, wasmer);` to prefix with `wasmer_`. A user not using symbols from the `unstable` module will continue to get working code, modulo some deprecations, after this patch.
This commit is contained in:
@@ -4,15 +4,13 @@
|
||||
|
||||
mod capture_files;
|
||||
|
||||
pub use super::unstable::wasi::wasi_get_unordered_imports;
|
||||
use super::{
|
||||
externals::{wasm_extern_t, wasm_extern_vec_t, wasm_func_t, wasm_memory_t},
|
||||
instance::wasm_instance_t,
|
||||
module::wasm_module_t,
|
||||
store::wasm_store_t,
|
||||
types::wasm_name_t,
|
||||
};
|
||||
// required due to really weird Rust resolution rules for macros
|
||||
// https://github.com/rust-lang/rust/issues/57966
|
||||
use crate::error::{update_last_error, CApiError};
|
||||
use std::cmp::min;
|
||||
use std::convert::TryFrom;
|
||||
@@ -168,7 +166,7 @@ pub extern "C" fn wasi_config_inherit_stdin(config: &mut wasi_config_t) {
|
||||
#[allow(non_camel_case_types)]
|
||||
pub struct wasi_env_t {
|
||||
/// cbindgen:ignore
|
||||
inner: WasiEnv,
|
||||
pub(super) inner: WasiEnv,
|
||||
}
|
||||
|
||||
/// Create a new WASI environment.
|
||||
@@ -345,192 +343,6 @@ pub unsafe extern "C" fn wasi_get_wasi_version(module: &wasm_module_t) -> wasi_v
|
||||
.unwrap_or(wasi_version_t::INVALID_VERSION)
|
||||
}
|
||||
|
||||
/// Non-standard type wrapping `wasm_extern_t` with the addition of
|
||||
/// two `wasm_name_t` respectively for the module name and the name of
|
||||
/// the extern (very likely to be an import). This non-standard type
|
||||
/// is used by the non-standard `wasi_get_unordered_imports` function.
|
||||
///
|
||||
/// The `module`, `name` and `extern` fields are all owned by this type.
|
||||
#[allow(non_camel_case_types)]
|
||||
#[derive(Clone)]
|
||||
pub struct wasm_named_extern_t {
|
||||
module: Box<wasm_name_t>,
|
||||
name: Box<wasm_name_t>,
|
||||
r#extern: Box<wasm_extern_t>,
|
||||
}
|
||||
|
||||
wasm_declare_boxed_vec!(named_extern);
|
||||
|
||||
/// So. Let's explain a dirty hack. `cbindgen` reads the code and
|
||||
/// collects symbols. What symbols do we need? None of the one
|
||||
/// declared in `wasm.h`, but for non-standard API, we need to collect
|
||||
/// all of them. The problem is that `wasm_named_extern_t` is the only
|
||||
/// non-standard type where extra symbols are generated by a macro
|
||||
/// (`wasm_declare_boxed_vec!`). If we want those macro-generated
|
||||
/// symbols to be collected by `cbindgen`, we need to _expand_ the
|
||||
/// crate (i.e. running something like `rustc -- -Zunstable-options
|
||||
/// --pretty=expanded`). Expanding code is unstable and available only
|
||||
/// on nightly compiler. We _don't want_ to use a nightly compiler
|
||||
/// only for that. So how can we help `cbindgen` to _see_ those
|
||||
/// symbols?
|
||||
///
|
||||
/// First solution: We write the C code directly in a file, which is
|
||||
/// then included in the generated header file with the `cbindgen`
|
||||
/// API. Problem, it's super easy to get it outdated, and it makes the
|
||||
/// build process more complex.
|
||||
///
|
||||
/// Second solution: We write those symbols in a custom module, that
|
||||
/// is just here for `cbindgen`, never used by our Rust code
|
||||
/// (otherwise it's duplicated code), with no particular
|
||||
/// implementation.
|
||||
///
|
||||
/// And that's why we have the following `cbindgen_hack`
|
||||
/// module.
|
||||
///
|
||||
/// But this module must not be compiled by `rustc`. How to force
|
||||
/// `rustc` to ignore a module? With conditional compilation. Because
|
||||
/// `cbindgen` does not support conditional compilation, it will
|
||||
/// always _ignore_ the `#[cfg]` attribute, and will always read the
|
||||
/// content of the module.
|
||||
///
|
||||
/// Sorry.
|
||||
#[doc(hidden)]
|
||||
#[cfg(__cbindgen_hack__ = "yes")]
|
||||
mod __cbindgen_hack__ {
|
||||
use super::*;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct wasm_named_extern_vec_t {
|
||||
pub size: usize,
|
||||
pub data: *mut *mut wasm_named_extern_t,
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wasm_named_extern_vec_new(
|
||||
out: *mut wasm_named_extern_vec_t,
|
||||
length: usize,
|
||||
init: *const *mut wasm_named_extern_t,
|
||||
) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wasm_named_extern_vec_new_uninitialized(
|
||||
out: *mut wasm_named_extern_vec_t,
|
||||
length: usize,
|
||||
) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wasm_named_extern_vec_copy(
|
||||
out_ptr: &mut wasm_named_extern_vec_t,
|
||||
in_ptr: &wasm_named_extern_vec_t,
|
||||
) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wasm_named_extern_vec_delete(
|
||||
ptr: Option<&mut wasm_named_extern_vec_t>,
|
||||
) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wasm_named_extern_vec_new_empty(out: *mut wasm_named_extern_vec_t) {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
/// Non-standard function to get the module name of a
|
||||
/// `wasm_named_extern_t`.
|
||||
///
|
||||
/// The returned value isn't owned by the caller.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wasm_named_extern_module(
|
||||
named_extern: Option<&wasm_named_extern_t>,
|
||||
) -> Option<&wasm_name_t> {
|
||||
Some(named_extern?.module.as_ref())
|
||||
}
|
||||
|
||||
/// Non-standard function to get the name of a `wasm_named_extern_t`.
|
||||
///
|
||||
/// The returned value isn't owned by the caller.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wasm_named_extern_name(
|
||||
named_extern: Option<&wasm_named_extern_t>,
|
||||
) -> Option<&wasm_name_t> {
|
||||
Some(named_extern?.name.as_ref())
|
||||
}
|
||||
|
||||
/// Non-standard function to get the wrapped extern of a
|
||||
/// `wasm_named_extern_t`.
|
||||
///
|
||||
/// The returned value isn't owned by the caller.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wasm_named_extern_unwrap(
|
||||
named_extern: Option<&wasm_named_extern_t>,
|
||||
) -> Option<&wasm_extern_t> {
|
||||
Some(named_extern?.r#extern.as_ref())
|
||||
}
|
||||
|
||||
/// Non-standard function to get the imports needed for the WASI
|
||||
/// implementation with no particular order. Each import has its
|
||||
/// associated module name and name, so that it can be re-order later
|
||||
/// based on the `wasm_module_t` requirements.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wasi_get_unordered_imports(
|
||||
store: Option<&wasm_store_t>,
|
||||
module: Option<&wasm_module_t>,
|
||||
wasi_env: Option<&wasi_env_t>,
|
||||
imports: &mut wasm_named_extern_vec_t,
|
||||
) -> bool {
|
||||
wasi_get_unordered_imports_inner(store, module, wasi_env, imports).is_some()
|
||||
}
|
||||
|
||||
fn wasi_get_unordered_imports_inner(
|
||||
store: Option<&wasm_store_t>,
|
||||
module: Option<&wasm_module_t>,
|
||||
wasi_env: Option<&wasi_env_t>,
|
||||
imports: &mut wasm_named_extern_vec_t,
|
||||
) -> Option<()> {
|
||||
let store = store?;
|
||||
let module = module?;
|
||||
let wasi_env = wasi_env?;
|
||||
|
||||
let store = &store.inner;
|
||||
|
||||
let version = c_try!(
|
||||
get_wasi_version(&module.inner, false).ok_or_else(|| CApiError {
|
||||
msg: "could not detect a WASI version on the given module".to_string(),
|
||||
})
|
||||
);
|
||||
|
||||
let import_object = generate_import_object_from_env(store, wasi_env.inner.clone(), version);
|
||||
|
||||
*imports = import_object
|
||||
.into_iter()
|
||||
.map(|((module, name), export)| {
|
||||
let module = Box::new(module.into());
|
||||
let name = Box::new(name.into());
|
||||
let extern_inner = Extern::from_vm_export(store, export);
|
||||
|
||||
Box::new(wasm_named_extern_t {
|
||||
module,
|
||||
name,
|
||||
r#extern: Box::new(wasm_extern_t {
|
||||
instance: None,
|
||||
inner: extern_inner,
|
||||
}),
|
||||
})
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.into();
|
||||
|
||||
Some(())
|
||||
}
|
||||
|
||||
/// Non-standard function to get the imports needed for the WASI
|
||||
/// implementation ordered as expected by the `wasm_module_t`.
|
||||
#[no_mangle]
|
||||
@@ -617,7 +429,7 @@ mod tests {
|
||||
wasm_byte_vec_t wat;
|
||||
wasmer_byte_vec_new_from_string(&wat, "(module (import \"wasi_unstable\" \"args_get\" (func (param i32 i32) (result i32))))");
|
||||
wasm_byte_vec_t wasm;
|
||||
wat2wasm(&wat, &wasm);
|
||||
wasmer_wat2wasm(&wat, &wasm);
|
||||
|
||||
wasm_module_t* module = wasm_module_new(store, &wasm);
|
||||
assert(module);
|
||||
@@ -648,7 +460,7 @@ mod tests {
|
||||
wasm_byte_vec_t wat;
|
||||
wasmer_byte_vec_new_from_string(&wat, "(module (import \"wasi_snapshot_preview1\" \"args_get\" (func (param i32 i32) (result i32))))");
|
||||
wasm_byte_vec_t wasm;
|
||||
wat2wasm(&wat, &wasm);
|
||||
wasmer_wat2wasm(&wat, &wasm);
|
||||
|
||||
wasm_module_t* module = wasm_module_new(store, &wasm);
|
||||
assert(module);
|
||||
@@ -679,7 +491,7 @@ mod tests {
|
||||
wasm_byte_vec_t wat;
|
||||
wasmer_byte_vec_new_from_string(&wat, "(module (import \"wasi_snpsht_prvw1\" \"args_get\" (func (param i32 i32) (result i32))))");
|
||||
wasm_byte_vec_t wasm;
|
||||
wat2wasm(&wat, &wasm);
|
||||
wasmer_wat2wasm(&wat, &wasm);
|
||||
|
||||
wasm_module_t* module = wasm_module_new(store, &wasm);
|
||||
assert(module);
|
||||
|
||||
Reference in New Issue
Block a user