Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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