From 0f78a8614e67e80c65abe055a80753e2808d27a6 Mon Sep 17 00:00:00 2001 From: tolumide-ng Date: Thu, 19 Mar 2026 21:46:19 +0100 Subject: [PATCH 1/3] Remove the explicit gc feature from the wasmtime dependency in the c-api crate --- .github/workflows/main.yml | 1 + crates/c-api-macros/src/lib.rs | 2 + crates/c-api/Cargo.toml | 2 +- crates/c-api/include/wasmtime/config.hh | 6 +++ crates/c-api/include/wasmtime/func.hh | 5 +- crates/c-api/include/wasmtime/store.h | 2 + crates/c-api/include/wasmtime/store.hh | 4 ++ crates/c-api/include/wasmtime/val.h | 7 +++ crates/c-api/include/wasmtime/val.hh | 5 ++ crates/c-api/src/config.rs | 4 ++ crates/c-api/src/func.rs | 20 ++++---- crates/c-api/src/global.rs | 30 ++++++++---- crates/c-api/src/lib.rs | 2 + crates/c-api/src/ref.rs | 7 ++- crates/c-api/src/store.rs | 1 + crates/c-api/src/table.rs | 49 +++++++++++++------ crates/c-api/src/val.rs | 64 +++++++++++++++++++++++-- 17 files changed, 171 insertions(+), 40 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9bb3688e99b1..bd6a56e9f267 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -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: | diff --git a/crates/c-api-macros/src/lib.rs b/crates/c-api-macros/src/lib.rs index fa1dd408147b..76d56bf0b87d 100644 --- a/crates/c-api-macros/src/lib.rs +++ b/crates/c-api-macros/src/lib.rs @@ -135,6 +135,7 @@ 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 { eprintln!("`{}` is not implemented", stringify!(#as_ref)); std::process::abort(); @@ -142,6 +143,7 @@ pub fn declare_ref(input: proc_macro::TokenStream) -> proc_macro::TokenStream { #[doc = #as_ref_const_docs] #[unsafe(no_mangle)] + #[cfg(feature = "gc")] pub extern fn #as_ref_const(a: &#ty) -> Box { eprintln!("`{}` is not implemented", stringify!(#as_ref_const)); std::process::abort(); diff --git a/crates/c-api/Cargo.toml b/crates/c-api/Cargo.toml index eccea9cc7602..8b2d4d002d05 100644 --- a/crates/c-api/Cargo.toml +++ b/crates/c-api/Cargo.toml @@ -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 } diff --git a/crates/c-api/include/wasmtime/config.hh b/crates/c-api/include/wasmtime/config.hh index 12d57245fb2f..0ec47bc38e98 100644 --- a/crates/c-api/include/wasmtime/config.hh +++ b/crates/c-api/include/wasmtime/config.hh @@ -303,6 +303,7 @@ 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 /// @@ -310,6 +311,7 @@ class Config { 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 /// @@ -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 @@ -383,6 +387,7 @@ 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 /// @@ -390,6 +395,7 @@ class Config { 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 diff --git a/crates/c-api/include/wasmtime/func.hh b/crates/c-api/include/wasmtime/func.hh index 84ec28e1d082..5b75f3b86985 100644 --- a/crates/c-api/include/wasmtime/func.hh +++ b/crates/c-api/include/wasmtime/func.hh @@ -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> { @@ -102,8 +103,9 @@ template <> struct WasmType> { p->externref = 0; } } + static std::optional load(Store::Context cx, - wasmtime_val_raw_t *p) { + wasmtime_val_raw_t *p) { if (p->externref == 0) { return std::nullopt; } @@ -112,6 +114,7 @@ template <> struct WasmType> { return ExternRef(val); } }; +#endif // WASMTIME_FEATURE_GC /// Type information for the `V128` host value used as a wasm value. template <> struct WasmType { diff --git a/crates/c-api/include/wasmtime/store.h b/crates/c-api/include/wasmtime/store.h index f440db1a3f2e..0fbbc1bd3f5f 100644 --- a/crates/c-api/include/wasmtime/store.h +++ b/crates/c-api/include/wasmtime/store.h @@ -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. diff --git a/crates/c-api/include/wasmtime/store.hh b/crates/c-api/include/wasmtime/store.hh index 4cad54b39e8d..0ad7e9388f14 100644 --- a/crates/c-api/include/wasmtime/store.hh +++ b/crates/c-api/include/wasmtime/store.hh @@ -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 gc() { @@ -103,6 +104,7 @@ public: } return std::monostate(); } +#endif /// Injects fuel to be consumed within this store. /// @@ -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 gc() { return context().gc(); } +#endif private: template diff --git a/crates/c-api/include/wasmtime/val.h b/crates/c-api/include/wasmtime/val.h index bb4cfa993cf0..89835a0de0a9 100644 --- a/crates/c-api/include/wasmtime/val.h +++ b/crates/c-api/include/wasmtime/val.h @@ -56,6 +56,7 @@ typedef struct wasmtime_anyref { void *__private3; } wasmtime_anyref_t; +#ifdef WASMTIME_FEATURE_GC /// \brief Helper function to initialize the `ref` provided to a null anyref /// value. static inline void wasmtime_anyref_set_null(wasmtime_anyref_t *ref) { @@ -71,6 +72,7 @@ static inline bool wasmtime_anyref_is_null(const wasmtime_anyref_t *ref) { return ref->store_id == 0; } + /** * \brief Creates a new reference pointing to the same data that `anyref` * points to (depending on the configured collector this might increase a @@ -201,6 +203,8 @@ 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. */ +#endif // WASMTIME_FEATURE_GC + typedef struct wasmtime_externref { /// Internal metadata tracking within the store, embedders should not /// configure or modify these fields. @@ -213,6 +217,7 @@ typedef struct wasmtime_externref { void *__private3; } wasmtime_externref_t; +#ifdef WASMTIME_FEATURE_GC /// \brief Helper function to initialize the `ref` provided to a null externref /// value. static inline void wasmtime_externref_set_null(wasmtime_externref_t *ref) { @@ -313,6 +318,7 @@ WASM_API_EXTERN void wasmtime_externref_from_raw(wasmtime_context_t *context, */ WASM_API_EXTERN uint32_t wasmtime_externref_to_raw( wasmtime_context_t *context, const wasmtime_externref_t *ref); +#endif // WASMTIME_FEATURE_GC /** * \typedef wasmtime_exnref_t @@ -397,6 +403,7 @@ typedef uint8_t wasmtime_valkind_t; /// stored in little-endian order. typedef uint8_t wasmtime_v128[16]; + /** * \typedef wasmtime_valunion_t * \brief Convenience alias for #wasmtime_valunion diff --git a/crates/c-api/include/wasmtime/val.hh b/crates/c-api/include/wasmtime/val.hh index 7f27aad84fbf..c08d44f4180c 100644 --- a/crates/c-api/include/wasmtime/val.hh +++ b/crates/c-api/include/wasmtime/val.hh @@ -17,6 +17,7 @@ class EqRef; class StructRef; class ArrayRef; +#ifdef WASMTIME_FEATURE_GC /** * \brief Representation of a WebAssembly `externref` value. * @@ -103,9 +104,12 @@ 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. */ @@ -204,6 +208,7 @@ public: /// \brief Downcast to arrayref. Returns null arrayref if not an arrayref. inline std::optional as_array(Store::Context cx) const; }; +#endif // WASMTIME_FEATURE_GC /// \brief Container for the `v128` WebAssembly type. struct V128 { diff --git a/crates/c-api/src/config.rs b/crates/c-api/src/config.rs index 365fd37b4c83..71d98f37d15e 100644 --- a/crates/c-api/src/config.rs +++ b/crates/c-api/src/config.rs @@ -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, @@ -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); } @@ -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); } diff --git a/crates/c-api/src/func.rs b/crates/c-api/src/func.rs index 6200f12146df..740bc44fe859 100644 --- a/crates/c-api/src/func.rs +++ b/crates/c-api/src/func.rs @@ -10,9 +10,11 @@ use std::mem::{self, MaybeUninit}; use std::panic::{self, AssertUnwindSafe}; use std::ptr; use std::str; +#[cfg(feature = "gc")] +use wasmtime::RootScope; 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, }; #[derive(Clone)] @@ -351,13 +353,15 @@ pub unsafe extern "C" fn wasmtime_func_call( nresults: usize, trap_ret: &mut *mut wasm_trap_t, ) -> Option> { - 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, ); @@ -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), diff --git a/crates/c-api/src/global.rs b/crates/c-api/src/global.rs index dd3605301bfc..4b35e1c6cfec 100644 --- a/crates/c-api/src/global.rs +++ b/crates/c-api/src/global.rs @@ -3,7 +3,9 @@ use crate::{ wasm_store_t, wasm_val_t, wasmtime_error_t, wasmtime_val_t, }; use std::mem::MaybeUninit; -use wasmtime::{Extern, Global, RootScope}; +#[cfg(feature = "gc")] +use wasmtime::RootScope; +use wasmtime::{Extern, Global}; #[derive(Clone)] #[repr(transparent)] @@ -84,9 +86,11 @@ pub unsafe extern "C" fn wasmtime_global_new( val: &wasmtime_val_t, ret: &mut Global, ) -> Option> { - let mut scope = RootScope::new(&mut store); - let val = val.to_val(&mut scope); - let global = Global::new(scope, gt.ty().ty.clone(), val); + #[cfg(feature = "gc")] + let mut store = RootScope::new(&mut store); + + let val = val.to_val(&mut store); + let global = Global::new(&mut store, gt.ty().ty.clone(), val); handle_result(global, |global| { *ret = global; }) @@ -106,9 +110,13 @@ pub extern "C" fn wasmtime_global_get( global: &Global, val: &mut MaybeUninit, ) { - let mut scope = RootScope::new(store); - let gval = global.get(&mut scope); - crate::initialize(val, wasmtime_val_t::from_val(&mut scope, gval)) + let mut store = store; + + #[cfg(feature = "gc")] + let mut store = RootScope::new(&mut store); + + let gval = global.get(&mut store); + crate::initialize(val, wasmtime_val_t::from_val(&mut store, gval)) } #[unsafe(no_mangle)] @@ -117,7 +125,9 @@ pub unsafe extern "C" fn wasmtime_global_set( global: &Global, val: &wasmtime_val_t, ) -> Option> { - let mut scope = RootScope::new(&mut store); - let val = val.to_val(&mut scope); - handle_result(global.set(scope, val), |()| {}) + #[cfg(feature = "gc")] + let mut store = RootScope::new(&mut store); + + let val = val.to_val(&mut store); + handle_result(global.set(&mut store, val), |()| {}) } diff --git a/crates/c-api/src/lib.rs b/crates/c-api/src/lib.rs index 4d9fdce1742d..70af6d85fa4d 100644 --- a/crates/c-api/src/lib.rs +++ b/crates/c-api/src/lib.rs @@ -30,6 +30,7 @@ mod memory; mod module; #[cfg(feature = "profiling")] mod profiling; +#[cfg(feature = "gc")] mod r#ref; mod sharedmemory; mod store; @@ -51,6 +52,7 @@ pub use crate::instance::*; pub use crate::linker::*; pub use crate::memory::*; pub use crate::module::*; +#[cfg(feature = "gc")] pub use crate::r#ref::*; pub use crate::store::*; pub use crate::table::*; diff --git a/crates/c-api/src/ref.rs b/crates/c-api/src/ref.rs index 9774a713c11c..b3b5c41bff64 100644 --- a/crates/c-api/src/ref.rs +++ b/crates/c-api/src/ref.rs @@ -1,4 +1,7 @@ -use crate::{WasmtimeStoreContextMut, abort}; +#![cfg(feature = "gc")] + +use crate::WasmtimeStoreContextMut; +use crate::abort; use std::mem::{ManuallyDrop, MaybeUninit}; use std::{num::NonZeroU64, os::raw::c_void, ptr}; use wasmtime::{ @@ -423,7 +426,7 @@ pub unsafe extern "C" fn wasmtime_externref_data( let data = e.data(cx).ok()??; Some(data.downcast_ref::().unwrap().data) }) - .unwrap_or(ptr::null_mut()) + .unwrap_or(core::ptr::null_mut()) } #[unsafe(no_mangle)] diff --git a/crates/c-api/src/store.rs b/crates/c-api/src/store.rs index 6ea7fdce7204..7d5c65b09910 100644 --- a/crates/c-api/src/store.rs +++ b/crates/c-api/src/store.rs @@ -249,6 +249,7 @@ pub extern "C" fn wasmtime_context_set_wasi_http(mut context: WasmtimeStoreConte } #[unsafe(no_mangle)] +#[cfg(feature = "gc")] pub extern "C" fn wasmtime_context_gc( mut context: WasmtimeStoreContextMut<'_>, ) -> Option> { diff --git a/crates/c-api/src/table.rs b/crates/c-api/src/table.rs index bffb1ffc80c8..3fc060f31625 100644 --- a/crates/c-api/src/table.rs +++ b/crates/c-api/src/table.rs @@ -1,9 +1,13 @@ use crate::{ - WasmtimeStoreContext, WasmtimeStoreContextMut, handle_result, wasm_extern_t, wasm_ref_t, - wasm_store_t, wasm_tabletype_t, wasmtime_error_t, wasmtime_val_t, + WasmtimeStoreContext, WasmtimeStoreContextMut, handle_result, wasm_extern_t, wasm_tabletype_t, + wasmtime_error_t, wasmtime_val_t, }; +#[cfg(feature = "gc")] +use crate::{wasm_ref_t, wasm_store_t}; use std::mem::MaybeUninit; -use wasmtime::{Extern, Ref, RootScope, Table, TableType, format_err}; +use wasmtime::{Extern, Table, format_err}; +#[cfg(feature = "gc")] +use wasmtime::{Ref, RootScope, TableType}; #[derive(Clone)] #[repr(transparent)] @@ -31,12 +35,14 @@ impl wasm_table_t { } } +#[cfg(feature = "gc")] fn option_wasm_ref_t_to_ref(r: Option<&wasm_ref_t>, table_ty: &TableType) -> Ref { r.map(|r| r.r.clone()) .unwrap_or_else(|| Ref::null(table_ty.element().heap_type())) } #[unsafe(no_mangle)] +#[cfg(feature = "gc")] pub unsafe extern "C" fn wasm_table_new( store: &mut wasm_store_t, tt: &wasm_tabletype_t, @@ -61,6 +67,7 @@ pub unsafe extern "C" fn wasm_table_type(t: &wasm_table_t) -> Box wasm_table_size_t } #[unsafe(no_mangle)] +#[cfg(feature = "gc")] pub unsafe extern "C" fn wasm_table_grow( t: &mut wasm_table_t, delta: wasm_table_size_t, @@ -120,12 +129,14 @@ pub unsafe extern "C" fn wasmtime_table_new( init: &wasmtime_val_t, out: &mut Table, ) -> Option> { - let mut scope = RootScope::new(&mut store); + #[cfg(feature = "gc")] + let mut store = RootScope::new(&mut store); + handle_result( - init.to_val(&mut scope) + init.to_val(&mut store) .ref_() .ok_or_else(|| format_err!("wasmtime_table_new init value is not a reference")) - .and_then(|init| Table::new(scope, tt.ty().ty.clone(), init)), + .and_then(|init| Table::new(&mut store, tt.ty().ty.clone(), init)), |table| *out = table, ) } @@ -145,10 +156,14 @@ pub extern "C" fn wasmtime_table_get( index: u64, ret: &mut MaybeUninit, ) -> bool { - let mut scope = RootScope::new(store); - match table.get(&mut scope, index) { + let mut store = store; + + #[cfg(feature = "gc")] + let mut store = RootScope::new(&mut store); + + match table.get(&mut store, index) { Some(r) => { - crate::initialize(ret, wasmtime_val_t::from_val(&mut scope, r.into())); + crate::initialize(ret, wasmtime_val_t::from_val(&mut store, r.into())); true } None => false, @@ -162,12 +177,14 @@ pub unsafe extern "C" fn wasmtime_table_set( index: u64, val: &wasmtime_val_t, ) -> Option> { - let mut scope = RootScope::new(&mut store); + #[cfg(feature = "gc")] + let mut store = RootScope::new(&mut store); + handle_result( - val.to_val(&mut scope) + val.to_val(&mut store) .ref_() .ok_or_else(|| format_err!("wasmtime_table_set value is not a reference")) - .and_then(|val| table.set(scope, index, val)), + .and_then(|val| table.set(&mut store, index, val)), |()| {}, ) } @@ -185,12 +202,14 @@ pub unsafe extern "C" fn wasmtime_table_grow( val: &wasmtime_val_t, prev_size: &mut u64, ) -> Option> { - let mut scope = RootScope::new(&mut store); + #[cfg(feature = "gc")] + let mut store = RootScope::new(&mut store); + handle_result( - val.to_val(&mut scope) + val.to_val(&mut store) .ref_() .ok_or_else(|| format_err!("wasmtime_table_grow value is not a reference")) - .and_then(|val| table.grow(scope, delta, val)), + .and_then(|val| table.grow(&mut store, delta, val)), |prev| *prev_size = prev, ) } diff --git a/crates/c-api/src/val.rs b/crates/c-api/src/val.rs index 8d8ff86dfcb9..8e8008031c74 100644 --- a/crates/c-api/src/val.rs +++ b/crates/c-api/src/val.rs @@ -1,11 +1,15 @@ +#[cfg(feature = "gc")] use crate::r#ref::ref_to_val; use crate::{ - WASM_I32, from_valtype, into_valtype, wasm_ref_t, wasm_valkind_t, wasmtime_anyref_t, - wasmtime_exnref_t, wasmtime_externref_t, wasmtime_valkind_t, + WASM_I32, from_valtype, into_valtype, wasm_valkind_t, wasmtime_exnref_t, wasmtime_valkind_t, }; +#[cfg(feature = "gc")] +use crate::{wasm_ref_t, wasmtime_anyref_t, wasmtime_externref_t}; use std::mem::{ManuallyDrop, MaybeUninit}; use std::ptr; -use wasmtime::{AsContextMut, Func, HeapType, Ref, RootScope, Val, ValType}; +use wasmtime::{AsContextMut, Func, Val, ValType}; +#[cfg(feature = "gc")] +use wasmtime::{HeapType, Ref, RootScope}; #[repr(C)] pub struct wasm_val_t { @@ -22,9 +26,11 @@ pub union wasm_val_union { pub u64: u64, pub f32: f32, pub f64: f64, + #[cfg(feature = "gc")] pub ref_: *mut wasm_ref_t, } +#[cfg(feature = "gc")] impl Drop for wasm_val_t { fn drop(&mut self) { match into_valtype(self.kind) { @@ -40,10 +46,13 @@ impl Drop for wasm_val_t { impl Clone for wasm_val_t { fn clone(&self) -> Self { + #[allow(unused_mut)] let mut ret = wasm_val_t { kind: self.kind, of: self.of, }; + + #[cfg(feature = "gc")] unsafe { match into_valtype(self.kind) { ValType::Ref(_) if !self.of.ref_.is_null() => { @@ -52,6 +61,7 @@ impl Clone for wasm_val_t { _ => {} } } + return ret; } } @@ -84,6 +94,7 @@ impl wasm_val_t { kind: from_valtype(&ValType::F64), of: wasm_val_union { u64: f }, }, + #[cfg(feature = "gc")] Val::FuncRef(f) => wasm_val_t { kind: from_valtype(&ValType::FUNCREF), of: wasm_val_union { @@ -94,6 +105,8 @@ impl wasm_val_t { }), }, }, + #[cfg(not(feature = "gc"))] + Val::FuncRef(_) => crate::abort("creating a wasm_val_t from a funcref"), Val::AnyRef(_) => crate::abort("creating a wasm_val_t from an anyref"), Val::ExternRef(_) => crate::abort("creating a wasm_val_t from an externref"), Val::ExnRef(_) => crate::abort("creating a wasm_val_t from an exnref"), @@ -108,6 +121,7 @@ impl wasm_val_t { ValType::I64 => Val::from(unsafe { self.of.i64 }), ValType::F32 => Val::from(unsafe { self.of.f32 }), ValType::F64 => Val::from(unsafe { self.of.f64 }), + #[cfg(feature = "gc")] ValType::Ref(r) => match r.heap_type() { HeapType::Func => unsafe { if self.of.ref_.is_null() { @@ -119,6 +133,8 @@ impl wasm_val_t { }, _ => unreachable!("wasm_val_t cannot contain non-function reference values"), }, + #[cfg(not(feature = "gc"))] + ValType::Ref(_) => unimplemented!("wasm_val_t: reference types require gc feature"), ValType::V128 => unimplemented!("wasm_val_t: v128"), } } @@ -146,9 +162,12 @@ pub union wasmtime_val_union { pub i64: i64, pub f32: u32, pub f64: u64, + #[cfg(feature = "gc")] pub anyref: ManuallyDrop, + #[cfg(feature = "gc")] pub externref: ManuallyDrop, pub exnref: ManuallyDrop, + #[cfg(feature = "gc")] pub funcref: wasmtime_func_t, pub v128: [u8; 16], } @@ -159,6 +178,7 @@ const _: () = { assert!(std::mem::align_of::() == std::mem::align_of::()); }; +#[cfg(feature = "gc")] impl Drop for wasmtime_val_t { fn drop(&mut self) { unsafe { @@ -179,6 +199,7 @@ impl Drop for wasmtime_val_t { } // The raw pointers are actually optional boxes. +#[cfg(feature = "gc")] unsafe impl Send for wasmtime_val_union where Option>: Send, @@ -186,6 +207,7 @@ where Option>: Send, { } +#[cfg(feature = "gc")] unsafe impl Sync for wasmtime_val_union where Option>: Sync, @@ -202,6 +224,7 @@ pub union wasmtime_func_t { } impl wasmtime_func_t { + #[cfg(feature = "gc")] unsafe fn as_wasmtime(&self) -> Option { if self.store_id == 0 { None @@ -227,10 +250,19 @@ impl wasmtime_val_t { /// that `val` is not require to be rooted in the store itself which would /// prevent GC. Callers should prefer this API where possible, creating a /// temporary `RootScope` when needed. + #[cfg(feature = "gc")] pub fn from_val(cx: &mut RootScope, val: Val) -> wasmtime_val_t { Self::from_val_unscoped(cx, val) } + /// Creates a new `wasmtime_val_t` from a `wasmtime::Val` (non-gc version). + /// + /// When gc feature is disabled, this does not require a `RootScope`. + #[cfg(not(feature = "gc"))] + pub fn from_val(cx: impl AsContextMut, val: Val) -> wasmtime_val_t { + Self::from_val_unscoped(cx, val) + } + /// Equivalent of [`wasmtime_val_t::from_val`] except that a `RootScope` /// is not required. /// @@ -239,6 +271,8 @@ impl wasmtime_val_t { /// to the embedder. In such a situation we know we previously entered with /// some other call so the root scope is on the stack there. pub fn from_val_unscoped(cx: impl AsContextMut, val: Val) -> wasmtime_val_t { + #[cfg(not(feature = "gc"))] + let _ = cx; match val { Val::I32(i) => wasmtime_val_t { kind: crate::WASMTIME_I32, @@ -256,18 +290,21 @@ impl wasmtime_val_t { kind: crate::WASMTIME_F64, of: wasmtime_val_union { f64: i }, }, + #[cfg(feature = "gc")] Val::AnyRef(a) => wasmtime_val_t { kind: crate::WASMTIME_ANYREF, of: wasmtime_val_union { anyref: ManuallyDrop::new(a.and_then(|a| a.to_owned_rooted(cx).ok()).into()), }, }, + #[cfg(feature = "gc")] Val::ExternRef(e) => wasmtime_val_t { kind: crate::WASMTIME_EXTERNREF, of: wasmtime_val_union { externref: ManuallyDrop::new(e.and_then(|e| e.to_owned_rooted(cx).ok()).into()), }, }, + #[cfg(feature = "gc")] Val::FuncRef(func) => wasmtime_val_t { kind: crate::WASMTIME_FUNCREF, of: wasmtime_val_union { @@ -280,6 +317,10 @@ impl wasmtime_val_t { exnref: ManuallyDrop::new(e.and_then(|e| e.to_owned_rooted(cx).ok()).into()), }, }, + #[cfg(not(feature = "gc"))] + Val::AnyRef(_) | Val::ExternRef(_) | Val::FuncRef(_) | Val::ExnRef(_) => { + crate::abort("reference types require gc feature") + } Val::V128(val) => wasmtime_val_t { kind: crate::WASMTIME_V128, of: wasmtime_val_union { @@ -297,27 +338,41 @@ impl wasmtime_val_t { /// API as the `Val` returned may contain a `Rooted` which requires a /// `RootScope` if we don't want the value to live for the entire lifetime /// of the `Store`. + #[cfg(feature = "gc")] pub unsafe fn to_val(&self, cx: &mut RootScope) -> Val { self.to_val_unscoped(cx) } + /// Convert this `wasmtime_val_t` into a `wasmtime::Val` (non-gc version). + /// + /// When gc feature is disabled, this does not require a `RootScope`. + #[cfg(not(feature = "gc"))] + pub unsafe fn to_val(&self, cx: impl AsContextMut) -> Val { + self.to_val_unscoped(cx) + } + /// Equivalent of `to_val` except doesn't require a `RootScope`. /// /// See notes on [`wasmtime_val_t::from_val_unscoped`] for notes on when to /// use this. pub unsafe fn to_val_unscoped(&self, cx: impl AsContextMut) -> Val { + #[cfg(not(feature = "gc"))] + let _ = cx; match self.kind { crate::WASMTIME_I32 => Val::I32(self.of.i32), crate::WASMTIME_I64 => Val::I64(self.of.i64), crate::WASMTIME_F32 => Val::F32(self.of.f32), crate::WASMTIME_F64 => Val::F64(self.of.f64), crate::WASMTIME_V128 => Val::V128(u128::from_le_bytes(self.of.v128).into()), + #[cfg(feature = "gc")] crate::WASMTIME_ANYREF => { Val::AnyRef(self.of.anyref.as_wasmtime().map(|a| a.to_rooted(cx))) } + #[cfg(feature = "gc")] crate::WASMTIME_EXTERNREF => { Val::ExternRef(self.of.externref.as_wasmtime().map(|e| e.to_rooted(cx))) } + #[cfg(feature = "gc")] crate::WASMTIME_FUNCREF => Val::FuncRef(self.of.funcref.as_wasmtime()), crate::WASMTIME_EXNREF => { Val::ExnRef(self.of.exnref.as_wasmtime().map(|e| e.to_rooted(cx))) @@ -338,9 +393,11 @@ pub unsafe extern "C" fn wasmtime_val_clone( dst: &mut MaybeUninit, ) { let of = match src.kind { + #[cfg(feature = "gc")] crate::WASMTIME_ANYREF => wasmtime_val_union { anyref: ManuallyDrop::new(src.of.anyref.as_wasmtime().into()), }, + #[cfg(feature = "gc")] crate::WASMTIME_EXTERNREF => wasmtime_val_union { externref: ManuallyDrop::new(src.of.externref.as_wasmtime().into()), }, @@ -352,6 +409,7 @@ pub unsafe extern "C" fn wasmtime_val_clone( crate::WASMTIME_F32 => wasmtime_val_union { f32: src.of.f32 }, crate::WASMTIME_F64 => wasmtime_val_union { f64: src.of.f64 }, crate::WASMTIME_V128 => wasmtime_val_union { v128: src.of.v128 }, + #[cfg(feature = "gc")] crate::WASMTIME_FUNCREF => wasmtime_val_union { funcref: src.of.funcref, }, From c575d9827e2b9dc71a8ef53e90154d8574b2c989 Mon Sep 17 00:00:00 2001 From: tolumide-ng Date: Mon, 6 Apr 2026 21:36:38 +0200 Subject: [PATCH 2/3] Fixes thrownexcpetion import which is behind gc --- crates/c-api/include/wasmtime/config.hh | 12 ++++++------ crates/c-api/include/wasmtime/func.hh | 4 ++-- crates/c-api/include/wasmtime/val.h | 11 +++++------ crates/c-api/include/wasmtime/val.hh | 1 - crates/c-api/src/exn.rs | 1 + crates/c-api/src/func.rs | 16 +++++++++++++--- crates/c-api/src/lib.rs | 2 ++ crates/c-api/src/ref.rs | 2 +- crates/c-api/src/val.rs | 15 ++++++++++----- 9 files changed, 40 insertions(+), 24 deletions(-) diff --git a/crates/c-api/include/wasmtime/config.hh b/crates/c-api/include/wasmtime/config.hh index 0ec47bc38e98..83184fe60cd8 100644 --- a/crates/c-api/include/wasmtime/config.hh +++ b/crates/c-api/include/wasmtime/config.hh @@ -303,7 +303,7 @@ class Config { wasmtime_config_wasm_tail_call_set(ptr.get(), enable); } - #ifdef WASMTIME_FEATURE_GC +#ifdef WASMTIME_FEATURE_GC /// \brief Configures whether the WebAssembly reference types proposal is /// enabled /// @@ -311,7 +311,7 @@ class Config { void wasm_reference_types(bool enable) { wasmtime_config_wasm_reference_types_set(ptr.get(), enable); } - #endif // WASMTIME_FEATURE_GC +#endif // WASMTIME_FEATURE_GC /// \brief Configures whether the WebAssembly simd proposal is enabled /// @@ -363,13 +363,13 @@ class Config { wasmtime_config_wasm_memory64_set(ptr.get(), enable); } - #ifdef WASMTIME_FEATURE_GC +#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 +#endif // WASMTIME_FEATURE_GC /// \brief Configures whether the WebAssembly function references proposal /// will be enabled @@ -387,7 +387,7 @@ class Config { wasmtime_config_wasm_wide_arithmetic_set(ptr.get(), enable); } - #ifdef WASMTIME_FEATURE_GC +#ifdef WASMTIME_FEATURE_GC /// \brief Configures whether the WebAssembly exceptions proposal will be /// enabled /// @@ -395,7 +395,7 @@ class Config { void wasm_exceptions(bool enable) { wasmtime_config_wasm_exceptions_set(ptr.get(), enable); } - #endif // WASMTIME_FEATURE_GC +#endif // WASMTIME_FEATURE_GC /// \brief Configures whether the WebAssembly custom-page-sizes proposal will /// be enabled diff --git a/crates/c-api/include/wasmtime/func.hh b/crates/c-api/include/wasmtime/func.hh index 5b75f3b86985..5425609451c2 100644 --- a/crates/c-api/include/wasmtime/func.hh +++ b/crates/c-api/include/wasmtime/func.hh @@ -103,9 +103,9 @@ template <> struct WasmType> { p->externref = 0; } } - + static std::optional load(Store::Context cx, - wasmtime_val_raw_t *p) { + wasmtime_val_raw_t *p) { if (p->externref == 0) { return std::nullopt; } diff --git a/crates/c-api/include/wasmtime/val.h b/crates/c-api/include/wasmtime/val.h index 89835a0de0a9..0c4f50fe2a0d 100644 --- a/crates/c-api/include/wasmtime/val.h +++ b/crates/c-api/include/wasmtime/val.h @@ -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; @@ -56,7 +57,6 @@ typedef struct wasmtime_anyref { void *__private3; } wasmtime_anyref_t; -#ifdef WASMTIME_FEATURE_GC /// \brief Helper function to initialize the `ref` provided to a null anyref /// value. static inline void wasmtime_anyref_set_null(wasmtime_anyref_t *ref) { @@ -72,7 +72,6 @@ static inline bool wasmtime_anyref_is_null(const wasmtime_anyref_t *ref) { return ref->store_id == 0; } - /** * \brief Creates a new reference pointing to the same data that `anyref` * points to (depending on the configured collector this might increase a @@ -203,7 +202,6 @@ 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. */ -#endif // WASMTIME_FEATURE_GC typedef struct wasmtime_externref { /// Internal metadata tracking within the store, embedders should not @@ -217,7 +215,6 @@ typedef struct wasmtime_externref { void *__private3; } wasmtime_externref_t; -#ifdef WASMTIME_FEATURE_GC /// \brief Helper function to initialize the `ref` provided to a null externref /// value. static inline void wasmtime_externref_set_null(wasmtime_externref_t *ref) { @@ -318,7 +315,6 @@ WASM_API_EXTERN void wasmtime_externref_from_raw(wasmtime_context_t *context, */ WASM_API_EXTERN uint32_t wasmtime_externref_to_raw( wasmtime_context_t *context, const wasmtime_externref_t *ref); -#endif // WASMTIME_FEATURE_GC /** * \typedef wasmtime_exnref_t @@ -399,11 +395,12 @@ typedef uint8_t wasmtime_valkind_t; /// exnref #define WASMTIME_EXNREF 8 +#endif // WASMTIME_FEATURE_GC + /// \brief A 128-bit value representing the WebAssembly `v128` type. Bytes are /// stored in little-endian order. typedef uint8_t wasmtime_v128[16]; - /** * \typedef wasmtime_valunion_t * \brief Convenience alias for #wasmtime_valunion @@ -423,6 +420,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 @@ -434,6 +432,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; diff --git a/crates/c-api/include/wasmtime/val.hh b/crates/c-api/include/wasmtime/val.hh index c08d44f4180c..2e0c4d5f15f4 100644 --- a/crates/c-api/include/wasmtime/val.hh +++ b/crates/c-api/include/wasmtime/val.hh @@ -108,7 +108,6 @@ public: class EqRef; - #ifdef WASMTIME_FEATURE_GC /** * \brief Representation of a WebAssembly `anyref` value. diff --git a/crates/c-api/src/exn.rs b/crates/c-api/src/exn.rs index 618644170fbb..8d516b52cc56 100644 --- a/crates/c-api/src/exn.rs +++ b/crates/c-api/src/exn.rs @@ -1,3 +1,4 @@ +#![cfg(feature = "gc")] use crate::{ WasmtimeStoreContextMut, handle_result, wasm_trap_t, wasmtime_error_t, wasmtime_val_t, }; diff --git a/crates/c-api/src/func.rs b/crates/c-api/src/func.rs index 740bc44fe859..dfd0b697e9e7 100644 --- a/crates/c-api/src/func.rs +++ b/crates/c-api/src/func.rs @@ -10,12 +10,12 @@ use std::mem::{self, MaybeUninit}; use std::panic::{self, AssertUnwindSafe}; use std::ptr; use std::str; -#[cfg(feature = "gc")] -use wasmtime::RootScope; use wasmtime::{ AsContext, AsContextMut, Error, Extern, Func, Result, StoreContext, StoreContextMut, Trap, Val, ValRaw, }; +#[cfg(feature = "gc")] +use wasmtime::{RootScope, ThrownException}; #[derive(Clone)] #[repr(transparent)] @@ -406,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::() || err.is::() +} + +#[cfg(not(feature = "gc"))] +fn is_trap_like_impl(err: &Error) -> bool { + err.is::() +} + fn store_err(err: Error, trap_ret: &mut *mut wasm_trap_t) -> Option> { - if err.is::() || err.is::() { + if is_trap_like_impl(&err) { *trap_ret = Box::into_raw(Box::new(wasm_trap_t::new(err))); None } else { diff --git a/crates/c-api/src/lib.rs b/crates/c-api/src/lib.rs index 70af6d85fa4d..72972336c62c 100644 --- a/crates/c-api/src/lib.rs +++ b/crates/c-api/src/lib.rs @@ -20,6 +20,7 @@ pub use wasmtime; mod config; mod engine; mod error; +#[cfg(feature = "gc")] mod exn; mod r#extern; mod func; @@ -44,6 +45,7 @@ mod vec; pub use crate::config::*; pub use crate::engine::*; pub use crate::error::*; +#[cfg(feature = "gc")] pub use crate::exn::*; pub use crate::r#extern::*; pub use crate::func::*; diff --git a/crates/c-api/src/ref.rs b/crates/c-api/src/ref.rs index b3b5c41bff64..bcdf0a6f82e0 100644 --- a/crates/c-api/src/ref.rs +++ b/crates/c-api/src/ref.rs @@ -3,7 +3,7 @@ use crate::WasmtimeStoreContextMut; use crate::abort; use std::mem::{ManuallyDrop, MaybeUninit}; -use std::{num::NonZeroU64, os::raw::c_void, ptr}; +use std::{num::NonZeroU64, os::raw::c_void}; use wasmtime::{ AnyRef, ArrayRef, ArrayRefPre, ArrayType, EqRef, ExnRef, ExternRef, FieldType, I31, Mutability, OwnedRooted, Ref, RootScope, StorageType, StructRef, StructRefPre, StructType, Val, ValType, diff --git a/crates/c-api/src/val.rs b/crates/c-api/src/val.rs index 8e8008031c74..7f4b51285ddd 100644 --- a/crates/c-api/src/val.rs +++ b/crates/c-api/src/val.rs @@ -1,10 +1,8 @@ #[cfg(feature = "gc")] use crate::r#ref::ref_to_val; -use crate::{ - WASM_I32, from_valtype, into_valtype, wasm_valkind_t, wasmtime_exnref_t, wasmtime_valkind_t, -}; +use crate::{WASM_I32, from_valtype, into_valtype, wasm_valkind_t, wasmtime_valkind_t}; #[cfg(feature = "gc")] -use crate::{wasm_ref_t, wasmtime_anyref_t, wasmtime_externref_t}; +use crate::{wasm_ref_t, wasmtime_anyref_t, wasmtime_exnref_t, wasmtime_externref_t}; use std::mem::{ManuallyDrop, MaybeUninit}; use std::ptr; use wasmtime::{AsContextMut, Func, Val, ValType}; @@ -46,7 +44,10 @@ impl Drop for wasm_val_t { impl Clone for wasm_val_t { fn clone(&self) -> Self { - #[allow(unused_mut)] + #[allow( + unused_mut, + reason = "needed for conditional mutation under cfg(feature = \"gc\")" + )] let mut ret = wasm_val_t { kind: self.kind, of: self.of, @@ -166,6 +167,7 @@ pub union wasmtime_val_union { pub anyref: ManuallyDrop, #[cfg(feature = "gc")] pub externref: ManuallyDrop, + #[cfg(feature = "gc")] pub exnref: ManuallyDrop, #[cfg(feature = "gc")] pub funcref: wasmtime_func_t, @@ -311,6 +313,7 @@ impl wasmtime_val_t { funcref: func.into(), }, }, + #[cfg(feature = "gc")] Val::ExnRef(e) => wasmtime_val_t { kind: crate::WASMTIME_EXNREF, of: wasmtime_val_union { @@ -374,6 +377,7 @@ impl wasmtime_val_t { } #[cfg(feature = "gc")] crate::WASMTIME_FUNCREF => Val::FuncRef(self.of.funcref.as_wasmtime()), + #[cfg(feature = "gc")] crate::WASMTIME_EXNREF => { Val::ExnRef(self.of.exnref.as_wasmtime().map(|e| e.to_rooted(cx))) } @@ -401,6 +405,7 @@ pub unsafe extern "C" fn wasmtime_val_clone( crate::WASMTIME_EXTERNREF => wasmtime_val_union { externref: ManuallyDrop::new(src.of.externref.as_wasmtime().into()), }, + #[cfg(feature = "gc")] crate::WASMTIME_EXNREF => wasmtime_val_union { exnref: ManuallyDrop::new(src.of.exnref.as_wasmtime().into()), }, From 788793f8ed654fd6ef517ed68847e5543c47d2a5 Mon Sep 17 00:00:00 2001 From: tolumide-ng Date: Thu, 9 Apr 2026 00:19:25 +0200 Subject: [PATCH 3/3] Adds more wasmtime_feature_gc gate, and moves some definition outside the gate --- crates/c-api/include/wasmtime/gc.h | 3 +++ crates/c-api/include/wasmtime/gc.hh | 5 +++++ crates/c-api/include/wasmtime/val.h | 3 +-- crates/c-api/include/wasmtime/val.hh | 2 ++ crates/wasmtime/src/runtime/gc/enabled/eqref.rs | 2 +- crates/wasmtime/src/runtime/gc/enabled/structref.rs | 1 + 6 files changed, 13 insertions(+), 3 deletions(-) diff --git a/crates/c-api/include/wasmtime/gc.h b/crates/c-api/include/wasmtime/gc.h index 701c296bec25..1b0ec1f076aa 100644 --- a/crates/c-api/include/wasmtime/gc.h +++ b/crates/c-api/include/wasmtime/gc.h @@ -11,6 +11,8 @@ #ifndef WASMTIME_GC_H #define WASMTIME_GC_H +#ifdef WASMTIME_FEATURE_GC + #include #ifdef __cplusplus @@ -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 diff --git a/crates/c-api/include/wasmtime/gc.hh b/crates/c-api/include/wasmtime/gc.hh index 7ce47841f66f..235f0e53bdaf 100644 --- a/crates/c-api/include/wasmtime/gc.hh +++ b/crates/c-api/include/wasmtime/gc.hh @@ -7,6 +7,9 @@ #ifndef WASMTIME_GC_HH #define WASMTIME_GC_HH +#include + +#ifdef WASMTIME_FEATURE_GC #include #include #include @@ -476,4 +479,6 @@ inline std::optional AnyRef::as_array(Store::Context cx) const { } // namespace wasmtime +#endif // WASMTIME_FEATURE_GC + #endif // WASMTIME_GC_HH diff --git a/crates/c-api/include/wasmtime/val.h b/crates/c-api/include/wasmtime/val.h index 0c4f50fe2a0d..1083e540fdd9 100644 --- a/crates/c-api/include/wasmtime/val.h +++ b/crates/c-api/include/wasmtime/val.h @@ -369,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; @@ -395,8 +396,6 @@ typedef uint8_t wasmtime_valkind_t; /// exnref #define WASMTIME_EXNREF 8 -#endif // WASMTIME_FEATURE_GC - /// \brief A 128-bit value representing the WebAssembly `v128` type. Bytes are /// stored in little-endian order. typedef uint8_t wasmtime_v128[16]; diff --git a/crates/c-api/include/wasmtime/val.hh b/crates/c-api/include/wasmtime/val.hh index 2e0c4d5f15f4..32c2ce5e3584 100644 --- a/crates/c-api/include/wasmtime/val.hh +++ b/crates/c-api/include/wasmtime/val.hh @@ -6,7 +6,9 @@ #define WASMTIME_VAL_HH #include +#ifdef WASMTIME_FEATURE_GC #include +#endif // WASMTIME_FEATURE_GC #include #include #include diff --git a/crates/wasmtime/src/runtime/gc/enabled/eqref.rs b/crates/wasmtime/src/runtime/gc/enabled/eqref.rs index 0c6be3e56dd9..eba879ecc400 100644 --- a/crates/wasmtime/src/runtime/gc/enabled/eqref.rs +++ b/crates/wasmtime/src/runtime/gc/enabled/eqref.rs @@ -1,5 +1,5 @@ //! Working with GC `eqref`s. - +#![cfg(feature = "gc")] use crate::{ AnyRef, ArrayRef, ArrayType, AsContext, AsContextMut, GcRefImpl, GcRootIndex, HeapType, I31, OwnedRooted, RefType, Rooted, StructRef, StructType, ValRaw, ValType, WasmTy, diff --git a/crates/wasmtime/src/runtime/gc/enabled/structref.rs b/crates/wasmtime/src/runtime/gc/enabled/structref.rs index b09afd2c5b42..e3b755159d9b 100644 --- a/crates/wasmtime/src/runtime/gc/enabled/structref.rs +++ b/crates/wasmtime/src/runtime/gc/enabled/structref.rs @@ -1,4 +1,5 @@ //! Working with GC `struct` objects. +#![cfg(feature = "gc")] use crate::runtime::vm::VMGcRef; use crate::store::{Asyncness, StoreId};