diff --git a/lib/runtime-c-api/src/lib.rs b/lib/runtime-c-api/src/lib.rs index ec19b249c..2fbf36cf8 100644 --- a/lib/runtime-c-api/src/lib.rs +++ b/lib/runtime-c-api/src/lib.rs @@ -13,13 +13,10 @@ use std::{ffi::c_void, ptr}; use wasmer_runtime::{Ctx, Global, ImportObject, Instance, Memory, Module, Table, Value}; use wasmer_runtime_core::export::{Context, Export, FuncPointer}; use wasmer_runtime_core::import::Namespace; -use wasmer_runtime_core::module::ImportName; +use wasmer_runtime_core::module::{ExportIndex, ImportName}; use wasmer_runtime_core::types::{ElementType, FuncSig, MemoryDescriptor, TableDescriptor, Type}; use wasmer_runtime_core::units::{Bytes, Pages}; -#[allow(non_camel_case_types)] -pub struct wasmer_import_object_t(); - #[allow(non_camel_case_types)] pub struct wasmer_module_t(); @@ -79,7 +76,11 @@ pub struct wasmer_table_t(); #[repr(C)] #[derive(Clone)] -pub struct wasmer_func_t(); +pub struct wasmer_import_func_t(); + +#[repr(C)] +#[derive(Clone)] +pub struct wasmer_export_func_t(); #[repr(C)] #[derive(Clone)] @@ -97,14 +98,6 @@ pub struct wasmer_limit_option_t { pub some: uint32_t, } -#[repr(C)] -pub struct wasmer_func_signature { - pub params: *const wasmer_value_tag, - pub params_len: c_int, - pub returns: *const wasmer_value_tag, - pub returns_len: c_int, -} - #[repr(C)] pub struct wasmer_import_t { module_name: wasmer_byte_array, @@ -129,6 +122,14 @@ pub struct wasmer_export_t; #[derive(Clone)] pub struct wasmer_exports_t; +#[repr(C)] +#[derive(Clone)] +pub struct wasmer_export_descriptor_t; + +#[repr(C)] +#[derive(Clone)] +pub struct wasmer_export_descriptors_t; + #[repr(u32)] #[derive(Clone)] pub enum wasmer_import_export_kind { @@ -141,7 +142,7 @@ pub enum wasmer_import_export_kind { #[repr(C)] #[derive(Clone, Copy)] pub union wasmer_import_export_value { - func: *const wasmer_func_t, + func: *const wasmer_import_func_t, table: *const wasmer_table_t, memory: *const wasmer_memory_t, global: *const wasmer_global_t, @@ -477,6 +478,91 @@ pub unsafe extern "C" fn wasmer_module_instantiate( wasmer_result_t::WASMER_OK } +/// Gets export descriptors for the given module +/// +/// The caller owns the object and should call `wasmer_export_descriptors_destroy` to free it. +#[allow(clippy::cast_ptr_alignment)] +#[no_mangle] +pub unsafe extern "C" fn wasmer_export_descriptors( + module: *mut wasmer_module_t, + export_descriptors: *mut *mut wasmer_export_descriptors_t, +) { + let mut module = unsafe { &*(module as *mut Module) }; + + let named_export_descriptors: Box = Box::new(NamedExportDescriptors( + module.info().exports.iter().map(|e| e.into()).collect(), + )); + unsafe { + *export_descriptors = + Box::into_raw(named_export_descriptors) as *mut wasmer_export_descriptors_t + }; +} + +pub struct NamedExportDescriptors(Vec); + +/// Frees the memory for the given export descriptors +#[allow(clippy::cast_ptr_alignment)] +#[no_mangle] +pub unsafe extern "C" fn wasmer_export_descriptors_destroy( + export_descriptors: *mut wasmer_export_descriptors_t, +) { + if !export_descriptors.is_null() { + drop(unsafe { Box::from_raw(export_descriptors as *mut NamedExportDescriptors) }); + } +} + +/// Gets the length of the export descriptors +#[allow(clippy::cast_ptr_alignment)] +#[no_mangle] +pub unsafe extern "C" fn wasmer_export_descriptors_len( + exports: *mut wasmer_export_descriptors_t, +) -> c_int { + if exports.is_null() { + return 0; + } + (*(exports as *mut NamedExportDescriptors)).0.len() as c_int +} + +/// Gets export descriptor by index +#[allow(clippy::cast_ptr_alignment)] +#[no_mangle] +pub unsafe extern "C" fn wasmer_export_descriptors_get( + export_descriptors: *mut wasmer_export_descriptors_t, + idx: c_int, +) -> *mut wasmer_export_descriptor_t { + if export_descriptors.is_null() { + return ptr::null_mut(); + } + let mut named_export_descriptors = + unsafe { &mut *(export_descriptors as *mut NamedExportDescriptors) }; + let ptr = &mut (*named_export_descriptors).0[idx as usize] as *mut NamedExportDescriptor + as *mut wasmer_export_descriptor_t; + ptr +} + +/// Gets name for the export descriptor +#[no_mangle] +#[allow(clippy::cast_ptr_alignment)] +pub unsafe extern "C" fn wasmer_export_descriptor_name( + export_descriptor: *mut wasmer_export_descriptor_t, +) -> wasmer_byte_array { + let named_export_descriptor = &*(export_descriptor as *mut NamedExportDescriptor); + wasmer_byte_array { + bytes: named_export_descriptor.name.as_ptr(), + bytes_len: named_export_descriptor.name.len() as u32, + } +} + +/// Gets export descriptor kind +#[no_mangle] +#[allow(clippy::cast_ptr_alignment)] +pub unsafe extern "C" fn wasmer_export_descriptor_kind( + export: *mut wasmer_export_descriptor_t, +) -> wasmer_import_export_kind { + let named_export_descriptor = &*(export as *mut NamedExportDescriptor); + named_export_descriptor.kind.clone() +} + /// Frees memory for the given Module #[allow(clippy::cast_ptr_alignment)] #[no_mangle] @@ -835,9 +921,16 @@ pub unsafe extern "C" fn wasmer_instance_exports( instance: *mut wasmer_instance_t, exports: *mut *mut wasmer_exports_t, ) { - let mut instance = unsafe { &mut *(instance as *mut Instance) }; - let named_exports: Box = - Box::new(NamedExports(instance.exports().map(|e| e.into()).collect())); + let mut instance_ref = unsafe { &mut *(instance as *mut Instance) }; + let mut exports_vec: Vec = Vec::with_capacity(instance_ref.exports().count()); + for (name, export) in instance_ref.exports() { + exports_vec.push(NamedExport { + name: name.clone(), + export: export.clone(), + instance: instance as *mut Instance, + }); + } + let named_exports: Box = Box::new(NamedExports(exports_vec)); unsafe { *exports = Box::into_raw(named_exports) as *mut wasmer_exports_t }; } @@ -892,18 +985,157 @@ pub unsafe extern "C" fn wasmer_export_kind( } } -/// Creates new func +/// Sets the result parameter to the arity of the params of the wasmer_export_func_t /// -/// The caller owns the object and should call `wasmer_func_destroy` to free it. +/// Returns `wasmer_result_t::WASMER_OK` upon success. +/// +/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` +/// and `wasmer_last_error_message` to get an error message. #[no_mangle] #[allow(clippy::cast_ptr_alignment)] -pub unsafe extern "C" fn wasmer_func_new( +pub unsafe extern "C" fn wasmer_export_func_params_arity( + func: *mut wasmer_export_func_t, + result: *mut uint32_t, +) -> wasmer_result_t { + let mut named_export = unsafe { &*(func as *mut NamedExport) }; + let mut export = &named_export.export; + let result = if let Export::Function { ref signature, .. } = *export { + unsafe { *result = signature.params().len() as uint32_t }; + wasmer_result_t::WASMER_OK + } else { + update_last_error(CApiError { + msg: "func ptr error in wasmer_export_func_params_arity".to_string(), + }); + wasmer_result_t::WASMER_ERROR + }; + result +} + +/// Sets the params buffer to the parameter types of the given wasmer_export_func_t +/// +/// Returns `wasmer_result_t::WASMER_OK` upon success. +/// +/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` +/// and `wasmer_last_error_message` to get an error message. +#[no_mangle] +#[allow(clippy::cast_ptr_alignment)] +pub unsafe extern "C" fn wasmer_export_func_params( + func: *mut wasmer_export_func_t, + params: *mut wasmer_value_tag, + params_len: c_int, +) -> wasmer_result_t { + let mut named_export = unsafe { &*(func as *mut NamedExport) }; + let mut export = &named_export.export; + let result = if let Export::Function { ref signature, .. } = *export { + let params: &mut [wasmer_value_tag] = + slice::from_raw_parts_mut(params, params_len as usize); + for (i, item) in signature.params().iter().enumerate() { + params[i] = item.into(); + } + wasmer_result_t::WASMER_OK + } else { + update_last_error(CApiError { + msg: "func ptr error in wasmer_export_func_params".to_string(), + }); + wasmer_result_t::WASMER_ERROR + }; + result +} + +/// Sets the returns buffer to the parameter types of the given wasmer_export_func_t +/// +/// Returns `wasmer_result_t::WASMER_OK` upon success. +/// +/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` +/// and `wasmer_last_error_message` to get an error message. +#[no_mangle] +#[allow(clippy::cast_ptr_alignment)] +pub unsafe extern "C" fn wasmer_export_func_returns( + func: *mut wasmer_export_func_t, + returns: *mut wasmer_value_tag, + returns_len: c_int, +) -> wasmer_result_t { + let mut named_export = unsafe { &*(func as *mut NamedExport) }; + let mut export = &named_export.export; + let result = if let Export::Function { ref signature, .. } = *export { + let returns: &mut [wasmer_value_tag] = + slice::from_raw_parts_mut(returns, returns_len as usize); + for (i, item) in signature.returns().iter().enumerate() { + returns[i] = item.into(); + } + wasmer_result_t::WASMER_OK + } else { + update_last_error(CApiError { + msg: "func ptr error in wasmer_export_func_returns".to_string(), + }); + wasmer_result_t::WASMER_ERROR + }; + result +} + +/// Sets the result parameter to the arity of the returns of the wasmer_export_func_t +/// +/// Returns `wasmer_result_t::WASMER_OK` upon success. +/// +/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` +/// and `wasmer_last_error_message` to get an error message. +#[no_mangle] +#[allow(clippy::cast_ptr_alignment)] +pub unsafe extern "C" fn wasmer_export_func_returns_arity( + func: *mut wasmer_export_func_t, + result: *mut uint32_t, +) -> wasmer_result_t { + let mut named_export = unsafe { &*(func as *mut NamedExport) }; + let mut export = &named_export.export; + let result = if let Export::Function { ref signature, .. } = *export { + unsafe { *result = signature.returns().len() as uint32_t }; + wasmer_result_t::WASMER_OK + } else { + update_last_error(CApiError { + msg: "func ptr error in wasmer_export_func_results_arity".to_string(), + }); + wasmer_result_t::WASMER_ERROR + }; + result +} + +/// Sets the result parameter to the arity of the params of the wasmer_import_func_t +/// +/// Returns `wasmer_result_t::WASMER_OK` upon success. +/// +/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` +/// and `wasmer_last_error_message` to get an error message. +#[no_mangle] +#[allow(clippy::cast_ptr_alignment)] +pub unsafe extern "C" fn wasmer_import_func_params_arity( + func: *mut wasmer_import_func_t, + result: *mut uint32_t, +) -> wasmer_result_t { + let mut export = unsafe { &mut *(func as *mut Export) }; + let result = if let Export::Function { ref signature, .. } = *export { + unsafe { *result = signature.params().len() as uint32_t }; + wasmer_result_t::WASMER_OK + } else { + update_last_error(CApiError { + msg: "func ptr error in wasmer_import_func_params_arity".to_string(), + }); + wasmer_result_t::WASMER_ERROR + }; + result +} + +/// Creates new func +/// +/// The caller owns the object and should call `wasmer_import_func_destroy` to free it. +#[no_mangle] +#[allow(clippy::cast_ptr_alignment)] +pub unsafe extern "C" fn wasmer_import_func_new( func: extern "C" fn(data: *mut c_void), params: *const wasmer_value_tag, params_len: c_int, returns: *const wasmer_value_tag, returns_len: c_int, -) -> *const wasmer_func_t { +) -> *const wasmer_import_func_t { let params: &[wasmer_value_tag] = slice::from_raw_parts(params, params_len as usize); let params: Vec = params.iter().cloned().map(|x| x.into()).collect(); let returns: &[wasmer_value_tag] = slice::from_raw_parts(returns, returns_len as usize); @@ -914,10 +1146,10 @@ pub unsafe extern "C" fn wasmer_func_new( ctx: Context::Internal, signature: Arc::new(FuncSig::new(params, returns)), }); - Box::into_raw(export) as *mut wasmer_func_t + Box::into_raw(export) as *mut wasmer_import_func_t } -/// Sets the result parameter to the arity of the params of the wasmer_func_t +/// Sets the params buffer to the parameter types of the given wasmer_import_func_t /// /// Returns `wasmer_result_t::WASMER_OK` upon success. /// @@ -925,33 +1157,8 @@ pub unsafe extern "C" fn wasmer_func_new( /// and `wasmer_last_error_message` to get an error message. #[no_mangle] #[allow(clippy::cast_ptr_alignment)] -pub unsafe extern "C" fn wasmer_func_params_arity( - func: *mut wasmer_func_t, - result: *mut uint32_t, -) -> wasmer_result_t { - let mut export = unsafe { &mut *(func as *mut Export) }; - let result = if let Export::Function { ref signature, .. } = *export { - unsafe { *result = signature.params().len() as uint32_t }; - wasmer_result_t::WASMER_OK - } else { - update_last_error(CApiError { - msg: "func ptr error in wasmer_func_params_arity".to_string(), - }); - wasmer_result_t::WASMER_ERROR - }; - result -} - -/// Sets the params buffer to the parameter types of the given wasmer_func_t -/// -/// Returns `wasmer_result_t::WASMER_OK` upon success. -/// -/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` -/// and `wasmer_last_error_message` to get an error message. -#[no_mangle] -#[allow(clippy::cast_ptr_alignment)] -pub unsafe extern "C" fn wasmer_func_params( - func: *mut wasmer_func_t, +pub unsafe extern "C" fn wasmer_import_func_params( + func: *mut wasmer_import_func_t, params: *mut wasmer_value_tag, params_len: c_int, ) -> wasmer_result_t { @@ -965,14 +1172,14 @@ pub unsafe extern "C" fn wasmer_func_params( wasmer_result_t::WASMER_OK } else { update_last_error(CApiError { - msg: "func ptr error in wasmer_func_params".to_string(), + msg: "func ptr error in wasmer_import_func_params".to_string(), }); wasmer_result_t::WASMER_ERROR }; result } -/// Sets the returns buffer to the parameter types of the given wasmer_func_t +/// Sets the returns buffer to the parameter types of the given wasmer_import_func_t /// /// Returns `wasmer_result_t::WASMER_OK` upon success. /// @@ -980,8 +1187,8 @@ pub unsafe extern "C" fn wasmer_func_params( /// and `wasmer_last_error_message` to get an error message. #[no_mangle] #[allow(clippy::cast_ptr_alignment)] -pub unsafe extern "C" fn wasmer_func_returns( - func: *mut wasmer_func_t, +pub unsafe extern "C" fn wasmer_import_func_returns( + func: *mut wasmer_import_func_t, returns: *mut wasmer_value_tag, returns_len: c_int, ) -> wasmer_result_t { @@ -995,14 +1202,14 @@ pub unsafe extern "C" fn wasmer_func_returns( wasmer_result_t::WASMER_OK } else { update_last_error(CApiError { - msg: "func ptr error in wasmer_func_returns".to_string(), + msg: "func ptr error in wasmer_import_func_returns".to_string(), }); wasmer_result_t::WASMER_ERROR }; result } -/// Sets the result parameter to the arity of the returns of the wasmer_func_t +/// Sets the result parameter to the arity of the returns of the wasmer_import_func_t /// /// Returns `wasmer_result_t::WASMER_OK` upon success. /// @@ -1010,8 +1217,8 @@ pub unsafe extern "C" fn wasmer_func_returns( /// and `wasmer_last_error_message` to get an error message. #[no_mangle] #[allow(clippy::cast_ptr_alignment)] -pub unsafe extern "C" fn wasmer_func_returns_arity( - func: *mut wasmer_func_t, +pub unsafe extern "C" fn wasmer_import_func_returns_arity( + func: *mut wasmer_import_func_t, result: *mut uint32_t, ) -> wasmer_result_t { let mut export = unsafe { &*(func as *mut Export) }; @@ -1020,7 +1227,7 @@ pub unsafe extern "C" fn wasmer_func_returns_arity( wasmer_result_t::WASMER_OK } else { update_last_error(CApiError { - msg: "func ptr error in wasmer_func_results_arity".to_string(), + msg: "func ptr error in wasmer_import_func_results_arity".to_string(), }); wasmer_result_t::WASMER_ERROR }; @@ -1030,20 +1237,19 @@ pub unsafe extern "C" fn wasmer_func_returns_arity( /// Frees memory for the given Func #[allow(clippy::cast_ptr_alignment)] #[no_mangle] -pub extern "C" fn wasmer_func_destroy(func: *mut wasmer_func_t) { +pub extern "C" fn wasmer_import_func_destroy(func: *mut wasmer_import_func_t) { if !func.is_null() { drop(unsafe { Box::from_raw(func as *mut Export) }); } } -/// Gets func from wasm_export +/// Gets export func from export #[no_mangle] #[allow(clippy::cast_ptr_alignment)] pub unsafe extern "C" fn wasmer_export_to_func( export: *mut wasmer_export_t, -) -> *const wasmer_func_t { - let named_export = &*(export as *mut NamedExport); - &named_export.export as *const Export as *const wasmer_func_t +) -> *const wasmer_export_func_t { + export as *const wasmer_export_func_t } /// Gets name from wasmer_export @@ -1066,8 +1272,8 @@ pub unsafe extern "C" fn wasmer_export_name(export: *mut wasmer_export_t) -> was /// and `wasmer_last_error_message` to get an error message. #[allow(clippy::cast_ptr_alignment)] #[no_mangle] -pub unsafe extern "C" fn wasmer_func_call( - func: *mut wasmer_func_t, +pub unsafe extern "C" fn wasmer_export_func_call( + func: *mut wasmer_export_func_t, params: *const wasmer_value_t, params_len: c_int, results: *mut wasmer_value_t, @@ -1089,46 +1295,42 @@ pub unsafe extern "C" fn wasmer_func_call( let params: &[wasmer_value_t] = slice::from_raw_parts(params, params_len as usize); let params: Vec = params.iter().cloned().map(|x| x.into()).collect(); - let export_func = unsafe { &*(func as *mut Export) }; + let named_export = unsafe { &*(func as *mut NamedExport) }; let results: &mut [wasmer_value_t] = slice::from_raw_parts_mut(results, results_len as usize); - // TODO implement func.call - update_last_error(CApiError { - msg: "wasmer_func_call not yet implemented".to_string(), - }); - wasmer_result_t::WASMER_ERROR - // let result = instance.call(func_name_r, ¶ms[..]); - // Box::into_raw(export_func); - // match result { - // Ok(results_vec) => { - // if results_vec.len() > 0 { - // let ret = match results_vec[0] { - // Value::I32(x) => wasmer_value_t { - // tag: wasmer_value_tag::WASM_I32, - // value: wasmer_value { I32: x }, - // }, - // Value::I64(x) => wasmer_value_t { - // tag: wasmer_value_tag::WASM_I64, - // value: wasmer_value { I64: x }, - // }, - // Value::F32(x) => wasmer_value_t { - // tag: wasmer_value_tag::WASM_F32, - // value: wasmer_value { F32: x }, - // }, - // Value::F64(x) => wasmer_value_t { - // tag: wasmer_value_tag::WASM_F64, - // value: wasmer_value { F64: x }, - // }, - // }; - // results[0] = ret; - // } - // wasmer_result_t::WASMER_OK - // } - // Err(err) => { - // update_last_error(err); - // wasmer_result_t::WASMER_ERROR - // } - // } + + let instance = &*named_export.instance; + let result = instance.call(&named_export.name, ¶ms[..]); + match result { + Ok(results_vec) => { + if results_vec.len() > 0 { + let ret = match results_vec[0] { + Value::I32(x) => wasmer_value_t { + tag: wasmer_value_tag::WASM_I32, + value: wasmer_value { I32: x }, + }, + Value::I64(x) => wasmer_value_t { + tag: wasmer_value_tag::WASM_I64, + value: wasmer_value { I64: x }, + }, + Value::F32(x) => wasmer_value_t { + tag: wasmer_value_tag::WASM_F32, + value: wasmer_value { F32: x }, + }, + Value::F64(x) => wasmer_value_t { + tag: wasmer_value_tag::WASM_F64, + value: wasmer_value { F64: x }, + }, + }; + results[0] = ret; + } + wasmer_result_t::WASMER_OK + } + Err(err) => { + update_last_error(err); + wasmer_result_t::WASMER_ERROR + } + } } /// Gets the memory within the context at the index `memory_idx`. @@ -1246,12 +1448,6 @@ impl From for Type { } } -impl From<(std::string::String, wasmer_runtime_core::export::Export)> for NamedExport { - fn from((name, export): (String, Export)) -> Self { - NamedExport { name, export } - } -} - impl From<&wasmer_runtime::wasm::Type> for wasmer_value_tag { fn from(ty: &Type) -> Self { match *ty { @@ -1263,6 +1459,21 @@ impl From<&wasmer_runtime::wasm::Type> for wasmer_value_tag { } } +impl From<(&std::string::String, &ExportIndex)> for NamedExportDescriptor { + fn from((name, export_index): (&String, &ExportIndex)) -> Self { + let kind = match *export_index { + ExportIndex::Memory(_) => wasmer_import_export_kind::WASM_MEMORY, + ExportIndex::Global(_) => wasmer_import_export_kind::WASM_GLOBAL, + ExportIndex::Table(_) => wasmer_import_export_kind::WASM_TABLE, + ExportIndex::Func(_) => wasmer_import_export_kind::WASM_FUNCTION, + }; + NamedExportDescriptor { + name: name.clone(), + kind, + } + } +} + // Error reporting thread_local! { @@ -1366,4 +1577,10 @@ struct NamedImportDescriptor { struct NamedExport { name: String, export: Export, + instance: *mut Instance, +} + +struct NamedExportDescriptor { + name: String, + kind: wasmer_import_export_kind, } diff --git a/lib/runtime-c-api/tests/.gitignore b/lib/runtime-c-api/tests/.gitignore index 773d7f43d..a39c13250 100644 --- a/lib/runtime-c-api/tests/.gitignore +++ b/lib/runtime-c-api/tests/.gitignore @@ -16,6 +16,7 @@ test-import-function test-memory test-module-imports test-module +test-module-exports test-tables test-validate rust-build \ No newline at end of file diff --git a/lib/runtime-c-api/tests/CMakeLists.txt b/lib/runtime-c-api/tests/CMakeLists.txt index 2db4f219a..697729580 100644 --- a/lib/runtime-c-api/tests/CMakeLists.txt +++ b/lib/runtime-c-api/tests/CMakeLists.txt @@ -8,6 +8,7 @@ add_executable(test-import-function test-import-function.c) add_executable(test-memory test-memory.c) add_executable(test-module-imports test-module-imports.c) add_executable(test-module test-module.c) +add_executable(test-module-exports test-module-exports.c) add_executable(test-validate test-validate.c) add_executable(test-tables test-tables.c) @@ -34,6 +35,8 @@ target_link_libraries(test-module-imports general ${WASMER_LIB}) target_link_libraries(test-module general ${WASMER_LIB}) +target_link_libraries(test-module-exports + general ${WASMER_LIB}) target_link_libraries(test-validate general ${WASMER_LIB}) target_link_libraries(test-tables @@ -47,6 +50,7 @@ add_test(test-import-function test-import-function) add_test(test-memory test-memory) add_test(test-module-imports test-module-imports) add_test(test-module test-module) +add_test(test-module-exports test-module-exports) add_test(test-validate test-validate) add_test(test-tables test-tables) diff --git a/lib/runtime-c-api/tests/test-exports.c b/lib/runtime-c-api/tests/test-exports.c index 3f458ebab..75368ad16 100644 --- a/lib/runtime-c-api/tests/test-exports.c +++ b/lib/runtime-c-api/tests/test-exports.c @@ -31,7 +31,7 @@ int main() wasmer_import_export_kind kind = wasmer_export_kind(export); assert(kind == WASM_FUNCTION); - wasmer_func_t *func = wasmer_export_to_func(export); + wasmer_export_func_t *func = wasmer_export_to_func(export); wasmer_byte_array name_bytes = wasmer_export_name(export); assert(name_bytes.bytes_len == 3); @@ -42,40 +42,40 @@ int main() } uint32_t params_arity; - wasmer_func_params_arity(func, ¶ms_arity); + wasmer_export_func_params_arity(func, ¶ms_arity); assert(params_arity == 2); wasmer_value_tag *params_sig = malloc(sizeof(wasmer_value_tag) * params_arity); - wasmer_func_params(func, params_sig , params_arity); + wasmer_export_func_params(func, params_sig , params_arity); assert(params_sig[0] == WASM_I32); assert(params_sig[1] == WASM_I32); free(params_sig); uint32_t returns_arity; - wasmer_func_returns_arity(func, &returns_arity); + wasmer_export_func_returns_arity(func, &returns_arity); assert(returns_arity == 1); wasmer_value_tag *returns_sig = malloc(sizeof(wasmer_value_tag) * returns_arity); - wasmer_func_returns(func, returns_sig , returns_arity); + wasmer_export_func_returns(func, returns_sig , returns_arity); assert(returns_sig[0] == WASM_I32); free(returns_sig); -// wasmer_value_t param_one; -// param_one.tag = WASM_I32; -// param_one.value.I32 = 7; -// wasmer_value_t param_two; -// param_two.tag = WASM_I32; -// param_two.value.I32 = 8; -// wasmer_value_t params[] = {param_one, param_two}; -// wasmer_value_t result_one; -// wasmer_value_t results[] = {result_one}; -// -// wasmer_result_t call_result = wasmer_func_call(func, params, 2, results, 1); -// printf("Call result: %d\n", call_result); -// printf("Result: %d\n", results[0].value.I32); -// assert(results[0].value.I32 == 15); -// assert(call_result == WASMER_OK); + wasmer_value_t param_one; + param_one.tag = WASM_I32; + param_one.value.I32 = 7; + wasmer_value_t param_two; + param_two.tag = WASM_I32; + param_two.value.I32 = 8; + wasmer_value_t params[] = {param_one, param_two}; + wasmer_value_t result_one; + wasmer_value_t results[] = {result_one}; + + wasmer_result_t call_result = wasmer_export_func_call(func, params, 2, results, 1); + printf("Call result: %d\n", call_result); + printf("Result: %d\n", results[0].value.I32); + assert(results[0].value.I32 == 15); + assert(call_result == WASMER_OK); printf("Destroy instance\n"); diff --git a/lib/runtime-c-api/tests/test-import-function.c b/lib/runtime-c-api/tests/test-import-function.c index e7caed874..b28465683 100644 --- a/lib/runtime-c-api/tests/test-import-function.c +++ b/lib/runtime-c-api/tests/test-import-function.c @@ -31,7 +31,7 @@ int main() wasmer_value_tag returns_sig[] = {}; printf("Creating new func\n"); - wasmer_func_t *func = wasmer_func_new(print_str, params_sig, 2, returns_sig, 0); + wasmer_import_func_t *func = wasmer_import_func_new(print_str, params_sig, 2, returns_sig, 0); wasmer_import_t import; char *module_name = "env"; @@ -84,7 +84,7 @@ int main() assert(0 == strcmp(actual_str, "Hello, World!")); printf("Destroying func\n"); - wasmer_func_destroy(func); + wasmer_import_func_destroy(func); printf("Destroy instance\n"); wasmer_instance_destroy(instance); return 0; diff --git a/lib/runtime-c-api/tests/test-module-exports.c b/lib/runtime-c-api/tests/test-module-exports.c new file mode 100644 index 000000000..48fe6f25b --- /dev/null +++ b/lib/runtime-c-api/tests/test-module-exports.c @@ -0,0 +1,53 @@ +#include +#include "../wasmer.h" +#include +#include + +int main() +{ + // Read the wasm file bytes + FILE *file = fopen("sum.wasm", "r"); + fseek(file, 0, SEEK_END); + long len = ftell(file); + uint8_t *bytes = malloc(len); + fseek(file, 0, SEEK_SET); + fread(bytes, 1, len, file); + fclose(file); + + wasmer_module_t *module = NULL; + wasmer_result_t compile_result = wasmer_compile(&module, bytes, len); + printf("Compile result: %d\n", compile_result); + assert(compile_result == WASMER_OK); + + wasmer_import_t imports[] = {}; + wasmer_instance_t *instance = NULL; + wasmer_result_t instantiate_result = wasmer_module_instantiate(module, &instance, imports, 0); + printf("Instantiate result: %d\n", compile_result); + assert(instantiate_result == WASMER_OK); + + wasmer_export_descriptors_t *exports = NULL; + wasmer_export_descriptors(module, &exports); + + int exports_len = wasmer_export_descriptors_len(exports); + printf("exports_len: %d\n", exports_len); + assert(exports_len == 1); + + wasmer_export_descriptor_t *export = wasmer_export_descriptors_get(exports, 0); + + wasmer_import_export_kind kind = wasmer_export_descriptor_kind(export); + assert(kind == WASM_FUNCTION); + + wasmer_byte_array name_bytes = wasmer_export_descriptor_name(export); + assert(name_bytes.bytes_len == 3); + char expected[] = {'s', 'u', 'm'}; + for(int idx = 0; idx < 3; idx++){ + printf("%c\n", name_bytes.bytes[idx]); + assert(name_bytes.bytes[idx] == expected[idx]); + } + + printf("Destroy module\n"); + wasmer_module_destroy(module); + printf("Destroy exports\n"); + wasmer_export_descriptors_destroy(exports); + return 0; +} \ No newline at end of file diff --git a/lib/runtime-c-api/wasmer.h b/lib/runtime-c-api/wasmer.h index 5f01ad65a..f790b140e 100644 --- a/lib/runtime-c-api/wasmer.h +++ b/lib/runtime-c-api/wasmer.h @@ -35,7 +35,7 @@ typedef struct wasmer_module_t wasmer_module_t; typedef struct { -} wasmer_export_t; +} wasmer_export_descriptor_t; typedef struct { const uint8_t *bytes; @@ -44,11 +44,11 @@ typedef struct { typedef struct { -} wasmer_func_t; +} wasmer_export_descriptors_t; typedef struct { -} wasmer_exports_t; +} wasmer_export_func_t; typedef union { int32_t I32; @@ -64,6 +64,14 @@ typedef struct { typedef struct { +} wasmer_export_t; + +typedef struct { + +} wasmer_exports_t; + +typedef struct { + } wasmer_global_t; typedef struct { @@ -81,6 +89,10 @@ typedef struct { typedef struct { +} wasmer_import_func_t; + +typedef struct { + } wasmer_memory_t; typedef struct { @@ -88,7 +100,7 @@ typedef struct { } wasmer_table_t; typedef union { - const wasmer_func_t *func; + const wasmer_import_func_t *func; const wasmer_table_t *table; const wasmer_memory_t *memory; const wasmer_global_t *global; @@ -121,6 +133,88 @@ wasmer_result_t wasmer_compile(wasmer_module_t **module, uint8_t *wasm_bytes, uint32_t wasm_bytes_len); +/** + * Gets export descriptor kind + */ +wasmer_import_export_kind wasmer_export_descriptor_kind(wasmer_export_descriptor_t *export_); + +/** + * Gets name for the export descriptor + */ +wasmer_byte_array wasmer_export_descriptor_name(wasmer_export_descriptor_t *export_descriptor); + +/** + * Gets export descriptors for the given module + * The caller owns the object and should call `wasmer_export_descriptors_destroy` to free it. + */ +void wasmer_export_descriptors(wasmer_module_t *module, + wasmer_export_descriptors_t **export_descriptors); + +/** + * Frees the memory for the given export descriptors + */ +void wasmer_export_descriptors_destroy(wasmer_export_descriptors_t *export_descriptors); + +/** + * Gets export descriptor by index + */ +wasmer_export_descriptor_t *wasmer_export_descriptors_get(wasmer_export_descriptors_t *export_descriptors, + int idx); + +/** + * Gets the length of the export descriptors + */ +int wasmer_export_descriptors_len(wasmer_export_descriptors_t *exports); + +/** + * Calls a `func` with the provided parameters. + * Results are set using the provided `results` pointer. + * Returns `wasmer_result_t::WASMER_OK` upon success. + * Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` + * and `wasmer_last_error_message` to get an error message. + */ +wasmer_result_t wasmer_export_func_call(wasmer_export_func_t *func, + const wasmer_value_t *params, + int params_len, + wasmer_value_t *results, + int results_len); + +/** + * Sets the params buffer to the parameter types of the given wasmer_export_func_t + * Returns `wasmer_result_t::WASMER_OK` upon success. + * Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` + * and `wasmer_last_error_message` to get an error message. + */ +wasmer_result_t wasmer_export_func_params(wasmer_export_func_t *func, + wasmer_value_tag *params, + int params_len); + +/** + * Sets the result parameter to the arity of the params of the wasmer_export_func_t + * Returns `wasmer_result_t::WASMER_OK` upon success. + * Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` + * and `wasmer_last_error_message` to get an error message. + */ +wasmer_result_t wasmer_export_func_params_arity(wasmer_export_func_t *func, uint32_t *result); + +/** + * Sets the returns buffer to the parameter types of the given wasmer_export_func_t + * Returns `wasmer_result_t::WASMER_OK` upon success. + * Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` + * and `wasmer_last_error_message` to get an error message. + */ +wasmer_result_t wasmer_export_func_returns(wasmer_export_func_t *func, + wasmer_value_tag *returns, + int returns_len); + +/** + * Sets the result parameter to the arity of the returns of the wasmer_export_func_t + * Returns `wasmer_result_t::WASMER_OK` upon success. + * Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` + * and `wasmer_last_error_message` to get an error message. + */ +wasmer_result_t wasmer_export_func_returns_arity(wasmer_export_func_t *func, uint32_t *result); + /** * Gets wasmer_export kind */ @@ -132,9 +226,9 @@ wasmer_import_export_kind wasmer_export_kind(wasmer_export_t *export_); wasmer_byte_array wasmer_export_name(wasmer_export_t *export_); /** - * Gets func from wasm_export + * Gets export func from export */ -const wasmer_func_t *wasmer_export_to_func(wasmer_export_t *export_); +const wasmer_export_func_t *wasmer_export_to_func(wasmer_export_t *export_); /** * Frees the memory for the given exports @@ -151,68 +245,6 @@ wasmer_export_t *wasmer_exports_get(wasmer_exports_t *exports, int idx); */ int wasmer_exports_len(wasmer_exports_t *exports); -/** - * Calls a `func` with the provided parameters. - * Results are set using the provided `results` pointer. - * Returns `wasmer_result_t::WASMER_OK` upon success. - * Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` - * and `wasmer_last_error_message` to get an error message. - */ -wasmer_result_t wasmer_func_call(wasmer_func_t *func, - const wasmer_value_t *params, - int params_len, - wasmer_value_t *results, - int results_len); - -/** - * Frees memory for the given Func - */ -void wasmer_func_destroy(wasmer_func_t *func); - -/** - * Creates new func - * The caller owns the object and should call `wasmer_func_destroy` to free it. - */ -const wasmer_func_t *wasmer_func_new(void (*func)(void *data), - const wasmer_value_tag *params, - int params_len, - const wasmer_value_tag *returns, - int returns_len); - -/** - * Sets the params buffer to the parameter types of the given wasmer_func_t - * Returns `wasmer_result_t::WASMER_OK` upon success. - * Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` - * and `wasmer_last_error_message` to get an error message. - */ -wasmer_result_t wasmer_func_params(wasmer_func_t *func, wasmer_value_tag *params, int params_len); - -/** - * Sets the result parameter to the arity of the params of the wasmer_func_t - * Returns `wasmer_result_t::WASMER_OK` upon success. - * Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` - * and `wasmer_last_error_message` to get an error message. - */ -wasmer_result_t wasmer_func_params_arity(wasmer_func_t *func, uint32_t *result); - -/** - * Sets the returns buffer to the parameter types of the given wasmer_func_t - * Returns `wasmer_result_t::WASMER_OK` upon success. - * Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` - * and `wasmer_last_error_message` to get an error message. - */ -wasmer_result_t wasmer_func_returns(wasmer_func_t *func, - wasmer_value_tag *returns, - int returns_len); - -/** - * Sets the result parameter to the arity of the returns of the wasmer_func_t - * Returns `wasmer_result_t::WASMER_OK` upon success. - * Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` - * and `wasmer_last_error_message` to get an error message. - */ -wasmer_result_t wasmer_func_returns_arity(wasmer_func_t *func, uint32_t *result); - /** * Frees memory for the given Global */ @@ -277,6 +309,57 @@ wasmer_import_descriptor_t *wasmer_import_descriptors_get(wasmer_import_descript */ int wasmer_import_descriptors_len(wasmer_import_descriptors_t *exports); +/** + * Frees memory for the given Func + */ +void wasmer_import_func_destroy(wasmer_import_func_t *func); + +/** + * Creates new func + * The caller owns the object and should call `wasmer_import_func_destroy` to free it. + */ +const wasmer_import_func_t *wasmer_import_func_new(void (*func)(void *data), + const wasmer_value_tag *params, + int params_len, + const wasmer_value_tag *returns, + int returns_len); + +/** + * Sets the params buffer to the parameter types of the given wasmer_import_func_t + * Returns `wasmer_result_t::WASMER_OK` upon success. + * Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` + * and `wasmer_last_error_message` to get an error message. + */ +wasmer_result_t wasmer_import_func_params(wasmer_import_func_t *func, + wasmer_value_tag *params, + int params_len); + +/** + * Sets the result parameter to the arity of the params of the wasmer_import_func_t + * Returns `wasmer_result_t::WASMER_OK` upon success. + * Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` + * and `wasmer_last_error_message` to get an error message. + */ +wasmer_result_t wasmer_import_func_params_arity(wasmer_import_func_t *func, uint32_t *result); + +/** + * Sets the returns buffer to the parameter types of the given wasmer_import_func_t + * Returns `wasmer_result_t::WASMER_OK` upon success. + * Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` + * and `wasmer_last_error_message` to get an error message. + */ +wasmer_result_t wasmer_import_func_returns(wasmer_import_func_t *func, + wasmer_value_tag *returns, + int returns_len); + +/** + * Sets the result parameter to the arity of the returns of the wasmer_import_func_t + * Returns `wasmer_result_t::WASMER_OK` upon success. + * Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` + * and `wasmer_last_error_message` to get an error message. + */ +wasmer_result_t wasmer_import_func_returns_arity(wasmer_import_func_t *func, uint32_t *result); + /** * Calls an instances exported function by `name` with the provided parameters. * Results are set using the provided `results` pointer. diff --git a/lib/runtime-c-api/wasmer.hh b/lib/runtime-c-api/wasmer.hh index 2af93433d..df9904e86 100644 --- a/lib/runtime-c-api/wasmer.hh +++ b/lib/runtime-c-api/wasmer.hh @@ -30,7 +30,7 @@ struct wasmer_instance_t; struct wasmer_module_t; -struct wasmer_export_t { +struct wasmer_export_descriptor_t { }; @@ -39,11 +39,11 @@ struct wasmer_byte_array { uint32_t bytes_len; }; -struct wasmer_func_t { +struct wasmer_export_descriptors_t { }; -struct wasmer_exports_t { +struct wasmer_export_func_t { }; @@ -59,6 +59,14 @@ struct wasmer_value_t { wasmer_value value; }; +struct wasmer_export_t { + +}; + +struct wasmer_exports_t { + +}; + struct wasmer_global_t { }; @@ -76,6 +84,10 @@ struct wasmer_import_descriptors_t { }; +struct wasmer_import_func_t { + +}; + struct wasmer_memory_t { }; @@ -85,7 +97,7 @@ struct wasmer_table_t { }; union wasmer_import_export_value { - const wasmer_func_t *func; + const wasmer_import_func_t *func; const wasmer_table_t *table; const wasmer_memory_t *memory; const wasmer_global_t *global; @@ -118,14 +130,74 @@ wasmer_result_t wasmer_compile(wasmer_module_t **module, uint8_t *wasm_bytes, uint32_t wasm_bytes_len); +/// Gets export descriptor kind +wasmer_import_export_kind wasmer_export_descriptor_kind(wasmer_export_descriptor_t *export_); + +/// Gets name for the export descriptor +wasmer_byte_array wasmer_export_descriptor_name(wasmer_export_descriptor_t *export_descriptor); + +/// Gets export descriptors for the given module +/// The caller owns the object and should call `wasmer_export_descriptors_destroy` to free it. +void wasmer_export_descriptors(wasmer_module_t *module, + wasmer_export_descriptors_t **export_descriptors); + +/// Frees the memory for the given export descriptors +void wasmer_export_descriptors_destroy(wasmer_export_descriptors_t *export_descriptors); + +/// Gets export descriptor by index +wasmer_export_descriptor_t *wasmer_export_descriptors_get(wasmer_export_descriptors_t *export_descriptors, + int idx); + +/// Gets the length of the export descriptors +int wasmer_export_descriptors_len(wasmer_export_descriptors_t *exports); + +/// Calls a `func` with the provided parameters. +/// Results are set using the provided `results` pointer. +/// Returns `wasmer_result_t::WASMER_OK` upon success. +/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` +/// and `wasmer_last_error_message` to get an error message. +wasmer_result_t wasmer_export_func_call(wasmer_export_func_t *func, + const wasmer_value_t *params, + int params_len, + wasmer_value_t *results, + int results_len); + +/// Sets the params buffer to the parameter types of the given wasmer_export_func_t +/// Returns `wasmer_result_t::WASMER_OK` upon success. +/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` +/// and `wasmer_last_error_message` to get an error message. +wasmer_result_t wasmer_export_func_params(wasmer_export_func_t *func, + wasmer_value_tag *params, + int params_len); + +/// Sets the result parameter to the arity of the params of the wasmer_export_func_t +/// Returns `wasmer_result_t::WASMER_OK` upon success. +/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` +/// and `wasmer_last_error_message` to get an error message. +wasmer_result_t wasmer_export_func_params_arity(wasmer_export_func_t *func, uint32_t *result); + +/// Sets the returns buffer to the parameter types of the given wasmer_export_func_t +/// Returns `wasmer_result_t::WASMER_OK` upon success. +/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` +/// and `wasmer_last_error_message` to get an error message. +wasmer_result_t wasmer_export_func_returns(wasmer_export_func_t *func, + wasmer_value_tag *returns, + int returns_len); + +/// Sets the result parameter to the arity of the returns of the wasmer_export_func_t +/// Returns `wasmer_result_t::WASMER_OK` upon success. +/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` +/// and `wasmer_last_error_message` to get an error message. +wasmer_result_t wasmer_export_func_returns_arity(wasmer_export_func_t *func, uint32_t *result); + /// Gets wasmer_export kind wasmer_import_export_kind wasmer_export_kind(wasmer_export_t *export_); /// Gets name from wasmer_export wasmer_byte_array wasmer_export_name(wasmer_export_t *export_); -/// Gets func from wasm_export -const wasmer_func_t *wasmer_export_to_func(wasmer_export_t *export_); +/// Gets export func from export +const wasmer_export_func_t *wasmer_export_to_func(wasmer_export_t *export_); /// Frees the memory for the given exports void wasmer_exports_destroy(wasmer_exports_t *exports); @@ -136,54 +208,6 @@ wasmer_export_t *wasmer_exports_get(wasmer_exports_t *exports, int idx); /// Gets the length of the exports int wasmer_exports_len(wasmer_exports_t *exports); -/// Calls a `func` with the provided parameters. -/// Results are set using the provided `results` pointer. -/// Returns `wasmer_result_t::WASMER_OK` upon success. -/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` -/// and `wasmer_last_error_message` to get an error message. -wasmer_result_t wasmer_func_call(wasmer_func_t *func, - const wasmer_value_t *params, - int params_len, - wasmer_value_t *results, - int results_len); - -/// Frees memory for the given Func -void wasmer_func_destroy(wasmer_func_t *func); - -/// Creates new func -/// The caller owns the object and should call `wasmer_func_destroy` to free it. -const wasmer_func_t *wasmer_func_new(void (*func)(void *data), - const wasmer_value_tag *params, - int params_len, - const wasmer_value_tag *returns, - int returns_len); - -/// Sets the params buffer to the parameter types of the given wasmer_func_t -/// Returns `wasmer_result_t::WASMER_OK` upon success. -/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` -/// and `wasmer_last_error_message` to get an error message. -wasmer_result_t wasmer_func_params(wasmer_func_t *func, wasmer_value_tag *params, int params_len); - -/// Sets the result parameter to the arity of the params of the wasmer_func_t -/// Returns `wasmer_result_t::WASMER_OK` upon success. -/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` -/// and `wasmer_last_error_message` to get an error message. -wasmer_result_t wasmer_func_params_arity(wasmer_func_t *func, uint32_t *result); - -/// Sets the returns buffer to the parameter types of the given wasmer_func_t -/// Returns `wasmer_result_t::WASMER_OK` upon success. -/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` -/// and `wasmer_last_error_message` to get an error message. -wasmer_result_t wasmer_func_returns(wasmer_func_t *func, - wasmer_value_tag *returns, - int returns_len); - -/// Sets the result parameter to the arity of the returns of the wasmer_func_t -/// Returns `wasmer_result_t::WASMER_OK` upon success. -/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` -/// and `wasmer_last_error_message` to get an error message. -wasmer_result_t wasmer_func_returns_arity(wasmer_func_t *func, uint32_t *result); - /// Frees memory for the given Global void wasmer_global_destroy(wasmer_global_t *global); @@ -224,6 +248,45 @@ wasmer_import_descriptor_t *wasmer_import_descriptors_get(wasmer_import_descript /// Gets the length of the import descriptors int wasmer_import_descriptors_len(wasmer_import_descriptors_t *exports); +/// Frees memory for the given Func +void wasmer_import_func_destroy(wasmer_import_func_t *func); + +/// Creates new func +/// The caller owns the object and should call `wasmer_import_func_destroy` to free it. +const wasmer_import_func_t *wasmer_import_func_new(void (*func)(void *data), + const wasmer_value_tag *params, + int params_len, + const wasmer_value_tag *returns, + int returns_len); + +/// Sets the params buffer to the parameter types of the given wasmer_import_func_t +/// Returns `wasmer_result_t::WASMER_OK` upon success. +/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` +/// and `wasmer_last_error_message` to get an error message. +wasmer_result_t wasmer_import_func_params(wasmer_import_func_t *func, + wasmer_value_tag *params, + int params_len); + +/// Sets the result parameter to the arity of the params of the wasmer_import_func_t +/// Returns `wasmer_result_t::WASMER_OK` upon success. +/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` +/// and `wasmer_last_error_message` to get an error message. +wasmer_result_t wasmer_import_func_params_arity(wasmer_import_func_t *func, uint32_t *result); + +/// Sets the returns buffer to the parameter types of the given wasmer_import_func_t +/// Returns `wasmer_result_t::WASMER_OK` upon success. +/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` +/// and `wasmer_last_error_message` to get an error message. +wasmer_result_t wasmer_import_func_returns(wasmer_import_func_t *func, + wasmer_value_tag *returns, + int returns_len); + +/// Sets the result parameter to the arity of the returns of the wasmer_import_func_t +/// Returns `wasmer_result_t::WASMER_OK` upon success. +/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` +/// and `wasmer_last_error_message` to get an error message. +wasmer_result_t wasmer_import_func_returns_arity(wasmer_import_func_t *func, uint32_t *result); + /// Calls an instances exported function by `name` with the provided parameters. /// Results are set using the provided `results` pointer. /// Returns `wasmer_result_t::WASMER_OK` upon success.