Skip to content

Commit

Permalink
add C API for epoch_deadline_callback and wasmtime_error_t creation (#…
Browse files Browse the repository at this point in the history
…6359)

* add C API for epoch_dead_callback and wasmtime_error_t creation

* revise C API wasmtime_error_new msg encoding
  • Loading branch information
theothergraham authored May 9, 2023
1 parent 6146656 commit cfb506b
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 3 deletions.
5 changes: 5 additions & 0 deletions crates/c-api/include/wasmtime/error.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down
21 changes: 18 additions & 3 deletions crates/c-api/include/wasmtime/store.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
14 changes: 14 additions & 0 deletions crates/c-api/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
42 changes: 42 additions & 0 deletions crates/c-api/src/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down

0 comments on commit cfb506b

Please sign in to comment.