diff --git a/crates/c-api/include/doc-wasm.h b/crates/c-api/include/doc-wasm.h index 73d57a647be3..356db1e1bc61 100644 --- a/crates/c-api/include/doc-wasm.h +++ b/crates/c-api/include/doc-wasm.h @@ -316,6 +316,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. + */ diff --git a/crates/c-api/include/wasmtime.h b/crates/c-api/include/wasmtime.h index 769cfc126859..b2efa3e81c86 100644 --- a/crates/c-api/include/wasmtime.h +++ b/crates/c-api/include/wasmtime.h @@ -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. diff --git a/crates/c-api/src/func.rs b/crates/c-api/src/func.rs index 5c63e9782f4d..87351e99cab7 100644 --- a/crates/c-api/src/func.rs +++ b/crates/c-api/src/func.rs @@ -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>; +pub type wasm_func_callback_t = extern "C" fn( + args: *const wasm_val_vec_t, + results: *mut wasm_val_vec_t, +) -> Option>; 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>; 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>; 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>; struct Finalizer { @@ -83,21 +85,25 @@ impl From 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> + 'static, + func: impl Fn(Caller<'_>, *const wasm_val_vec_t, *mut wasm_val_vec_t) -> Option> + + 'static, ) -> Box { 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::>(); - let mut out_results = vec![wasm_val_t::default(); results.len()]; - let out = func(caller, params.as_ptr(), out_results.as_mut_ptr()); + .collect::>() + .into(); + let mut out_results: wasm_val_vec_t = vec![wasm_val_t::default(); results.len()].into(); + let out = func(caller, ¶ms, &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, + 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, - num_results: usize, + args: *const wasm_val_vec_t, + results: *mut wasm_val_vec_t, trap_ptr: &mut *mut wasm_trap_t, ) -> Option> { _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, ) } diff --git a/crates/c-api/src/instance.rs b/crates/c-api/src/instance.rs index 5a41d68a1ccb..9a2dd3b2ca98 100644 --- a/crates/c-api/src/instance.rs +++ b/crates/c-api/src/instance.rs @@ -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, + imports: *const wasm_extern_vec_t, result: Option<&mut *mut wasm_trap_t>, ) -> Option> { 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, - num_imports: usize, + imports: *const wasm_extern_vec_t, instance_ptr: &mut *mut wasm_instance_t, trap_ptr: &mut *mut wasm_trap_t, ) -> Option> { - _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], + imports: &[Option>], instance_ptr: &mut *mut wasm_instance_t, trap_ptr: &mut *mut wasm_trap_t, ) -> Option> { 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::>(); handle_instantiate( Instance::new(store, module.module(), &imports), diff --git a/crates/c-api/src/vec.rs b/crates/c-api/src/vec.rs index 21a47f071750..fec8c7dd0d1b 100644 --- a/crates/c-api/src/vec.rs +++ b/crates/c-api/src/vec.rs @@ -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(); diff --git a/crates/c-api/wasm-c-api b/crates/c-api/wasm-c-api index d9a80099d496..c9d31284651b 160000 --- a/crates/c-api/wasm-c-api +++ b/crates/c-api/wasm-c-api @@ -1 +1 @@ -Subproject commit d9a80099d496b5cdba6f3fe8fc77586e0e505ddc +Subproject commit c9d31284651b975f05ac27cee0bab1377560b87e diff --git a/examples/externref.c b/examples/externref.c index 5828d1766566..725e2e0e2f4c 100644 --- a/examples/externref.c +++ b/examples/externref.c @@ -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); diff --git a/examples/fib-debug/main.c b/examples/fib-debug/main.c index a4e22dee3c95..722ddb01d920 100644 --- a/examples/fib-debug/main.c +++ b/examples/fib-debug/main.c @@ -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, ¶ms_vec, &results_vec, &trap); if (error != NULL || trap != NULL) exit_with_error("failed to call function", error, trap); diff --git a/examples/gcd.c b/examples/gcd.c index 76ca77faf7d7..d811458bb422 100644 --- a/examples/gcd.c +++ b/examples/gcd.c @@ -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, ¶ms_vec, &results_vec, &trap); if (error != NULL || trap != NULL) exit_with_error("failed to call gcd", error, trap); assert(results[0].kind == WASM_I32); diff --git a/examples/hello.c b/examples/hello.c index a14ef18aca1e..7c14612945e1 100644 --- a/examples/hello.c +++ b/examples/hello.c @@ -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); diff --git a/examples/hello.cc b/examples/hello.cc index c83be4257666..f44b49c1fcb5 100644 --- a/examples/hello.cc +++ b/examples/hello.cc @@ -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); diff --git a/examples/interrupt.c b/examples/interrupt.c index d8ccd9a8f422..e6540a2d8dd7 100644 --- a/examples/interrupt.c +++ b/examples/interrupt.c @@ -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"); diff --git a/examples/linking.c b/examples/linking.c index f4c53b1f5ad3..d9bc0f93c142 100644 --- a/examples/linking.c +++ b/examples/linking.c @@ -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); diff --git a/examples/memory.c b/examples/memory.c index a8391e8c20ae..24e26dbd4c0d 100644 --- a/examples/memory.c +++ b/examples/memory.c @@ -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); diff --git a/examples/multi.c b/examples/multi.c index a1514b18331e..35537064470f 100644 --- a/examples/multi.c +++ b/examples/multi.c @@ -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); diff --git a/examples/serialize.c b/examples/serialize.c index c25a1bf4011c..023e1db30b5e 100644 --- a/examples/serialize.c +++ b/examples/serialize.c @@ -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); diff --git a/examples/threads.c b/examples/threads.c index bc04ba69c634..06aa1f0aa70a 100644 --- a/examples/threads.c +++ b/examples/threads.c @@ -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; } diff --git a/examples/wasi-fs/main.c b/examples/wasi-fs/main.c index 6452cb7d4130..8633bfbd6cd0 100644 --- a/examples/wasi-fs/main.c +++ b/examples/wasi-fs/main.c @@ -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); diff --git a/examples/wasi/main.c b/examples/wasi/main.c index a8514c69caf4..3bb71ec4de34 100644 --- a/examples/wasi/main.c +++ b/examples/wasi/main.c @@ -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);