Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
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
2 changes: 2 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,8 @@ jobs:

# Ensure all our examples build and execute
- run: cargo run -p run-examples
env:
RUST_BACKTRACE: 1

# Build and test all features except for lightbeam
- run: |
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ rusty-tags.*
tags
target
.z3-trace
foo
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

35 changes: 18 additions & 17 deletions crates/c-api/include/doc-wasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -1147,19 +1147,22 @@

/**
* \struct wasm_ref_t
* \brief Unimplemented and used in Wasmtime right now.
* \brief A reference type: either a funcref or an externref.
*
* \typedef wasm_ref_t
* \brief Convenience alias for #wasm_ref_t
*
* \fn void wasm_ref_delete(own wasm_ref_t *v);
* \brief Deletes a reference.
* \brief Delete a reference.
*
* \fn own wasm_ref_t *wasm_ref_copy(const wasm_ref_t *)
* \brief Unimplemented in Wasmtime, aborts the process if called.
* \brief Copy a reference.
*
* \fn bool wasm_ref_same(const wasm_ref_t *, const wasm_ref_t *)
* \brief Unimplemented in Wasmtime, aborts the process if called.
* \brief Are the given references pointing to the same externref?
*
* > Note: Wasmtime does not support checking funcrefs for equality, and this
* > function will always return false for funcrefs.
*
* \fn void* wasm_ref_get_host_info(const wasm_ref_t *);
* \brief Unimplemented in Wasmtime, always returns `NULL`.
Expand Down Expand Up @@ -1614,6 +1617,9 @@
* If a trap happens during execution or some other error then a non-`NULL` trap
* is returned. In this situation the `results` are is unmodified.
*
* Does not take ownership of `wasm_val_t` arguments. Gives ownership of
* `wasm_val_t` results.
*
* > Note: to avoid the UB associated with passing the wrong number of results
* > or parameters by accident, or to distinguish between traps and other
* > errors, it's recommended to use #wasmtime_func_call.
Expand Down Expand Up @@ -1758,10 +1764,9 @@
* Returns an error if the #wasm_ref_t does not match the element type of the
* table provided or if it comes from a different store than the one provided.
*
* Does not take ownship of the `init` value.
*
* > Note: for funcref tables you can use #wasmtime_funcref_table_new as well.
* >
* > Additionally the #wasm_ref_t does not have much support in Wasmtime, so you
* > may not be able to create an appropriate initial value.
*
* \fn wasm_tabletype_t *wasm_table_type(const wasm_table_t *);
* \brief Returns the type of this table.
Expand All @@ -1774,12 +1779,10 @@
* Attempts to get a value at an index in this table. This function returns
* `NULL` if the index is out of bounds.
*
* Gives ownership of the resulting `wasm_ref_t*`.
*
* > Note: for funcref tables you can use #wasmtime_funcref_table_get to learn
* > about out-of-bounds errors.
* >
* > Additionally the #wasm_ref_t does not have much
* > support in Wasmtime, so you may not be able to do much with the returned
* > value.
*
* \fn void wasm_table_set(wasm_table_t *, wasm_table_size_t index, wasm_ref_t *);
* \brief Sets an element in this table.
Expand All @@ -1791,11 +1794,10 @@
* * The #wasm_ref_t comes from a different store than the table provided.
* * The #wasm_ref_t does not have an appropriate type to store in this table.
*
* Does not take ownership of the given `wasm_ref_t*`.
*
* > Note: for funcref tables you can use #wasmtime_funcref_table_set to learn
* > about errors.
* >
* > Additionally the #wasm_ref_t does not have much support in Wasmtime, so you
* > may not be able to create an appropriate initial value.
*
* \fn wasm_table_size_t wasm_table_size(const wasm_table_t *);
* \brief Gets the current size, in elements, of this table.
Expand All @@ -1813,10 +1815,9 @@
* * The #wasm_ref_t comes from a different store than the table provided.
* * The #wasm_ref_t does not have an appropriate type to store in this table.
*
* Does not take ownership of the givein `init` value.
*
* > Note: for funcref tables you can use #wasmtime_funcref_table_grow as well.
* >
* > Additionally the #wasm_ref_t does not have much support in Wasmtime, so you
* > may not be able to create an appropriate initial value.
*/

