Skip to content

Commit

Permalink
Add func signature lookup functions
Browse files Browse the repository at this point in the history
  • Loading branch information
bjfish committed Feb 17, 2019
1 parent 56079ad commit 7bb947a
Show file tree
Hide file tree
Showing 4 changed files with 205 additions and 0 deletions.
125 changes: 125 additions & 0 deletions lib/runtime-c-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -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! {
Expand Down
20 changes: 20 additions & 0 deletions lib/runtime-c-api/tests/test-exports.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,26 @@ int main()
assert(name_bytes.bytes[idx] == expected[idx]);
}

uint32_t params_arity;
wasmer_func_params_arity(func, &params_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;
Expand Down
34 changes: 34 additions & 0 deletions lib/runtime-c-api/wasmer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down
26 changes: 26 additions & 0 deletions lib/runtime-c-api/wasmer.hh
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down

0 comments on commit 7bb947a

Please sign in to comment.