Skip to content
Open
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 @@ -409,6 +409,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: 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
16 changes: 16 additions & 0 deletions crates/c-api/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,20 +91,32 @@ pub extern "C" fn wasmtime_config_wasm_tail_call_set(c: &mut wasm_config_t, enab

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

#[cfg(not(feature = "gc"))]
let _ = (c, enable);
}

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

#[cfg(not(feature = "gc"))]
let _ = (c, enable);
}

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

#[cfg(not(feature = "gc"))]
let _ = (c, enable);
}

#[unsafe(no_mangle)]
Expand Down Expand Up @@ -477,7 +489,11 @@ pub extern "C" fn wasmtime_config_wasm_wide_arithmetic_set(c: &mut wasm_config_t

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

#[cfg(not(feature = "gc"))]
let _ = (c, enable);
}

#[unsafe(no_mangle)]
Expand Down
100 changes: 69 additions & 31 deletions crates/c-api/src/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -351,38 +353,74 @@ 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);
let (wt_params, wt_results) = translate_args(
&mut params,
crate::slice_from_raw_parts(args, nargs)
.iter()
.map(|i| i.to_val(&mut scope)),
nresults,
);
#[cfg(feature = "gc")]
{
let mut scope = RootScope::new(&mut store);
let mut params = mem::take(&mut scope.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)),
nresults,
);

// We're calling arbitrary code here most of the time, and we in general
// want to try to insulate callers against bugs in wasmtime/wasi/etc if we
// 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)
}));
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));
// We're calling arbitrary code here most of the time, and we in general
// want to try to insulate callers against bugs in wasmtime/wasi/etc if we
// 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)
}));
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));
}
params.truncate(0);
scope.as_context_mut().data_mut().wasm_val_storage = params;
None
}
Ok(Err(trap)) => store_err(trap, trap_ret),
Err(panic) => {
let err = error_from_panic(panic);
*trap_ret = Box::into_raw(Box::new(wasm_trap_t::new(err)));
None
}
params.truncate(0);
scope.as_context_mut().data_mut().wasm_val_storage = params;
None
}
Ok(Err(trap)) => store_err(trap, trap_ret),
Err(panic) => {
let err = error_from_panic(panic);
*trap_ret = Box::into_raw(Box::new(wasm_trap_t::new(err)));
None
}

#[cfg(not(feature = "gc"))]
{
let mut params = mem::take(&mut store.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_unscoped(&mut store)),
nresults,
);

let result = panic::catch_unwind(AssertUnwindSafe(|| {
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_unscoped(&mut store, *val));
}
params.truncate(0);
store.data_mut().wasm_val_storage = params;
None
}
Ok(Err(trap)) => store_err(trap, trap_ret),
Err(panic) => {
let err = error_from_panic(panic);
*trap_ret = Box::into_raw(Box::new(wasm_trap_t::new(err)));
None
}
}
}
}
Expand Down
60 changes: 47 additions & 13 deletions crates/c-api/src/global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -84,12 +86,24 @@ pub unsafe extern "C" fn wasmtime_global_new(
val: &wasmtime_val_t,
ret: &mut Global,
) -> Option<Box<wasmtime_error_t>> {
let mut scope = RootScope::new(&mut store);
let val = val.to_val(&mut scope);
let global = Global::new(scope, gt.ty().ty.clone(), val);
handle_result(global, |global| {
*ret = global;
})
#[cfg(feature = "gc")]
{
let mut scope = RootScope::new(&mut store);
let val = val.to_val(&mut scope);
let global = Global::new(scope, gt.ty().ty.clone(), val);
handle_result(global, |global| {
*ret = global;
})
}

#[cfg(not(feature = "gc"))]
{
let val = val.to_val_unscoped(&mut store);
let global = Global::new(&mut store, gt.ty().ty.clone(), val);
handle_result(global, |global| {
*ret = global;
})
}
}

#[unsafe(no_mangle)]
Expand All @@ -106,9 +120,20 @@ pub extern "C" fn wasmtime_global_get(
global: &Global,
val: &mut MaybeUninit<wasmtime_val_t>,
) {
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 scope = RootScope::new(&mut store);
let gval = global.get(&mut scope);
crate::initialize(val, wasmtime_val_t::from_val(&mut scope, gval))
}

#[cfg(not(feature = "gc"))]
{
let gval = global.get(&mut store);
crate::initialize(val, wasmtime_val_t::from_val_unscoped(&mut store, gval))
}
}

#[unsafe(no_mangle)]
Expand All @@ -117,7 +142,16 @@ pub unsafe extern "C" fn wasmtime_global_set(
global: &Global,
val: &wasmtime_val_t,
) -> Option<Box<wasmtime_error_t>> {
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 scope = RootScope::new(&mut store);
let val = val.to_val(&mut scope);
handle_result(global.set(scope, val), |()| {})
}

#[cfg(not(feature = "gc"))]
{
let val = val.to_val_unscoped(&mut store);
handle_result(global.set(&mut store, val), |()| {})
}
}
Loading
Loading