/**
Expand Down
60 changes: 60 additions & 0 deletions crates/c-api/include/wasmtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,9 @@ WASM_API_EXTERN const wasm_name_t *wasmtime_frame_module_name(const wasm_frame_t
*
* The `trap` pointer cannot be `NULL`. The `args` and `results` pointers may be
* `NULL` if the corresponding length is zero.
*
* Does not take ownership of `wasm_val_t` arguments. Gives ownership of
* `wasm_val_t` results.
*/
WASM_API_EXTERN own wasmtime_error_t *wasmtime_func_call(
wasm_func_t *func,
Expand Down Expand Up @@ -833,6 +836,63 @@ WASM_API_EXTERN wasmtime_error_t *wasmtime_funcref_table_grow(
wasm_table_size_t *prev_size
);

/**
* \brief Create a new `externref` value.
*
* Creates a new `externref` value wrapping the provided data, and writes it to
* `valp`.
*
* This function does not take an associated finalizer to clean up the data when
* the reference is reclaimed. If you need a finalizer to clean up the data,
* then use #wasmtime_externref_new_with_finalizer.
*/
WASM_API_EXTERN void wasmtime_externref_new(void *data, wasm_val_t *valp);

/**
* \brief A finalizer for an `externref`'s wrapped data.
*
* A finalizer callback to clean up an `externref`'s wrapped data after the
* `externref` has been reclaimed. This is an opportunity to run destructors,
* free dynamically allocated memory, close file handles, etc.
*/
typedef void (*wasmtime_externref_finalizer_t)(void*);

/**
* \brief Create a new `externref` value with a finalizer.
*
* Creates a new `externref` value wrapping the provided data, and writes it to
* `valp`.
*
* When the reference is reclaimed, the wrapped data is cleaned up with the
* provided finalizer. If you do not need to clean up the wrapped data, then use
* #wasmtime_externref_new.
*/
WASM_API_EXTERN void wasmtime_externref_new_with_finalizer(
void *data,
wasmtime_externref_finalizer_t finalizer,
wasm_val_t *valp
);

/**
* \brief Get an `externref`'s wrapped data
*
* If the given value is a reference to a non-null `externref`, writes the
* wrapped data that was passed into #wasmtime_externref_new or
* #wasmtime_externref_new_with_finalizer when creating the given `externref` to
* `datap`, and returns `true`.
*
* If the value is a reference to a null `externref`, writes `NULL` to `datap`
* and returns `true`.
*
* If the given value is not an `externref`, returns `false` and leaves `datap`
* unmodified.
*
* Does not take ownership of `val`.
*
* Both `val` and `datap` must not be `NULL`.
*/
WASM_API_EXTERN bool wasmtime_externref_data(wasm_val_t* val, void** datap);

#undef own

#ifdef __cplusplus
Expand Down
12 changes: 7 additions & 5 deletions crates/c-api/src/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::{wasm_extern_t, wasm_functype_t, wasm_store_t, wasm_val_t};
use crate::{wasm_name_t, wasm_trap_t, wasmtime_error_t};
use anyhow::anyhow;
use std::ffi::c_void;
use std::mem::MaybeUninit;
use std::panic::{self, AssertUnwindSafe};
use std::ptr;
use std::str;
Expand Down Expand Up @@ -89,6 +90,7 @@ fn create_function(
let func = Func::new(store, ty, move |caller, params, results| {
let params = params
.iter()
.cloned()
.map(|p| wasm_val_t::from_val(p))
.collect::<Vec<_>>();
let mut out_results = vec![wasm_val_t::default(); results.len()];
Expand Down Expand Up @@ -163,7 +165,7 @@ pub extern "C" fn wasmtime_func_new_with_env(
pub unsafe extern "C" fn wasm_func_call(
wasm_func: &wasm_func_t,
args: *const wasm_val_t,
results: *mut wasm_val_t,
results: *mut MaybeUninit<wasm_val_t>,
) -> *mut wasm_trap_t {
let func = wasm_func.func();
let mut trap = ptr::null_mut();
Expand All @@ -186,7 +188,7 @@ pub unsafe extern "C" fn wasmtime_func_call(
func: &wasm_func_t,
args: *const wasm_val_t,
num_args: usize,
results: *mut wasm_val_t,
results: *mut MaybeUninit<wasm_val_t>,
num_results: usize,
trap_ptr: &mut *mut wasm_trap_t,
) -> Option<Box<wasmtime_error_t>> {
Expand All @@ -201,7 +203,7 @@ pub unsafe extern "C" fn wasmtime_func_call(
fn _wasmtime_func_call(
func: &wasm_func_t,
args: &[wasm_val_t],
results: &mut [wasm_val_t],
results: &mut [MaybeUninit<wasm_val_t>],
trap_ptr: &mut *mut wasm_trap_t,
) -> Option<Box<wasmtime_error_t>> {
let func = func.func();
Expand All @@ -217,8 +219,8 @@ fn _wasmtime_func_call(
let result = panic::catch_unwind(AssertUnwindSafe(|| func.call(&params)));
match result {
Ok(Ok(out)) => {
for (slot, val) in results.iter_mut().zip(out.iter()) {
*slot = wasm_val_t::from_val(val);
for (slot, val) in results.iter_mut().zip(out.into_vec().into_iter()) {
crate::initialize(slot, wasm_val_t::from_val(val));
}
None
}
Expand Down
5 changes: 3 additions & 2 deletions crates/c-api/src/global.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::{handle_result, wasmtime_error_t};
use crate::{wasm_extern_t, wasm_globaltype_t, wasm_store_t, wasm_val_t};
use std::mem::MaybeUninit;
use std::ptr;
use wasmtime::{Extern, Global};

Expand Down Expand Up @@ -72,8 +73,8 @@ pub extern "C" fn wasm_global_type(g: &wasm_global_t) -> Box<wasm_globaltype_t>
}

#[no_mangle]
pub extern "C" fn wasm_global_get(g: &wasm_global_t, out: &mut wasm_val_t) {
out.set(g.global().get());
pub extern "C" fn wasm_global_get(g: &wasm_global_t, out: &mut MaybeUninit<wasm_val_t>) {
crate::initialize(out, wasm_val_t::from_val(g.global().get()));
}

#[no_mangle]
Expand Down
18 changes: 8 additions & 10 deletions crates/c-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,13 @@ pub struct wasm_shared_module_t {
_unused: [u8; 0],
}

struct HostInfoState {
info: *mut std::ffi::c_void,
finalizer: Option<extern "C" fn(arg1: *mut std::ffi::c_void)>,
}

impl Drop for HostInfoState {
fn drop(&mut self) {
if let Some(f) = &self.finalizer {
f(self.info);
}
/// Initialize a `MaybeUninit<T>`
///
/// TODO: Replace calls to this function with
/// https://doc.rust-lang.org/nightly/std/mem/union.MaybeUninit.html#method.write
/// once it is stable.
pub(crate) fn initialize<T>(dst: &mut std::mem::MaybeUninit<T>, val: T) {
unsafe {
std::ptr::write(dst.as_mut_ptr(), val);
}
}
Loading