diff --git a/lib/runtime-c-api/src/lib.rs b/lib/runtime-c-api/src/lib.rs index 733e10fb83a..6b6e5567fbf 100644 --- a/lib/runtime-c-api/src/lib.rs +++ b/lib/runtime-c-api/src/lib.rs @@ -674,6 +674,120 @@ pub unsafe extern "C" fn wasmer_func_new( Box::into_raw(export) as *mut wasmer_func_t } +/// 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. +#[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 { Box::from_raw(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 + }; + Box::into_raw(export); + 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, + params: *mut wasmer_value_tag, + params_len: c_int, +) -> wasmer_result_t { + let mut export = unsafe { Box::from_raw(func as *mut 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_func_params".to_string(), + }); + wasmer_result_t::WASMER_ERROR + }; + Box::into_raw(export); + 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. +#[no_mangle] +#[allow(clippy::cast_ptr_alignment)] +pub unsafe extern "C" fn wasmer_func_returns( + func: *mut wasmer_func_t, + returns: *mut wasmer_value_tag, + returns_len: c_int, +) -> wasmer_result_t { + let mut export = unsafe { Box::from_raw(func as *mut 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_func_returns".to_string(), + }); + wasmer_result_t::WASMER_ERROR + }; + Box::into_raw(export); + result +} + +/// 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. +#[no_mangle] +#[allow(clippy::cast_ptr_alignment)] +pub unsafe extern "C" fn wasmer_func_returns_arity( + func: *mut wasmer_func_t, + result: *mut uint32_t, +) -> wasmer_result_t { + let mut export = unsafe { Box::from_raw(func as *mut 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_func_results_arity".to_string(), + }); + wasmer_result_t::WASMER_ERROR + }; + Box::into_raw(export); + result +} + /// Frees memory for the given Func #[allow(clippy::cast_ptr_alignment)] #[no_mangle] @@ -955,6 +1069,17 @@ impl From<(std::string::String, wasmer_runtime_core::export::Export)> for NamedE } } +impl From<&wasmer_runtime::wasm::Type> for wasmer_value_tag { + fn from(ty: &Type) -> Self { + match *ty { + Type::I32 => wasmer_value_tag::WASM_I32, + Type::I64 => wasmer_value_tag::WASM_I64, + Type::F32 => wasmer_value_tag::WASM_F32, + Type::F64 => wasmer_value_tag::WASM_F64, + } + } +} + // Error reporting thread_local! { diff --git a/lib/runtime-c-api/tests/test-exports.c b/lib/runtime-c-api/tests/test-exports.c index c0c6a4a7b5a..2ac339e6a0a 100644 --- a/lib/runtime-c-api/tests/test-exports.c +++ b/lib/runtime-c-api/tests/test-exports.c @@ -43,6 +43,26 @@ int main() assert(name_bytes.bytes[idx] == expected[idx]); } + uint32_t params_arity; + wasmer_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); + 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); + assert(returns_arity == 1); + + wasmer_value_tag *returns_sig = malloc(sizeof(wasmer_value_tag) * returns_arity); + wasmer_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; diff --git a/lib/runtime-c-api/wasmer.h b/lib/runtime-c-api/wasmer.h index 3434d1a10b1..6af262a0aff 100644 --- a/lib/runtime-c-api/wasmer.h +++ b/lib/runtime-c-api/wasmer.h @@ -168,6 +168,40 @@ const wasmer_func_t *wasmer_func_new(void (*func)(void *data), 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 */ diff --git a/lib/runtime-c-api/wasmer.hh b/lib/runtime-c-api/wasmer.hh index 3b6ca95514d..e00c175311c 100644 --- a/lib/runtime-c-api/wasmer.hh +++ b/lib/runtime-c-api/wasmer.hh @@ -147,6 +147,32 @@ const wasmer_func_t *wasmer_func_new(void (*func)(void *data), 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);