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
1 change: 1 addition & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,7 @@ jobs:
-p wasmtime-c-api --no-default-features
-p wasmtime-c-api --no-default-features --features wat
-p wasmtime-c-api --no-default-features --features wasi
-p wasmtime-c-api --no-default-features --features gc

- name: wasmtime-wasi-http
checks: |
Expand Down
2 changes: 2 additions & 0 deletions crates/c-api-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,15 @@ pub fn declare_ref(input: proc_macro::TokenStream) -> proc_macro::TokenStream {

#[doc = #as_ref_docs]
#[unsafe(no_mangle)]
#[cfg(feature = "gc")]
pub extern fn #as_ref(a: &#ty) -> Box<crate::wasm_ref_t> {
eprintln!("`{}` is not implemented", stringify!(#as_ref));
std::process::abort();
}

#[doc = #as_ref_const_docs]
#[unsafe(no_mangle)]
#[cfg(feature = "gc")]
pub extern fn #as_ref_const(a: &#ty) -> Box<crate::wasm_ref_t> {
eprintln!("`{}` is not implemented", stringify!(#as_ref_const));
std::process::abort();
Expand Down
2 changes: 1 addition & 1 deletion crates/c-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ doctest = false

[dependencies]
env_logger = { workspace = true, optional = true }
wasmtime = { workspace = true, features = ['runtime', 'gc', 'std'] }
wasmtime = { workspace = true, features = ['runtime', 'std'] }
wasmtime-c-api-macros = { workspace = true }
log = { workspace = true }
tracing = { workspace = true }
Expand Down
6 changes: 6 additions & 0 deletions crates/c-api/include/wasmtime/config.hh
Original file line number Diff line number Diff line change
Expand Up @@ -303,13 +303,15 @@ class Config {
wasmtime_config_wasm_tail_call_set(ptr.get(), enable);
}

#ifdef WASMTIME_FEATURE_GC
/// \brief Configures whether the WebAssembly reference types proposal is
/// enabled
///
/// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.wasm_reference_types
void wasm_reference_types(bool enable) {
wasmtime_config_wasm_reference_types_set(ptr.get(), enable);
}
#endif // WASMTIME_FEATURE_GC

/// \brief Configures whether the WebAssembly simd proposal is enabled
///
Expand Down Expand Up @@ -361,11 +363,13 @@ class Config {
wasmtime_config_wasm_memory64_set(ptr.get(), enable);
}

#ifdef WASMTIME_FEATURE_GC
/// \brief Configures whether the WebAssembly Garbage Collection proposal will
/// be enabled
///
/// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.wasm_gc
void wasm_gc(bool enable) { wasmtime_config_wasm_gc_set(ptr.get(), enable); }
#endif // WASMTIME_FEATURE_GC

/// \brief Configures whether the WebAssembly function references proposal
/// will be enabled
Expand All @@ -383,13 +387,15 @@ class Config {
wasmtime_config_wasm_wide_arithmetic_set(ptr.get(), enable);
}

#ifdef WASMTIME_FEATURE_GC
/// \brief Configures whether the WebAssembly exceptions proposal will be
/// enabled
///
/// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.wasm_exceptions
void wasm_exceptions(bool enable) {
wasmtime_config_wasm_exceptions_set(ptr.get(), enable);
}
#endif // WASMTIME_FEATURE_GC

/// \brief Configures whether the WebAssembly custom-page-sizes proposal will
/// be enabled
Expand Down
3 changes: 3 additions & 0 deletions crates/c-api/include/wasmtime/func.hh
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ NATIVE_WASM_TYPE(double, F64, f64)

#undef NATIVE_WASM_TYPE

#ifdef WASMTIME_FEATURE_GC
/// Type information for `externref`, represented on the host as an optional
/// `ExternRef`.
template <> struct WasmType<std::optional<ExternRef>> {
Expand All @@ -102,6 +103,7 @@ template <> struct WasmType<std::optional<ExternRef>> {
p->externref = 0;
}
}

static std::optional<ExternRef> load(Store::Context cx,
wasmtime_val_raw_t *p) {
if (p->externref == 0) {
Expand All @@ -112,6 +114,7 @@ template <> struct WasmType<std::optional<ExternRef>> {
return ExternRef(val);
}
};
#endif // WASMTIME_FEATURE_GC

/// Type information for the `V128` host value used as a wasm value.
template <> struct WasmType<V128> {
Expand Down
3 changes: 3 additions & 0 deletions crates/c-api/include/wasmtime/gc.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#ifndef WASMTIME_GC_H
#define WASMTIME_GC_H

#ifdef WASMTIME_FEATURE_GC

#include <wasmtime/val.h>

#ifdef __cplusplus
Expand Down Expand Up @@ -593,4 +595,5 @@ WASM_API_EXTERN bool wasmtime_anyref_as_array(wasmtime_context_t *context,
} // extern "C"
#endif

#endif // WASMTIME_FEATURE_GC
#endif // WASMTIME_GC_H
5 changes: 5 additions & 0 deletions crates/c-api/include/wasmtime/gc.hh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
#ifndef WASMTIME_GC_HH
#define WASMTIME_GC_HH

#include <wasmtime/config.hh>

#ifdef WASMTIME_FEATURE_GC
#include <vector>
#include <wasmtime/gc.h>
#include <wasmtime/val.hh>
Expand Down Expand Up @@ -476,4 +479,6 @@ inline std::optional<ArrayRef> AnyRef::as_array(Store::Context cx) const {

} // namespace wasmtime

#endif // WASMTIME_FEATURE_GC

#endif // WASMTIME_GC_HH
2 changes: 2 additions & 0 deletions crates/c-api/include/wasmtime/store.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,10 @@ WASM_API_EXTERN void wasmtime_context_set_data(wasmtime_context_t *context,
*
* The `context` argument must not be NULL.
*/
#ifdef WASMTIME_FEATURE_GC
WASM_API_EXTERN wasmtime_error_t *
wasmtime_context_gc(wasmtime_context_t *context);
#endif

/**
* \brief Set fuel to this context's store for wasm to consume while executing.
Expand Down
4 changes: 4 additions & 0 deletions crates/c-api/include/wasmtime/store.hh
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ public:
/// Creates a context referencing the provided `Caller`.
Context(Caller *caller);

#ifdef WASMTIME_FEATURE_GC
/// Runs a garbage collection pass in the referenced store to collect loose
/// `externref` values, if any are available.
Result<std::monostate> gc() {
Expand All @@ -103,6 +104,7 @@ public:
}
return std::monostate();
}
#endif

/// Injects fuel to be consumed within this store.
///
Expand Down Expand Up @@ -253,9 +255,11 @@ public:
/// Explicit function to acquire a `Context` from this store.
Context context() { return this; }

#ifdef WASMTIME_FEATURE_GC
/// Runs a garbage collection pass in the referenced store to collect loose
/// GC-managed objects, if any are available.
Result<std::monostate> gc() { return context().gc(); }
#endif

private:
template <typename F>
Expand Down
5 changes: 5 additions & 0 deletions crates/c-api/include/wasmtime/val.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
extern "C" {
#endif

#ifdef WASMTIME_FEATURE_GC
struct wasmtime_eqref;
/// Convenience alias for #wasmtime_eqref
typedef struct wasmtime_eqref wasmtime_eqref_t;
Expand Down Expand Up @@ -201,6 +202,7 @@ WASM_API_EXTERN bool wasmtime_anyref_i31_get_s(wasmtime_context_t *context,
* `wasmtime_externref_set_null`. Null can be tested for with the
* `wasmtime_externref_is_null` function.
*/

typedef struct wasmtime_externref {
/// Internal metadata tracking within the store, embedders should not
/// configure or modify these fields.
Expand Down Expand Up @@ -367,6 +369,7 @@ WASM_API_EXTERN void wasmtime_exnref_clone(const wasmtime_exnref_t *ref,
* After this call, `ref` is left in an undefined state and should not be used.
*/
WASM_API_EXTERN void wasmtime_exnref_unroot(wasmtime_exnref_t *ref);
#endif // WASMTIME_FEATURE_GC

/// \brief Discriminant stored in #wasmtime_val::kind
typedef uint8_t wasmtime_valkind_t;
Expand Down Expand Up @@ -416,6 +419,7 @@ typedef union wasmtime_valunion {
float32_t f32;
/// Field used if #wasmtime_val_t::kind is #WASMTIME_F64
float64_t f64;
#ifdef WASMTIME_FEATURE_GC
/// Field used if #wasmtime_val_t::kind is #WASMTIME_ANYREF
wasmtime_anyref_t anyref;
/// Field used if #wasmtime_val_t::kind is #WASMTIME_EXTERNREF
Expand All @@ -427,6 +431,7 @@ typedef union wasmtime_valunion {
/// Use `wasmtime_funcref_is_null` to test whether this is a null function
/// reference.
wasmtime_func_t funcref;
#endif // WASMTIME_FEATURE_GC
/// Field used if #wasmtime_val_t::kind is #WASMTIME_V128
wasmtime_v128 v128;
} wasmtime_valunion_t;
Expand Down
6 changes: 6 additions & 0 deletions crates/c-api/include/wasmtime/val.hh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
#define WASMTIME_VAL_HH

#include <optional>
#ifdef WASMTIME_FEATURE_GC
#include <wasmtime/gc.h>
#endif // WASMTIME_FEATURE_GC
#include <wasmtime/store.hh>
#include <wasmtime/types/val.hh>
#include <wasmtime/val.h>
Expand All @@ -17,6 +19,7 @@ class EqRef;
class StructRef;
class ArrayRef;

#ifdef WASMTIME_FEATURE_GC
/**
* \brief Representation of a WebAssembly `externref` value.
*
Expand Down Expand Up @@ -103,9 +106,11 @@ public:
return wasmtime_externref_to_raw(cx.capi(), &val);
}
};
#endif // WASMTIME_FEATURE_GC

class EqRef;

#ifdef WASMTIME_FEATURE_GC
/**
* \brief Representation of a WebAssembly `anyref` value.
*/
Expand Down Expand Up @@ -204,6 +209,7 @@ public:
/// \brief Downcast to arrayref. Returns null arrayref if not an arrayref.
inline std::optional<ArrayRef> as_array(Store::Context cx) const;
};
#endif // WASMTIME_FEATURE_GC

/// \brief Container for the `v128` WebAssembly type.
struct V128 {
Expand Down
4 changes: 4 additions & 0 deletions crates/c-api/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,13 @@ pub extern "C" fn wasmtime_config_wasm_tail_call_set(c: &mut wasm_config_t, enab
}

#[unsafe(no_mangle)]
#[cfg(feature = "gc")]
pub extern "C" fn wasmtime_config_wasm_reference_types_set(c: &mut wasm_config_t, enable: bool) {
c.config.wasm_reference_types(enable);
}

#[unsafe(no_mangle)]
#[cfg(feature = "gc")]
pub extern "C" fn wasmtime_config_wasm_function_references_set(
c: &mut wasm_config_t,
enable: bool,
Expand All @@ -103,6 +105,7 @@ pub extern "C" fn wasmtime_config_wasm_function_references_set(
}

#[unsafe(no_mangle)]
#[cfg(feature = "gc")]
pub extern "C" fn wasmtime_config_wasm_gc_set(c: &mut wasm_config_t, enable: bool) {
c.config.wasm_gc(enable);
}
Expand Down Expand Up @@ -476,6 +479,7 @@ pub extern "C" fn wasmtime_config_wasm_wide_arithmetic_set(c: &mut wasm_config_t
}

#[unsafe(no_mangle)]
#[cfg(feature = "gc")]
pub extern "C" fn wasmtime_config_wasm_exceptions_set(c: &mut wasm_config_t, enable: bool) {
c.config.wasm_exceptions(enable);
}
Expand Down
1 change: 1 addition & 0 deletions crates/c-api/src/exn.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![cfg(feature = "gc")]
use crate::{
WasmtimeStoreContextMut, handle_result, wasm_trap_t, wasmtime_error_t, wasmtime_val_t,
};
Expand Down
32 changes: 23 additions & 9 deletions crates/c-api/src/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ use std::panic::{self, AssertUnwindSafe};
use std::ptr;
use std::str;
use wasmtime::{
AsContext, AsContextMut, Error, Extern, Func, Result, RootScope, StoreContext, StoreContextMut,
Trap, Val, ValRaw,
AsContext, AsContextMut, Error, Extern, Func, Result, StoreContext, StoreContextMut, Trap, Val,
ValRaw,
};
#[cfg(feature = "gc")]
use wasmtime::{RootScope, ThrownException};

#[derive(Clone)]
#[repr(transparent)]
Expand Down Expand Up @@ -351,13 +353,15 @@ pub unsafe extern "C" fn wasmtime_func_call(
nresults: usize,
trap_ret: &mut *mut wasm_trap_t,
) -> Option<Box<wasmtime_error_t>> {
let mut scope = RootScope::new(&mut store);
let mut params = mem::take(&mut scope.as_context_mut().data_mut().wasm_val_storage);
#[cfg(feature = "gc")]
let mut store = RootScope::new(&mut store);
let mut params = mem::take(&mut store.as_context_mut().data_mut().wasm_val_storage);

let (wt_params, wt_results) = translate_args(
&mut params,
crate::slice_from_raw_parts(args, nargs)
.iter()
.map(|i| i.to_val(&mut scope)),
.map(|i| i.to_val(&mut store)),
nresults,
);

Expand All @@ -366,16 +370,16 @@ pub unsafe extern "C" fn wasmtime_func_call(
// can. As a result we catch panics here and transform them to traps to
// allow the caller to have any insulation possible against Rust panics.
let result = panic::catch_unwind(AssertUnwindSafe(|| {
func.call(&mut scope, wt_params, wt_results)
func.call(&mut store, wt_params, wt_results)
}));
match result {
Ok(Ok(())) => {
let results = crate::slice_from_raw_parts_mut(results, nresults);
for (slot, val) in results.iter_mut().zip(wt_results.iter()) {
crate::initialize(slot, wasmtime_val_t::from_val(&mut scope, *val));
crate::initialize(slot, wasmtime_val_t::from_val(&mut store, *val));
}
params.truncate(0);
scope.as_context_mut().data_mut().wasm_val_storage = params;
store.as_context_mut().data_mut().wasm_val_storage = params;
None
}
Ok(Err(trap)) => store_err(trap, trap_ret),
Expand All @@ -402,8 +406,18 @@ pub unsafe extern "C" fn wasmtime_func_call_unchecked(
}
}

#[cfg(feature = "gc")]
fn is_trap_like_impl(err: &Error) -> bool {
err.is::<Trap>() || err.is::<ThrownException>()
}

#[cfg(not(feature = "gc"))]
fn is_trap_like_impl(err: &Error) -> bool {
err.is::<Trap>()
}

fn store_err(err: Error, trap_ret: &mut *mut wasm_trap_t) -> Option<Box<wasmtime_error_t>> {
if err.is::<Trap>() || err.is::<wasmtime::ThrownException>() {
if is_trap_like_impl(&err) {
*trap_ret = Box::into_raw(Box::new(wasm_trap_t::new(err)));
None
} else {
Expand Down
Loading
Loading