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
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