Update WebAssembly C API submodule to latest commit. (#2579)

* Update WebAssembly C API submodule to latest commit.

This commit updates the WebAssembly C API submodule (for `wasm.h`) to the
latest commit out of master.

This fixes the behavior of `wasm_name_new_from_string` such that it no longer
copies the null character into the name, which caused unexpected failures when
using the Wasmtime linker as imports wouldn't resolve when the null was
present.

Along with this change were breaking changes to `wasm_func_call`, the host
callback signatures, and `wasm_instance_new` to take a vector type instead of a
pointer to an unsized array.

As a result, Wasmtime language bindings based on the C API will need to be
updated once this change is pulled in.

Fixes #2211.
Fixes #2131.

* Update Doxygen comments for wasm.h changes.
This commit is contained in:
Peter Huene
2021-01-14 07:36:12 -08:00
committed by GitHub
parent cde07b9a79
commit f94db6556c
19 changed files with 207 additions and 144 deletions

View File

@@ -317,6 +317,12 @@
* \fn wasm_name_new_new_uninitialized
* \brief Convenience alias
*
* \fn wasm_name_new_from_string
* \brief Create a new name from a C string.
*
* \fn wasm_name_new_from_string_nt
* \brief Create a new name from a C string with null terminator.
*
* \fn wasm_name_copy
* \brief Convenience alias
*
@@ -407,7 +413,7 @@
*
* See #wasm_byte_vec_delete for more information.
*
* \fn own wasm_valtype_t* wasm_valtype_copy(wasm_valtype_t *)
* \fn own wasm_valtype_t* wasm_valtype_copy(const wasm_valtype_t *)
* \brief Creates a new value which matches the provided one.
*
* The caller is responsible for deleting the returned value.
@@ -477,7 +483,7 @@
*
* See #wasm_byte_vec_delete for more information.
*
* \fn own wasm_functype_t* wasm_functype_copy(wasm_functype_t *)
* \fn own wasm_functype_t* wasm_functype_copy(const wasm_functype_t *)
* \brief Creates a new value which matches the provided one.
*
* The caller is responsible for deleting the returned value.
@@ -548,7 +554,7 @@
*
* See #wasm_byte_vec_delete for more information.
*
* \fn own wasm_globaltype_t* wasm_globaltype_copy(wasm_globaltype_t *)
* \fn own wasm_globaltype_t* wasm_globaltype_copy(const wasm_globaltype_t *)
* \brief Creates a new value which matches the provided one.
*
* The caller is responsible for deleting the returned value.
@@ -625,7 +631,7 @@
*
* See #wasm_byte_vec_delete for more information.
*
* \fn own wasm_tabletype_t* wasm_tabletype_copy(wasm_tabletype_t *)
* \fn own wasm_tabletype_t* wasm_tabletype_copy(const wasm_tabletype_t *)
* \brief Creates a new value which matches the provided one.
*
* The caller is responsible for deleting the returned value.
@@ -711,7 +717,7 @@
*
* See #wasm_byte_vec_delete for more information.
*
* \fn own wasm_memorytype_t* wasm_memorytype_copy(wasm_memorytype_t *)
* \fn own wasm_memorytype_t* wasm_memorytype_copy(const wasm_memorytype_t *)
* \brief Creates a new value which matches the provided one.
*
* The caller is responsible for deleting the returned value.
@@ -780,7 +786,7 @@
*
* See #wasm_byte_vec_delete for more information.
*
* \fn own wasm_externtype_t* wasm_externtype_copy(wasm_externtype_t *)
* \fn own wasm_externtype_t* wasm_externtype_copy(const wasm_externtype_t *)
* \brief Creates a new value which matches the provided one.
*
* The caller is responsible for deleting the returned value.
@@ -957,7 +963,7 @@
*
* See #wasm_byte_vec_delete for more information.
*
* \fn own wasm_importtype_t* wasm_importtype_copy(wasm_importtype_t *)
* \fn own wasm_importtype_t* wasm_importtype_copy(const wasm_importtype_t *)
* \brief Creates a new value which matches the provided one.
*
* The caller is responsible for deleting the returned value.
@@ -1038,7 +1044,7 @@
*
* See #wasm_byte_vec_delete for more information.
*
* \fn own wasm_exporttype_t* wasm_exporttype_copy(wasm_exporttype_t *)
* \fn own wasm_exporttype_t* wasm_exporttype_copy(const wasm_exporttype_t *)
* \brief Creates a new value which matches the provided one.
*
* The caller is responsible for deleting the returned value.
@@ -1520,8 +1526,6 @@
* and types of results as the original type signature. It is undefined behavior
* to return other types or different numbers of values.
*
* This function takes ownership of all of the parameters given. It's expected
* that the caller will invoke `wasm_val_delete` for each one provided.
* Ownership of the results and the trap returned, if any, is passed to the
* caller of this function.
*
@@ -1608,7 +1612,7 @@
* \fn size_t wasm_func_result_arity(const wasm_func_t *);
* \brief Returns the number of results returned by this function.
*
* \fn own wasm_trap_t *wasm_func_call(const wasm_func_t *, const wasm_val_t args[], const wasm_val_t results[]);
* \fn own wasm_trap_t *wasm_func_call(const wasm_func_t *, const wasm_val_vec_t *args, wasm_val_vec_t *results);
* \brief Calls the provided function with the arguments given.
*
* This function is used to call WebAssembly from the host. The parameter array
@@ -2164,7 +2168,7 @@
* \fn wasm_ref_as_instance_const(const wasm_ref_t *);
* \brief Unimplemented in Wasmtime, aborts the process if called.
*
* \fn own wasm_instance_t *wasm_instance_new(wasm_store_t *, const wasm_module_t *, const wasm_extern_t *const[], wasm_trap_t **);
* \fn own wasm_instance_t *wasm_instance_new(wasm_store_t *, const wasm_module_t *, const wasm_extern_vec_t *, wasm_trap_t **);
* \brief Instantiates a module with the provided imports.
*
* This function will instantiate the provided #wasm_module_t into the provided
@@ -2194,3 +2198,29 @@
* the same length as #wasm_module_exports called on the original module. Each
* element is 1:1 matched with the elements in the list of #wasm_module_exports.
*/
/**
* \def WASM_EMPTY_VEC
* \brief Used to initialize an empty vector type.
*
* \def WASM_ARRAY_VEC
* \brief Used to initialize a vector type from a C array.
*
* \def WASM_I32_VAL
* \brief Used to initialize a 32-bit integer wasm_val_t value.
*
* \def WASM_I64_VAL
* \brief Used to initialize a 64-bit integer wasm_val_t value.
*
* \def WASM_F32_VAL
* \brief Used to initialize a 32-bit floating point wasm_val_t value.
*
* \def WASM_F64_VAL
* \brief Used to initialize a 64-bit floating point wasm_val_t value.
*
* \def WASM_REF_VAL
* \brief Used to initialize an externref wasm_val_t value.
*
* \def WASM_INIT_VAL
* \brief Used to initialize a null externref wasm_val_t value.
*/

View File

@@ -671,7 +671,6 @@ WASM_API_EXTERN const wasm_name_t *wasmtime_frame_module_name(const wasm_frame_t
*
* This function is similar to #wasm_func_call, but with a few tweaks:
*
* * `args` and `results` have a size parameter saying how big the arrays are
* * An error *and* a trap can be returned
* * Errors are returned if `args` have the wrong types, if the args/results
* arrays have the wrong lengths, or if values come from the wrong store.
@@ -697,10 +696,8 @@ WASM_API_EXTERN const wasm_name_t *wasmtime_frame_module_name(const wasm_frame_t
*/
WASM_API_EXTERN own wasmtime_error_t *wasmtime_func_call(
wasm_func_t *func,
const wasm_val_t *args,
size_t num_args,
wasm_val_t *results,
size_t num_results,
const wasm_val_vec_t *args,
wasm_val_vec_t *results,
own wasm_trap_t **trap
);
@@ -741,7 +738,6 @@ WASM_API_EXTERN own wasmtime_error_t *wasmtime_global_set(
* This function is similar to #wasm_instance_new, but with a few tweaks:
*
* * An error message can be returned from this function.
* * The number of imports specified is passed as an argument
* * The `trap` pointer is required to not be NULL.
*
* The states of return values from this function are similar to
@@ -759,8 +755,7 @@ WASM_API_EXTERN own wasmtime_error_t *wasmtime_global_set(
WASM_API_EXTERN own wasmtime_error_t *wasmtime_instance_new(
wasm_store_t *store,
const wasm_module_t *module,
const wasm_extern_t* const imports[],
size_t num_imports,
const wasm_extern_vec_t* imports,
own wasm_instance_t **instance,
own wasm_trap_t **trap
);
@@ -1016,7 +1011,7 @@ WASM_API_EXTERN own wasmtime_error_t *wasmtime_module_deserialize(
*
* See #wasm_byte_vec_delete for more information.
*
* \fn own wasm_instancetype_t* wasm_instancetype_copy(wasm_instancetype_t *)
* \fn own wasm_instancetype_t* wasm_instancetype_copy(const wasm_instancetype_t *)
* \brief Creates a new value which matches the provided one.
*
* The caller is responsible for deleting the returned value.
@@ -1113,7 +1108,7 @@ WASM_API_EXTERN const wasm_instancetype_t* wasm_externtype_as_instancetype_const
*
* See #wasm_byte_vec_delete for more information.
*
* \fn own wasm_moduletype_t* wasm_moduletype_copy(wasm_moduletype_t *)
* \fn own wasm_moduletype_t* wasm_moduletype_copy(const wasm_moduletype_t *)
* \brief Creates a new value which matches the provided one.
*
* The caller is responsible for deleting the returned value.

View File

@@ -1,4 +1,4 @@
use crate::{wasm_extern_t, wasm_functype_t, wasm_store_t, wasm_val_t};
use crate::{wasm_extern_t, wasm_functype_t, wasm_store_t, wasm_val_t, wasm_val_vec_t};
use crate::{wasm_name_t, wasm_trap_t, wasmtime_error_t};
use anyhow::anyhow;
use std::ffi::c_void;
@@ -21,26 +21,28 @@ pub struct wasmtime_caller_t<'a> {
caller: Caller<'a>,
}
pub type wasm_func_callback_t =
extern "C" fn(args: *const wasm_val_t, results: *mut wasm_val_t) -> Option<Box<wasm_trap_t>>;
pub type wasm_func_callback_t = extern "C" fn(
args: *const wasm_val_vec_t,
results: *mut wasm_val_vec_t,
) -> Option<Box<wasm_trap_t>>;
pub type wasm_func_callback_with_env_t = extern "C" fn(
env: *mut std::ffi::c_void,
args: *const wasm_val_t,
results: *mut wasm_val_t,
args: *const wasm_val_vec_t,
results: *mut wasm_val_vec_t,
) -> Option<Box<wasm_trap_t>>;
pub type wasmtime_func_callback_t = extern "C" fn(
caller: *const wasmtime_caller_t,
args: *const wasm_val_t,
results: *mut wasm_val_t,
args: *const wasm_val_vec_t,
results: *mut wasm_val_vec_t,
) -> Option<Box<wasm_trap_t>>;
pub type wasmtime_func_callback_with_env_t = extern "C" fn(
caller: *const wasmtime_caller_t,
env: *mut std::ffi::c_void,
args: *const wasm_val_t,
results: *mut wasm_val_t,
args: *const wasm_val_vec_t,
results: *mut wasm_val_vec_t,
) -> Option<Box<wasm_trap_t>>;
struct Finalizer {
@@ -83,21 +85,25 @@ impl From<Func> for wasm_func_t {
fn create_function(
store: &wasm_store_t,
ty: &wasm_functype_t,
func: impl Fn(Caller<'_>, *const wasm_val_t, *mut wasm_val_t) -> Option<Box<wasm_trap_t>> + 'static,
func: impl Fn(Caller<'_>, *const wasm_val_vec_t, *mut wasm_val_vec_t) -> Option<Box<wasm_trap_t>>
+ 'static,
) -> Box<wasm_func_t> {
let store = &store.store;
let ty = ty.ty().ty.clone();
let func = Func::new(store, ty, move |caller, params, results| {
let params = params
let params: wasm_val_vec_t = params
.iter()
.cloned()
.map(|p| wasm_val_t::from_val(p))
.collect::<Vec<_>>();
let mut out_results = vec![wasm_val_t::default(); results.len()];
let out = func(caller, params.as_ptr(), out_results.as_mut_ptr());
.collect::<Vec<_>>()
.into();
let mut out_results: wasm_val_vec_t = vec![wasm_val_t::default(); results.len()].into();
let out = func(caller, &params, &mut out_results);
if let Some(trap) = out {
return Err(trap.trap.clone());
}
let out_results = out_results.as_slice();
for i in 0..results.len() {
results[i] = out_results[i].val();
}
@@ -164,17 +170,14 @@ pub extern "C" fn wasmtime_func_new_with_env(
#[no_mangle]
pub unsafe extern "C" fn wasm_func_call(
wasm_func: &wasm_func_t,
args: *const wasm_val_t,
results: *mut MaybeUninit<wasm_val_t>,
args: *const wasm_val_vec_t,
results: *mut wasm_val_vec_t,
) -> *mut wasm_trap_t {
let func = wasm_func.func();
let mut trap = ptr::null_mut();
let error = wasmtime_func_call(
let error = _wasmtime_func_call(
wasm_func,
args,
func.param_arity(),
results,
func.result_arity(),
(*args).as_slice(),
(*results).as_uninit_slice(),
&mut trap,
);
match error {
@@ -186,16 +189,14 @@ pub unsafe extern "C" fn wasm_func_call(
#[no_mangle]
pub unsafe extern "C" fn wasmtime_func_call(
func: &wasm_func_t,
args: *const wasm_val_t,
num_args: usize,
results: *mut MaybeUninit<wasm_val_t>,
num_results: usize,
args: *const wasm_val_vec_t,
results: *mut wasm_val_vec_t,
trap_ptr: &mut *mut wasm_trap_t,
) -> Option<Box<wasmtime_error_t>> {
_wasmtime_func_call(
func,
std::slice::from_raw_parts(args, num_args),
std::slice::from_raw_parts_mut(results, num_results),
(*args).as_slice(),
(*results).as_uninit_slice(),
trap_ptr,
)
}

View File

@@ -40,16 +40,15 @@ impl wasm_instance_t {
pub unsafe extern "C" fn wasm_instance_new(
store: &wasm_store_t,
wasm_module: &wasm_module_t,
imports: *const Box<wasm_extern_t>,
imports: *const wasm_extern_vec_t,
result: Option<&mut *mut wasm_trap_t>,
) -> Option<Box<wasm_instance_t>> {
let mut instance = ptr::null_mut();
let mut trap = ptr::null_mut();
let err = wasmtime_instance_new(
let err = _wasmtime_instance_new(
store,
wasm_module,
imports,
wasm_module.module().imports().len(),
(*imports).as_slice(),
&mut instance,
&mut trap,
);
@@ -83,31 +82,27 @@ pub unsafe extern "C" fn wasm_instance_new(
pub unsafe extern "C" fn wasmtime_instance_new(
store: &wasm_store_t,
module: &wasm_module_t,
imports: *const Box<wasm_extern_t>,
num_imports: usize,
imports: *const wasm_extern_vec_t,
instance_ptr: &mut *mut wasm_instance_t,
trap_ptr: &mut *mut wasm_trap_t,
) -> Option<Box<wasmtime_error_t>> {
_wasmtime_instance_new(
store,
module,
std::slice::from_raw_parts(imports, num_imports),
instance_ptr,
trap_ptr,
)
_wasmtime_instance_new(store, module, (*imports).as_slice(), instance_ptr, trap_ptr)
}
fn _wasmtime_instance_new(
store: &wasm_store_t,
module: &wasm_module_t,
imports: &[Box<wasm_extern_t>],
imports: &[Option<Box<wasm_extern_t>>],
instance_ptr: &mut *mut wasm_instance_t,
trap_ptr: &mut *mut wasm_trap_t,
) -> Option<Box<wasmtime_error_t>> {
let store = &store.store;
let imports = imports
.iter()
.map(|import| import.which.clone())
.filter_map(|import| match import {
Some(i) => Some(i.which.clone()),
None => None,
})
.collect::<Vec<_>>();
handle_instantiate(
Instance::new(store, module.module(), &imports),

View File

@@ -4,6 +4,7 @@ use crate::{
wasm_moduletype_t, wasm_tabletype_t, wasm_val_t, wasm_valtype_t,
};
use std::mem;
use std::mem::MaybeUninit;
use std::ptr;
use std::slice;
@@ -54,6 +55,18 @@ macro_rules! declare_vecs {
}
}
pub fn as_uninit_slice(&mut self) -> &mut [MaybeUninit<$elem_ty>] {
// Note that we're careful to not create a slice with a null
// pointer as the data pointer, since that isn't defined
// behavior in Rust.
if self.size == 0 {
&mut []
} else {
assert!(!self.data.is_null());
unsafe { slice::from_raw_parts_mut(self.data as _, self.size) }
}
}
pub fn take(&mut self) -> Vec<$elem_ty> {
if self.data.is_null() {
return Vec::new();

View File

@@ -75,7 +75,8 @@ int main() {
printf("Instantiating module...\n");
wasm_trap_t *trap = NULL;
wasm_instance_t *instance = NULL;
error = wasmtime_instance_new(store, module, NULL, 0, &instance, &trap);
wasm_extern_vec_t imports = WASM_EMPTY_VEC;
error = wasmtime_instance_new(store, module, &imports, &instance, &trap);
if (instance == NULL)
exit_with_error("failed to instantiate", error, trap);
@@ -139,10 +140,11 @@ int main() {
assert(func != NULL);
// And call it!
wasm_val_t args[1];
wasm_val_copy(&args[0], &externref);
wasm_val_t args[1] = { externref };
wasm_val_t results[1];
error = wasmtime_func_call(func, args, 1, results, 1, &trap);
wasm_val_vec_t args_vec = WASM_ARRAY_VEC(args);
wasm_val_vec_t results_vec = WASM_ARRAY_VEC(results);
error = wasmtime_func_call(func, &args_vec, &results_vec, &trap);
if (error != NULL || trap != NULL)
exit_with_error("failed to call function", error, trap);
@@ -161,7 +163,6 @@ int main() {
ret = 0;
wasm_val_delete(&results[0]);
wasm_val_delete(&args[0]);
wasm_val_delete(&global_val);
wasm_val_delete(&elem);
wasm_extern_vec_delete(&externs);

View File

@@ -71,7 +71,8 @@ int main(int argc, const char* argv[]) {
printf("Instantiating module...\n");
wasm_instance_t* instance = NULL;
wasm_trap_t *trap = NULL;
error = wasmtime_instance_new(store, module, NULL, 0, &instance, &trap);
wasm_extern_vec_t imports = WASM_EMPTY_VEC;
error = wasmtime_instance_new(store, module, &imports, &instance, &trap);
if (error != NULL || trap != NULL)
exit_with_error("failed to instantiate", error, trap);
wasm_module_delete(module);
@@ -95,9 +96,11 @@ int main(int argc, const char* argv[]) {
// Call.
printf("Calling fib...\n");
wasm_val_t params[1] = { {.kind = WASM_I32, .of = {.i32 = 6}} };
wasm_val_t params[1] = { WASM_I32_VAL(6) };
wasm_val_t results[1];
error = wasmtime_func_call(run_func, params, 1, results, 1, &trap);
wasm_val_vec_t params_vec = WASM_ARRAY_VEC(params);
wasm_val_vec_t results_vec = WASM_ARRAY_VEC(results);
error = wasmtime_func_call(run_func, &params_vec, &results_vec, &trap);
if (error != NULL || trap != NULL)
exit_with_error("failed to call function", error, trap);

View File

@@ -65,7 +65,8 @@ int main() {
wasm_byte_vec_delete(&wasm);
wasm_trap_t *trap = NULL;
wasm_instance_t *instance = NULL;
error = wasmtime_instance_new(store, module, NULL, 0, &instance, &trap);
wasm_extern_vec_t imports = WASM_EMPTY_VEC;
error = wasmtime_instance_new(store, module, &imports, &instance, &trap);
if (instance == NULL)
exit_with_error("failed to instantiate", error, trap);
@@ -79,13 +80,11 @@ int main() {
// And call it!
int a = 6;
int b = 27;
wasm_val_t params[2];
wasm_val_t params[2] = { WASM_I32_VAL(a), WASM_I32_VAL(b) };
wasm_val_t results[1];
params[0].kind = WASM_I32;
params[0].of.i32 = a;
params[1].kind = WASM_I32;
params[1].of.i32 = b;
error = wasmtime_func_call(gcd, params, 2, results, 1, &trap);
wasm_val_vec_t params_vec = WASM_ARRAY_VEC(params);
wasm_val_vec_t results_vec = WASM_ARRAY_VEC(results);
error = wasmtime_func_call(gcd, &params_vec, &results_vec, &trap);
if (error != NULL || trap != NULL)
exit_with_error("failed to call gcd", error, trap);
assert(results[0].kind == WASM_I32);

View File

@@ -26,7 +26,7 @@ to tweak the `-lpthread` and such annotations as well as the name of the
static void exit_with_error(const char *message, wasmtime_error_t *error, wasm_trap_t *trap);
static wasm_trap_t* hello_callback(const wasm_val_t args[], wasm_val_t results[]) {
static wasm_trap_t* hello_callback(const wasm_val_vec_t* args, wasm_val_vec_t* results) {
printf("Calling back...\n");
printf("> Hello World!\n");
return NULL;
@@ -86,8 +86,9 @@ int main() {
printf("Instantiating module...\n");
wasm_trap_t *trap = NULL;
wasm_instance_t *instance = NULL;
const wasm_extern_t *imports[] = { wasm_func_as_extern(hello) };
error = wasmtime_instance_new(store, module, imports, 1, &instance, &trap);
wasm_extern_t* imports[] = { wasm_func_as_extern(hello) };
wasm_extern_vec_t imports_vec = WASM_ARRAY_VEC(imports);
error = wasmtime_instance_new(store, module, &imports_vec, &instance, &trap);
if (instance == NULL)
exit_with_error("failed to instantiate", error, trap);
@@ -101,7 +102,9 @@ int main() {
// And call it!
printf("Calling export...\n");
error = wasmtime_func_call(run, NULL, 0, NULL, 0, &trap);
wasm_val_vec_t args_vec = WASM_EMPTY_VEC;
wasm_val_vec_t results_vec = WASM_EMPTY_VEC;
error = wasmtime_func_call(run, &args_vec, &results_vec, &trap);
if (error != NULL || trap != NULL)
exit_with_error("failed to call function", error, trap);

View File

@@ -26,7 +26,7 @@ to tweak the `-lpthread` and such annotations as well as the name of the
static void exit_with_error(const char *message, wasmtime_error_t *error, wasm_trap_t *trap);
static wasm_trap_t* hello_callback(const wasm_val_t args[], wasm_val_t results[]) {
static wasm_trap_t* hello_callback(const wasm_val_vec_t* args, wasm_val_vec_t* results) {
printf("Calling back...\n");
printf("> Hello World!\n");
return NULL;
@@ -86,8 +86,9 @@ int main() {
printf("Instantiating module...\n");
wasm_trap_t *trap = NULL;
wasm_instance_t *instance = NULL;
const wasm_extern_t *imports[] = { wasm_func_as_extern(hello) };
error = wasmtime_instance_new(store, module, imports, 1, &instance, &trap);
wasm_extern_t* imports[] = { wasm_func_as_extern(hello) };
wasm_extern_vec_t imports_vec = WASM_ARRAY_VEC(imports);
error = wasmtime_instance_new(store, module, &imports_vec, &instance, &trap);
if (instance == NULL)
exit_with_error("failed to instantiate", error, trap);
@@ -101,7 +102,9 @@ int main() {
// And call it!
printf("Calling export...\n");
error = wasmtime_func_call(run, NULL, 0, NULL, 0, &trap);
wasm_val_vec_t args_vec = WASM_EMPTY_VEC;
wasm_val_vec_t results_vec = WASM_EMPTY_VEC;
error = wasmtime_func_call(run, &args_vec, &results_vec, &trap);
if (error != NULL || trap != NULL)
exit_with_error("failed to call function", error, trap);

View File

@@ -42,6 +42,7 @@ static void* helper(void *_handle) {
printf("Sending an interrupt\n");
wasmtime_interrupt_handle_interrupt(handle);
wasmtime_interrupt_handle_delete(handle);
return 0;
}
static void spawn_interrupt(wasmtime_interrupt_handle_t *handle) {
@@ -89,11 +90,12 @@ int main() {
wasm_module_t *module = NULL;
wasm_trap_t *trap = NULL;
wasm_instance_t *instance = NULL;
wasm_extern_vec_t imports = WASM_EMPTY_VEC;
error = wasmtime_module_new(engine, &wasm, &module);
wasm_byte_vec_delete(&wasm);
if (error != NULL)
exit_with_error("failed to compile module", error, NULL);
error = wasmtime_instance_new(store, module, NULL, 0, &instance, &trap);
error = wasmtime_instance_new(store, module, &imports, &instance, &trap);
if (instance == NULL)
exit_with_error("failed to instantiate", error, trap);
@@ -109,7 +111,9 @@ int main() {
// And call it!
printf("Entering infinite loop...\n");
error = wasmtime_func_call(run, NULL, 0, NULL, 0, &trap);
wasm_val_vec_t args_vec = WASM_EMPTY_VEC;
wasm_val_vec_t results_vec = WASM_EMPTY_VEC;
error = wasmtime_func_call(run, &args_vec, &results_vec, &trap);
assert(error == NULL);
assert(trap != NULL);
printf("Got a trap!...\n");

View File

@@ -100,7 +100,9 @@ int main() {
assert(linking1_externs.size == 1);
wasm_func_t *run = wasm_extern_as_func(linking1_externs.data[0]);
assert(run != NULL);
error = wasmtime_func_call(run, NULL, 0, NULL, 0, &trap);
wasm_val_vec_t args_vec = WASM_EMPTY_VEC;
wasm_val_vec_t results_vec = WASM_EMPTY_VEC;
error = wasmtime_func_call(run, &args_vec, &results_vec, &trap);
if (error != NULL || trap != NULL)
exit_with_error("failed to call run", error, trap);

View File

@@ -54,10 +54,11 @@ void check(bool success) {
}
}
void check_call(wasm_func_t* func, wasm_val_t args[], size_t num_args, int32_t expected) {
void check_call(wasm_func_t* func, const wasm_val_vec_t* args_vec, int32_t expected) {
wasm_val_t results[1];
wasm_val_vec_t results_vec = WASM_ARRAY_VEC(results);
wasm_trap_t *trap = NULL;
wasmtime_error_t *error = wasmtime_func_call(func, args, num_args, results, 1, &trap);
wasmtime_error_t *error = wasmtime_func_call(func, args_vec, &results_vec, &trap);
if (error != NULL || trap != NULL)
exit_with_error("failed to call function", error, trap);
if (results[0].of.i32 != expected) {
@@ -67,42 +68,44 @@ void check_call(wasm_func_t* func, wasm_val_t args[], size_t num_args, int32_t e
}
void check_call0(wasm_func_t* func, int32_t expected) {
check_call(func, NULL, 0, expected);
wasm_val_vec_t args_vec = WASM_EMPTY_VEC;
check_call(func, &args_vec, expected);
}
void check_call1(wasm_func_t* func, int32_t arg, int32_t expected) {
wasm_val_t args[] = { {.kind = WASM_I32, .of = {.i32 = arg}} };
check_call(func, args, 1, expected);
wasm_val_t args[] = { WASM_I32_VAL(arg) };
wasm_val_vec_t args_vec = WASM_ARRAY_VEC(args);
check_call(func, &args_vec, expected);
}
void check_call2(wasm_func_t* func, int32_t arg1, int32_t arg2, int32_t expected) {
wasm_val_t args[2] = {
{.kind = WASM_I32, .of = {.i32 = arg1}},
{.kind = WASM_I32, .of = {.i32 = arg2}}
};
check_call(func, args, 2, expected);
wasm_val_t args[] = { WASM_I32_VAL(arg1), WASM_I32_VAL(arg2) };
wasm_val_vec_t args_vec = WASM_ARRAY_VEC(args);
check_call(func, &args_vec, expected);
}
void check_ok(wasm_func_t* func, wasm_val_t args[], size_t num_args) {
void check_ok(wasm_func_t* func, const wasm_val_vec_t* args_vec) {
wasm_trap_t *trap = NULL;
wasmtime_error_t *error = wasmtime_func_call(func, args, num_args, NULL, 0, &trap);
wasm_val_vec_t results_vec = WASM_EMPTY_VEC;
wasmtime_error_t *error = wasmtime_func_call(func, args_vec, &results_vec, &trap);
if (error != NULL || trap != NULL)
exit_with_error("failed to call function", error, trap);
}
void check_ok2(wasm_func_t* func, int32_t arg1, int32_t arg2) {
wasm_val_t args[2] = {
{.kind = WASM_I32, .of = {.i32 = arg1}},
{.kind = WASM_I32, .of = {.i32 = arg2}}
};
check_ok(func, args, 2);
wasm_val_t args[] = { WASM_I32_VAL(arg1), WASM_I32_VAL(arg2) };
wasm_val_vec_t args_vec = WASM_ARRAY_VEC(args);
check_ok(func, &args_vec);
}
void check_trap(wasm_func_t* func, wasm_val_t args[], size_t num_args, size_t num_results) {
wasm_val_t results[1];
void check_trap(wasm_func_t* func, const wasm_val_vec_t* args_vec, size_t num_results) {
assert(num_results <= 1);
wasm_val_t results[1];
wasm_val_vec_t results_vec;
results_vec.data = results;
results_vec.size = num_results;
wasm_trap_t *trap = NULL;
wasmtime_error_t *error = wasmtime_func_call(func, args, num_args, results, num_results, &trap);
wasmtime_error_t *error = wasmtime_func_call(func, args_vec, &results_vec, &trap);
if (error != NULL)
exit_with_error("failed to call function", error, NULL);
if (trap == NULL) {
@@ -113,16 +116,15 @@ void check_trap(wasm_func_t* func, wasm_val_t args[], size_t num_args, size_t nu
}
void check_trap1(wasm_func_t* func, int32_t arg) {
wasm_val_t args[1] = { {.kind = WASM_I32, .of = {.i32 = arg}} };
check_trap(func, args, 1, 1);
wasm_val_t args[] = { WASM_I32_VAL(arg) };
wasm_val_vec_t args_vec = WASM_ARRAY_VEC(args);
check_trap(func, &args_vec, 1);
}
void check_trap2(wasm_func_t* func, int32_t arg1, int32_t arg2) {
wasm_val_t args[2] = {
{.kind = WASM_I32, .of = {.i32 = arg1}},
{.kind = WASM_I32, .of = {.i32 = arg2}}
};
check_trap(func, args, 2, 0);
wasm_val_t args[] = { WASM_I32_VAL(arg1), WASM_I32_VAL(arg2) };
wasm_val_vec_t args_vec = WASM_ARRAY_VEC(args);
check_trap(func, &args_vec, 0);
}
int main(int argc, const char* argv[]) {
@@ -167,7 +169,8 @@ int main(int argc, const char* argv[]) {
printf("Instantiating module...\n");
wasm_instance_t* instance = NULL;
wasm_trap_t *trap = NULL;
error = wasmtime_instance_new(store, module, NULL, 0, &instance, &trap);
wasm_extern_vec_t imports = WASM_EMPTY_VEC;
error = wasmtime_instance_new(store, module, &imports, &instance, &trap);
if (!instance)
exit_with_error("failed to instantiate", error, trap);

View File

@@ -32,14 +32,14 @@ static void exit_with_error(const char *message, wasmtime_error_t *error, wasm_t
// A function to be called from Wasm code.
wasm_trap_t* callback(
const wasm_val_t args[], wasm_val_t results[]
const wasm_val_vec_t* args, wasm_val_vec_t* results
) {
printf("Calling back...\n");
printf("> %"PRIu32" %"PRIu64"\n", args[0].of.i32, args[1].of.i64);
printf("> %"PRIu32" %"PRIu64"\n", args->data[0].of.i32, args->data[1].of.i64);
printf("\n");
wasm_val_copy(&results[0], &args[1]);
wasm_val_copy(&results[1], &args[0]);
wasm_val_copy(&results->data[0], &args->data[1]);
wasm_val_copy(&results->data[1], &args->data[0]);
return NULL;
}
@@ -112,10 +112,11 @@ int main(int argc, const char* argv[]) {
// Instantiate.
printf("Instantiating module...\n");
const wasm_extern_t* imports[] = {wasm_func_as_extern(callback_func)};
wasm_extern_t* imports[] = {wasm_func_as_extern(callback_func)};
wasm_extern_vec_t imports_vec = WASM_ARRAY_VEC(imports);
wasm_instance_t* instance = NULL;
wasm_trap_t* trap = NULL;
error = wasmtime_instance_new(store, module, imports, 1, &instance, &trap);
error = wasmtime_instance_new(store, module, &imports_vec, &instance, &trap);
if (!instance)
exit_with_error("failed to instantiate", error, trap);
@@ -140,13 +141,11 @@ int main(int argc, const char* argv[]) {
// Call.
printf("Calling export...\n");
wasm_val_t args[2];
args[0].kind = WASM_I32;
args[0].of.i32 = 1;
args[1].kind = WASM_I64;
args[1].of.i64 = 2;
wasm_val_t args[2] = { WASM_I32_VAL(1), WASM_I64_VAL(2) };
wasm_val_t results[2];
error = wasmtime_func_call(run_func, args, 2, results, 2, &trap);
wasm_val_vec_t args_vec = WASM_ARRAY_VEC(args);
wasm_val_vec_t results_vec = WASM_ARRAY_VEC(results);
error = wasmtime_func_call(run_func, &args_vec, &results_vec, &trap);
if (error != NULL || trap != NULL)
exit_with_error("failed to call run", error, trap);

View File

@@ -26,7 +26,7 @@ to tweak the `-lpthread` and such annotations as well as the name of the
static void exit_with_error(const char *message, wasmtime_error_t *error, wasm_trap_t *trap);
static wasm_trap_t* hello_callback(const wasm_val_t args[], wasm_val_t results[]) {
static wasm_trap_t* hello_callback(const wasm_val_vec_t* args, wasm_val_vec_t* results) {
printf("Calling back...\n");
printf("> Hello World!\n");
return NULL;
@@ -111,8 +111,9 @@ int deserialize(wasm_byte_vec_t* buffer) {
printf("Instantiating module...\n");
wasm_trap_t *trap = NULL;
wasm_instance_t *instance = NULL;
const wasm_extern_t *imports[] = { wasm_func_as_extern(hello) };
error = wasmtime_instance_new(store, module, imports, 1, &instance, &trap);
wasm_extern_t *imports[] = { wasm_func_as_extern(hello) };
wasm_extern_vec_t imports_vec = WASM_ARRAY_VEC(imports);
error = wasmtime_instance_new(store, module, &imports_vec, &instance, &trap);
if (instance == NULL)
exit_with_error("failed to instantiate", error, trap);
@@ -126,7 +127,9 @@ int deserialize(wasm_byte_vec_t* buffer) {
// And call it!
printf("Calling export...\n");
error = wasmtime_func_call(run, NULL, 0, NULL, 0, &trap);
wasm_val_vec_t args_vec = WASM_EMPTY_VEC;
wasm_val_vec_t results_vec = WASM_EMPTY_VEC;
error = wasmtime_func_call(run, &args_vec, &results_vec, &trap);
if (error != NULL || trap != NULL)
exit_with_error("failed to call function", error, trap);

View File

@@ -17,9 +17,9 @@ const int N_THREADS = 10;
const int N_REPS = 3;
// A function to be called from Wasm code.
own wasm_trap_t* callback(const wasm_val_t args[], wasm_val_t results[]) {
assert(args[0].kind == WASM_I32);
printf("> Thread %d running\n", args[0].of.i32);
own wasm_trap_t* callback(const wasm_val_vec_t* args, wasm_val_vec_t* results) {
assert(args->data[0].kind == WASM_I32);
printf("> Thread %d running\n", args->data[0].of.i32);
return NULL;
}
@@ -53,11 +53,12 @@ void* run(void* args_abs) {
wasm_globaltype_delete(global_type);
// Instantiate.
const wasm_extern_t* imports[] = {
wasm_extern_t* imports[] = {
wasm_func_as_extern(func), wasm_global_as_extern(global),
};
wasm_extern_vec_t imports_vec = WASM_ARRAY_VEC(imports);
own wasm_instance_t* instance =
wasm_instance_new(store, module, imports, NULL);
wasm_instance_new(store, module, &imports_vec, NULL);
if (!instance) {
printf("> Error instantiating module!\n");
return NULL;
@@ -82,7 +83,9 @@ void* run(void* args_abs) {
wasm_instance_delete(instance);
// Call.
if (wasm_func_call(run_func, NULL, NULL)) {
wasm_val_vec_t args_vec = WASM_EMPTY_VEC;
wasm_val_vec_t results_vec = WASM_EMPTY_VEC;
if (wasm_func_call(run_func, &args_vec, &results_vec)) {
printf("> Error calling function!\n");
return NULL;
}

View File

@@ -91,7 +91,10 @@ int main() {
wasmtime_linker_get_default(linker, &empty, &func);
if (error != NULL)
exit_with_error("failed to locate default export for module", error, NULL);
error = wasmtime_func_call(func, NULL, 0, NULL, 0, &trap);
wasm_val_vec_t args_vec = WASM_EMPTY_VEC;
wasm_val_vec_t results_vec = WASM_EMPTY_VEC;
error = wasmtime_func_call(func, &args_vec, &results_vec, &trap);
if (error != NULL)
exit_with_error("error calling default export", error, trap);

View File

@@ -90,7 +90,10 @@ int main() {
wasmtime_linker_get_default(linker, &empty, &func);
if (error != NULL)
exit_with_error("failed to locate default export for module", error, NULL);
error = wasmtime_func_call(func, NULL, 0, NULL, 0, &trap);
wasm_val_vec_t args_vec = WASM_EMPTY_VEC;
wasm_val_vec_t results_vec = WASM_EMPTY_VEC;
error = wasmtime_func_call(func, &args_vec, &results_vec, &trap);
if (error != NULL)
exit_with_error("error calling default export", error, trap);