Browse Source
add C API for epoch_deadline_callback and wasmtime_error_t creation (#6359)
* add C API for epoch_dead_callback and wasmtime_error_t creation
* revise C API wasmtime_error_new msg encoding
pull/6337/head
theothergraham
2 years ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with
79 additions and
3 deletions
-
crates/c-api/include/wasmtime/error.h
-
crates/c-api/include/wasmtime/store.h
-
crates/c-api/src/error.rs
-
crates/c-api/src/store.rs
|
|
@ -30,6 +30,11 @@ extern "C" { |
|
|
|
*/ |
|
|
|
typedef struct wasmtime_error wasmtime_error_t; |
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Creates a new error with the provided message. |
|
|
|
*/ |
|
|
|
WASM_API_EXTERN wasmtime_error_t *wasmtime_error_new(const char*); |
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Deletes an error. |
|
|
|
*/ |
|
|
|
|
|
@ -206,15 +206,30 @@ WASM_API_EXTERN wasmtime_error_t *wasmtime_context_set_wasi(wasmtime_context_t * |
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Configures the relative deadline at which point WebAssembly code will |
|
|
|
* trap. |
|
|
|
* trap or invoke the callback function. |
|
|
|
* |
|
|
|
* This function configures the store-local epoch deadline after which point |
|
|
|
* WebAssembly code will trap. |
|
|
|
* WebAssembly code will trap or invoke the callback function. |
|
|
|
* |
|
|
|
* See also #wasmtime_config_epoch_interruption_set. |
|
|
|
* See also #wasmtime_config_epoch_interruption_set and |
|
|
|
* #wasmtime_store_epoch_deadline_callback. |
|
|
|
*/ |
|
|
|
WASM_API_EXTERN void wasmtime_context_set_epoch_deadline(wasmtime_context_t *context, uint64_t ticks_beyond_current); |
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Configures epoch deadline callback to C function. |
|
|
|
* |
|
|
|
* This function configures a store-local callback function that will be |
|
|
|
* called when the running WebAssembly function has exceeded its epoch |
|
|
|
* deadline. That function can return a #wasmtime_error_t to terminate |
|
|
|
* the function, or set the delta argument and return NULL to update the |
|
|
|
* epoch deadline and resume function execution. |
|
|
|
* |
|
|
|
* See also #wasmtime_config_epoch_interruption_set and |
|
|
|
* #wasmtime_context_set_epoch_deadline. |
|
|
|
*/ |
|
|
|
WASM_API_EXTERN void wasmtime_store_epoch_deadline_callback(wasmtime_store_t *store, wasmtime_error_t* (*func)(wasmtime_context_t*, void*, uint64_t*), void *data); |
|
|
|
|
|
|
|
#ifdef __cplusplus |
|
|
|
} // extern "C"
|
|
|
|
#endif |
|
|
|
|
|
@ -14,6 +14,20 @@ impl From<Error> for wasmtime_error_t { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
impl Into<Error> for wasmtime_error_t { |
|
|
|
fn into(self) -> Error { |
|
|
|
self.error |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
#[no_mangle] |
|
|
|
pub extern "C" fn wasmtime_error_new( |
|
|
|
msg: *const std::ffi::c_char, |
|
|
|
) -> Option<Box<wasmtime_error_t>> { |
|
|
|
let msg_string = String::from_utf8_lossy(unsafe { std::ffi::CStr::from_ptr(msg).to_bytes() }); |
|
|
|
Some(Box::new(wasmtime_error_t::from(anyhow!(msg_string)))) |
|
|
|
} |
|
|
|
|
|
|
|
pub(crate) fn handle_result<T>( |
|
|
|
result: Result<T>, |
|
|
|
ok: impl FnOnce(T), |
|
|
|
|
|
@ -106,6 +106,48 @@ pub extern "C" fn wasmtime_store_new( |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
// Internal structure to add Send/Sync to the c_void member.
|
|
|
|
#[derive(Debug)] |
|
|
|
pub struct CallbackDataPtr { |
|
|
|
pub ptr: *mut c_void, |
|
|
|
} |
|
|
|
|
|
|
|
impl CallbackDataPtr { |
|
|
|
fn as_mut_ptr(&self) -> *mut c_void { |
|
|
|
self.ptr |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
unsafe impl Send for CallbackDataPtr {} |
|
|
|
unsafe impl Sync for CallbackDataPtr {} |
|
|
|
|
|
|
|
#[no_mangle] |
|
|
|
pub extern "C" fn wasmtime_store_epoch_deadline_callback( |
|
|
|
store: &mut wasmtime_store_t, |
|
|
|
func: extern "C" fn( |
|
|
|
CStoreContextMut<'_>, |
|
|
|
*mut c_void, |
|
|
|
*mut u64, |
|
|
|
) -> Option<Box<wasmtime_error_t>>, |
|
|
|
data: *mut c_void, |
|
|
|
) { |
|
|
|
let sendable = CallbackDataPtr { ptr: data }; |
|
|
|
store.store.epoch_deadline_callback(move |mut store_ctx| { |
|
|
|
let mut delta: u64 = 0; |
|
|
|
let result = (func)( |
|
|
|
store_ctx.as_context_mut(), |
|
|
|
sendable.as_mut_ptr(), |
|
|
|
&mut delta as *mut u64, |
|
|
|
); |
|
|
|
match result { |
|
|
|
Some(err) => Err(wasmtime::Error::from(<wasmtime_error_t as Into< |
|
|
|
anyhow::Error, |
|
|
|
>>::into(*err))), |
|
|
|
None => Ok(delta), |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
#[no_mangle] |
|
|
|
pub extern "C" fn wasmtime_store_context(store: &mut wasmtime_store_t) -> CStoreContextMut<'_> { |
|
|
|
store.store.as_context_mut() |
|
|
|