Skip to content

Commit

Permalink
c-api: Support InstancePre (bytecodealliance#7140)
Browse files Browse the repository at this point in the history
* c-api: Support InstancePre

Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>

* c-api: Consolidate all the instance_pre functionality

Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>

* c-api: Add async instantiate support to pre instances

Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>

* c-api: Add star to comment for doxygen

prtest:full

Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>

---------

Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
  • Loading branch information
rockwotj authored and alexcrichton committed Oct 4, 2023
1 parent 9e73327 commit bad0329
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 6 deletions.
26 changes: 25 additions & 1 deletion crates/c-api/include/wasmtime/async.h
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,31 @@ WASM_API_EXTERN wasmtime_call_future_t *wasmtime_linker_instantiate_async(
const wasmtime_module_t *module,
wasmtime_instance_t *instance,
wasm_trap_t** trap_ret,
wasmtime_error_t** wasmtime_error_t);
wasmtime_error_t** error_ret);

/**
* \brief Instantiates instance within the given store.
*
* This will also run the function's startup function, if there is one.
*
* For more information on async instantiation see #wasmtime_linker_instantiate_async.
*
* \param instance_pre the pre-initialized instance
* \param store the store in which to create the instance
* \param instance where to store the returned instance
* \param trap_ret where to store the returned trap
* \param error_ret where to store the returned trap
*
* The `trap_ret` and `error_ret` pointers may *not* be `NULL` and the returned memory is owned by the caller.
*
* All arguments to this function must outlive the returned future and be unmodified until the future is deleted.
*/
WASM_API_EXTERN wasmtime_call_future_t *wasmtime_instance_pre_instantiate_async(
const wasmtime_instance_pre_t* instance_pre,
wasmtime_context_t *store,
wasmtime_instance_t *instance,
wasm_trap_t** trap_ret,
wasmtime_error_t** error_ret);

#ifdef __cplusplus
} // extern "C"
Expand Down
45 changes: 45 additions & 0 deletions crates/c-api/include/wasmtime/instance.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,51 @@ WASM_API_EXTERN bool wasmtime_instance_export_nth(
wasmtime_extern_t *item
);

/**
* \brief A #wasmtime_instance_t, pre-instantiation, that is ready to be instantiated.
*
* Must be deleted using #wasmtime_instance_pre_delete.
*
* For more information see the Rust documentation:
* https://docs.wasmtime.dev/api/wasmtime/struct.InstancePre.html
*/
typedef struct wasmtime_instance_pre wasmtime_instance_pre_t;

/**
* \brief Delete a previously created wasmtime_instance_pre_t.
*/
WASM_API_EXTERN void
wasmtime_instance_pre_delete(wasmtime_instance_pre_t *instance);

/**
* \brief Instantiates instance within the given store.
*
* This will also run the function's startup function, if there is one.
*
* For more information on instantiation see #wasmtime_instance_new.
*
* \param instance_pre the pre-initialized instance
* \param store the store in which to create the instance
* \param instance where to store the returned instance
* \param trap_ptr where to store the returned trap
*
* \return One of three things can happen as a result of this function. First
* the module could be successfully instantiated and returned through
* `instance`, meaning the return value and `trap` are both set to `NULL`.
* Second the start function may trap, meaning the return value and `instance`
* are set to `NULL` and `trap` describes the trap that happens. Finally
* instantiation may fail for another reason, in which case an error is returned
* and `trap` and `instance` are set to `NULL`.
*
* This function does not take ownership of any of its arguments, and all return
* values are owned by the caller.
*/
WASM_API_EXTERN wasmtime_error_t* wasmtime_instance_pre_instantiate(
const wasmtime_instance_pre_t* instance_pre,
wasmtime_store_t *store,
wasmtime_instance_t* instance,
wasm_trap_t **trap_ptr);

#ifdef __cplusplus
} // extern "C"
#endif
Expand Down
18 changes: 18 additions & 0 deletions crates/c-api/include/wasmtime/linker.h
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,24 @@ WASM_API_EXTERN bool wasmtime_linker_get(
wasmtime_extern_t *item
);

/**
* \brief Preform all the checks for instantiating `module` with the linker,
* except that instantiation doesn't actually finish.
*
* \param linker the linker used to instantiate the provided module.
* \param module the module that is being instantiated.
* \param instance_pre the returned instance_pre, if successful.
*
* \return An error or `NULL` if successful.
*
* For more information see the Rust documentation at:
* https://docs.wasmtime.dev/api/wasmtime/struct.Linker.html#method.instantiate_pre
*/
WASM_API_EXTERN wasmtime_error_t* wasmtime_linker_instantiate_pre(
const wasmtime_linker_t *linker,
const wasmtime_module_t *module,
wasmtime_instance_t **instance_pre);

#ifdef __cplusplus
} // extern "C"
#endif
Expand Down
36 changes: 34 additions & 2 deletions crates/c-api/src/async.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ use wasmtime::{AsContextMut, Caller, Func, Instance, Result, Trap, Val};

