chore(runtime-c-api) Update C/C++ headers.

This commit is contained in:
Ivan Enderlin
2020-01-20 15:59:30 +01:00
parent 8283b6d0da
commit 13f87b1618
2 changed files with 498 additions and 68 deletions

View File

@ -66,15 +66,37 @@ typedef uint8_t Version;
* List of export/import kinds. * List of export/import kinds.
*/ */
enum wasmer_import_export_kind { enum wasmer_import_export_kind {
/**
* The export/import is a function.
*/
WASM_FUNCTION = 0, WASM_FUNCTION = 0,
/**
* The export/import is a global.
*/
WASM_GLOBAL = 1, WASM_GLOBAL = 1,
/**
* The export/import is a memory.
*/
WASM_MEMORY = 2, WASM_MEMORY = 2,
/**
* The export/import is a table.
*/
WASM_TABLE = 3, WASM_TABLE = 3,
}; };
typedef uint32_t wasmer_import_export_kind; typedef uint32_t wasmer_import_export_kind;
/**
* The `wasmer_result_t` struct is a type that represents either a
* success, or a failure.
*/
typedef enum { typedef enum {
/**
* Represents a success.
*/
WASMER_OK = 1, WASMER_OK = 1,
/**
* Represents a failure.
*/
WASMER_ERROR = 2, WASMER_ERROR = 2,
} wasmer_result_t; } wasmer_result_t;
@ -164,7 +186,11 @@ typedef struct {
} wasmer_memory_t; } wasmer_memory_t;
/** /**
* Opaque pointer to `NamedExports`. * 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.
*/ */
typedef struct { typedef struct {
@ -226,7 +252,9 @@ typedef struct {
* `wasmer_instance_context_memory()` function. * `wasmer_instance_context_memory()` function.
* *
* It is also possible to get the instance context outside a host * It is also possible to get the instance context outside a host
* function by using the `wasmer_instance_context_get()` function. * function by using the `wasmer_instance_context_get()`
* function. See also `wasmer_instance_context_data_set()` to set the
* instance context data.
* *
* Example: * Example:
* *
@ -484,7 +512,23 @@ const wasmer_export_func_t *wasmer_export_to_func(const wasmer_export_t *export_
wasmer_result_t wasmer_export_to_memory(const wasmer_export_t *export_, wasmer_memory_t **memory); 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); void wasmer_exports_destroy(wasmer_exports_t *exports);
@ -708,13 +752,55 @@ wasmer_import_object_iter_t *wasmer_import_object_iterate_functions(const wasmer
wasmer_import_object_t *wasmer_import_object_new(void); wasmer_import_object_t *wasmer_import_object_new(void);
/** /**
* Calls an instances exported function by `name` with the provided parameters. * Calls an exported function of a WebAssembly instance by `name`
* Results are set using the provided `results` pointer. * with the provided parameters. The exported function results are
* stored on the provided `results` pointer.
* *
* Returns `wasmer_result_t::WASMER_OK` upon success. * 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.
* *
* Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` * Potential errors are the following:
* and `wasmer_last_error_message` to get an error message. *
* * `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, wasmer_result_t wasmer_instance_call(wasmer_instance_t *instance,
const char *name, const char *name,
@ -724,37 +810,157 @@ wasmer_result_t wasmer_instance_call(wasmer_instance_t *instance,
uint32_t results_len); 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); void *wasmer_instance_context_data_get(const wasmer_instance_context_t *ctx);
/** /**
* Sets the `data` field of the instance context. This context will be * Sets the data that can be hold by an instance context.
* passed to all imported function for instance. *
* 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*) my_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); 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); const wasmer_instance_context_t *wasmer_instance_context_get(wasmer_instance_t *instance);
/** /**
* Gets the memory within the context at the index `memory_idx`. * Gets the `memory_idx`th memory of the instance.
* The index is always 0 until multiple memories are supported. *
* 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, const wasmer_memory_t *wasmer_instance_context_memory(const wasmer_instance_context_t *ctx,
uint32_t _memory_idx); 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); void wasmer_instance_destroy(wasmer_instance_t *instance);
/** /**
* Gets Exports for the given instance * Gets all the exports of the given WebAssembly instance.
* *
* The caller owns the object and should call `wasmer_exports_destroy` to free it. * 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); void wasmer_instance_exports(wasmer_instance_t *instance, wasmer_exports_t **exports);
@ -768,6 +974,9 @@ void wasmer_instance_exports(wasmer_instance_t *instance, wasmer_exports_t **exp
* `wasmer_last_error_length()` with `wasmer_last_error_message()` must * `wasmer_last_error_length()` with `wasmer_last_error_message()` must
* be used to read the error message. * be used to read the error message.
* *
* The caller is responsible to free the instance with
* `wasmer_instance_destroy()`.
*
* Example: * Example:
* *
* ```c * ```c
@ -794,6 +1003,9 @@ void wasmer_instance_exports(wasmer_instance_t *instance, wasmer_exports_t **exp
* wasmer_last_error_message(error, error_length); * wasmer_last_error_message(error, error_length);
* // Do something with `error`… * // Do something with `error`…
* } * }
*
* // 5. Free the memory!
* wasmer_instance_destroy(instance);
* ``` * ```
*/ */
wasmer_result_t wasmer_instantiate(wasmer_instance_t **instance, wasmer_result_t wasmer_instantiate(wasmer_instance_t **instance,
@ -803,33 +1015,43 @@ wasmer_result_t wasmer_instantiate(wasmer_instance_t **instance,
int imports_len); 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 * This can be used to dynamically allocate a buffer with the correct number of
* bytes needed to store a message. * bytes needed to store a message.
* *
* # Example * See `wasmer_last_error_message()` to get a full example.
*
* ```c
* int error_len = wasmer_last_error_length();
* char *error_str = malloc(error_len);
* ```
*/ */
int wasmer_last_error_length(void); int wasmer_last_error_length(void);
/** /**
* Stores the last error message into the provided buffer up to the given `length`. * Gets the last error message if any into the provided buffer
* The `length` parameter must be large enough to store the last error message. * `buffer` up to the given `length`.
* *
* Returns the length of the string in bytes. * The `length` parameter must be large enough to store the last
* Returns `-1` if an error occurs. * error message. Ideally, the value should come from
* `wasmer_last_error_length()`.
* *
* # Example * 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 * ```c
* int error_len = wasmer_last_error_length(); * int error_length = wasmer_last_error_length();
* char *error_str = malloc(error_len); *
* wasmer_last_error_message(error_str, error_len); * if (error_length > 0) {
* printf("Error str: `%s`\n", error_str); * 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); int wasmer_last_error_message(char *buffer, int length);

View File

@ -55,14 +55,22 @@ enum class Version : uint8_t {
/// List of export/import kinds. /// List of export/import kinds.
enum class wasmer_import_export_kind : uint32_t { enum class wasmer_import_export_kind : uint32_t {
/// The export/import is a function.
WASM_FUNCTION = 0, WASM_FUNCTION = 0,
/// The export/import is a global.
WASM_GLOBAL = 1, WASM_GLOBAL = 1,
/// The export/import is a memory.
WASM_MEMORY = 2, WASM_MEMORY = 2,
/// The export/import is a table.
WASM_TABLE = 3, WASM_TABLE = 3,
}; };
/// The `wasmer_result_t` struct is a type that represents either a
/// success, or a failure.
enum class wasmer_result_t { enum class wasmer_result_t {
/// Represents a success.
WASMER_OK = 1, WASMER_OK = 1,
/// Represents a failure.
WASMER_ERROR = 2, WASMER_ERROR = 2,
}; };
@ -138,7 +146,11 @@ struct wasmer_memory_t {
}; };
/// Opaque pointer to `NamedExports`. /// 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 { struct wasmer_exports_t {
}; };
@ -196,7 +208,9 @@ struct wasmer_import_object_iter_t {
/// `wasmer_instance_context_memory()` function. /// `wasmer_instance_context_memory()` function.
/// ///
/// It is also possible to get the instance context outside a host /// It is also possible to get the instance context outside a host
/// function by using the `wasmer_instance_context_get()` function. /// function by using the `wasmer_instance_context_get()`
/// function. See also `wasmer_instance_context_data_set()` to set the
/// instance context data.
/// ///
/// Example: /// Example:
/// ///
@ -406,7 +420,23 @@ const wasmer_export_func_t *wasmer_export_to_func(const wasmer_export_t *export_
/// and `wasmer_last_error_message` to get an error message. /// 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); 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); void wasmer_exports_destroy(wasmer_exports_t *exports);
/// Gets wasmer_export by index /// Gets wasmer_export by index
@ -570,13 +600,55 @@ wasmer_import_object_iter_t *wasmer_import_object_iterate_functions(const wasmer
/// See also `wasmer_import_object_append` /// See also `wasmer_import_object_append`
wasmer_import_object_t *wasmer_import_object_new(); wasmer_import_object_t *wasmer_import_object_new();
/// Calls an instances exported function by `name` with the provided parameters. /// Calls an exported function of a WebAssembly instance by `name`
/// Results are set using the provided `results` pointer. /// with the provided parameters. The exported function results are
/// stored on the provided `results` pointer.
/// ///
/// Returns `wasmer_result_t::WASMER_OK` upon success. /// 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.
/// ///
/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` /// Potential errors are the following:
/// and `wasmer_last_error_message` to get an error message. ///
/// * `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, wasmer_result_t wasmer_instance_call(wasmer_instance_t *instance,
const char *name, const char *name,
const wasmer_value_t *params, const wasmer_value_t *params,
@ -584,27 +656,147 @@ wasmer_result_t wasmer_instance_call(wasmer_instance_t *instance,
wasmer_value_t *results, wasmer_value_t *results,
uint32_t results_len); 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); void *wasmer_instance_context_data_get(const wasmer_instance_context_t *ctx);
/// Sets the `data` field of the instance context. This context will be /// Sets the data that can be hold by an instance context.
/// passed to all imported function for instance. ///
void wasmer_instance_context_data_set(wasmer_instance_t *instance, void *data_ptr); /// 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*) my_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); const wasmer_instance_context_t *wasmer_instance_context_get(wasmer_instance_t *instance);
/// Gets the memory within the context at the index `memory_idx`. /// Gets the `memory_idx`th memory of the instance.
/// The index is always 0 until multiple memories are supported. ///
/// 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, const wasmer_memory_t *wasmer_instance_context_memory(const wasmer_instance_context_t *ctx,
uint32_t _memory_idx); 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); void wasmer_instance_destroy(wasmer_instance_t *instance);
/// Gets Exports for the given instance /// Gets all the exports of the given WebAssembly instance.
/// ///
/// The caller owns the object and should call `wasmer_exports_destroy` to free it. /// 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); void wasmer_instance_exports(wasmer_instance_t *instance, wasmer_exports_t **exports);
/// Creates a new WebAssembly instance from the given bytes and imports. /// Creates a new WebAssembly instance from the given bytes and imports.
@ -616,6 +808,9 @@ void wasmer_instance_exports(wasmer_instance_t *instance, wasmer_exports_t **exp
/// `wasmer_last_error_length()` with `wasmer_last_error_message()` must /// `wasmer_last_error_length()` with `wasmer_last_error_message()` must
/// be used to read the error message. /// be used to read the error message.
/// ///
/// The caller is responsible to free the instance with
/// `wasmer_instance_destroy()`.
///
/// Example: /// Example:
/// ///
/// ```c /// ```c
@ -642,6 +837,9 @@ void wasmer_instance_exports(wasmer_instance_t *instance, wasmer_exports_t **exp
/// wasmer_last_error_message(error, error_length); /// wasmer_last_error_message(error, error_length);
/// // Do something with `error`… /// // Do something with `error`…
/// } /// }
///
/// // 5. Free the memory!
/// wasmer_instance_destroy(instance);
/// ``` /// ```
wasmer_result_t wasmer_instantiate(wasmer_instance_t **instance, wasmer_result_t wasmer_instantiate(wasmer_instance_t **instance,
uint8_t *wasm_bytes, uint8_t *wasm_bytes,
@ -649,31 +847,41 @@ wasmer_result_t wasmer_instantiate(wasmer_instance_t **instance,
wasmer_import_t *imports, wasmer_import_t *imports,
int imports_len); 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 /// This can be used to dynamically allocate a buffer with the correct number of
/// bytes needed to store a message. /// bytes needed to store a message.
/// ///
/// # Example /// See `wasmer_last_error_message()` to get a full example.
///
/// ```c
/// int error_len = wasmer_last_error_length();
/// char *error_str = malloc(error_len);
/// ```
int wasmer_last_error_length(); int wasmer_last_error_length();
/// Stores the last error message into the provided buffer up to the given `length`. /// Gets the last error message if any into the provided buffer
/// The `length` parameter must be large enough to store the last error message. /// `buffer` up to the given `length`.
/// ///
/// Returns the length of the string in bytes. /// The `length` parameter must be large enough to store the last
/// Returns `-1` if an error occurs. /// error message. Ideally, the value should come from
/// `wasmer_last_error_length()`.
/// ///
/// # Example /// 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 /// ```c
/// int error_len = wasmer_last_error_length(); /// int error_length = wasmer_last_error_length();
/// char *error_str = malloc(error_len); ///
/// wasmer_last_error_message(error_str, error_len); /// if (error_length > 0) {
/// printf("Error str: `%s`\n", error_str); /// 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); int wasmer_last_error_message(char *buffer, int length);