diff --git a/CHANGELOG.md b/CHANGELOG.md index 06af7a1a893..44fad8cf589 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ - [#2056](https://github.com/wasmerio/wasmer/pull/2056) Change back to depend on the `enumset` crate instead of `wasmer_enumset` ### Fixed +- [#2058](https://github.com/wasmerio/wasmer/pull/2058) Expose WASI versions to C correctly. - [#2044](https://github.com/wasmerio/wasmer/pull/2044) Do not build C headers on docs.rs. ## 1.0.1 - 2021-01-12 diff --git a/lib/c-api/src/wasm_c_api/wasi/mod.rs b/lib/c-api/src/wasm_c_api/wasi/mod.rs index 67e217fc97d..a9b83842ef3 100644 --- a/lib/c-api/src/wasm_c_api/wasi/mod.rs +++ b/lib/c-api/src/wasm_c_api/wasi/mod.rs @@ -286,22 +286,40 @@ fn read_inner(wasi_file: &mut Box, inner_buffer: &mut [u8]) -> isi } } +/// The version of WASI. This is determined by the imports namespace +/// string. #[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[repr(u32)] +#[repr(C)] #[allow(non_camel_case_types)] pub enum wasi_version_t { - Latest = 0, - Snapshot0 = 1, - Snapshot1 = 2, - InvalidVersion = u32::max_value(), + /// An invalid version. + INVALID_VERSION = -1, + + /// Latest version. + /// + /// It's a “floating” version, i.e. it's an alias to the latest + /// version (for the moment, `Snapshot1`). Using this version is a + /// way to ensure that modules will run only if they come with the + /// latest WASI version (in case of security issues for instance), + /// by just updating the runtime. + /// + /// Note that this version is never returned by an API. It is + /// provided only by the user. + LATEST = 0, + + /// `wasi_unstable`. + SNAPSHOT0 = 1, + + /// `wasi_snapshot_preview1`. + SNAPSHOT1 = 2, } impl From for wasi_version_t { fn from(other: WasiVersion) -> Self { match other { - WasiVersion::Snapshot0 => wasi_version_t::Snapshot0, - WasiVersion::Snapshot1 => wasi_version_t::Snapshot1, - WasiVersion::Latest => wasi_version_t::Latest, + WasiVersion::Snapshot0 => wasi_version_t::SNAPSHOT0, + WasiVersion::Snapshot1 => wasi_version_t::SNAPSHOT1, + WasiVersion::Latest => wasi_version_t::LATEST, } } } @@ -311,10 +329,10 @@ impl TryFrom for WasiVersion { fn try_from(other: wasi_version_t) -> Result { Ok(match other { - wasi_version_t::Snapshot0 => WasiVersion::Snapshot0, - wasi_version_t::Snapshot1 => WasiVersion::Snapshot1, - wasi_version_t::Latest => WasiVersion::Latest, - wasi_version_t::InvalidVersion => return Err("Invalid WASI version cannot be used"), + wasi_version_t::INVALID_VERSION => return Err("Invalid WASI version cannot be used"), + wasi_version_t::SNAPSHOT0 => WasiVersion::Snapshot0, + wasi_version_t::SNAPSHOT1 => WasiVersion::Snapshot1, + wasi_version_t::LATEST => WasiVersion::Latest, }) } } @@ -323,7 +341,7 @@ impl TryFrom for WasiVersion { pub unsafe extern "C" fn wasi_get_wasi_version(module: &wasm_module_t) -> wasi_version_t { get_wasi_version(&module.inner, false) .map(Into::into) - .unwrap_or(wasi_version_t::InvalidVersion) + .unwrap_or(wasi_version_t::INVALID_VERSION) } /// Takes ownership of `wasi_env_t`. @@ -396,3 +414,101 @@ pub unsafe extern "C" fn wasi_get_start_function( /// cbindgen:ignore #[no_mangle] pub unsafe extern "C" fn wasm_extern_delete(_item: Option>) {} + +#[cfg(test)] +mod tests { + use inline_c::assert_c; + + #[test] + fn test_wasi_get_wasi_version_snapshot0() { + (assert_c! { + #include "tests/wasmer_wasm.h" + + int main() { + wasm_engine_t* engine = wasm_engine_new(); + wasm_store_t* store = wasm_store_new(engine); + + 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); + + wasm_module_t* module = wasm_module_new(store, &wasm); + assert(module); + + assert(wasi_get_wasi_version(module) == SNAPSHOT0); + + wasm_module_delete(module); + wasm_byte_vec_delete(&wasm); + wasm_byte_vec_delete(&wat); + wasm_store_delete(store); + wasm_engine_delete(engine); + + return 0; + } + }) + .success(); + } + + #[test] + fn test_wasi_get_wasi_version_snapshot1() { + (assert_c! { + #include "tests/wasmer_wasm.h" + + int main() { + wasm_engine_t* engine = wasm_engine_new(); + wasm_store_t* store = wasm_store_new(engine); + + 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); + + wasm_module_t* module = wasm_module_new(store, &wasm); + assert(module); + + assert(wasi_get_wasi_version(module) == SNAPSHOT1); + + wasm_module_delete(module); + wasm_byte_vec_delete(&wasm); + wasm_byte_vec_delete(&wat); + wasm_store_delete(store); + wasm_engine_delete(engine); + + return 0; + } + }) + .success(); + } + + #[test] + fn test_wasi_get_wasi_version_invalid() { + (assert_c! { + #include "tests/wasmer_wasm.h" + + int main() { + wasm_engine_t* engine = wasm_engine_new(); + wasm_store_t* store = wasm_store_new(engine); + + 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); + + wasm_module_t* module = wasm_module_new(store, &wasm); + assert(module); + + assert(wasi_get_wasi_version(module) == INVALID_VERSION); + + wasm_module_delete(module); + wasm_byte_vec_delete(&wasm); + wasm_byte_vec_delete(&wat); + wasm_store_delete(store); + wasm_engine_delete(engine); + + return 0; + } + }) + .success(); + } +} diff --git a/lib/c-api/src/wasm_c_api/wat.rs b/lib/c-api/src/wasm_c_api/wat.rs index a0219016f69..07d634b883e 100644 --- a/lib/c-api/src/wasm_c_api/wat.rs +++ b/lib/c-api/src/wasm_c_api/wat.rs @@ -42,9 +42,6 @@ mod tests { #include "tests/wasmer_wasm.h" int main() { - wasm_engine_t* engine = wasm_engine_new(); - wasm_store_t* store = wasm_store_new(engine); - wasm_byte_vec_t wat; wasmer_byte_vec_new_from_string(&wat, "(module)"); wasm_byte_vec_t wasm; @@ -65,8 +62,6 @@ mod tests { wasm_byte_vec_delete(&wasm); wasm_byte_vec_delete(&wat); - wasm_store_delete(store); - wasm_engine_delete(engine); return 0; } @@ -80,9 +75,6 @@ mod tests { #include "tests/wasmer_wasm.h" int main() { - wasm_engine_t* engine = wasm_engine_new(); - wasm_store_t* store = wasm_store_new(engine); - wasm_byte_vec_t wat; wasmer_byte_vec_new_from_string(&wat, "(module"); wasm_byte_vec_t wasm; @@ -92,8 +84,6 @@ mod tests { assert(wasmer_last_error_length() > 0); wasm_byte_vec_delete(&wat); - wasm_store_delete(store); - wasm_engine_delete(engine); return 0; } diff --git a/lib/c-api/wasmer_wasm.h b/lib/c-api/wasmer_wasm.h index a60e261e305..a6ee053e402 100644 --- a/lib/c-api/wasmer_wasm.h +++ b/lib/c-api/wasmer_wasm.h @@ -62,6 +62,48 @@ #include #include "wasm.h" +#if defined(WASMER_WASI_ENABLED) +/** + * The version of WASI. This is determined by the imports namespace + * string. + */ +typedef enum { +#if defined(WASMER_WASI_ENABLED) + /** + * An invalid version. + */ + INVALID_VERSION = -1, +#endif +#if defined(WASMER_WASI_ENABLED) + /** + * Latest version. + * + * It's a “floating” version, i.e. it's an alias to the latest + * version (for the moment, `Snapshot1`). Using this version is a + * way to ensure that modules will run only if they come with the + * latest WASI version (in case of security issues for instance), + * by just updating the runtime. + * + * Note that this version is never returned by an API. It is + * provided only by the user. + */ + LATEST = 0, +#endif +#if defined(WASMER_WASI_ENABLED) + /** + * `wasi_unstable`. + */ + SNAPSHOT0 = 1, +#endif +#if defined(WASMER_WASI_ENABLED) + /** + * `wasi_snapshot_preview1`. + */ + SNAPSHOT1 = 2, +#endif +} wasi_version_t; +#endif + #if defined(WASMER_COMPILER_ENABLED) /** * Kind of compilers that can be used by the engines. @@ -120,10 +162,6 @@ typedef struct wasi_config_t wasi_config_t; typedef struct wasi_env_t wasi_env_t; #endif -#if defined(WASMER_WASI_ENABLED) -typedef struct wasi_version_t wasi_version_t; -#endif - #ifdef __cplusplus extern "C" { #endif // __cplusplus diff --git a/lib/wasi/src/utils.rs b/lib/wasi/src/utils.rs index bba0a3a2745..b5b088484d3 100644 --- a/lib/wasi/src/utils.rs +++ b/lib/wasi/src/utils.rs @@ -13,6 +13,7 @@ pub fn is_wasi_module(module: &Module) -> bool { pub enum WasiVersion { /// `wasi_unstable`. Snapshot0, + /// `wasi_snapshot_preview1`. Snapshot1,