use crate::{
bad_utf8, handle_result, to_str, translate_args, wasm_config_t, wasm_functype_t, wasm_trap_t,
wasmtime_caller_t, wasmtime_error_t, wasmtime_linker_t, wasmtime_module_t, wasmtime_val_t,
wasmtime_val_union, CStoreContextMut, WASMTIME_I32,
wasmtime_caller_t, wasmtime_error_t, wasmtime_instance_pre_t, wasmtime_linker_t,
wasmtime_module_t, wasmtime_val_t, wasmtime_val_union, CStoreContextMut, WASMTIME_I32,
};

#[no_mangle]
Expand Down Expand Up @@ -303,3 +303,35 @@ pub extern "C" fn wasmtime_linker_instantiate_async<'a>(
));
Box::new(crate::wasmtime_call_future_t { underlying: fut })
}

async fn do_instance_pre_instantiate_async(
instance_pre: &wasmtime_instance_pre_t,
store: CStoreContextMut<'_>,
instance_ptr: &mut Instance,
trap_ret: &mut *mut wasm_trap_t,
err_ret: &mut *mut wasmtime_error_t,
) {
let result = instance_pre.underlying.instantiate_async(store).await;
match result {
Ok(instance) => *instance_ptr = instance,
Err(err) => handle_call_error(err, trap_ret, err_ret),
}
}

#[no_mangle]
pub extern "C" fn wasmtime_instance_pre_instantiate_async<'a>(
instance_pre: &'a wasmtime_instance_pre_t,
store: CStoreContextMut<'a>,
instance_ptr: &'a mut Instance,
trap_ret: &'a mut *mut wasm_trap_t,
err_ret: &'a mut *mut wasmtime_error_t,
) -> Box<crate::wasmtime_call_future_t<'a>> {
let fut = Box::pin(do_instance_pre_instantiate_async(
instance_pre,
store,
instance_ptr,
trap_ret,
err_ret,
));
Box::new(crate::wasmtime_call_future_t { underlying: fut })
}
24 changes: 22 additions & 2 deletions crates/c-api/src/instance.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use crate::{
wasm_extern_t, wasm_extern_vec_t, wasm_module_t, wasm_store_t, wasm_trap_t, wasmtime_error_t,
wasmtime_extern_t, wasmtime_module_t, CStoreContextMut, StoreRef,
wasmtime_extern_t, wasmtime_module_t, CStoreContextMut, StoreData, StoreRef,
};
use std::mem::MaybeUninit;
use wasmtime::{Instance, Trap};
use wasmtime::{Instance, InstancePre, Trap};

#[derive(Clone)]
pub struct wasm_instance_t {
Expand Down Expand Up @@ -150,3 +150,23 @@ pub unsafe extern "C" fn wasmtime_instance_export_nth(
None => false,
}
}

#[repr(transparent)]
pub struct wasmtime_instance_pre_t {
pub(crate) underlying: InstancePre<StoreData>,
}

#[no_mangle]
pub unsafe extern "C" fn wasmtime_instance_pre_delete(_instance_pre: Box<wasmtime_instance_pre_t>) {
}

#[no_mangle]
pub unsafe extern "C" fn wasmtime_instance_pre_instantiate(
instance_pre: &wasmtime_instance_pre_t,
store: CStoreContextMut<'_>,
instance_ptr: &mut Instance,
trap_ptr: &mut *mut wasm_trap_t,
) -> Option<Box<wasmtime_error_t>> {
let result = instance_pre.underlying.instantiate(store);
handle_instantiate(result, instance_ptr, trap_ptr)
}
15 changes: 14 additions & 1 deletion crates/c-api/src/linker.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
bad_utf8, handle_result, wasm_engine_t, wasm_functype_t, wasm_trap_t, wasmtime_error_t,
wasmtime_extern_t, wasmtime_module_t, CStoreContext, CStoreContextMut,
wasmtime_extern_t, wasmtime_instance_pre_t, wasmtime_module_t, CStoreContext, CStoreContextMut,
};
use std::ffi::c_void;
use std::mem::MaybeUninit;
Expand Down Expand Up @@ -138,6 +138,19 @@ pub extern "C" fn wasmtime_linker_instantiate(
super::instance::handle_instantiate(result, instance_ptr, trap_ptr)
}

#[no_mangle]
pub unsafe extern "C" fn wasmtime_linker_instantiate_pre(
linker: &wasmtime_linker_t,
module: &wasmtime_module_t,
instance_ptr: &mut *mut wasmtime_instance_pre_t,
) -> Option<Box<wasmtime_error_t>> {
let linker = &linker.linker;
handle_result(linker.instantiate_pre(&module.module), |i| {
let instance_pre = Box::new(wasmtime_instance_pre_t { underlying: i });
*instance_ptr = Box::into_raw(instance_pre)
})
}

#[no_mangle]
pub unsafe extern "C" fn wasmtime_linker_module(
linker: &mut wasmtime_linker_t,
Expand Down

0 comments on commit bad0329

Please sign in to comment.