From 434285c0f9cd959dae4d5850e21aa9a99eeb65fc Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Tue, 26 Jan 2021 12:20:44 +0100 Subject: [PATCH 01/10] fix(c-api) Use uppercase enum variants for constants of `wasi_version_t`. --- lib/c-api/src/wasm_c_api/wasi/mod.rs | 24 ++++++++++++------------ lib/c-api/wasmer_wasm.h | 22 ++++++++++++++++++---- 2 files changed, 30 insertions(+), 16 deletions(-) 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 1ef66b35645..92b444554d8 100644 --- a/lib/c-api/src/wasm_c_api/wasi/mod.rs +++ b/lib/c-api/src/wasm_c_api/wasi/mod.rs @@ -268,18 +268,18 @@ fn read_inner(wasi_file: &mut Box, inner_buffer: &mut [u8]) -> isi #[repr(u32)] #[allow(non_camel_case_types)] pub enum wasi_version_t { - Latest = 0, - Snapshot0 = 1, - Snapshot1 = 2, - InvalidVersion = u32::max_value(), + LATEST = 0, + SNAPSHOT0 = 1, + SNAPSHOT1 = 2, + INVALID_VERSION = 4294967295, // u32::MAX, } 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, } } } @@ -289,10 +289,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::SNAPSHOT0 => WasiVersion::Snapshot0, + wasi_version_t::SNAPSHOT1 => WasiVersion::Snapshot1, + wasi_version_t::LATEST => WasiVersion::Latest, + wasi_version_t::INVALID_VERSION => return Err("Invalid WASI version cannot be used"), }) } } @@ -301,7 +301,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`. diff --git a/lib/c-api/wasmer_wasm.h b/lib/c-api/wasmer_wasm.h index c4debd5abfe..3b24b3744c8 100644 --- a/lib/c-api/wasmer_wasm.h +++ b/lib/c-api/wasmer_wasm.h @@ -62,6 +62,24 @@ #include #include "wasm.h" +#if defined(WASMER_WASI_ENABLED) +enum wasi_version_t { +#if defined(WASMER_WASI_ENABLED) + LATEST = 0, +#endif +#if defined(WASMER_WASI_ENABLED) + SNAPSHOT0 = 1, +#endif +#if defined(WASMER_WASI_ENABLED) + SNAPSHOT1 = 2, +#endif +#if defined(WASMER_WASI_ENABLED) + INVALID_VERSION = 4294967295, +#endif +}; +typedef uint32_t wasi_version_t; +#endif + #if defined(WASMER_COMPILER_ENABLED) /** * Kind of compilers that can be used by the engines. @@ -120,10 +138,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 - #if defined(WASMER_WASI_ENABLED) void wasi_config_arg(wasi_config_t *config, const char *arg); #endif From af2b8d5923ad550983e43d4eccfcd419216fff4b Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Tue, 26 Jan 2021 13:19:04 +0100 Subject: [PATCH 02/10] doc(c-api) Document `wasi_version_t`. --- lib/c-api/src/wasm_c_api/wasi/mod.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) 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 92b444554d8..77873a2e4a5 100644 --- a/lib/c-api/src/wasm_c_api/wasi/mod.rs +++ b/lib/c-api/src/wasm_c_api/wasi/mod.rs @@ -264,13 +264,31 @@ 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)] #[allow(non_camel_case_types)] pub enum wasi_version_t { + /// 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, + + /// An invalid version. It matches `u32` maximum value. INVALID_VERSION = 4294967295, // u32::MAX, } From 361ea40042ccf09240e6317e740207ccdb9d1a9b Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Tue, 26 Jan 2021 13:19:20 +0100 Subject: [PATCH 03/10] chore(c-api) Update headers. --- lib/c-api/wasmer_wasm.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/lib/c-api/wasmer_wasm.h b/lib/c-api/wasmer_wasm.h index 3b24b3744c8..a755c952445 100644 --- a/lib/c-api/wasmer_wasm.h +++ b/lib/c-api/wasmer_wasm.h @@ -63,17 +63,42 @@ #include "wasm.h" #if defined(WASMER_WASI_ENABLED) +/** + * The version of WASI. This is determined by the imports namespace + * string. + */ enum wasi_version_t { #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 #if defined(WASMER_WASI_ENABLED) + /** + * An invalid version. It matches `u32` maximum value. + */ INVALID_VERSION = 4294967295, #endif }; From c576eb000f91a7f9d85116a8eb2a096dcb114e95 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Tue, 26 Jan 2021 13:19:31 +0100 Subject: [PATCH 04/10] chore(wasi) Fix coding style. --- lib/wasi/src/utils.rs | 1 + 1 file changed, 1 insertion(+) 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, From 343e0ae241cacfe5ccfbbe24c77207ad412a5d56 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Tue, 26 Jan 2021 13:20:24 +0100 Subject: [PATCH 05/10] doc(changelog) Add #2058. --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4ca60668f9..a03ffacb76f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,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) `wasm_version_t` wasn't bound correctly to C. - [#2044](https://github.com/wasmerio/wasmer/pull/2044) Do not build C headers on docs.rs. ## 1.0.1 - 2021-01-12 From 276537a00f1da60cd1cab84fc5b4992817a9179d Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Wed, 27 Jan 2021 11:27:22 +0100 Subject: [PATCH 06/10] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a03ffacb76f..35a4b107056 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,7 +16,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) `wasm_version_t` wasn't bound correctly to C. +- [#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 From c03d61b78a1a0bbd5f542cf1235e88b6a639ee6a Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Thu, 28 Jan 2021 09:11:50 +0100 Subject: [PATCH 07/10] test(c-api) Simplify `wat2wasm` test cases. --- lib/c-api/src/wasm_c_api/wat.rs | 10 ---------- 1 file changed, 10 deletions(-) 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; } From 7a435ef740b4c31e8662261b1ad67e43d2f8d0ad Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Thu, 28 Jan 2021 09:12:10 +0100 Subject: [PATCH 08/10] feat(c-api) `wasi_version_t` has a C representation now. On Windows, using a `u32` representation for `wasi_version_t` fails if a C++ compiler is used to treat a C program. So we change our strategy here. We use a C representation to be FFI-safe, and the `INVALID_VERSION` variant is now set to -1 instead of `u32::MAX`. This patch also adds unit tests for `wasi_get_wasi_version` so that we are sure of the behavior of this `type` on all platforms. --- lib/c-api/src/wasm_c_api/wasi/mod.rs | 108 +++++++++++++++++++++++++-- 1 file changed, 103 insertions(+), 5 deletions(-) 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 77873a2e4a5..8776315fa46 100644 --- a/lib/c-api/src/wasm_c_api/wasi/mod.rs +++ b/lib/c-api/src/wasm_c_api/wasi/mod.rs @@ -267,9 +267,12 @@ 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 { + /// An invalid version. + INVALID_VERSION = -1, + /// Latest version. /// /// It's a “floating” version, i.e. it's an alias to the latest @@ -287,9 +290,6 @@ pub enum wasi_version_t { /// `wasi_snapshot_preview1`. SNAPSHOT1 = 2, - - /// An invalid version. It matches `u32` maximum value. - INVALID_VERSION = 4294967295, // u32::MAX, } impl From for wasi_version_t { @@ -307,10 +307,10 @@ impl TryFrom for WasiVersion { fn try_from(other: wasi_version_t) -> Result { Ok(match other { + 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, - wasi_version_t::INVALID_VERSION => return Err("Invalid WASI version cannot be used"), }) } } @@ -392,3 +392,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(); + } +} From af5052598a0419ed7f20cf8c4194df8018b799ce Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Thu, 28 Jan 2021 09:15:25 +0100 Subject: [PATCH 09/10] chore(c-api) Update headers. --- lib/c-api/wasmer_wasm.h | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/lib/c-api/wasmer_wasm.h b/lib/c-api/wasmer_wasm.h index a755c952445..fb2d84d10d0 100644 --- a/lib/c-api/wasmer_wasm.h +++ b/lib/c-api/wasmer_wasm.h @@ -67,7 +67,13 @@ * The version of WASI. This is determined by the imports namespace * string. */ -enum wasi_version_t { +typedef enum { +#if defined(WASMER_WASI_ENABLED) + /** + * An invalid version. + */ + INVALID_VERSION = -1, +#endif #if defined(WASMER_WASI_ENABLED) /** * Latest version. @@ -95,14 +101,7 @@ enum wasi_version_t { */ SNAPSHOT1 = 2, #endif -#if defined(WASMER_WASI_ENABLED) - /** - * An invalid version. It matches `u32` maximum value. - */ - INVALID_VERSION = 4294967295, -#endif -}; -typedef uint32_t wasi_version_t; +} wasi_version_t; #endif #if defined(WASMER_COMPILER_ENABLED) From ca7fc908b5372f07fae61e8405698f8a3240c189 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Thu, 28 Jan 2021 09:23:56 +0100 Subject: [PATCH 10/10] chore(c-api) Update headers. --- lib/c-api/wasmer_wasm.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/c-api/wasmer_wasm.h b/lib/c-api/wasmer_wasm.h index d6aa8ef20c3..a6ee053e402 100644 --- a/lib/c-api/wasmer_wasm.h +++ b/lib/c-api/wasmer_wasm.h @@ -162,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