From 3ecd71940fe5f273afc502ca6fcdc44700cc398d Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 1 Feb 2021 11:48:55 +0100 Subject: [PATCH 01/29] doc(c-api) Remove auto-doc from `wasmer_wasm.h`. --- lib/c-api/build.rs | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/lib/c-api/build.rs b/lib/c-api/build.rs index 6fcc41b6456..1f6fab7c10b 100644 --- a/lib/c-api/build.rs +++ b/lib/c-api/build.rs @@ -184,10 +184,12 @@ fn build_wasmer_c_api_headers(crate_dir: &str, out_dir: &str) { out_header_file.set_extension("h"); // Build and generate the header file. - exclude_items_from_wasm_c_api(new_builder(Language::C, crate_dir, guard, &pre_header)) - .generate() - .expect("Unable to generate C bindings") - .write_to_file(out_header_file.as_path()); + exclude_items_from_wasm_c_api( + new_builder(Language::C, crate_dir, guard, &pre_header).with_documentation(true), + ) + .generate() + .expect("Unable to generate C bindings") + .write_to_file(out_header_file.as_path()); // Copy the generated bindings from `OUT_DIR` to // `CARGO_MANIFEST_DIR`. @@ -203,10 +205,12 @@ fn build_wasmer_c_api_headers(crate_dir: &str, out_dir: &str) { out_header_file.set_extension("hh"); // Build and generate the header file. - exclude_items_from_wasm_c_api(new_builder(Language::Cxx, crate_dir, guard, &pre_header)) - .generate() - .expect("Unable to generate C++ bindings") - .write_to_file(out_header_file.as_path()); + exclude_items_from_wasm_c_api( + new_builder(Language::Cxx, crate_dir, guard, &pre_header).with_documentation(true), + ) + .generate() + .expect("Unable to generate C++ bindings") + .write_to_file(out_header_file.as_path()); // Copy the generated bindings from `OUT_DIR` to // `CARGO_MANIFEST_DIR`. @@ -247,7 +251,7 @@ fn new_builder(language: Language, crate_dir: &str, include_guard: &str, header: .with_crate(crate_dir) .with_include_guard(include_guard) .with_header(header) - .with_documentation(true) + .with_documentation(false) .with_define("target_family", "windows", "_WIN32") .with_define("target_arch", "x86_64", "ARCH_X86_64") .with_define("feature", "jit", JIT_FEATURE_AS_C_DEFINE) From c1092864e190029c4f9038697911168c648480f2 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 1 Feb 2021 11:49:03 +0100 Subject: [PATCH 02/29] doc(c-api) Improve `wasmer_wasm.h` intro to explain stability and documentation. --- lib/c-api/build.rs | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/lib/c-api/build.rs b/lib/c-api/build.rs index 1f6fab7c10b..8212c3bfb37 100644 --- a/lib/c-api/build.rs +++ b/lib/c-api/build.rs @@ -89,8 +89,41 @@ fn build_wasm_c_api_headers(crate_dir: &str, out_dir: &str) { out_header_file.push("wasmer_wasm"); let mut pre_header = format!( - r#"// The Wasmer C/C++ header file compatible with the `wasm-c-api` standard API. -// This file is generated by lib/c-api/build.rs. + r#"// The Wasmer C/C++ header file compatible with the [`wasm-c-api`] +// standard API, as `wasm.h` (included here). +// +// This file is automatically generated by `lib/c-api/build.rs` of the +// [`wasmer-c-api`] Rust crate. +// +// # Stability +// +// The [`wasm-c-api`] standard API is a _living_ standard. There is no +// commitment for stability yet. We (Wasmer) will try our best to keep +// backward compatibility as much as possible. Nonetheless, some +// necessary API aren't yet standardized, and as such, we provide a +// custom API, e.g. `wasi_*` types and functions. +// +// The documentation makes it clear whether a function is unstable. +// +// When a type or a function will be deprecated, it will be marked as +// such with the appropriated compiler warning, and will be removed at +// the next release round. +// +// # Documentation +// +// At the time of writing, the [`wasm-c-api`] standard has no +// documentation. This file also does not include inline +// documentation. However, we have made (and we continue to make) an +// important effort to document everything. [See the documentation +// online][documentation]. Please refer to this page for the real +// canonical documentation. It also contains numerous examples. +// +// To generate the documentation locally, run `cargo doc --open` from +// within the [`wasmer-c-api`] Rust crate. +// +// [`wasm-c-api`]: https://github.com/WebAssembly/wasm-c-api +// [`wasmer-c-api`]: https://github.com/wasmerio/wasmer/tree/master/lib/c-api +// [documentation]: https://wasmerio.github.io/wasmer/crates/wasmer_c_api/ #if !defined(WASMER_WASM_H_PRELUDE) From cbc8b4a77322133b7a1f27b4222b1552a6e89f61 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 1 Feb 2021 11:50:11 +0100 Subject: [PATCH 03/29] chore(c-api) Update headers. --- lib/c-api/wasmer_wasm.h | 437 ++++------------------------------------ 1 file changed, 35 insertions(+), 402 deletions(-) diff --git a/lib/c-api/wasmer_wasm.h b/lib/c-api/wasmer_wasm.h index d3ae2b7636c..e0e2772d7ff 100644 --- a/lib/c-api/wasmer_wasm.h +++ b/lib/c-api/wasmer_wasm.h @@ -1,5 +1,38 @@ -// The Wasmer C/C++ header file compatible with the `wasm-c-api` standard API. -// This file is generated by lib/c-api/build.rs. +// The Wasmer C/C++ header file compatible with the [`wasm-c-api`] +// standard API, as `wasm.h` (included here). +// +// This file is automatically generated by `lib/c-api/build.rs` of the +// [`wasmer-c-api`] Rust crate. +// +// # Stability +// +// The [`wasm-c-api`] standard API is a _living_ standard. There is no +// commitment for stability yet. We (Wasmer) will try our best to keep +// backward compatibility as much as possible. Nonetheless, some +// necessary API aren't yet standardized, and as such, we provide a +// custom API, e.g. `wasi_*` types and functions. +// +// The documentation makes it clear whether a function is unstable. +// +// When a type or a function will be deprecated, it will be marked as +// such with the appropriated compiler warning, and will be removed at +// the next release round. +// +// # Documentation +// +// At the time of writing, the [`wasm-c-api`] standard has no +// documentation. This file also does not include inline +// documentation. However, we have made (and we continue to make) an +// important effort to document everything. [See the documentation +// online][documentation]. Please refer to this page for the real +// canonical documentation. It also contains numerous examples. +// +// To generate the documentation locally, run `cargo doc --open` from +// within the [`wasmer-c-api`] Rust crate. +// +// [`wasm-c-api`]: https://github.com/WebAssembly/wasm-c-api +// [`wasmer-c-api`]: https://github.com/wasmerio/wasmer/tree/master/lib/c-api +// [documentation]: https://wasmerio.github.io/wasmer/crates/wasmer_c_api/ #if !defined(WASMER_WASM_H_PRELUDE) @@ -63,94 +96,33 @@ #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. - * - * This is a Wasmer-specific type with Wasmer-specific functions for - * manipulating it. - */ typedef enum { - /** - * Variant to represent the Cranelift compiler. See the - * [`wasmer_compiler_cranelift`] Rust crate. - */ CRANELIFT = 0, - /** - * Variant to represent the LLVM compiler. See the - * [`wasmer_compiler_llvm`] Rust crate. - */ LLVM = 1, - /** - * Variant to represent the Singlepass compiler. See the - * [`wasmer_compiler_singlepass`] Rust crate. - */ SINGLEPASS = 2, } wasmer_compiler_t; #endif -/** - * Kind of engines that can be used by the store. - * - * This is a Wasmer-specific type with Wasmer-specific functions for - * manipulating it. - */ typedef enum { - /** - * Variant to represent the JIT engine. See the - * [`wasmer_engine_jit`] Rust crate. - */ JIT = 0, - /** - * Variant to represent the Native engine. See the - * [`wasmer_engine_native`] Rust crate. - */ NATIVE = 1, - /** - * Variant to represent the Object File engine. See the - * [`wasmer_engine_object_file`] Rust crate. - */ OBJECT_FILE = 2, } wasmer_engine_t; @@ -211,9 +183,6 @@ void wasi_env_delete(wasi_env_t *_state); #endif #if defined(WASMER_WASI_ENABLED) -/** - * Takes ownership over the `wasi_config_t`. - */ wasi_env_t *wasi_env_new(wasi_config_t *config); #endif @@ -226,25 +195,14 @@ intptr_t wasi_env_read_stdout(wasi_env_t *env, char *buffer, uintptr_t buffer_le #endif #if defined(WASMER_WASI_ENABLED) -/** - * This function is deprecated. You may safely remove all calls to it and everything - * will continue to work. - */ bool wasi_env_set_instance(wasi_env_t *env, const wasm_instance_t *instance); #endif #if defined(WASMER_WASI_ENABLED) -/** - * This function is deprecated. You may safely remove all calls to it and everything - * will continue to work. - */ void wasi_env_set_memory(wasi_env_t *env, const wasm_memory_t *memory); #endif #if defined(WASMER_WASI_ENABLED) -/** - * Takes ownership of `wasi_env_t`. - */ bool wasi_get_imports(const wasm_store_t *store, const wasm_module_t *module, const wasi_env_t *wasi_env, @@ -260,354 +218,29 @@ wasi_version_t wasi_get_wasi_version(const wasm_module_t *module); #endif #if defined(WASMER_COMPILER_ENABLED) -/** - * Updates the configuration to specify a particular compiler to use. - * - * This is a Wasmer-specific function. - * - * # Example - * - * ```rust,no_run - * # use inline_c::assert_c; - * # fn main() { - * # (assert_c! { - * # #include "tests/wasmer_wasm.h" - * # - * int main() { - * // Create the configuration. - * wasm_config_t* config = wasm_config_new(); - * - * // Use the Cranelift compiler. - * wasm_config_set_compiler(config, CRANELIFT); - * - * // Create the engine. - * wasm_engine_t* engine = wasm_engine_new_with_config(config); - * - * // Check we have an engine! - * assert(engine); - * - * // Free everything. - * wasm_engine_delete(engine); - * - * return 0; - * } - * # }) - * # .success(); - * # } - * ``` - */ void wasm_config_set_compiler(wasm_config_t *config, wasmer_compiler_t compiler); #endif -/** - * Updates the configuration to specify a particular engine to use. - * - * This is a Wasmer-specific function. - * - * # Example - * - * ```rust,no_run - * # use inline_c::assert_c; - * # fn main() { - * # (assert_c! { - * # #include "tests/wasmer_wasm.h" - * # - * int main() { - * // Create the configuration. - * wasm_config_t* config = wasm_config_new(); - * - * // Use the JIT engine. - * wasm_config_set_engine(config, JIT); - * - * // Create the engine. - * wasm_engine_t* engine = wasm_engine_new_with_config(config); - * - * // Check we have an engine! - * assert(engine); - * - * // Free everything. - * wasm_engine_delete(engine); - * - * return 0; - * } - * # }) - * # .success(); - * # } - * ``` - */ void wasm_config_set_engine(wasm_config_t *config, wasmer_engine_t engine); -/** - * Unstable non-standard Wasmer-specific API to get the module's - * name, otherwise `out->size` is set to `0` and `out->data` to - * `NULL`. - * - * # Example - * - * ```rust - * # use inline_c::assert_c; - * # fn main() { - * # (assert_c! { - * # #include "tests/wasmer_wasm.h" - * # - * int main() { - * // Create the engine and the store. - * wasm_engine_t* engine = wasm_engine_new(); - * wasm_store_t* store = wasm_store_new(engine); - * - * // Create a WebAssembly module from a WAT definition. - * wasm_byte_vec_t wat; - * wasmer_byte_vec_new_from_string(&wat, "(module $moduleName)"); - * // ^~~~~~~~~~~ that's the name! - * wasm_byte_vec_t wasm; - * wat2wasm(&wat, &wasm); - * - * // Create the module. - * wasm_module_t* module = wasm_module_new(store, &wasm); - * - * // Read the module's name. - * wasm_name_t name; - * wasm_module_name(module, &name); - * - * // It works! - * wasmer_assert_name(&name, "moduleName"); - * - * // Free everything. - * wasm_byte_vec_delete(&name); - * 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(); - * # } - * ``` - */ void wasm_module_name(const wasm_module_t *module, wasm_name_t *out); -/** - * Unstable non-standard Wasmer-specific API to set the module's - * name. The function returns `true` if the name has been updated, - * `false` otherwise. - * - * # Example - * - * ```rust - * # use inline_c::assert_c; - * # fn main() { - * # (assert_c! { - * # #include "tests/wasmer_wasm.h" - * # - * int main() { - * // Create the engine and the store. - * wasm_engine_t* engine = wasm_engine_new(); - * wasm_store_t* store = wasm_store_new(engine); - * - * // Create a WebAssembly module from a WAT definition. - * wasm_byte_vec_t wat; - * wasmer_byte_vec_new_from_string(&wat, "(module)"); - * wasm_byte_vec_t wasm; - * wat2wasm(&wat, &wasm); - * - * // Create the module. - * wasm_module_t* module = wasm_module_new(store, &wasm); - * - * // Read the module's name. There is none for the moment. - * { - * wasm_name_t name; - * wasm_module_name(module, &name); - * - * assert(name.size == 0); - * } - * - * // So, let's set a new name. - * { - * wasm_name_t name; - * wasmer_byte_vec_new_from_string(&name, "hello"); - * wasm_module_set_name(module, &name); - * } - * - * // And now, let's see the new name. - * { - * wasm_name_t name; - * wasm_module_name(module, &name); - * - * // It works! - * wasmer_assert_name(&name, "hello"); - * - * wasm_byte_vec_delete(&name); - * } - * - * // Free everything. - * 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(); - * # } - * ``` - */ bool wasm_module_set_name(wasm_module_t *module, const wasm_name_t *name); -/** - * Gets the length in bytes of the last error if any, zero otherwise. - * - * This can be used to dynamically allocate a buffer with the correct number of - * bytes needed to store a message. - * - * # Example - * - * See this module's documentation to get a complete example. - */ int wasmer_last_error_length(void); -/** - * Gets the last error message if any into the provided buffer - * `buffer` up to the given `length`. - * - * The `length` parameter must be large enough to store the last - * error message. Ideally, the value should come from - * [`wasmer_last_error_length`]. - * - * The function returns the length of the string in bytes, `-1` if an - * error occurs. Potential errors are: - * - * * The `buffer` is a null pointer, - * * The `buffer` is too small to hold the error message. - * - * Note: The error message always has a trailing NUL character. - * - * Important note: If the provided `buffer` is non-null, once this - * function has been called, regardless whether it fails or succeeds, - * the error is cleared. - * - * # Example - * - * See this module's documentation to get a complete example. - */ int wasmer_last_error_message(char *buffer, int length); -/** - * Get the version of the Wasmer C API. - * - * The `.h` files already define variables like `WASMER_VERSION*`, - * but if this file is unreachable, one can use this function to - * retrieve the full semver version of the Wasmer C API. - * - * The returned string is statically allocated. It must _not_ be - * freed! - * - * # Example - * - * See the module's documentation. - */ const char *wasmer_version(void); -/** - * Get the major version of the Wasmer C API. - * - * See [`wasmer_version`] to learn more. - * - * # Example - * - * ```rust - * # use inline_c::assert_c; - * # fn main() { - * # (assert_c! { - * # #include "tests/wasmer_wasm.h" - * # - * int main() { - * // Get and print the version components. - * uint8_t version_major = wasmer_version_major(); - * uint8_t version_minor = wasmer_version_minor(); - * uint8_t version_patch = wasmer_version_patch(); - * - * printf("%d.%d.%d", version_major, version_minor, version_patch); - * - * return 0; - * } - * # }) - * # .success() - * # .stdout( - * # format!( - * # "{}.{}.{}", - * # env!("CARGO_PKG_VERSION_MAJOR"), - * # env!("CARGO_PKG_VERSION_MINOR"), - * # env!("CARGO_PKG_VERSION_PATCH") - * # ) - * # ); - * # } - * ``` - */ uint8_t wasmer_version_major(void); -/** - * Get the minor version of the Wasmer C API. - * - * See [`wasmer_version_major`] to learn more and get an example. - */ uint8_t wasmer_version_minor(void); -/** - * Get the patch version of the Wasmer C API. - * - * See [`wasmer_version_major`] to learn more and get an example. - */ uint8_t wasmer_version_patch(void); -/** - * Get the minor version of the Wasmer C API. - * - * See [`wasmer_version_major`] to learn more. - * - * The returned string is statically allocated. It must _not_ be - * freed! - * - * # Example - * - * ```rust - * # use inline_c::assert_c; - * # fn main() { - * # (assert_c! { - * # #include "tests/wasmer_wasm.h" - * # - * int main() { - * // Get and print the pre version. - * const char* version_pre = wasmer_version_pre(); - * printf("%s", version_pre); - * - * // No need to free the string. It's statically allocated on - * // the Rust side. - * - * return 0; - * } - * # }) - * # .success() - * # .stdout(env!("CARGO_PKG_VERSION_PRE")); - * # } - * ``` - */ const char *wasmer_version_pre(void); -/** - * Parses in-memory bytes as either the WAT format, or a binary Wasm - * module. This is wasmer-specific. - * - * In case of failure, `wat2wasm` sets the `out->data = NULL` and `out->size = 0`. - * - * # Example - * - * See the module's documentation. - */ void wat2wasm(const wasm_byte_vec_t *wat, wasm_byte_vec_t *out); #ifdef __cplusplus From 277d85c5ae4469dc36fb545a9c2e66d4231029a7 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 1 Feb 2021 11:55:38 +0100 Subject: [PATCH 04/29] fix(c-api) Mark `wasi_env_set_(instance|memory)` as deprecated. --- lib/c-api/src/wasm_c_api/wasi/mod.rs | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 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 bb85dc16cc6..cd288db4e30 100644 --- a/lib/c-api/src/wasm_c_api/wasi/mod.rs +++ b/lib/c-api/src/wasm_c_api/wasi/mod.rs @@ -199,30 +199,22 @@ pub extern "C" fn wasi_env_delete(_state: Option>) {} /// This function is deprecated. You may safely remove all calls to it and everything /// will continue to work. -// Dead code: deprecate or remove -#[allow(unused_variables)] +/// +/// cbindgen:prefix=DEPRECATED("This function is longer necessary. You may safely remove all calls to it and everything will continue to work.") #[no_mangle] -pub extern "C" fn wasi_env_set_instance(env: &mut wasi_env_t, instance: &wasm_instance_t) -> bool { - /* - let memory = if let Ok(memory) = instance.inner.exports.get_memory("memory") { - memory - } else { - return false; - }; - env.inner.set_memory(memory.clone()); - */ - +pub extern "C" fn wasi_env_set_instance( + _env: &mut wasi_env_t, + _instance: &wasm_instance_t, +) -> bool { true } /// This function is deprecated. You may safely remove all calls to it and everything /// will continue to work. -// Dead code: deprecate or remove -#[allow(unused_variables)] +/// +/// cbindgen:prefix=DEPRECATED("This function is no longer necessary. You may safely remove all calls to it and everything will continue to work.") #[no_mangle] -pub extern "C" fn wasi_env_set_memory(env: &mut wasi_env_t, memory: &wasm_memory_t) { - //env.inner.set_memory(memory.inner.clone()); -} +pub extern "C" fn wasi_env_set_memory(_env: &mut wasi_env_t, _memory: &wasm_memory_t) {} #[no_mangle] pub unsafe extern "C" fn wasi_env_read_stdout( From a6ce35b82408eef80b9500c35f4ef5b27e545b46 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 1 Feb 2021 11:55:46 +0100 Subject: [PATCH 05/29] chore(c-api) Update headers. --- lib/c-api/wasmer_wasm.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/c-api/wasmer_wasm.h b/lib/c-api/wasmer_wasm.h index e0e2772d7ff..a53fddbae39 100644 --- a/lib/c-api/wasmer_wasm.h +++ b/lib/c-api/wasmer_wasm.h @@ -195,11 +195,15 @@ intptr_t wasi_env_read_stdout(wasi_env_t *env, char *buffer, uintptr_t buffer_le #endif #if defined(WASMER_WASI_ENABLED) -bool wasi_env_set_instance(wasi_env_t *env, const wasm_instance_t *instance); +DEPRECATED("This function is longer necessary. You may safely remove all calls to it and everything will continue to work.") +bool wasi_env_set_instance(wasi_env_t *_env, + const wasm_instance_t *_instance); #endif #if defined(WASMER_WASI_ENABLED) -void wasi_env_set_memory(wasi_env_t *env, const wasm_memory_t *memory); +DEPRECATED("This function is no longer necessary. You may safely remove all calls to it and everything will continue to work.") +void wasi_env_set_memory(wasi_env_t *_env, + const wasm_memory_t *_memory); #endif #if defined(WASMER_WASI_ENABLED) From a5d6ec0f99db95d0b242f1dd0dac6b7f7bd7ff8e Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 1 Feb 2021 11:57:41 +0100 Subject: [PATCH 06/29] doc(changelog) Add #2083. --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff38fecb0b9..26083c934ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ - [#2054](https://github.com/wasmerio/wasmer/pull/2054) Add `wasm_config_delete` to the Wasm C API. ### Changed +- [#2083](https://github.com/wasmerio/wasmer/pull/2083) Mark `wasi_env_set_(instance|memory)` as deprecated. You may simply remove them with no side-effect. - [#2056](https://github.com/wasmerio/wasmer/pull/2056) Change back to depend on the `enumset` crate instead of `wasmer_enumset` ### Fixed From dc0cf7d4a48ff2b05bc6de7efb4b17b8bd55197d Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 25 Jan 2021 14:42:46 +0100 Subject: [PATCH 07/29] feat(c-api) Implement `wasi_get_unordered_imports`. --- lib/c-api/src/wasm_c_api/wasi/mod.rs | 120 ++++++++++++++++++++++++++- 1 file changed, 119 insertions(+), 1 deletion(-) 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 cd288db4e30..9a50b61d840 100644 --- a/lib/c-api/src/wasm_c_api/wasi/mod.rs +++ b/lib/c-api/src/wasm_c_api/wasi/mod.rs @@ -9,6 +9,7 @@ use super::{ 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 @@ -341,7 +342,124 @@ pub unsafe extern "C" fn wasi_get_wasi_version(module: &wasm_module_t) -> wasi_v .unwrap_or(wasi_version_t::INVALID_VERSION) } -/// Takes ownership of `wasi_env_t`. +/// 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. +#[allow(non_camel_case_types)] +#[derive(Clone)] +pub struct wasm_named_extern_t { + module: Box, + name: Box, + r#extern: Box, +} + +wasm_declare_boxed_vec!(named_extern); + +/// Non-standard function to get the module name of a +/// `wasm_named_extern_t`. +#[no_mangle] +pub extern "C" fn wasm_named_extern_module(named_extern: &wasm_named_extern_t) -> &wasm_name_t { + named_extern.module.as_ref() +} + +/// Non-standard function to get the name of a `wasm_named_extern_t`. +#[no_mangle] +pub extern "C" fn wasm_named_extern_name(named_extern: &wasm_named_extern_t) -> &wasm_name_t { + named_extern.name.as_ref() +} + +/// Non-standard function to get the wrapped extern of a +/// `wasm_named_extern_t`. +#[no_mangle] +pub extern "C" fn wasm_named_extern_extern(named_extern: &wasm_named_extern_t) -> &wasm_extern_t { + 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. +/// +/// This function takes ownership of `wasm_env_t`. +#[no_mangle] +pub unsafe extern "C" fn wasi_get_unordered_imports( + store: &wasm_store_t, + module: &wasm_module_t, + wasi_env: &wasi_env_t, + imports: &mut wasm_named_extern_vec_t, +) -> bool { + wasi_get_unordered_imports_inner(store, module, wasi_env, imports).is_some() +} + +unsafe fn wasi_get_unordered_imports_inner( + store: &wasm_store_t, + module: &wasm_module_t, + wasi_env: &wasi_env_t, + imports: &mut wasm_named_extern_vec_t, +) -> Option<()> { + 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 = { + let mut module: Box = module.into_boxed_str(); + let module_ptr = module.as_mut_ptr(); + let module_len = module.bytes().len(); + let module_inner = wasm_name_t { + size: module_len, + data: module_ptr, + }; + + Box::leak(module); + + Box::new(module_inner) + }; + let name = { + let mut name: Box = name.into_boxed_str(); + let name_ptr = name.as_mut_ptr(); + let name_len = name.bytes().len(); + let name_inner = wasm_name_t { + size: name_len, + data: name_ptr, + }; + + Box::leak(name); + + Box::new(name_inner) + }; + + let extern_inner = Extern::from_vm_export(store, export); + let r#extern = Box::new(wasm_extern_t { + instance: None, + inner: extern_inner, + }); + + Box::new(wasm_named_extern_t { + module, + name, + r#extern, + }) + }) + .collect::>() + .into(); + + Some(()) +} + +/// Non-standard function to get the imports needed for the WASI +/// implementation ordered as expected by the `wasm_module_t`. +/// +/// This function takes ownership of `wasm_env_t`. #[no_mangle] pub unsafe extern "C" fn wasi_get_imports( store: &wasm_store_t, From 00bf74c488be34c0f44869e22bfba08c336af939 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 25 Jan 2021 14:43:20 +0100 Subject: [PATCH 08/29] chore(c-api) Reorder field for the sake of consistency. --- lib/c-api/src/wasm_c_api/types/import.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/c-api/src/wasm_c_api/types/import.rs b/lib/c-api/src/wasm_c_api/types/import.rs index a1f94f800a3..4b253e074fe 100644 --- a/lib/c-api/src/wasm_c_api/types/import.rs +++ b/lib/c-api/src/wasm_c_api/types/import.rs @@ -79,8 +79,8 @@ impl From<&ImportType> for wasm_importtype_t { let extern_type = Box::new(other.ty().into()); wasm_importtype_t { - name, module, + name, extern_type, } } From 0ad4d319d64b60f1914561e3e1bd4c4999e8574b Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 25 Jan 2021 14:43:42 +0100 Subject: [PATCH 09/29] chore(c-api) Update headers. --- lib/c-api/wasmer.h | 48 +++++++++++++++++++++++++++++++++++++++++ lib/c-api/wasmer.hh | 38 ++++++++++++++++++++++++++++++++ lib/c-api/wasmer_wasm.h | 23 ++++++++++++++++++++ 3 files changed, 109 insertions(+) diff --git a/lib/c-api/wasmer.h b/lib/c-api/wasmer.h index 43bb8e87e9f..b97902c3cef 100644 --- a/lib/c-api/wasmer.h +++ b/lib/c-api/wasmer.h @@ -166,6 +166,16 @@ enum wasmer_value_tag typedef uint32_t wasmer_value_tag; #endif // __cplusplus +#if defined(WASMER_WASI_ENABLED) +/** + * 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. + */ +typedef struct wasm_named_extern_t wasm_named_extern_t; +#endif + typedef struct { } wasmer_module_t; @@ -431,6 +441,44 @@ typedef struct { extern "C" { #endif // __cplusplus +#if defined(WASMER_WASI_ENABLED) +/** + * 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. + * + * This function takes ownership of `wasm_env_t`. + */ +bool wasi_get_unordered_imports(const wasm_store_t *store, + const wasm_module_t *module, + const wasi_env_t *wasi_env, + wasm_named_extern_vec_t *imports); +#endif + +#if defined(WASMER_WASI_ENABLED) +/** + * Non-standard function to get the wrapped extern of a + * `wasm_named_extern_t`. + */ +const wasm_extern_t *wasm_named_extern_extern(const wasm_named_extern_t *named_extern); +#endif + +#if defined(WASMER_WASI_ENABLED) +/** + * Non-standard function to get the module name of a + * `wasm_named_extern_t`. + */ +const wasm_name_t *wasm_named_extern_module(const wasm_named_extern_t *named_extern); +#endif + +#if defined(WASMER_WASI_ENABLED) +/** + * Non-standard function to get the name of a `wasm_named_extern_t`. + */ +const wasm_name_t *wasm_named_extern_name(const wasm_named_extern_t *named_extern); +#endif + /** * Creates a new Module from the given wasm bytes. * diff --git a/lib/c-api/wasmer.hh b/lib/c-api/wasmer.hh index 33a27385db9..a8e6a907f91 100644 --- a/lib/c-api/wasmer.hh +++ b/lib/c-api/wasmer.hh @@ -112,6 +112,14 @@ enum class wasmer_value_tag : uint32_t { WASM_F64, }; +#if defined(WASMER_WASI_ENABLED) +/// 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. +struct wasm_named_extern_t; +#endif + struct wasmer_module_t { }; @@ -329,6 +337,36 @@ struct wasmer_wasi_map_dir_entry_t { extern "C" { +#if defined(WASMER_WASI_ENABLED) +/// 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. +/// +/// This function takes ownership of `wasm_env_t`. +bool wasi_get_unordered_imports(const wasm_store_t *store, + const wasm_module_t *module, + const wasi_env_t *wasi_env, + wasm_named_extern_vec_t *imports); +#endif + +#if defined(WASMER_WASI_ENABLED) +/// Non-standard function to get the wrapped extern of a +/// `wasm_named_extern_t`. +const wasm_extern_t *wasm_named_extern_extern(const wasm_named_extern_t *named_extern); +#endif + +#if defined(WASMER_WASI_ENABLED) +/// Non-standard function to get the module name of a +/// `wasm_named_extern_t`. +const wasm_name_t *wasm_named_extern_module(const wasm_named_extern_t *named_extern); +#endif + +#if defined(WASMER_WASI_ENABLED) +/// Non-standard function to get the name of a `wasm_named_extern_t`. +const wasm_name_t *wasm_named_extern_name(const wasm_named_extern_t *named_extern); +#endif + /// Creates a new Module from the given wasm bytes. /// /// Returns `wasmer_result_t::WASMER_OK` upon success. diff --git a/lib/c-api/wasmer_wasm.h b/lib/c-api/wasmer_wasm.h index a53fddbae39..1bbffe372d0 100644 --- a/lib/c-api/wasmer_wasm.h +++ b/lib/c-api/wasmer_wasm.h @@ -134,6 +134,10 @@ typedef struct wasi_config_t wasi_config_t; typedef struct wasi_env_t wasi_env_t; #endif +#if defined(WASMER_WASI_ENABLED) +typedef struct wasm_named_extern_t wasm_named_extern_t; +#endif + #ifdef __cplusplus extern "C" { #endif // __cplusplus @@ -217,6 +221,13 @@ bool wasi_get_imports(const wasm_store_t *store, wasm_func_t *wasi_get_start_function(wasm_instance_t *instance); #endif +#if defined(WASMER_WASI_ENABLED) +bool wasi_get_unordered_imports(const wasm_store_t *store, + const wasm_module_t *module, + const wasi_env_t *wasi_env, + wasm_named_extern_vec_t *imports); +#endif + #if defined(WASMER_WASI_ENABLED) wasi_version_t wasi_get_wasi_version(const wasm_module_t *module); #endif @@ -231,6 +242,18 @@ 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); +#if defined(WASMER_WASI_ENABLED) +const wasm_extern_t *wasm_named_extern_extern(const wasm_named_extern_t *named_extern); +#endif + +#if defined(WASMER_WASI_ENABLED) +const wasm_name_t *wasm_named_extern_module(const wasm_named_extern_t *named_extern); +#endif + +#if defined(WASMER_WASI_ENABLED) +const wasm_name_t *wasm_named_extern_name(const wasm_named_extern_t *named_extern); +#endif + int wasmer_last_error_length(void); int wasmer_last_error_message(char *buffer, int length); From ffd07bcfd7cff71d51cfed859bc0cb159bdec160 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 25 Jan 2021 15:49:31 +0100 Subject: [PATCH 10/29] feat(c-api) Expand macros of the crate when generating C bindings. --- lib/c-api/build.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/c-api/build.rs b/lib/c-api/build.rs index 8212c3bfb37..a13df440517 100644 --- a/lib/c-api/build.rs +++ b/lib/c-api/build.rs @@ -61,6 +61,10 @@ macro_rules! map_feature_as_c_define { } fn main() { + if ::std::env::var("_CBINDGEN_IS_RUNNING").is_ok() { + return; + } + let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); let out_dir = env::var("OUT_DIR").unwrap(); @@ -285,6 +289,12 @@ fn new_builder(language: Language, crate_dir: &str, include_guard: &str, header: .with_include_guard(include_guard) .with_header(header) .with_documentation(false) + .with_parse_expand(&[env::var("CARGO_PKG_NAME").unwrap()]) + .with_parse_expand_features(if env::var("CARGO_FEATURE_SYSTEM_LIBFFI").is_ok() { + &["system-libffi"] + } else { + &[] + }) .with_define("target_family", "windows", "_WIN32") .with_define("target_arch", "x86_64", "ARCH_X86_64") .with_define("feature", "jit", JIT_FEATURE_AS_C_DEFINE) From 8b29156d2de238493c232f42b83082acd1ec9b7c Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 25 Jan 2021 15:58:16 +0100 Subject: [PATCH 11/29] fixup --- lib/c-api/build.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/c-api/build.rs b/lib/c-api/build.rs index a13df440517..1e4630fcf4e 100644 --- a/lib/c-api/build.rs +++ b/lib/c-api/build.rs @@ -61,7 +61,7 @@ macro_rules! map_feature_as_c_define { } fn main() { - if ::std::env::var("_CBINDGEN_IS_RUNNING").is_ok() { + if env::var("_CBINDGEN_IS_RUNNING").is_ok() { return; } @@ -278,7 +278,7 @@ fn add_wasmer_version(pre_header: &mut String) { /// Create a fresh new `Builder`, already pre-configured. fn new_builder(language: Language, crate_dir: &str, include_guard: &str, header: &str) -> Builder { - Builder::new() + let builder = Builder::new() .with_config(cbindgen::Config { sort_by: cbindgen::SortKey::Name, cpp_compat: true, @@ -290,17 +290,17 @@ fn new_builder(language: Language, crate_dir: &str, include_guard: &str, header: .with_header(header) .with_documentation(false) .with_parse_expand(&[env::var("CARGO_PKG_NAME").unwrap()]) - .with_parse_expand_features(if env::var("CARGO_FEATURE_SYSTEM_LIBFFI").is_ok() { - &["system-libffi"] - } else { - &[] - }) .with_define("target_family", "windows", "_WIN32") .with_define("target_arch", "x86_64", "ARCH_X86_64") .with_define("feature", "jit", JIT_FEATURE_AS_C_DEFINE) .with_define("feature", "compiler", COMPILER_FEATURE_AS_C_DEFINE) .with_define("feature", "wasi", WASI_FEATURE_AS_C_DEFINE) - .with_define("feature", "emscripten", EMSCRIPTEN_FEATURE_AS_C_DEFINE) + .with_define("feature", "emscripten", EMSCRIPTEN_FEATURE_AS_C_DEFINE); + + #[cfg(feature = "system-libffi")] + let builder = builder.with_parse_expand_features(&["system-libffi"]); + + builder } /// Exclude types and functions from the `deprecated` API. From 5de7d71e848430017c88ec0aa43398a563f42080 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 25 Jan 2021 15:59:48 +0100 Subject: [PATCH 12/29] chore(c-api) Update headers. --- lib/c-api/wasmer_wasm.h | 86 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/lib/c-api/wasmer_wasm.h b/lib/c-api/wasmer_wasm.h index 1bbffe372d0..53e1009eb39 100644 --- a/lib/c-api/wasmer_wasm.h +++ b/lib/c-api/wasmer_wasm.h @@ -154,6 +154,20 @@ void wasi_config_capture_stderr(wasi_config_t *config); void wasi_config_capture_stdout(wasi_config_t *config); #endif +/** + *Represents a vector of `wasm_named_extern_t`. + * + *Read the documentation of [`wasm_named_extern_t`] to see more concrete examples. + */ +typedef struct { + uintptr_t size; + wasm_named_extern_t **data; +} wasm_named_extern_vec_t; + +#if defined(WASMER_WASI_ENABLED) +void wasi_config_arg(wasi_config_t *config, const char *arg); +#endif + #if defined(WASMER_WASI_ENABLED) void wasi_config_env(wasi_config_t *config, const char *key, const char *value); #endif @@ -254,6 +268,78 @@ const wasm_name_t *wasm_named_extern_module(const wasm_named_extern_t *named_ext const wasm_name_t *wasm_named_extern_name(const wasm_named_extern_t *named_extern); #endif +<<<<<<< HEAD +======= +#if defined(WASMER_WASI_ENABLED) +/** + *Performs a deep copy of a vector of [`wasm_named_extern_t`]. + */ +void wasm_named_extern_vec_copy(wasm_named_extern_vec_t *out_ptr, + const wasm_named_extern_vec_t *in_ptr); +#endif + +#if defined(WASMER_WASI_ENABLED) +/** + *Deletes a vector of [`wasm_named_extern_t`]. + * + *# Example + * + *See the [`wasm_named_extern_vec_t`] type to get an example. + */ +void wasm_named_extern_vec_delete(wasm_named_extern_vec_t *ptr); +#endif + +#if defined(WASMER_WASI_ENABLED) +/** + *Creates a new vector of [`wasm_named_extern_t`]. + */ +void wasm_named_extern_vec_new(wasm_named_extern_vec_t *out, + uintptr_t length, + wasm_named_extern_t *const *init); +#endif + +#if defined(WASMER_WASI_ENABLED) +/** + *Creates an empty vector of [`wasm_named_extern_t`]. + * + *# Example + * + *```rust # use inline_c::assert_c; # fn main() { # (assert_c! { # #include "tests/wasmer_wasm.h" # int main() { // Creates an empty vector of `wasm_named_extern_t`. wasm_named_extern_vec_t vector; wasm_named_extern_vec_new_empty(&vector); + * + * // Check that it is empty. assert(vector.size == 0); + * + * // Free it. wasm_named_extern_vec_delete(&vector); } # }) # .success(); # } ``` + */ +void wasm_named_extern_vec_new_empty(wasm_named_extern_vec_t *out); +#endif + +#if defined(WASMER_WASI_ENABLED) +/** + *Creates a new uninitialized vector of [`wasm_named_extern_t`]. + * + *# Example + * + *```rust # use inline_c::assert_c; # fn main() { # (assert_c! { # #include "tests/wasmer_wasm.h" # int main() { // Creates an empty vector of `wasm_named_extern_t`. wasm_named_extern_vec_t vector; wasm_named_extern_vec_new_uninitialized(&vector, 3); + * + * // Check that it contains 3 items. assert(vector.size == 3); + * + * // Free it. wasm_named_extern_vec_delete(&vector); } # }) # .success(); # } ``` + */ +void wasm_named_extern_vec_new_uninitialized(wasm_named_extern_vec_t *out, + uintptr_t length); +#endif + +/** + * Gets the length in bytes of the last error if any, zero otherwise. + * + * This can be used to dynamically allocate a buffer with the correct number of + * bytes needed to store a message. + * + * # Example + * + * See this module's documentation to get a complete example. + */ +>>>>>>> 75989d7f0 (chore(c-api) Update headers.) int wasmer_last_error_length(void); int wasmer_last_error_message(char *buffer, int length); From 5abac74618c8a04734a143f6f1a45d77a12af460 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Tue, 26 Jan 2021 10:51:05 +0100 Subject: [PATCH 13/29] feat(c-api) Rename `wasm_named_extern_extern` to `wasm_named_extern_unwrap`. --- lib/c-api/src/wasm_c_api/wasi/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 9a50b61d840..7a83ecc150d 100644 --- a/lib/c-api/src/wasm_c_api/wasi/mod.rs +++ b/lib/c-api/src/wasm_c_api/wasi/mod.rs @@ -372,7 +372,7 @@ pub extern "C" fn wasm_named_extern_name(named_extern: &wasm_named_extern_t) -> /// Non-standard function to get the wrapped extern of a /// `wasm_named_extern_t`. #[no_mangle] -pub extern "C" fn wasm_named_extern_extern(named_extern: &wasm_named_extern_t) -> &wasm_extern_t { +pub extern "C" fn wasm_named_extern_unwrap(named_extern: &wasm_named_extern_t) -> &wasm_extern_t { named_extern.r#extern.as_ref() } From 79b5d5c032bcc139cff203181bf40d26ca9aa5cb Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Tue, 26 Jan 2021 10:51:45 +0100 Subject: [PATCH 14/29] chore(c-api) Exclude more functions from Wasm C API for the Wasmer C API. --- lib/c-api/build.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/c-api/build.rs b/lib/c-api/build.rs index 1e4630fcf4e..a5731e44aa1 100644 --- a/lib/c-api/build.rs +++ b/lib/c-api/build.rs @@ -468,14 +468,23 @@ fn exclude_items_from_wasm_c_api(builder: Builder) -> Builder { .exclude_item("wasi_env_set_memory") .exclude_item("wasi_env_t") .exclude_item("wasi_get_imports") - .exclude_item("wasi_get_imports_inner") .exclude_item("wasi_get_start_function") + .exclude_item("wasi_get_unordered_imports") .exclude_item("wasi_get_wasi_version") .exclude_item("wasi_version_t") .exclude_item("wasm_config_set_compiler") .exclude_item("wasm_config_set_engine") .exclude_item("wasm_module_name") .exclude_item("wasm_module_set_name") + .exclude_item("wasm_named_extern_module") + .exclude_item("wasm_named_extern_name") + .exclude_item("wasm_named_extern_t") + .exclude_item("wasm_named_extern_unwrap") + .exclude_item("wasm_named_extern_vec_copy") + .exclude_item("wasm_named_extern_vec_delete") + .exclude_item("wasm_named_extern_vec_new") + .exclude_item("wasm_named_extern_vec_new_empty") + .exclude_item("wasm_named_extern_vec_new_uninitialized") .exclude_item("wasmer_compiler_t") .exclude_item("wasmer_engine_t") .exclude_item("wat2wasm") From 18761cad7dfb4d5d839d5ae2f189644f87337bb7 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Tue, 26 Jan 2021 10:57:42 +0100 Subject: [PATCH 15/29] feat(c-api) Implement `wasm_extern_copy`. This patch also moves `wasm_extern_delete` into the correct Rust module. --- lib/c-api/src/wasm_c_api/externals/mod.rs | 78 +++++++++++++++++++++++ lib/c-api/src/wasm_c_api/wasi/mod.rs | 6 -- 2 files changed, 78 insertions(+), 6 deletions(-) diff --git a/lib/c-api/src/wasm_c_api/externals/mod.rs b/lib/c-api/src/wasm_c_api/externals/mod.rs index 05fc8043543..ab7088ab70a 100644 --- a/lib/c-api/src/wasm_c_api/externals/mod.rs +++ b/lib/c-api/src/wasm_c_api/externals/mod.rs @@ -20,6 +20,84 @@ pub struct wasm_extern_t { wasm_declare_boxed_vec!(extern); +/// Copy a `wasm_extern_t`. +/// +/// # Example +/// +/// ```rust +/// # use inline_c::assert_c; +/// # fn main() { +/// # (assert_c! { +/// # #include "tests/wasmer_wasm.h" +/// # +/// int main() { +/// // Create the engine and the store. +/// wasm_engine_t* engine = wasm_engine_new(); +/// wasm_store_t* store = wasm_store_new(engine); +/// +/// // Create a WebAssembly module from a WAT definition. +/// wasm_byte_vec_t wat; +/// wasmer_byte_vec_new_from_string( +/// &wat, +/// "(module\n" +/// " (func (export \"function\")))" +/// ); +/// wasm_byte_vec_t wasm; +/// wat2wasm(&wat, &wasm); +/// +/// // Create the module. +/// wasm_module_t* module = wasm_module_new(store, &wasm); +/// +/// // Instantiate the module. +/// wasm_extern_vec_t imports = WASM_EMPTY_VEC; +/// wasm_trap_t* traps = NULL; +/// +/// wasm_instance_t* instance = wasm_instance_new(store, module, &imports, &traps); +/// assert(instance); +/// +/// // Read the exports. +/// wasm_extern_vec_t exports; +/// wasm_instance_exports(instance, &exports); +/// +/// // We have 1 of them. +/// assert(exports.size == 1); +/// +/// // It is a function. +/// wasm_extern_t* function = exports.data[0]; +/// assert(wasm_extern_kind(function) == WASM_EXTERN_FUNC); +/// +/// // Let's copy the function. +/// wasm_extern_t* function_copy = wasm_extern_copy(function); +/// assert(wasm_extern_kind(function_copy) == WASM_EXTERN_FUNC); +/// +/// // Free everything. +/// wasm_extern_delete(function_copy); +/// wasm_instance_delete(instance); +/// 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(); +/// # } +/// ``` +#[no_mangle] +pub unsafe extern "C" fn wasm_extern_copy(r#extern: &wasm_extern_t) -> Box { + Box::new(r#extern.clone()) +} + +/// Delete an extern. +/// +/// # Example +/// +/// See `wasm_extern_copy`. +#[no_mangle] +pub unsafe extern "C" fn wasm_extern_delete(_extern: Option>) {} + #[no_mangle] pub unsafe extern "C" fn wasm_func_as_extern( func: Option<&wasm_func_t>, 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 7a83ecc150d..c844c3b19f3 100644 --- a/lib/c-api/src/wasm_c_api/wasi/mod.rs +++ b/lib/c-api/src/wasm_c_api/wasi/mod.rs @@ -524,12 +524,6 @@ pub unsafe extern "C" fn wasi_get_start_function( })) } -/// Delete a `wasm_extern_t` allocated by the API. -/// -/// cbindgen:ignore -#[no_mangle] -pub unsafe extern "C" fn wasm_extern_delete(_item: Option>) {} - #[cfg(test)] mod tests { use inline_c::assert_c; From 1042dad5ebbbac994ea9a5311cdfbb103647a659 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Tue, 26 Jan 2021 10:59:05 +0100 Subject: [PATCH 16/29] chore(c-api) Update headers. --- lib/c-api/wasmer_wasm.h | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/lib/c-api/wasmer_wasm.h b/lib/c-api/wasmer_wasm.h index 53e1009eb39..83ad74f3f1c 100644 --- a/lib/c-api/wasmer_wasm.h +++ b/lib/c-api/wasmer_wasm.h @@ -257,19 +257,28 @@ 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); #if defined(WASMER_WASI_ENABLED) -const wasm_extern_t *wasm_named_extern_extern(const wasm_named_extern_t *named_extern); +/** + * Non-standard function to get the module name of a + * `wasm_named_extern_t`. + */ +const wasm_name_t *wasm_named_extern_module(const wasm_named_extern_t *named_extern); #endif #if defined(WASMER_WASI_ENABLED) -const wasm_name_t *wasm_named_extern_module(const wasm_named_extern_t *named_extern); +/** + * Non-standard function to get the name of a `wasm_named_extern_t`. + */ +const wasm_name_t *wasm_named_extern_name(const wasm_named_extern_t *named_extern); #endif #if defined(WASMER_WASI_ENABLED) -const wasm_name_t *wasm_named_extern_name(const wasm_named_extern_t *named_extern); +/** + * Non-standard function to get the wrapped extern of a + * `wasm_named_extern_t`. + */ +const wasm_extern_t *wasm_named_extern_unwrap(const wasm_named_extern_t *named_extern); #endif -<<<<<<< HEAD -======= #if defined(WASMER_WASI_ENABLED) /** *Performs a deep copy of a vector of [`wasm_named_extern_t`]. @@ -339,7 +348,6 @@ void wasm_named_extern_vec_new_uninitialized(wasm_named_extern_vec_t *out, * * See this module's documentation to get a complete example. */ ->>>>>>> 75989d7f0 (chore(c-api) Update headers.) int wasmer_last_error_length(void); int wasmer_last_error_message(char *buffer, int length); From 5fc3e9fbca7131695440b0d88676c8878271e77e Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Tue, 26 Jan 2021 11:00:36 +0100 Subject: [PATCH 17/29] chore(c-api) Update headers. --- lib/c-api/wasmer.h | 153 +++++--------------------------------------- lib/c-api/wasmer.hh | 123 +++++------------------------------ 2 files changed, 32 insertions(+), 244 deletions(-) diff --git a/lib/c-api/wasmer.h b/lib/c-api/wasmer.h index b97902c3cef..7c77122932f 100644 --- a/lib/c-api/wasmer.h +++ b/lib/c-api/wasmer.h @@ -166,56 +166,22 @@ enum wasmer_value_tag typedef uint32_t wasmer_value_tag; #endif // __cplusplus -#if defined(WASMER_WASI_ENABLED) -/** - * 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. - */ -typedef struct wasm_named_extern_t wasm_named_extern_t; -#endif - typedef struct { } wasmer_module_t; /** - * Opaque pointer to an Instance type plus metadata. - * - * This type represents a WebAssembly instance. It - * is generally generated by the `wasmer_instantiate()` function, or by - * the `wasmer_module_instantiate()` function for the most common paths. + * Opaque pointer to `NamedExportDescriptor`. */ typedef struct { -} wasmer_instance_t; +} wasmer_export_descriptor_t; typedef struct { const uint8_t *bytes; uint32_t bytes_len; } wasmer_byte_array; -#if defined(WASMER_EMSCRIPTEN_ENABLED) -/** - * Type used to construct an import_object_t with Emscripten imports. - */ -typedef struct { - -} wasmer_emscripten_globals_t; -#endif - -typedef struct { - -} wasmer_import_object_t; - -/** - * Opaque pointer to `NamedExportDescriptor`. - */ -typedef struct { - -} wasmer_export_descriptor_t; - /** * Opaque pointer to `NamedExportDescriptors`. */ @@ -331,6 +297,10 @@ typedef struct { typedef struct { +} wasmer_import_object_t; + +typedef struct { + } wasmer_table_t; /** @@ -354,6 +324,17 @@ typedef struct { } wasmer_import_object_iter_t; +/** + * Opaque pointer to an Instance type plus metadata. + * + * This type represents a WebAssembly instance. It + * is generally generated by the `wasmer_instantiate()` function, or by + * the `wasmer_module_instantiate()` function for the most common paths. + */ +typedef struct { + +} wasmer_instance_t; + /** * Opaque pointer to a `wasmer_vm::Ctx` value in Rust. * @@ -437,48 +418,6 @@ typedef struct { } wasmer_wasi_map_dir_entry_t; #endif -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -#if defined(WASMER_WASI_ENABLED) -/** - * 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. - * - * This function takes ownership of `wasm_env_t`. - */ -bool wasi_get_unordered_imports(const wasm_store_t *store, - const wasm_module_t *module, - const wasi_env_t *wasi_env, - wasm_named_extern_vec_t *imports); -#endif - -#if defined(WASMER_WASI_ENABLED) -/** - * Non-standard function to get the wrapped extern of a - * `wasm_named_extern_t`. - */ -const wasm_extern_t *wasm_named_extern_extern(const wasm_named_extern_t *named_extern); -#endif - -#if defined(WASMER_WASI_ENABLED) -/** - * Non-standard function to get the module name of a - * `wasm_named_extern_t`. - */ -const wasm_name_t *wasm_named_extern_module(const wasm_named_extern_t *named_extern); -#endif - -#if defined(WASMER_WASI_ENABLED) -/** - * Non-standard function to get the name of a `wasm_named_extern_t`. - */ -const wasm_name_t *wasm_named_extern_name(const wasm_named_extern_t *named_extern); -#endif - /** * Creates a new Module from the given wasm bytes. * @@ -491,64 +430,6 @@ wasmer_result_t wasmer_compile(wasmer_module_t **module, uint8_t *wasm_bytes, uint32_t wasm_bytes_len); -#if defined(WASMER_EMSCRIPTEN_ENABLED) -/** - * Convenience function for setting up arguments and calling the Emscripten - * main function. - * - * WARNING: - * - * Do not call this function on untrusted code when operating without - * additional sandboxing in place. - * Emscripten has access to many host system calls and therefore may do very - * bad things. - */ -wasmer_result_t wasmer_emscripten_call_main(wasmer_instance_t *instance, - const wasmer_byte_array *args, - unsigned int args_len); -#endif - -#if defined(WASMER_EMSCRIPTEN_ENABLED) -/** - * Destroy `wasmer_emscrpten_globals_t` created by - * `wasmer_emscripten_get_emscripten_globals`. - */ -void wasmer_emscripten_destroy_globals(wasmer_emscripten_globals_t *globals); -#endif - -#if defined(WASMER_EMSCRIPTEN_ENABLED) -/** - * Create a `wasmer_import_object_t` with Emscripten imports, use - * `wasmer_emscripten_get_emscripten_globals` to get a - * `wasmer_emscripten_globals_t` from a `wasmer_module_t`. - * - * WARNING: - * - * This `import_object_t` contains thin-wrappers around host system calls. - * Do not use this to execute untrusted code without additional sandboxing. - */ -wasmer_import_object_t *wasmer_emscripten_generate_import_object(wasmer_emscripten_globals_t *globals); -#endif - -#if defined(WASMER_EMSCRIPTEN_ENABLED) -/** - * Create a `wasmer_emscripten_globals_t` from a Wasm module. - */ -wasmer_emscripten_globals_t *wasmer_emscripten_get_globals(const wasmer_module_t *module); -#endif - -#if defined(WASMER_EMSCRIPTEN_ENABLED) -/** - * Execute global constructors (required if the module is compiled from C++) - * and sets up the internal environment. - * - * This function sets the data pointer in the same way that - * [`wasmer_instance_context_data_set`] does. - */ -wasmer_result_t wasmer_emscripten_set_up(wasmer_instance_t *instance, - wasmer_emscripten_globals_t *globals); -#endif - /** * Gets export descriptor kind */ diff --git a/lib/c-api/wasmer.hh b/lib/c-api/wasmer.hh index a8e6a907f91..d2e5985c91e 100644 --- a/lib/c-api/wasmer.hh +++ b/lib/c-api/wasmer.hh @@ -112,24 +112,12 @@ enum class wasmer_value_tag : uint32_t { WASM_F64, }; -#if defined(WASMER_WASI_ENABLED) -/// 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. -struct wasm_named_extern_t; -#endif - struct wasmer_module_t { }; -/// Opaque pointer to an Instance type plus metadata. -/// -/// This type represents a WebAssembly instance. It -/// is generally generated by the `wasmer_instantiate()` function, or by -/// the `wasmer_module_instantiate()` function for the most common paths. -struct wasmer_instance_t { +/// Opaque pointer to `NamedExportDescriptor`. +struct wasmer_export_descriptor_t { }; @@ -138,22 +126,6 @@ struct wasmer_byte_array { uint32_t bytes_len; }; -#if defined(WASMER_EMSCRIPTEN_ENABLED) -/// Type used to construct an import_object_t with Emscripten imports. -struct wasmer_emscripten_globals_t { - -}; -#endif - -struct wasmer_import_object_t { - -}; - -/// Opaque pointer to `NamedExportDescriptor`. -struct wasmer_export_descriptor_t { - -}; - /// Opaque pointer to `NamedExportDescriptors`. struct wasmer_export_descriptors_t { @@ -249,6 +221,10 @@ struct wasmer_import_func_t { }; +struct wasmer_import_object_t { + +}; + struct wasmer_table_t { }; @@ -272,6 +248,15 @@ struct wasmer_import_object_iter_t { }; +/// Opaque pointer to an Instance type plus metadata. +/// +/// This type represents a WebAssembly instance. It +/// is generally generated by the `wasmer_instantiate()` function, or by +/// the `wasmer_module_instantiate()` function for the most common paths. +struct wasmer_instance_t { + +}; + /// Opaque pointer to a `wasmer_vm::Ctx` value in Rust. /// /// An instance context is passed to any host function (aka imported @@ -337,36 +322,6 @@ struct wasmer_wasi_map_dir_entry_t { extern "C" { -#if defined(WASMER_WASI_ENABLED) -/// 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. -/// -/// This function takes ownership of `wasm_env_t`. -bool wasi_get_unordered_imports(const wasm_store_t *store, - const wasm_module_t *module, - const wasi_env_t *wasi_env, - wasm_named_extern_vec_t *imports); -#endif - -#if defined(WASMER_WASI_ENABLED) -/// Non-standard function to get the wrapped extern of a -/// `wasm_named_extern_t`. -const wasm_extern_t *wasm_named_extern_extern(const wasm_named_extern_t *named_extern); -#endif - -#if defined(WASMER_WASI_ENABLED) -/// Non-standard function to get the module name of a -/// `wasm_named_extern_t`. -const wasm_name_t *wasm_named_extern_module(const wasm_named_extern_t *named_extern); -#endif - -#if defined(WASMER_WASI_ENABLED) -/// Non-standard function to get the name of a `wasm_named_extern_t`. -const wasm_name_t *wasm_named_extern_name(const wasm_named_extern_t *named_extern); -#endif - /// Creates a new Module from the given wasm bytes. /// /// Returns `wasmer_result_t::WASMER_OK` upon success. @@ -377,54 +332,6 @@ wasmer_result_t wasmer_compile(wasmer_module_t **module, uint8_t *wasm_bytes, uint32_t wasm_bytes_len); -#if defined(WASMER_EMSCRIPTEN_ENABLED) -/// Convenience function for setting up arguments and calling the Emscripten -/// main function. -/// -/// WARNING: -/// -/// Do not call this function on untrusted code when operating without -/// additional sandboxing in place. -/// Emscripten has access to many host system calls and therefore may do very -/// bad things. -wasmer_result_t wasmer_emscripten_call_main(wasmer_instance_t *instance, - const wasmer_byte_array *args, - unsigned int args_len); -#endif - -#if defined(WASMER_EMSCRIPTEN_ENABLED) -/// Destroy `wasmer_emscrpten_globals_t` created by -/// `wasmer_emscripten_get_emscripten_globals`. -void wasmer_emscripten_destroy_globals(wasmer_emscripten_globals_t *globals); -#endif - -#if defined(WASMER_EMSCRIPTEN_ENABLED) -/// Create a `wasmer_import_object_t` with Emscripten imports, use -/// `wasmer_emscripten_get_emscripten_globals` to get a -/// `wasmer_emscripten_globals_t` from a `wasmer_module_t`. -/// -/// WARNING: -/// -/// This `import_object_t` contains thin-wrappers around host system calls. -/// Do not use this to execute untrusted code without additional sandboxing. -wasmer_import_object_t *wasmer_emscripten_generate_import_object(wasmer_emscripten_globals_t *globals); -#endif - -#if defined(WASMER_EMSCRIPTEN_ENABLED) -/// Create a `wasmer_emscripten_globals_t` from a Wasm module. -wasmer_emscripten_globals_t *wasmer_emscripten_get_globals(const wasmer_module_t *module); -#endif - -#if defined(WASMER_EMSCRIPTEN_ENABLED) -/// Execute global constructors (required if the module is compiled from C++) -/// and sets up the internal environment. -/// -/// This function sets the data pointer in the same way that -/// [`wasmer_instance_context_data_set`] does. -wasmer_result_t wasmer_emscripten_set_up(wasmer_instance_t *instance, - wasmer_emscripten_globals_t *globals); -#endif - /// Gets export descriptor kind wasmer_import_export_kind wasmer_export_descriptor_kind(wasmer_export_descriptor_t *export_); From 83c69a562380b990f0ac8132e3792640ed85d464 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Thu, 28 Jan 2021 14:01:47 +0100 Subject: [PATCH 18/29] feat(c-api) Implement `From` for `wasm_name_t`. --- lib/c-api/src/wasm_c_api/types/export.rs | 19 +++-------- lib/c-api/src/wasm_c_api/types/import.rs | 32 +++--------------- lib/c-api/src/wasm_c_api/types/mod.rs | 13 ++++++++ lib/c-api/src/wasm_c_api/wasi/mod.rs | 42 +++++------------------- 4 files changed, 30 insertions(+), 76 deletions(-) diff --git a/lib/c-api/src/wasm_c_api/types/export.rs b/lib/c-api/src/wasm_c_api/types/export.rs index 1654de8193e..9c70d04736b 100644 --- a/lib/c-api/src/wasm_c_api/types/export.rs +++ b/lib/c-api/src/wasm_c_api/types/export.rs @@ -42,21 +42,12 @@ impl From for wasm_exporttype_t { impl From<&ExportType> for wasm_exporttype_t { fn from(other: &ExportType) -> Self { - let name = { - let mut heap_str: Box = other.name().to_string().into_boxed_str(); - let char_ptr = heap_str.as_mut_ptr(); - let str_len = heap_str.bytes().len(); - let name_inner = wasm_name_t { - size: str_len, - data: char_ptr, - }; - Box::leak(heap_str); - - Box::new(name_inner) - }; - + let name = other.name().to_string().into(); let extern_type = Box::new(other.ty().into()); - wasm_exporttype_t { name, extern_type } + wasm_exporttype_t { + name: Box::new(name), + extern_type, + } } } diff --git a/lib/c-api/src/wasm_c_api/types/import.rs b/lib/c-api/src/wasm_c_api/types/import.rs index 4b253e074fe..a8b215836ea 100644 --- a/lib/c-api/src/wasm_c_api/types/import.rs +++ b/lib/c-api/src/wasm_c_api/types/import.rs @@ -50,37 +50,13 @@ impl From for wasm_importtype_t { impl From<&ImportType> for wasm_importtype_t { fn from(other: &ImportType) -> Self { - let module = { - let mut heap_str: Box = other.module().to_string().into_boxed_str(); - let char_ptr = heap_str.as_mut_ptr(); - let str_len = heap_str.bytes().len(); - let module_inner = wasm_name_t { - size: str_len, - data: char_ptr, - }; - Box::leak(heap_str); - - Box::new(module_inner) - }; - - let name = { - let mut heap_str: Box = other.name().to_string().into_boxed_str(); - let char_ptr = heap_str.as_mut_ptr(); - let str_len = heap_str.bytes().len(); - let name_inner = wasm_name_t { - size: str_len, - data: char_ptr, - }; - Box::leak(heap_str); - - Box::new(name_inner) - }; - + let module = other.module().to_string().into(); + let name = other.name().to_string().into(); let extern_type = Box::new(other.ty().into()); wasm_importtype_t { - module, - name, + module: Box::new(module), + name: Box::new(name), extern_type, } } diff --git a/lib/c-api/src/wasm_c_api/types/mod.rs b/lib/c-api/src/wasm_c_api/types/mod.rs index c518bce80a5..5f692b7c87e 100644 --- a/lib/c-api/src/wasm_c_api/types/mod.rs +++ b/lib/c-api/src/wasm_c_api/types/mod.rs @@ -28,6 +28,19 @@ wasm_declare_vec!(byte); #[allow(non_camel_case_types)] pub type wasm_name_t = wasm_byte_vec_t; +impl From for wasm_name_t { + fn from(string: String) -> Self { + let mut boxed_str: Box = string.into_boxed_str(); + let data = boxed_str.as_mut_ptr(); + let size = boxed_str.bytes().len(); + let wasm_byte = Self { data, size }; + + Box::leak(boxed_str); + + wasm_byte + } +} + // opaque type over `ExternRef`? #[allow(non_camel_case_types)] pub struct wasm_ref_t; 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 c844c3b19f3..8e286ca2d18 100644 --- a/lib/c-api/src/wasm_c_api/wasi/mod.rs +++ b/lib/c-api/src/wasm_c_api/wasi/mod.rs @@ -411,43 +411,17 @@ unsafe fn wasi_get_unordered_imports_inner( *imports = import_object .into_iter() .map(|((module, name), export)| { - let module = { - let mut module: Box = module.into_boxed_str(); - let module_ptr = module.as_mut_ptr(); - let module_len = module.bytes().len(); - let module_inner = wasm_name_t { - size: module_len, - data: module_ptr, - }; - - Box::leak(module); - - Box::new(module_inner) - }; - let name = { - let mut name: Box = name.into_boxed_str(); - let name_ptr = name.as_mut_ptr(); - let name_len = name.bytes().len(); - let name_inner = wasm_name_t { - size: name_len, - data: name_ptr, - }; - - Box::leak(name); - - Box::new(name_inner) - }; - + let module = module.into(); + let name = name.into(); let extern_inner = Extern::from_vm_export(store, export); - let r#extern = Box::new(wasm_extern_t { - instance: None, - inner: extern_inner, - }); Box::new(wasm_named_extern_t { - module, - name, - r#extern, + module: Box::new(module), + name: Box::new(name), + r#extern: Box::new(wasm_extern_t { + instance: None, + inner: extern_inner, + }), }) }) .collect::>() From e379fd79fb9f0ccbc890d26c13122a2ae79321c7 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Thu, 28 Jan 2021 14:07:54 +0100 Subject: [PATCH 19/29] chore(c-api) Merge `_CBINDGEN_IS_RUNNING` with `DOCS_RS`. --- lib/c-api/build.rs | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/lib/c-api/build.rs b/lib/c-api/build.rs index a5731e44aa1..81730af83df 100644 --- a/lib/c-api/build.rs +++ b/lib/c-api/build.rs @@ -61,27 +61,21 @@ macro_rules! map_feature_as_c_define { } fn main() { - if env::var("_CBINDGEN_IS_RUNNING").is_ok() { + if !running_self() { return; } let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); let out_dir = env::var("OUT_DIR").unwrap(); - if building_c_api_headers() { - build_wasm_c_api_headers(&crate_dir, &out_dir); - build_wasmer_c_api_headers(&crate_dir, &out_dir); - } - + build_wasm_c_api_headers(&crate_dir, &out_dir); + build_wasmer_c_api_headers(&crate_dir, &out_dir); build_inline_c_env_vars(); } -/// Check whether we should build the C API headers. -/// -/// For the moment, it's always enabled, unless if the `DOCS_RS` -/// environment variable is present. -fn building_c_api_headers() -> bool { - env::var("DOCS_RS").is_err() +/// Check whether we should build the C API headers or set `inline-c` up. +fn running_self() -> bool { + env::var("DOCS_RS").is_err() && env::var("_CBINDGEN_IS_RUNNING").is_err() } /// Build the header files for the `wasm_c_api` API. From 37aee2d7ad32e22b437cc0f3f92d8a6321ce9303 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Thu, 28 Jan 2021 14:11:08 +0100 Subject: [PATCH 20/29] chore(c-api) Simplify code. --- lib/c-api/src/wasm_c_api/types/export.rs | 7 ++----- lib/c-api/src/wasm_c_api/types/import.rs | 8 ++++---- lib/c-api/src/wasm_c_api/types/mod.rs | 4 ++-- lib/c-api/src/wasm_c_api/wasi/mod.rs | 8 ++++---- 4 files changed, 12 insertions(+), 15 deletions(-) diff --git a/lib/c-api/src/wasm_c_api/types/export.rs b/lib/c-api/src/wasm_c_api/types/export.rs index 9c70d04736b..205566d5eee 100644 --- a/lib/c-api/src/wasm_c_api/types/export.rs +++ b/lib/c-api/src/wasm_c_api/types/export.rs @@ -42,12 +42,9 @@ impl From for wasm_exporttype_t { impl From<&ExportType> for wasm_exporttype_t { fn from(other: &ExportType) -> Self { - let name = other.name().to_string().into(); + let name = Box::new(other.name().to_string().into()); let extern_type = Box::new(other.ty().into()); - wasm_exporttype_t { - name: Box::new(name), - extern_type, - } + wasm_exporttype_t { name, extern_type } } } diff --git a/lib/c-api/src/wasm_c_api/types/import.rs b/lib/c-api/src/wasm_c_api/types/import.rs index a8b215836ea..13a56c46d17 100644 --- a/lib/c-api/src/wasm_c_api/types/import.rs +++ b/lib/c-api/src/wasm_c_api/types/import.rs @@ -50,13 +50,13 @@ impl From for wasm_importtype_t { impl From<&ImportType> for wasm_importtype_t { fn from(other: &ImportType) -> Self { - let module = other.module().to_string().into(); - let name = other.name().to_string().into(); + let module = Box::new(other.module().to_string().into()); + let name = Box::new(other.name().to_string().into()); let extern_type = Box::new(other.ty().into()); wasm_importtype_t { - module: Box::new(module), - name: Box::new(name), + module, + name, extern_type, } } diff --git a/lib/c-api/src/wasm_c_api/types/mod.rs b/lib/c-api/src/wasm_c_api/types/mod.rs index 5f692b7c87e..c022ba17ef1 100644 --- a/lib/c-api/src/wasm_c_api/types/mod.rs +++ b/lib/c-api/src/wasm_c_api/types/mod.rs @@ -33,11 +33,11 @@ impl From for wasm_name_t { let mut boxed_str: Box = string.into_boxed_str(); let data = boxed_str.as_mut_ptr(); let size = boxed_str.bytes().len(); - let wasm_byte = Self { data, size }; + let wasm_name = Self { data, size }; Box::leak(boxed_str); - wasm_byte + wasm_name } } 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 8e286ca2d18..a7d4ed1b832 100644 --- a/lib/c-api/src/wasm_c_api/wasi/mod.rs +++ b/lib/c-api/src/wasm_c_api/wasi/mod.rs @@ -411,13 +411,13 @@ unsafe fn wasi_get_unordered_imports_inner( *imports = import_object .into_iter() .map(|((module, name), export)| { - let module = module.into(); - let name = name.into(); + 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: Box::new(module), - name: Box::new(name), + module, + name, r#extern: Box::new(wasm_extern_t { instance: None, inner: extern_inner, From b640a8ca62e309edb0ef8d94c71c9e5c7f10cf42 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Thu, 28 Jan 2021 14:14:34 +0100 Subject: [PATCH 21/29] doc(changelog) Add #2053. --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 26083c934ba..f9de445eaff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ ## **[Unreleased]** ### Added +- [#2053](https://github.com/wasmerio/wasmer/pull/2053) Implement the non-standard `wasi_get_unordered_imports` function in the C API. - [#2059](https://github.com/wasmerio/wasmer/pull/2059) Ability to capture `stdout` and `stderr` with WASI in the C API. - [#2040](https://github.com/wasmerio/wasmer/pull/2040) Add `InstanceHandle::vmoffsets` to expose the offsets of the `vmctx` region. - [#2026](https://github.com/wasmerio/wasmer/pull/2010) Expose trap code of a `RuntimeError`, if it's a `Trap`. From 0861b739746e247d8c492473dad013221615f4c9 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 1 Feb 2021 12:04:10 +0100 Subject: [PATCH 22/29] Fix rebase. --- lib/c-api/wasmer.h | 4 ++ lib/c-api/wasmer_wasm.h | 84 +++++------------------------------------ 2 files changed, 14 insertions(+), 74 deletions(-) diff --git a/lib/c-api/wasmer.h b/lib/c-api/wasmer.h index 7c77122932f..f5b0dcb4fd4 100644 --- a/lib/c-api/wasmer.h +++ b/lib/c-api/wasmer.h @@ -418,6 +418,10 @@ typedef struct { } wasmer_wasi_map_dir_entry_t; #endif +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + /** * Creates a new Module from the given wasm bytes. * diff --git a/lib/c-api/wasmer_wasm.h b/lib/c-api/wasmer_wasm.h index 83ad74f3f1c..b4a6dd4a19a 100644 --- a/lib/c-api/wasmer_wasm.h +++ b/lib/c-api/wasmer_wasm.h @@ -138,6 +138,13 @@ typedef struct wasi_env_t wasi_env_t; typedef struct wasm_named_extern_t wasm_named_extern_t; #endif +#if defined(WASMER_WASI_ENABLED) +typedef struct { + uintptr_t size; + wasm_named_extern_t **data; +} wasm_named_extern_vec_t; +#endif + #ifdef __cplusplus extern "C" { #endif // __cplusplus @@ -154,20 +161,6 @@ void wasi_config_capture_stderr(wasi_config_t *config); void wasi_config_capture_stdout(wasi_config_t *config); #endif -/** - *Represents a vector of `wasm_named_extern_t`. - * - *Read the documentation of [`wasm_named_extern_t`] to see more concrete examples. - */ -typedef struct { - uintptr_t size; - wasm_named_extern_t **data; -} wasm_named_extern_vec_t; - -#if defined(WASMER_WASI_ENABLED) -void wasi_config_arg(wasi_config_t *config, const char *arg); -#endif - #if defined(WASMER_WASI_ENABLED) void wasi_config_env(wasi_config_t *config, const char *key, const char *value); #endif @@ -257,97 +250,40 @@ 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); #if defined(WASMER_WASI_ENABLED) -/** - * Non-standard function to get the module name of a - * `wasm_named_extern_t`. - */ const wasm_name_t *wasm_named_extern_module(const wasm_named_extern_t *named_extern); #endif #if defined(WASMER_WASI_ENABLED) -/** - * Non-standard function to get the name of a `wasm_named_extern_t`. - */ const wasm_name_t *wasm_named_extern_name(const wasm_named_extern_t *named_extern); #endif #if defined(WASMER_WASI_ENABLED) -/** - * Non-standard function to get the wrapped extern of a - * `wasm_named_extern_t`. - */ const wasm_extern_t *wasm_named_extern_unwrap(const wasm_named_extern_t *named_extern); #endif #if defined(WASMER_WASI_ENABLED) -/** - *Performs a deep copy of a vector of [`wasm_named_extern_t`]. - */ void wasm_named_extern_vec_copy(wasm_named_extern_vec_t *out_ptr, const wasm_named_extern_vec_t *in_ptr); #endif #if defined(WASMER_WASI_ENABLED) -/** - *Deletes a vector of [`wasm_named_extern_t`]. - * - *# Example - * - *See the [`wasm_named_extern_vec_t`] type to get an example. - */ void wasm_named_extern_vec_delete(wasm_named_extern_vec_t *ptr); #endif #if defined(WASMER_WASI_ENABLED) -/** - *Creates a new vector of [`wasm_named_extern_t`]. - */ void wasm_named_extern_vec_new(wasm_named_extern_vec_t *out, uintptr_t length, wasm_named_extern_t *const *init); #endif #if defined(WASMER_WASI_ENABLED) -/** - *Creates an empty vector of [`wasm_named_extern_t`]. - * - *# Example - * - *```rust # use inline_c::assert_c; # fn main() { # (assert_c! { # #include "tests/wasmer_wasm.h" # int main() { // Creates an empty vector of `wasm_named_extern_t`. wasm_named_extern_vec_t vector; wasm_named_extern_vec_new_empty(&vector); - * - * // Check that it is empty. assert(vector.size == 0); - * - * // Free it. wasm_named_extern_vec_delete(&vector); } # }) # .success(); # } ``` - */ void wasm_named_extern_vec_new_empty(wasm_named_extern_vec_t *out); #endif #if defined(WASMER_WASI_ENABLED) -/** - *Creates a new uninitialized vector of [`wasm_named_extern_t`]. - * - *# Example - * - *```rust # use inline_c::assert_c; # fn main() { # (assert_c! { # #include "tests/wasmer_wasm.h" # int main() { // Creates an empty vector of `wasm_named_extern_t`. wasm_named_extern_vec_t vector; wasm_named_extern_vec_new_uninitialized(&vector, 3); - * - * // Check that it contains 3 items. assert(vector.size == 3); - * - * // Free it. wasm_named_extern_vec_delete(&vector); } # }) # .success(); # } ``` - */ -void wasm_named_extern_vec_new_uninitialized(wasm_named_extern_vec_t *out, - uintptr_t length); -#endif - -/** - * Gets the length in bytes of the last error if any, zero otherwise. - * - * This can be used to dynamically allocate a buffer with the correct number of - * bytes needed to store a message. - * - * # Example - * - * See this module's documentation to get a complete example. - */ +void wasm_named_extern_vec_new_uninitialized(wasm_named_extern_vec_t *out, uintptr_t length); +#endif + int wasmer_last_error_length(void); int wasmer_last_error_message(char *buffer, int length); From bbbbe53602b4453e624376e0bd036a9d39b62760 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 1 Feb 2021 13:38:51 +0100 Subject: [PATCH 23/29] test(c-api) Move a doctest into a test. --- lib/c-api/src/wasm_c_api/externals/mod.rs | 116 +++++++++++----------- 1 file changed, 57 insertions(+), 59 deletions(-) diff --git a/lib/c-api/src/wasm_c_api/externals/mod.rs b/lib/c-api/src/wasm_c_api/externals/mod.rs index ab7088ab70a..8870417bb0b 100644 --- a/lib/c-api/src/wasm_c_api/externals/mod.rs +++ b/lib/c-api/src/wasm_c_api/externals/mod.rs @@ -25,65 +25,6 @@ wasm_declare_boxed_vec!(extern); /// # Example /// /// ```rust -/// # use inline_c::assert_c; -/// # fn main() { -/// # (assert_c! { -/// # #include "tests/wasmer_wasm.h" -/// # -/// int main() { -/// // Create the engine and the store. -/// wasm_engine_t* engine = wasm_engine_new(); -/// wasm_store_t* store = wasm_store_new(engine); -/// -/// // Create a WebAssembly module from a WAT definition. -/// wasm_byte_vec_t wat; -/// wasmer_byte_vec_new_from_string( -/// &wat, -/// "(module\n" -/// " (func (export \"function\")))" -/// ); -/// wasm_byte_vec_t wasm; -/// wat2wasm(&wat, &wasm); -/// -/// // Create the module. -/// wasm_module_t* module = wasm_module_new(store, &wasm); -/// -/// // Instantiate the module. -/// wasm_extern_vec_t imports = WASM_EMPTY_VEC; -/// wasm_trap_t* traps = NULL; -/// -/// wasm_instance_t* instance = wasm_instance_new(store, module, &imports, &traps); -/// assert(instance); -/// -/// // Read the exports. -/// wasm_extern_vec_t exports; -/// wasm_instance_exports(instance, &exports); -/// -/// // We have 1 of them. -/// assert(exports.size == 1); -/// -/// // It is a function. -/// wasm_extern_t* function = exports.data[0]; -/// assert(wasm_extern_kind(function) == WASM_EXTERN_FUNC); -/// -/// // Let's copy the function. -/// wasm_extern_t* function_copy = wasm_extern_copy(function); -/// assert(wasm_extern_kind(function_copy) == WASM_EXTERN_FUNC); -/// -/// // Free everything. -/// wasm_extern_delete(function_copy); -/// wasm_instance_delete(instance); -/// 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(); -/// # } /// ``` #[no_mangle] pub unsafe extern "C" fn wasm_extern_copy(r#extern: &wasm_extern_t) -> Box { @@ -203,3 +144,60 @@ pub unsafe extern "C" fn wasm_extern_as_table( None } } + +#[cfg(test)] +mod tests { + use inline_c::assert_c; + + #[test] + fn test_extern_copy() { + (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\n" + " (func (export \"function\")))" + ); + wasm_byte_vec_t wasm; + wat2wasm(&wat, &wasm); + + wasm_module_t* module = wasm_module_new(store, &wasm); + assert(module); + + wasm_extern_vec_t imports = WASM_EMPTY_VEC; + wasm_trap_t* traps = NULL; + + wasm_instance_t* instance = wasm_instance_new(store, module, &imports, &traps); + assert(instance); + + wasm_extern_vec_t exports; + wasm_instance_exports(instance, &exports); + + assert(exports.size == 1); + + wasm_extern_t* function = exports.data[0]; + assert(wasm_extern_kind(function) == WASM_EXTERN_FUNC); + + wasm_extern_t* function_copy = wasm_extern_copy(function); + assert(wasm_extern_kind(function_copy) == WASM_EXTERN_FUNC); + + wasm_extern_delete(function_copy); + wasm_instance_delete(instance); + 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 b1dc0416dd4fd554345aa70a9adf2abe42f778c8 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 1 Feb 2021 13:42:06 +0100 Subject: [PATCH 24/29] chore(c-api) Make type explicit for the sake of simplicity. --- lib/c-api/src/wasm_c_api/types/export.rs | 4 ++-- lib/c-api/src/wasm_c_api/types/import.rs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/c-api/src/wasm_c_api/types/export.rs b/lib/c-api/src/wasm_c_api/types/export.rs index 205566d5eee..6a78805cb77 100644 --- a/lib/c-api/src/wasm_c_api/types/export.rs +++ b/lib/c-api/src/wasm_c_api/types/export.rs @@ -42,8 +42,8 @@ impl From for wasm_exporttype_t { impl From<&ExportType> for wasm_exporttype_t { fn from(other: &ExportType) -> Self { - let name = Box::new(other.name().to_string().into()); - let extern_type = Box::new(other.ty().into()); + let name: Box = Box::new(other.name().to_string().into()); + let extern_type: Box = Box::new(other.ty().into()); wasm_exporttype_t { name, extern_type } } diff --git a/lib/c-api/src/wasm_c_api/types/import.rs b/lib/c-api/src/wasm_c_api/types/import.rs index 13a56c46d17..9d060584dd3 100644 --- a/lib/c-api/src/wasm_c_api/types/import.rs +++ b/lib/c-api/src/wasm_c_api/types/import.rs @@ -50,9 +50,9 @@ impl From for wasm_importtype_t { impl From<&ImportType> for wasm_importtype_t { fn from(other: &ImportType) -> Self { - let module = Box::new(other.module().to_string().into()); - let name = Box::new(other.name().to_string().into()); - let extern_type = Box::new(other.ty().into()); + let module: Box = Box::new(other.module().to_string().into()); + let name: Box = Box::new(other.name().to_string().into()); + let extern_type: Box = Box::new(other.ty().into()); wasm_importtype_t { module, From 9e63ba9a256ac141c73c4e1156bcec878dfdbe6d Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 1 Feb 2021 14:55:45 +0100 Subject: [PATCH 25/29] fix(c-api) Fix memory leak and owernship in WASI. In `wasi_get_imports` and `wasi_get_unordered_imports`, we said the ownership of `wasi_env_t` was taken by the function, but it wasn't the case. This patch changes the type from `&wasi_env_t` to `Box` to take ownership of it. The rest of the patch updates the documentation, and improves null protections with `Option`. --- lib/c-api/src/wasm_c_api/wasi/mod.rs | 68 +++++++++++++++++++--------- 1 file changed, 47 insertions(+), 21 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 a7d4ed1b832..31f1120ca3a 100644 --- a/lib/c-api/src/wasm_c_api/wasi/mod.rs +++ b/lib/c-api/src/wasm_c_api/wasi/mod.rs @@ -171,7 +171,9 @@ pub struct wasi_env_t { inner: WasiEnv, } -/// Takes ownership over the `wasi_config_t`. +/// Create a new WASI environment. +/// +/// It take ownership over the `wasi_config_t`. #[no_mangle] pub extern "C" fn wasi_env_new(mut config: Box) -> Option> { if !config.inherit_stdout { @@ -195,6 +197,7 @@ pub extern "C" fn wasi_env_new(mut config: Box) -> Option>) {} @@ -346,6 +349,8 @@ pub unsafe extern "C" fn wasi_get_wasi_version(module: &wasm_module_t) -> wasi_v /// 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 { @@ -358,22 +363,34 @@ wasm_declare_boxed_vec!(named_extern); /// 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: &wasm_named_extern_t) -> &wasm_name_t { - named_extern.module.as_ref() +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: &wasm_named_extern_t) -> &wasm_name_t { - named_extern.name.as_ref() +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: &wasm_named_extern_t) -> &wasm_extern_t { - named_extern.r#extern.as_ref() +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 @@ -384,20 +401,24 @@ pub extern "C" fn wasm_named_extern_unwrap(named_extern: &wasm_named_extern_t) - /// This function takes ownership of `wasm_env_t`. #[no_mangle] pub unsafe extern "C" fn wasi_get_unordered_imports( - store: &wasm_store_t, - module: &wasm_module_t, - wasi_env: &wasi_env_t, + store: Option<&wasm_store_t>, + module: Option<&wasm_module_t>, + wasi_env: Option>, imports: &mut wasm_named_extern_vec_t, ) -> bool { wasi_get_unordered_imports_inner(store, module, wasi_env, imports).is_some() } unsafe fn wasi_get_unordered_imports_inner( - store: &wasm_store_t, - module: &wasm_module_t, - wasi_env: &wasi_env_t, + store: Option<&wasm_store_t>, + module: Option<&wasm_module_t>, + wasi_env: Option>, 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!( @@ -436,9 +457,9 @@ unsafe fn wasi_get_unordered_imports_inner( /// This function takes ownership of `wasm_env_t`. #[no_mangle] pub unsafe extern "C" fn wasi_get_imports( - store: &wasm_store_t, - module: &wasm_module_t, - wasi_env: &wasi_env_t, + store: Option<&wasm_store_t>, + module: Option<&wasm_module_t>, + wasi_env: Option>, imports: &mut wasm_extern_vec_t, ) -> bool { wasi_get_imports_inner(store, module, wasi_env, imports).is_some() @@ -446,11 +467,15 @@ pub unsafe extern "C" fn wasi_get_imports( /// Takes ownership of `wasi_env_t`. unsafe fn wasi_get_imports_inner( - store: &wasm_store_t, - module: &wasm_module_t, - wasi_env: &wasi_env_t, + store: Option<&wasm_store_t>, + module: Option<&wasm_module_t>, + wasi_env: Option>, imports: &mut wasm_extern_vec_t, ) -> Option<()> { + let store = store?; + let module = module?; + let wasi_env = wasi_env?; + let store = &store.inner; let version = c_try!( @@ -491,9 +516,10 @@ unsafe fn wasi_get_imports_inner( pub unsafe extern "C" fn wasi_get_start_function( instance: &mut wasm_instance_t, ) -> Option> { - let f = c_try!(instance.inner.exports.get_function("_start")); + let start = c_try!(instance.inner.exports.get_function("_start")); + Some(Box::new(wasm_func_t { - inner: f.clone(), + inner: start.clone(), instance: Some(instance.inner.clone()), })) } From 8ab82cf589b562f116701c9195ed38908b81390e Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 1 Feb 2021 14:58:42 +0100 Subject: [PATCH 26/29] doc(c-api) Fix documentation. --- lib/c-api/src/wasm_c_api/externals/mod.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lib/c-api/src/wasm_c_api/externals/mod.rs b/lib/c-api/src/wasm_c_api/externals/mod.rs index 8870417bb0b..952d644a710 100644 --- a/lib/c-api/src/wasm_c_api/externals/mod.rs +++ b/lib/c-api/src/wasm_c_api/externals/mod.rs @@ -21,11 +21,6 @@ pub struct wasm_extern_t { wasm_declare_boxed_vec!(extern); /// Copy a `wasm_extern_t`. -/// -/// # Example -/// -/// ```rust -/// ``` #[no_mangle] pub unsafe extern "C" fn wasm_extern_copy(r#extern: &wasm_extern_t) -> Box { Box::new(r#extern.clone()) From d48bc1e67e72f1b16e4257e3dc60003605e0f45b Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 1 Feb 2021 14:58:54 +0100 Subject: [PATCH 27/29] chore(c-api) Update headers. --- lib/c-api/wasmer_wasm.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/c-api/wasmer_wasm.h b/lib/c-api/wasmer_wasm.h index b4a6dd4a19a..ba819b8e930 100644 --- a/lib/c-api/wasmer_wasm.h +++ b/lib/c-api/wasmer_wasm.h @@ -220,7 +220,7 @@ void wasi_env_set_memory(wasi_env_t *_env, #if defined(WASMER_WASI_ENABLED) bool wasi_get_imports(const wasm_store_t *store, const wasm_module_t *module, - const wasi_env_t *wasi_env, + wasi_env_t *wasi_env, wasm_extern_vec_t *imports); #endif @@ -231,7 +231,7 @@ wasm_func_t *wasi_get_start_function(wasm_instance_t *instance); #if defined(WASMER_WASI_ENABLED) bool wasi_get_unordered_imports(const wasm_store_t *store, const wasm_module_t *module, - const wasi_env_t *wasi_env, + wasi_env_t *wasi_env, wasm_named_extern_vec_t *imports); #endif From 9a835a4fdca1f09803055e203ddbd8ed76e8d197 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 1 Feb 2021 15:00:13 +0100 Subject: [PATCH 28/29] doc(c-api) Remove incorrect link. --- lib/c-api/src/wasm_c_api/externals/mod.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/c-api/src/wasm_c_api/externals/mod.rs b/lib/c-api/src/wasm_c_api/externals/mod.rs index 952d644a710..23dff955ef1 100644 --- a/lib/c-api/src/wasm_c_api/externals/mod.rs +++ b/lib/c-api/src/wasm_c_api/externals/mod.rs @@ -27,10 +27,6 @@ pub unsafe extern "C" fn wasm_extern_copy(r#extern: &wasm_extern_t) -> Box>) {} From 98bff43f351e56353f9be76269c3403c02e51479 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 1 Feb 2021 15:49:53 +0100 Subject: [PATCH 29/29] chore(c-api) Remove useless `unsafe` keywords. --- lib/c-api/src/wasm_c_api/wasi/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 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 31f1120ca3a..deadbd043e5 100644 --- a/lib/c-api/src/wasm_c_api/wasi/mod.rs +++ b/lib/c-api/src/wasm_c_api/wasi/mod.rs @@ -409,7 +409,7 @@ pub unsafe extern "C" fn wasi_get_unordered_imports( wasi_get_unordered_imports_inner(store, module, wasi_env, imports).is_some() } -unsafe fn wasi_get_unordered_imports_inner( +fn wasi_get_unordered_imports_inner( store: Option<&wasm_store_t>, module: Option<&wasm_module_t>, wasi_env: Option>, @@ -466,7 +466,7 @@ pub unsafe extern "C" fn wasi_get_imports( } /// Takes ownership of `wasi_env_t`. -unsafe fn wasi_get_imports_inner( +fn wasi_get_imports_inner( store: Option<&wasm_store_t>, module: Option<&wasm_module_t>, wasi_env: Option>,