diff --git a/third_party/wasmer/Cargo.toml b/third_party/wasmer/Cargo.toml
index 9f08f1646d4..bfe61724256 100644
--- a/third_party/wasmer/Cargo.toml
+++ b/third_party/wasmer/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "wasmer"
-version = "0.7.0"
+version = "0.17.1"
[lib]
name = "wasmer"
@@ -8,4 +8,4 @@ crate-type = ["staticlib"]
path = "wasmer.rs"
[dependencies]
-wasmer-runtime-c-api = "0.7.0"
+wasmer-runtime-c-api = "0.17.1"
diff --git a/third_party/wasmer/LICENSE b/third_party/wasmer/LICENSE
index 079740dd377..62bb543eb9e 100644
--- a/third_party/wasmer/LICENSE
+++ b/third_party/wasmer/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2019 Wasmer, Inc. and its affiliates.
+Copyright (c) 2019-present Wasmer, Inc. and its affiliates.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/third_party/wasmer/README.md b/third_party/wasmer/README.md
index 1e741cfd121..d1475b7fdea 100644
--- a/third_party/wasmer/README.md
+++ b/third_party/wasmer/README.md
@@ -1,31 +1,31 @@
-
+
-
-
+
+
-
+
-
+
-
-
+
+
# Wasmer Runtime C API
Wasmer is a standalone JIT WebAssembly runtime, aiming to be fully
-compatible with Emscripten, Rust and Go. [Learn
+compatible with WASI, Emscripten, Rust and Go. [Learn
more](https://github.com/wasmerio/wasmer).
This crate exposes a C and a C++ API for the Wasmer runtime.
@@ -36,6 +36,10 @@ The C and C++ header files can be found in the source tree of this
crate, respectively [`wasmer.h`][wasmer_h] and
[`wasmer.hh`][wasmer_hh]. They are automatically generated, and always
up-to-date in this repository.
+The runtime shared library (so, dll, dylib) can also be downloaded in Wasmer [release page](https://github.com/wasmerio/wasmer/releases).
+
+You can find the full C API documentation here:
+https://wasmerio.github.io/wasmer/c/runtime-c-api/
Here is a simple example to use the C API:
@@ -104,10 +108,14 @@ int main()
# Testing
+Tests are run using the release build of the library. If you make
+changes or compile with non-default features, please ensure you
+rebuild in release mode for the tests to see the changes.
+
The tests can be run via `cargo test`, such as:
```sh
-$ cargo test -- --nocapture
+$ cargo test --release -- --nocapture
```
To run tests manually, enter the `lib/runtime-c-api/tests` directory
diff --git a/third_party/wasmer/wasmer.hh b/third_party/wasmer/wasmer.hh
index cf7a1c7b321..647e637d03f 100644
--- a/third_party/wasmer/wasmer.hh
+++ b/third_party/wasmer/wasmer.hh
@@ -1,3 +1,36 @@
+
+#if !defined(WASMER_H_MACROS)
+
+#define WASMER_H_MACROS
+
+// Define the `ARCH_X86_X64` constant.
+#if defined(MSVC) && defined(_M_AMD64)
+# define ARCH_X86_64
+#elif (defined(GCC) || defined(__GNUC__) || defined(__clang__)) && defined(__x86_64__)
+# define ARCH_X86_64
+#endif
+
+// Compatibility with non-Clang compilers.
+#if !defined(__has_attribute)
+# define __has_attribute(x) 0
+#endif
+
+// Compatibility with non-Clang compilers.
+#if !defined(__has_declspec_attribute)
+# define __has_declspec_attribute(x) 0
+#endif
+
+// Define the `DEPRECATED` macro.
+#if defined(GCC) || defined(__GNUC__) || __has_attribute(deprecated)
+# define DEPRECATED(message) __attribute__((deprecated(message)))
+#elif defined(MSVC) || __has_declspec_attribute(deprecated)
+# define DEPRECATED(message) __declspec(deprecated(message))
+#endif
+
+#define WASMER_WASI_ENABLED
+#endif // WASMER_H_MACROS
+
+
#ifndef WASMER_H
#define WASMER_H
@@ -6,22 +39,52 @@
#include
#include
+#if defined(WASMER_WASI_ENABLED)
+enum class Version : uint8_t {
+ /// Version cannot be detected or is unknown.
+ Unknown = 0,
+ /// Latest version. See `wasmer_wasi::WasiVersion::Latest` to
+ /// learn more.
+ Latest = 1,
+ /// `wasi_unstable`.
+ Snapshot0 = 2,
+ /// `wasi_snapshot_preview1`.
+ Snapshot1 = 3,
+};
+#endif
+
+/// List of export/import kinds.
enum class wasmer_import_export_kind : uint32_t {
- WASM_FUNCTION,
- WASM_GLOBAL,
- WASM_MEMORY,
- WASM_TABLE,
+ /// The export/import is a function.
+ WASM_FUNCTION = 0,
+ /// The export/import is a global.
+ WASM_GLOBAL = 1,
+ /// The export/import is a memory.
+ WASM_MEMORY = 2,
+ /// The export/import is a table.
+ WASM_TABLE = 3,
};
+/// The `wasmer_result_t` enum is a type that represents either a
+/// success, or a failure.
enum class wasmer_result_t {
+ /// Represents a success.
WASMER_OK = 1,
+ /// Represents a failure.
WASMER_ERROR = 2,
};
+/// Represents all possibles WebAssembly value types.
+///
+/// See `wasmer_value_t` to get a complete example.
enum class wasmer_value_tag : uint32_t {
+ /// Represents the `i32` WebAssembly type.
WASM_I32,
+ /// Represents the `i64` WebAssembly type.
WASM_I64,
+ /// Represents the `f32` WebAssembly type.
WASM_F32,
+ /// Represents the `f64` WebAssembly type.
WASM_F64,
};
@@ -29,7 +92,12 @@ struct wasmer_module_t {
};
-struct wasmer_export_descriptor_t {
+/// Opaque pointer to a `wasmer_runtime::Instance` value in Rust.
+///
+/// A `wasmer_runtime::Instance` 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 {
};
@@ -38,14 +106,38 @@ 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 {
};
+/// Opaque pointer to `wasmer_export_t`.
struct wasmer_export_func_t {
};
+/// Represents a WebAssembly value.
+///
+/// This is a [Rust union][rust-union], which is equivalent to the C
+/// union. See `wasmer_value_t` to get a complete example.
+///
+/// [rust-union]: https://doc.rust-lang.org/reference/items/unions.html
union wasmer_value {
int32_t I32;
int64_t I64;
@@ -53,19 +145,53 @@ union wasmer_value {
double F64;
};
+/// Represents a WebAssembly type and value pair,
+/// i.e. `wasmer_value_tag` and `wasmer_value`. Since the latter is an
+/// union, it's the safe way to read or write a WebAssembly value in
+/// C.
+///
+/// Example:
+///
+/// ```c
+/// // Create a WebAssembly value.
+/// wasmer_value_t wasm_value = {
+/// .tag = WASM_I32,
+/// .value.I32 = 42,
+/// };
+///
+/// // Read a WebAssembly value.
+/// if (wasm_value.tag == WASM_I32) {
+/// int32_t x = wasm_value.value.I32;
+/// // …
+/// }
+/// ```
struct wasmer_value_t {
+ /// The value type.
wasmer_value_tag tag;
+ /// The value.
wasmer_value value;
};
+/// Opaque pointer to `NamedExport`.
struct wasmer_export_t {
};
+/// Opaque pointer to a `wasmer_runtime::Memory` value in Rust.
+///
+/// A `wasmer_runtime::Memory` represents a WebAssembly memory. It is
+/// possible to create one with `wasmer_memory_new()` and pass it as
+/// imports of an instance, or to read it from exports of an instance
+/// with `wasmer_export_to_memory()`.
struct wasmer_memory_t {
};
+/// Opaque pointer to the opaque structure `crate::NamedExports`,
+/// which is a wrapper around a vector of the opaque structure
+/// `crate::NamedExport`.
+///
+/// Check the `wasmer_instance_exports()` function to learn more.
struct wasmer_exports_t {
};
@@ -91,14 +217,11 @@ struct wasmer_import_func_t {
};
-struct wasmer_import_object_t {
-
-};
-
struct wasmer_table_t {
};
+/// Union of import/export value.
union wasmer_import_export_value {
const wasmer_import_func_t *func;
const wasmer_table_t *table;
@@ -113,21 +236,55 @@ struct wasmer_import_t {
wasmer_import_export_value value;
};
-struct wasmer_instance_t {
+struct wasmer_import_object_iter_t {
};
+/// Opaque pointer to a `wasmer_runtime::Ctx` value in Rust.
+///
+/// An instance context is passed to any host function (aka imported
+/// function) as the first argument. It is necessary to read the
+/// instance data or the memory, respectively with the
+/// `wasmer_instance_context_data_get()` function, and the
+/// `wasmer_instance_context_memory()` function.
+///
+/// It is also possible to get the instance context outside a host
+/// function by using the `wasmer_instance_context_get()`
+/// function. See also `wasmer_instance_context_data_set()` to set the
+/// instance context data.
+///
+/// Example:
+///
+/// ```c
+/// // A host function that prints data from the WebAssembly memory to
+/// // the standard output.
+/// void print(wasmer_instance_context_t *context, int32_t pointer, int32_t length) {
+/// // Use `wasmer_instance_context` to get back the first instance memory.
+/// const wasmer_memory_t *memory = wasmer_instance_context_memory(context, 0);
+///
+/// // Continue…
+/// }
+/// ```
struct wasmer_instance_context_t {
};
+/// The `wasmer_limit_option_t` struct represents an optional limit
+/// for `wasmer_limits_t`.
struct wasmer_limit_option_t {
+ /// Whether the limit is set.
bool has_some;
+ /// The limit value.
uint32_t some;
};
+/// The `wasmer_limits_t` struct is a type that describes a memory
+/// options. See the `wasmer_memory_t` struct or the
+/// `wasmer_memory_new()` function to get more information.
struct wasmer_limits_t {
+ /// The minimum number of allowed pages.
uint32_t min;
+ /// The maximum number of allowed pages.
wasmer_limit_option_t max;
};
@@ -135,28 +292,95 @@ struct wasmer_serialized_module_t {
};
+#if (!defined(_WIN32) && defined(ARCH_X86_64))
struct wasmer_trampoline_buffer_builder_t {
};
+#endif
+#if (!defined(_WIN32) && defined(ARCH_X86_64))
struct wasmer_trampoline_callable_t {
};
+#endif
+#if (!defined(_WIN32) && defined(ARCH_X86_64))
struct wasmer_trampoline_buffer_t {
};
+#endif
+
+#if defined(WASMER_WASI_ENABLED)
+/// Opens a directory that's visible to the WASI module as `alias` but
+/// is backed by the host file at `host_file_path`
+struct wasmer_wasi_map_dir_entry_t {
+ /// What the WASI module will see in its virtual root
+ wasmer_byte_array alias;
+ /// The backing file that the WASI module will interact with via the alias
+ wasmer_byte_array host_file_path;
+};
+#endif
extern "C" {
/// Creates a new Module from the given wasm bytes.
+///
/// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
/// and `wasmer_last_error_message` to get an error message.
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_);
@@ -164,6 +388,7 @@ wasmer_import_export_kind wasmer_export_descriptor_kind(wasmer_export_descriptor
wasmer_byte_array wasmer_export_descriptor_name(wasmer_export_descriptor_t *export_descriptor);
/// Gets export descriptors for the given module
+///
/// The caller owns the object and should call `wasmer_export_descriptors_destroy` to free it.
void wasmer_export_descriptors(const wasmer_module_t *module,
wasmer_export_descriptors_t **export_descriptors);
@@ -180,17 +405,21 @@ int wasmer_export_descriptors_len(wasmer_export_descriptors_t *exports);
/// Calls a `func` with the provided parameters.
/// Results are set using the provided `results` pointer.
+///
/// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
/// and `wasmer_last_error_message` to get an error message.
wasmer_result_t wasmer_export_func_call(const wasmer_export_func_t *func,
const wasmer_value_t *params,
- int params_len,
+ unsigned int params_len,
wasmer_value_t *results,
- int results_len);
+ unsigned int results_len);
/// Sets the params buffer to the parameter types of the given wasmer_export_func_t
+///
/// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
/// and `wasmer_last_error_message` to get an error message.
wasmer_result_t wasmer_export_func_params(const wasmer_export_func_t *func,
@@ -198,13 +427,17 @@ wasmer_result_t wasmer_export_func_params(const wasmer_export_func_t *func,
uint32_t params_len);
/// Sets the result parameter to the arity of the params of the wasmer_export_func_t
+///
/// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
/// and `wasmer_last_error_message` to get an error message.
wasmer_result_t wasmer_export_func_params_arity(const wasmer_export_func_t *func, uint32_t *result);
/// Sets the returns buffer to the parameter types of the given wasmer_export_func_t
+///
/// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
/// and `wasmer_last_error_message` to get an error message.
wasmer_result_t wasmer_export_func_returns(const wasmer_export_func_t *func,
@@ -212,7 +445,9 @@ wasmer_result_t wasmer_export_func_returns(const wasmer_export_func_t *func,
uint32_t returns_len);
/// Sets the result parameter to the arity of the returns of the wasmer_export_func_t
+///
/// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
/// and `wasmer_last_error_message` to get an error message.
wasmer_result_t wasmer_export_func_returns_arity(const wasmer_export_func_t *func,
@@ -228,12 +463,30 @@ wasmer_byte_array wasmer_export_name(wasmer_export_t *export_);
const wasmer_export_func_t *wasmer_export_to_func(const wasmer_export_t *export_);
/// Gets a memory pointer from an export pointer.
+///
/// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
/// and `wasmer_last_error_message` to get an error message.
wasmer_result_t wasmer_export_to_memory(const wasmer_export_t *export_, wasmer_memory_t **memory);
-/// Frees the memory for the given exports
+/// Frees the memory for the given exports.
+///
+/// Check the `wasmer_instance_exports()` function to get a complete
+/// example.
+///
+/// If `exports` is a null pointer, this function does nothing.
+///
+/// Example:
+///
+/// ```c
+/// // Get some exports.
+/// wasmer_exports_t *exports = NULL;
+/// wasmer_instance_exports(instance, &exports);
+///
+/// // Destroy the exports.
+/// wasmer_exports_destroy(exports);
+/// ```
void wasmer_exports_destroy(wasmer_exports_t *exports);
/// Gets wasmer_export by index
@@ -268,6 +521,7 @@ wasmer_byte_array wasmer_import_descriptor_module_name(wasmer_import_descriptor_
wasmer_byte_array wasmer_import_descriptor_name(wasmer_import_descriptor_t *import_descriptor);
/// Gets import descriptors for the given module
+///
/// The caller owns the object and should call `wasmer_import_descriptors_destroy` to free it.
void wasmer_import_descriptors(const wasmer_module_t *module,
wasmer_import_descriptors_t **import_descriptors);
@@ -285,8 +539,23 @@ unsigned int wasmer_import_descriptors_len(wasmer_import_descriptors_t *exports)
/// Frees memory for the given Func
void wasmer_import_func_destroy(wasmer_import_func_t *func);
-/// Creates new func
-/// The caller owns the object and should call `wasmer_import_func_destroy` to free it.
+/// Creates new host function, aka imported function. `func` is a
+/// function pointer, where the first argument is the famous `vm::Ctx`
+/// (in Rust), or `wasmer_instance_context_t` (in C). All arguments
+/// must be typed with compatible WebAssembly native types:
+///
+/// | WebAssembly type | C/C++ type |
+/// | ---------------- | ---------- |
+/// | `i32` | `int32_t` |
+/// | `i64` | `int64_t` |
+/// | `f32` | `float` |
+/// | `f64` | `double` |
+///
+/// The function pointer must have a lifetime greater than the
+/// WebAssembly instance lifetime.
+///
+/// The caller owns the object and should call
+/// `wasmer_import_func_destroy` to free it.
wasmer_import_func_t *wasmer_import_func_new(void (*func)(void *data),
const wasmer_value_tag *params,
unsigned int params_len,
@@ -294,7 +563,9 @@ wasmer_import_func_t *wasmer_import_func_new(void (*func)(void *data),
unsigned int returns_len);
/// Sets the params buffer to the parameter types of the given wasmer_import_func_t
+///
/// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
/// and `wasmer_last_error_message` to get an error message.
wasmer_result_t wasmer_import_func_params(const wasmer_import_func_t *func,
@@ -302,13 +573,17 @@ wasmer_result_t wasmer_import_func_params(const wasmer_import_func_t *func,
unsigned int params_len);
/// Sets the result parameter to the arity of the params of the wasmer_import_func_t
+///
/// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
/// and `wasmer_last_error_message` to get an error message.
wasmer_result_t wasmer_import_func_params_arity(const wasmer_import_func_t *func, uint32_t *result);
/// Sets the returns buffer to the parameter types of the given wasmer_import_func_t
+///
/// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
/// and `wasmer_last_error_message` to get an error message.
wasmer_result_t wasmer_import_func_returns(const wasmer_import_func_t *func,
@@ -316,7 +591,9 @@ wasmer_result_t wasmer_import_func_returns(const wasmer_import_func_t *func,
unsigned int returns_len);
/// Sets the result parameter to the arity of the returns of the wasmer_import_func_t
+///
/// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
/// and `wasmer_last_error_message` to get an error message.
wasmer_result_t wasmer_import_func_returns_arity(const wasmer_import_func_t *func,
@@ -327,18 +604,101 @@ void wasmer_import_object_destroy(wasmer_import_object_t *import_object);
/// Extends an existing import object with new imports
wasmer_result_t wasmer_import_object_extend(wasmer_import_object_t *import_object,
- wasmer_import_t *imports,
+ const wasmer_import_t *imports,
unsigned int imports_len);
+/// Gets an entry from an ImportObject at the name and namespace.
+/// Stores `name`, `namespace`, and `import_export_value` in `import`.
+/// Thus these must remain valid for the lifetime of `import`.
+///
+/// The caller owns all data involved.
+/// `import_export_value` will be written to based on `tag`.
+wasmer_result_t wasmer_import_object_get_import(const wasmer_import_object_t *import_object,
+ wasmer_byte_array namespace_,
+ wasmer_byte_array name,
+ wasmer_import_t *import,
+ wasmer_import_export_value *import_export_value,
+ uint32_t tag);
+
+/// Frees the memory allocated in `wasmer_import_object_iter_next`
+///
+/// This function does not free the memory in `wasmer_import_object_t`;
+/// it only frees memory allocated while querying a `wasmer_import_object_t`.
+void wasmer_import_object_imports_destroy(wasmer_import_t *imports, uint32_t imports_len);
+
+/// Returns true if further calls to `wasmer_import_object_iter_next` will
+/// not return any new data
+bool wasmer_import_object_iter_at_end(wasmer_import_object_iter_t *import_object_iter);
+
+/// Frees the memory allocated by `wasmer_import_object_iterate_functions`
+void wasmer_import_object_iter_destroy(wasmer_import_object_iter_t *import_object_iter);
+
+/// Writes the next value to `import`. `WASMER_ERROR` is returned if there
+/// was an error or there's nothing left to return.
+///
+/// To free the memory allocated here, pass the import to `wasmer_import_object_imports_destroy`.
+/// To check if the iterator is done, use `wasmer_import_object_iter_at_end`.
+wasmer_result_t wasmer_import_object_iter_next(wasmer_import_object_iter_t *import_object_iter,
+ wasmer_import_t *import);
+
+/// Create an iterator over the functions in the import object.
+/// Get the next import with `wasmer_import_object_iter_next`
+/// Free the iterator with `wasmer_import_object_iter_destroy`
+wasmer_import_object_iter_t *wasmer_import_object_iterate_functions(const wasmer_import_object_t *import_object);
+
/// Creates a new empty import object.
/// See also `wasmer_import_object_append`
wasmer_import_object_t *wasmer_import_object_new();
-/// Calls an instances exported function by `name` with the provided parameters.
-/// Results are set using the provided `results` pointer.
-/// Returns `wasmer_result_t::WASMER_OK` upon success.
-/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
-/// and `wasmer_last_error_message` to get an error message.
+/// Calls an exported function of a WebAssembly instance by `name`
+/// with the provided parameters. The exported function results are
+/// stored on the provided `results` pointer.
+///
+/// This function returns `wasmer_result_t::WASMER_OK` upon success,
+/// `wasmer_result_t::WASMER_ERROR` otherwise. You can use
+/// `wasmer_last_error_message()` to get the generated error message.
+///
+/// Potential errors are the following:
+///
+/// * `instance` is a null pointer,
+/// * `name` is a null pointer,
+/// * `params` is a null pointer.
+///
+/// Example of calling an exported function that needs two parameters, and returns one value:
+///
+/// ```c
+/// // First argument.
+/// wasmer_value_t argument_one = {
+/// .tag = WASM_I32,
+/// .value.I32 = 3,
+/// };
+///
+/// // Second argument.
+/// wasmer_value_t argument_two = {
+/// .tag = WASM_I32,
+/// .value.I32 = 4,
+/// };
+///
+/// // First result.
+/// wasmer_value_t result_one;
+///
+/// // All arguments and results.
+/// wasmer_value_t arguments[] = {argument_one, argument_two};
+/// wasmer_value_t results[] = {result_one};
+///
+/// wasmer_result_t call_result = wasmer_instance_call(
+/// instance, // instance pointer
+/// "sum", // the exported function name
+/// arguments, // the arguments
+/// 2, // the number of arguments
+/// results, // the results
+/// 1 // the number of results
+/// );
+///
+/// if (call_result == WASMER_OK) {
+/// printf("Result is: %d\n", results[0].value.I32);
+/// }
+/// ```
wasmer_result_t wasmer_instance_call(wasmer_instance_t *instance,
const char *name,
const wasmer_value_t *params,
@@ -346,89 +706,362 @@ wasmer_result_t wasmer_instance_call(wasmer_instance_t *instance,
wasmer_value_t *results,
uint32_t results_len);
-/// Gets the `data` field within the context.
+/// Gets the data that can be hold by an instance.
+///
+/// This function is complementary of
+/// `wasmer_instance_context_data_set()`. Please read its
+/// documentation. You can also read the documentation of
+/// `wasmer_instance_context_t` to get other examples.
+///
+/// This function returns nothing if `ctx` is a null pointer.
void *wasmer_instance_context_data_get(const wasmer_instance_context_t *ctx);
-/// Sets the `data` field of the instance context. This context will be
-/// passed to all imported function for instance.
-void wasmer_instance_context_data_set(wasmer_instance_t *instance, void *data_ptr);
+/// Sets the data that can be hold by an instance context.
+///
+/// An instance context (represented by the opaque
+/// `wasmer_instance_context_t` structure) can hold user-defined
+/// data. This function sets the data. This function is complementary
+/// of `wasmer_instance_context_data_get()`.
+///
+/// This function does nothing if `instance` is a null pointer.
+///
+/// Example:
+///
+/// ```c
+/// // Define your own data.
+/// typedef struct {
+/// // …
+/// } my_data;
+///
+/// // Allocate them and set them on the given instance.
+/// my_data *data = malloc(sizeof(my_data));
+/// data->… = …;
+/// wasmer_instance_context_data_set(instance, (void*) data);
+///
+/// // You can read your data.
+/// {
+/// my_data *data = (my_data*) wasmer_instance_context_data_get(wasmer_instance_context_get(instance));
+/// // …
+/// }
+/// ```
+void wasmer_instance_context_data_set(wasmer_instance_t *instance,
+ void *data_ptr);
-/// Extracts the instance's context and returns it.
+/// Returns the instance context. Learn more by looking at the
+/// `wasmer_instance_context_t` struct.
+///
+/// This function returns `null` if `instance` is a null pointer.
+///
+/// Example:
+///
+/// ```c
+/// const wasmer_instance_context_get *context = wasmer_instance_context_get(instance);
+/// my_data *data = (my_data *) wasmer_instance_context_data_get(context);
+/// // Do something with `my_data`.
+/// ```
+///
+/// It is often useful with `wasmer_instance_context_data_set()`.
const wasmer_instance_context_t *wasmer_instance_context_get(wasmer_instance_t *instance);
-/// Gets the memory within the context at the index `memory_idx`.
-/// The index is always 0 until multiple memories are supported.
+/// Gets the `memory_idx`th memory of the instance.
+///
+/// Note that the index is always `0` until multiple memories are supported.
+///
+/// This function is mostly used inside host functions (aka imported
+/// functions) to read the instance memory.
+///
+/// Example of a _host function_ that reads and prints a string based on a pointer and a length:
+///
+/// ```c
+/// void print_string(const wasmer_instance_context_t *context, int32_t pointer, int32_t length) {
+/// // Get the 0th memory.
+/// const wasmer_memory_t *memory = wasmer_instance_context_memory(context, 0);
+///
+/// // Get the memory data as a pointer.
+/// uint8_t *memory_bytes = wasmer_memory_data(memory);
+///
+/// // Print what we assumed to be a string!
+/// printf("%.*s", length, memory_bytes + pointer);
+/// }
+/// ```
const wasmer_memory_t *wasmer_instance_context_memory(const wasmer_instance_context_t *ctx,
uint32_t _memory_idx);
-/// Frees memory for the given Instance
+/// Frees memory for the given `wasmer_instance_t`.
+///
+/// Check the `wasmer_instantiate()` function to get a complete
+/// example.
+///
+/// If `instance` is a null pointer, this function does nothing.
+///
+/// Example:
+///
+/// ```c
+/// // Get an instance.
+/// wasmer_instance_t *instance = NULL;
+/// wasmer_instantiate(&instance, bytes, bytes_length, imports, 0);
+///
+/// // Destroy the instance.
+/// wasmer_instance_destroy(instance);
+/// ```
void wasmer_instance_destroy(wasmer_instance_t *instance);
-/// Gets Exports for the given instance
-/// The caller owns the object and should call `wasmer_exports_destroy` to free it.
+/// Gets all the exports of the given WebAssembly instance.
+///
+/// This function stores a Rust vector of exports into `exports` as an
+/// opaque pointer of kind `wasmer_exports_t`.
+///
+/// As is, you can do anything with `exports` except using the
+/// companion functions, like `wasmer_exports_len()`,
+/// `wasmer_exports_get()` or `wasmer_export_kind()`. See the example below.
+///
+/// **Warning**: The caller owns the object and should call
+/// `wasmer_exports_destroy()` to free it.
+///
+/// Example:
+///
+/// ```c
+/// // Get the exports.
+/// wasmer_exports_t *exports = NULL;
+/// wasmer_instance_exports(instance, &exports);
+///
+/// // Get the number of exports.
+/// int exports_length = wasmer_exports_len(exports);
+/// printf("Number of exports: %d\n", exports_length);
+///
+/// // Read the first export.
+/// wasmer_export_t *export = wasmer_exports_get(exports, 0);
+///
+/// // Get the kind of the export.
+/// wasmer_import_export_kind export_kind = wasmer_export_kind(export);
+///
+/// // Assert it is a function (why not).
+/// assert(export_kind == WASM_FUNCTION);
+///
+/// // Read the export name.
+/// wasmer_byte_array name_bytes = wasmer_export_name(export);
+///
+/// assert(name_bytes.bytes_len == sizeof("sum") - 1);
+/// assert(memcmp(name_bytes.bytes, "sum", sizeof("sum") - 1) == 0);
+///
+/// // Destroy the exports.
+/// wasmer_exports_destroy(exports);
+/// ```
void wasmer_instance_exports(wasmer_instance_t *instance, wasmer_exports_t **exports);
-/// Creates a new Instance from the given wasm bytes and imports.
-/// Returns `wasmer_result_t::WASMER_OK` upon success.
-/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
-/// and `wasmer_last_error_message` to get an error message.
+/// Creates a new WebAssembly instance from the given bytes and imports.
+///
+/// The result is stored in the first argument `instance` if
+/// successful, i.e. when the function returns
+/// `wasmer_result_t::WASMER_OK`. Otherwise
+/// `wasmer_result_t::WASMER_ERROR` is returned, and
+/// `wasmer_last_error_length()` with `wasmer_last_error_message()` must
+/// be used to read the error message.
+///
+/// The caller is responsible to free the instance with
+/// `wasmer_instance_destroy()`.
+///
+/// Example:
+///
+/// ```c
+/// // 1. Read a WebAssembly module from a file.
+/// FILE *file = fopen("sum.wasm", "r");
+/// fseek(file, 0, SEEK_END);
+/// long bytes_length = ftell(file);
+/// uint8_t *bytes = malloc(bytes_length);
+/// fseek(file, 0, SEEK_SET);
+/// fread(bytes, 1, bytes_length, file);
+/// fclose(file);
+///
+/// // 2. Declare the imports (here, none).
+/// wasmer_import_t imports[] = {};
+///
+/// // 3. Instantiate the WebAssembly module.
+/// wasmer_instance_t *instance = NULL;
+/// wasmer_result_t result = wasmer_instantiate(&instance, bytes, bytes_length, imports, 0);
+///
+/// // 4. Check for errors.
+/// if (result != WASMER_OK) {
+/// int error_length = wasmer_last_error_length();
+/// char *error = malloc(error_length);
+/// wasmer_last_error_message(error, error_length);
+/// // Do something with `error`…
+/// }
+///
+/// // 5. Free the memory!
+/// wasmer_instance_destroy(instance);
+/// ```
wasmer_result_t wasmer_instantiate(wasmer_instance_t **instance,
uint8_t *wasm_bytes,
uint32_t wasm_bytes_len,
wasmer_import_t *imports,
int imports_len);
-/// Gets the length in bytes of the last error.
+/// Gets the length in bytes of the last error if any.
+///
/// This can be used to dynamically allocate a buffer with the correct number of
/// bytes needed to store a message.
-/// # Example
-/// ```c
-/// int error_len = wasmer_last_error_length();
-/// char *error_str = malloc(error_len);
-/// ```
+///
+/// See `wasmer_last_error_message()` to get a full example.
int wasmer_last_error_length();
-/// Stores the last error message into the provided buffer up to the given `length`.
-/// The `length` parameter must be large enough to store the last error message.
-/// Returns the length of the string in bytes.
-/// Returns `-1` if an error occurs.
-/// # Example
+/// 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 smal to hold the error message.
+///
+/// Note: The error message always has a trailing null character.
+///
+/// Example:
+///
/// ```c
-/// int error_len = wasmer_last_error_length();
-/// char *error_str = malloc(error_len);
-/// wasmer_last_error_message(error_str, error_len);
-/// printf("Error str: `%s`\n", error_str);
+/// int error_length = wasmer_last_error_length();
+///
+/// if (error_length > 0) {
+/// char *error_message = malloc(error_length);
+/// wasmer_last_error_message(error_message, error_length);
+/// printf("Error message: `%s`\n", error_message);
+/// } else {
+/// printf("No error message\n");
+/// }
/// ```
int wasmer_last_error_message(char *buffer, int length);
-/// Gets the start pointer to the bytes within a Memory
-uint8_t *wasmer_memory_data(const wasmer_memory_t *mem);
+/// Gets a pointer to the beginning of the contiguous memory data
+/// bytes.
+///
+/// The function returns `NULL` if `memory` is a null pointer.
+///
+/// Note that when the memory grows, it can be reallocated, and thus
+/// the returned pointer can be invalidated.
+///
+/// Example:
+///
+/// ```c
+/// uint8_t *memory_data = wasmer_memory_data(memory);
+/// char *str = (char*) malloc(sizeof(char) * 7);
+///
+/// for (uint32_t nth = 0; nth < 7; ++nth) {
+/// str[nth] = (char) memory_data[nth];
+/// }
+/// ```
+uint8_t *wasmer_memory_data(const wasmer_memory_t *memory);
-/// Gets the size in bytes of a Memory
-uint32_t wasmer_memory_data_length(wasmer_memory_t *mem);
+/// Gets the size in bytes of the memory data.
+///
+/// This function returns 0 if `memory` is a null pointer.
+///
+/// Example:
+///
+/// ```c
+/// uint32_t memory_data_length = wasmer_memory_data_length(memory);
+/// ```
+uint32_t wasmer_memory_data_length(const wasmer_memory_t *memory);
-/// Frees memory for the given Memory
+/// Frees memory for the given `wasmer_memory_t`.
+///
+/// Check the `wasmer_memory_new()` function to get a complete
+/// example.
+///
+/// If `memory` is a null pointer, this function does nothing.
+///
+/// Example:
+///
+/// ```c
+/// // Get a memory.
+/// wasmer_memory_t *memory = NULL;
+/// wasmer_result_t result = wasmer_memory_new(&memory, memory_descriptor);
+///
+/// // Destroy the memory.
+/// wasmer_memory_destroy(memory);
+/// ```
void wasmer_memory_destroy(wasmer_memory_t *memory);
-/// Grows a Memory by the given number of pages.
-/// Returns `wasmer_result_t::WASMER_OK` upon success.
-/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
-/// and `wasmer_last_error_message` to get an error message.
+/// Grows a memory by the given number of pages (of 65Kb each).
+///
+/// The functions return `wasmer_result_t::WASMER_OK` upon success,
+/// `wasmer_result_t::WASMER_ERROR` otherwise. Use
+/// `wasmer_last_error_length()` with `wasmer_last_error_message()` to
+/// read the error message.
+///
+/// Example:
+///
+/// ```c
+/// wasmer_result_t result = wasmer_memory_grow(memory, 10);
+///
+/// if (result != WASMER_OK) {
+/// // …
+/// }
+/// ```
wasmer_result_t wasmer_memory_grow(wasmer_memory_t *memory, uint32_t delta);
-/// Returns the current length in pages of the given memory
+/// Reads the current length (in pages) of the given memory.
+///
+/// The function returns zero if `memory` is a null pointer.
+///
+/// Example:
+///
+/// ```c
+/// uint32_t memory_length = wasmer_memory_length(memory);
+///
+/// printf("Memory pages length: %d\n", memory_length);
+/// ```
uint32_t wasmer_memory_length(const wasmer_memory_t *memory);
-/// Creates a new Memory for the given descriptor and initializes the given
-/// pointer to pointer to a pointer to the new memory.
-/// The caller owns the object and should call `wasmer_memory_destroy` to free it.
-/// Returns `wasmer_result_t::WASMER_OK` upon success.
-/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
-/// and `wasmer_last_error_message` to get an error message.
+/// Creates a new empty WebAssembly memory for the given descriptor.
+///
+/// The result is stored in the first argument `memory` if successful,
+/// i.e. when the function returns
+/// `wasmer_result_t::WASMER_OK`. Otherwise,
+/// `wasmer_result_t::WASMER_ERROR` is returned, and
+/// `wasmer_last_error_length()` with `wasmer_last_error_message()`
+/// must be used to read the error message.
+///
+/// The caller owns the memory and is responsible to free it with
+/// `wasmer_memory_destroy()`.
+///
+/// Example:
+///
+/// ```c
+/// // 1. The memory object.
+/// wasmer_memory_t *memory = NULL;
+///
+/// // 2. The memory descriptor.
+/// wasmer_limits_t memory_descriptor = {
+/// .min = 10,
+/// .max = {
+/// .has_some = true,
+/// .some = 15,
+/// },
+/// };
+///
+/// // 3. Initialize the memory.
+/// wasmer_result_t result = wasmer_memory_new(&memory, memory_descriptor);
+///
+/// if (result != WASMER_OK) {
+/// int error_length = wasmer_last_error_length();
+/// char *error = malloc(error_length);
+/// wasmer_last_error_message(error, error_length);
+/// // Do something with `error`…
+/// }
+///
+/// // 4. Free the memory!
+/// wasmer_memory_destroy(memory);
+/// ```
wasmer_result_t wasmer_memory_new(wasmer_memory_t **memory, wasmer_limits_t limits);
/// Deserialize the given serialized module.
+///
/// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
/// and `wasmer_last_error_message` to get an error message.
wasmer_result_t wasmer_module_deserialize(wasmer_module_t **module,
@@ -438,15 +1071,18 @@ wasmer_result_t wasmer_module_deserialize(wasmer_module_t **module,
void wasmer_module_destroy(wasmer_module_t *module);
/// Given:
-/// A prepared `wasmer` import-object
-/// A compiled wasmer module
+/// * A prepared `wasmer` import-object
+/// * A compiled wasmer module
+///
/// Instantiates a wasmer instance
wasmer_result_t wasmer_module_import_instantiate(wasmer_instance_t **instance,
const wasmer_module_t *module,
const wasmer_import_object_t *import_object);
/// Creates a new Instance from the given module and imports.
+///
/// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
/// and `wasmer_last_error_message` to get an error message.
wasmer_result_t wasmer_module_instantiate(const wasmer_module_t *module,
@@ -455,8 +1091,11 @@ wasmer_result_t wasmer_module_instantiate(const wasmer_module_t *module,
int imports_len);
/// Serialize the given Module.
+///
/// The caller owns the object and should call `wasmer_serialized_module_destroy` to free it.
+///
/// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
/// and `wasmer_last_error_message` to get an error message.
wasmer_result_t wasmer_module_serialize(wasmer_serialized_module_t **serialized_module,
@@ -469,8 +1108,11 @@ wasmer_byte_array wasmer_serialized_module_bytes(const wasmer_serialized_module_
void wasmer_serialized_module_destroy(wasmer_serialized_module_t *serialized_module);
/// Transform a sequence of bytes into a serialized module.
+///
/// The caller owns the object and should call `wasmer_serialized_module_destroy` to free it.
+///
/// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
/// and `wasmer_last_error_message` to get an error message.
wasmer_result_t wasmer_serialized_module_from_bytes(wasmer_serialized_module_t **serialized_module,
@@ -481,7 +1123,9 @@ wasmer_result_t wasmer_serialized_module_from_bytes(wasmer_serialized_module_t *
void wasmer_table_destroy(wasmer_table_t *table);
/// Grows a Table by the given number of elements.
+///
/// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
/// and `wasmer_last_error_message` to get an error message.
wasmer_result_t wasmer_table_grow(wasmer_table_t *table, uint32_t delta);
@@ -491,42 +1135,139 @@ uint32_t wasmer_table_length(wasmer_table_t *table);
/// Creates a new Table for the given descriptor and initializes the given
/// pointer to pointer to a pointer to the new Table.
+///
/// The caller owns the object and should call `wasmer_table_destroy` to free it.
+///
/// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
/// and `wasmer_last_error_message` to get an error message.
wasmer_result_t wasmer_table_new(wasmer_table_t **table, wasmer_limits_t limits);
+#if (!defined(_WIN32) && defined(ARCH_X86_64))
/// Adds a callinfo trampoline to the builder.
+///
+/// Deprecated. In a future version `DynamicFunc::new` will be exposed to the C API and should be used instead of this function.
uintptr_t wasmer_trampoline_buffer_builder_add_callinfo_trampoline(wasmer_trampoline_buffer_builder_t *builder,
const wasmer_trampoline_callable_t *func,
const void *ctx,
uint32_t num_params);
+#endif
+#if (!defined(_WIN32) && defined(ARCH_X86_64))
/// Adds a context trampoline to the builder.
uintptr_t wasmer_trampoline_buffer_builder_add_context_trampoline(wasmer_trampoline_buffer_builder_t *builder,
const wasmer_trampoline_callable_t *func,
const void *ctx);
+#endif
+#if (!defined(_WIN32) && defined(ARCH_X86_64))
/// Finalizes the trampoline builder into an executable buffer.
wasmer_trampoline_buffer_t *wasmer_trampoline_buffer_builder_build(wasmer_trampoline_buffer_builder_t *builder);
+#endif
+#if (!defined(_WIN32) && defined(ARCH_X86_64))
/// Creates a new trampoline builder.
wasmer_trampoline_buffer_builder_t *wasmer_trampoline_buffer_builder_new();
+#endif
+#if (!defined(_WIN32) && defined(ARCH_X86_64))
/// Destroys the trampoline buffer if not null.
void wasmer_trampoline_buffer_destroy(wasmer_trampoline_buffer_t *buffer);
+#endif
+#if (!defined(_WIN32) && defined(ARCH_X86_64))
/// Returns the callable pointer for the trampoline with index `idx`.
const wasmer_trampoline_callable_t *wasmer_trampoline_buffer_get_trampoline(const wasmer_trampoline_buffer_t *buffer,
uintptr_t idx);
+#endif
+#if (!defined(_WIN32) && defined(ARCH_X86_64))
/// Returns the context added by `add_context_trampoline`, from within the callee function.
void *wasmer_trampoline_get_context();
+#endif
-/// Returns true for valid wasm bytes and false for invalid bytes
+/// Stop the execution of a host function, aka imported function. The
+/// function must be used _only_ inside a host function.
+///
+/// The pointer to `wasmer_instance_context_t` is received by the host
+/// function as its first argument. Just passing it to `ctx` is fine.
+///
+/// The error message must have a greater lifetime than the host
+/// function itself since the error is read outside the host function
+/// with `wasmer_last_error_message`.
+///
+/// This function returns `wasmer_result_t::WASMER_ERROR` if `ctx` or
+/// `error_message` are null.
+///
+/// This function never returns otherwise.
+wasmer_result_t wasmer_trap(const wasmer_instance_context_t *ctx, const char *error_message);
+
+/// Validates a sequence of bytes hoping it represents a valid WebAssembly module.
+///
+/// The function returns true if the bytes are valid, false otherwise.
+///
+/// Example:
+///
+/// ```c
+/// bool result = wasmer_validate(bytes, bytes_length);
+///
+/// if (false == result) {
+/// // Do something…
+/// }
+/// ```
bool wasmer_validate(const uint8_t *wasm_bytes, uint32_t wasm_bytes_len);
+#if defined(WASMER_WASI_ENABLED)
+/// Convenience function that creates a WASI import object with no arguments,
+/// environment variables, preopened files, or mapped directories.
+///
+/// This function is the same as calling [`wasmer_wasi_generate_import_object`] with all
+/// empty values.
+wasmer_import_object_t *wasmer_wasi_generate_default_import_object();
+#endif
+
+#if defined(WASMER_WASI_ENABLED)
+/// Creates a WASI import object.
+///
+/// This function treats null pointers as empty collections.
+/// For example, passing null for a string in `args`, will lead to a zero
+/// length argument in that position.
+wasmer_import_object_t *wasmer_wasi_generate_import_object(const wasmer_byte_array *args,
+ unsigned int args_len,
+ const wasmer_byte_array *envs,
+ unsigned int envs_len,
+ const wasmer_byte_array *preopened_files,
+ unsigned int preopened_files_len,
+ const wasmer_wasi_map_dir_entry_t *mapped_dirs,
+ unsigned int mapped_dirs_len);
+#endif
+
+#if defined(WASMER_WASI_ENABLED)
+/// Creates a WASI import object for a specific version.
+///
+/// This function is similar to `wasmer_wasi_generate_import_object`
+/// except that the first argument describes the WASI version.
+///
+/// The version is expected to be of kind `Version`.
+wasmer_import_object_t *wasmer_wasi_generate_import_object_for_version(unsigned char version,
+ const wasmer_byte_array *args,
+ unsigned int args_len,
+ const wasmer_byte_array *envs,
+ unsigned int envs_len,
+ const wasmer_byte_array *preopened_files,
+ unsigned int preopened_files_len,
+ const wasmer_wasi_map_dir_entry_t *mapped_dirs,
+ unsigned int mapped_dirs_len);
+#endif
+
+#if defined(WASMER_WASI_ENABLED)
+/// Find the version of WASI used by the module.
+///
+/// In case of error, the returned version is `Version::Unknown`.
+Version wasmer_wasi_get_version(const wasmer_module_t *module);
+#endif
+
} // extern "C"
#endif // WASMER_H