Skip to content

Commit 88d0cb2

Browse files
committed
WIP.
1 parent a076222 commit 88d0cb2

File tree

5 files changed

+220
-107
lines changed

5 files changed

+220
-107
lines changed

crates/wasmtime/src/runtime/store.rs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,6 @@ use crate::prelude::*;
8989
use crate::runtime::vm::GcRootsList;
9090
#[cfg(feature = "stack-switching")]
9191
use crate::runtime::vm::VMContRef;
92-
#[cfg(feature = "gc")]
93-
use crate::runtime::vm::VMExnRef;
9492
use crate::runtime::vm::mpk::ProtectionKey;
9593
use crate::runtime::vm::{
9694
self, GcStore, Imports, InstanceAllocationRequest, InstanceAllocator, InstanceHandle,
@@ -2144,18 +2142,6 @@ at https://bytecodealliance.org/security.
21442142
Ok(ptr)
21452143
}
21462144

2147-
/// Throws an exception.
2148-
///
2149-
/// # Safety
2150-
///
2151-
/// Must be invoked when Wasm code is on the stack.
2152-
#[cfg(feature = "gc")]
2153-
pub(crate) unsafe fn throw_ref(&mut self, exnref: VMExnRef) -> ! {
2154-
let mut nogc = AutoAssertNoGc::new(self);
2155-
// SAFETY: this is invoked when Wasm is on the stack.
2156-
unsafe { vm::throw(&mut nogc, exnref) }
2157-
}
2158-
21592145
/// Constructs and executes an `InstanceAllocationRequest` and pushes the
21602146
/// returned instance into the store.
21612147
///

crates/wasmtime/src/runtime/trampoline/func.rs

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use crate::prelude::*;
44
use crate::runtime::vm::{StoreBox, VMArrayCallHostFuncContext, VMContext, VMOpaqueContext};
55
use crate::type_registry::RegisteredType;
6+
use crate::vm::InstanceAndStore;
67
use crate::{FuncType, ValRaw};
78
use core::ptr::NonNull;
89

@@ -34,30 +35,32 @@ unsafe extern "C" fn array_call_shim<F>(
3435
where
3536
F: Fn(NonNull<VMContext>, &mut [ValRaw]) -> Result<()> + 'static,
3637
{
37-
// Be sure to catch Rust panics to manually shepherd them across the wasm
38-
// boundary, and then otherwise delegate as normal.
39-
crate::runtime::vm::catch_unwind_and_record_trap(|| {
40-
// SAFETY: this function itself requires that the `vmctx` is valid to
41-
// use here.
42-
let state = unsafe {
43-
let vmctx = VMArrayCallHostFuncContext::from_opaque(vmctx);
44-
vmctx.as_ref().host_state()
45-
};
38+
InstanceAndStore::from_vmctx(vmctx, |pair| {
39+
// Be sure to catch Rust panics to manually shepherd them across the wasm
40+
// boundary, and then otherwise delegate as normal.
41+
crate::runtime::vm::catch_unwind_and_record_trap(pair, |_| {
42+
// SAFETY: this function itself requires that the `vmctx` is valid to
43+
// use here.
44+
let state = unsafe {
45+
let vmctx = VMArrayCallHostFuncContext::from_opaque(vmctx);
46+
vmctx.as_ref().host_state()
47+
};
4648

47-
// Double-check ourselves in debug mode, but we control
48-
// the `Any` here so an unsafe downcast should also
49-
// work.
50-
//
51-
// SAFETY: this function is only usable with `TrampolineState<F>`.
52-
let state = unsafe {
53-
debug_assert!(state.is::<TrampolineState<F>>());
54-
&*(state as *const _ as *const TrampolineState<F>)
55-
};
56-
let mut values_vec = NonNull::slice_from_raw_parts(values_vec, values_vec_len);
57-
// SAFETY: it's a contract of this function itself that the values
58-
// provided are valid to view as a slice.
59-
let values_vec = unsafe { values_vec.as_mut() };
60-
(state.func)(caller_vmctx, values_vec)
49+
// Double-check ourselves in debug mode, but we control
50+
// the `Any` here so an unsafe downcast should also
51+
// work.
52+
//
53+
// SAFETY: this function is only usable with `TrampolineState<F>`.
54+
let state = unsafe {
55+
debug_assert!(state.is::<TrampolineState<F>>());
56+
&*(state as *const _ as *const TrampolineState<F>)
57+
};
58+
let mut values_vec = NonNull::slice_from_raw_parts(values_vec, values_vec_len);
59+
// SAFETY: it's a contract of this function itself that the values
60+
// provided are valid to view as a slice.
61+
let values_vec = unsafe { values_vec.as_mut() };
62+
(state.func)(caller_vmctx, values_vec)
63+
})
6164
})
6265
}
6366

crates/wasmtime/src/runtime/vm/libcalls.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,10 @@ pub mod raw {
121121
) $(-> libcall!(@ty $result))? {
122122
$(#[cfg($attr)])?
123123
{
124-
crate::runtime::vm::traphandlers::catch_unwind_and_record_trap(|| unsafe {
125-
InstanceAndStore::from_vmctx(vmctx, |pair| {
124+
InstanceAndStore::from_vmctx(vmctx, |pair| {
125+
crate::runtime::vm::traphandlers::catch_unwind_and_record_trap(pair, |pair| unsafe {
126126
let (instance, store) = pair.unpack_mut();
127+
127128
super::$name(store, instance, $($pname),*)
128129
})
129130
})
@@ -1574,11 +1575,11 @@ unsafe fn throw_ref(
15741575
_instance: Pin<&mut Instance>,
15751576
exnref: u32,
15761577
) -> Result<()> {
1578+
use super::TrapOrException;
1579+
15771580
let exnref = VMGcRef::from_raw_u32(exnref).ok_or_else(|| Trap::NullReference)?;
15781581
let exnref = exnref
15791582
.into_exnref(&*store.unwrap_gc_store().gc_heap)
15801583
.expect("gc ref should be an exception object");
1581-
unsafe {
1582-
store.store_opaque_mut().throw_ref(exnref);
1583-
}
1584+
Err(TrapOrException::Exception(exnref))
15841585
}

crates/wasmtime/src/runtime/vm/throw.rs

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,19 @@
22
33
use core::ptr::NonNull;
44

5-
use wasmtime_environ::{TagIndex, Trap};
5+
use wasmtime_environ::TagIndex;
66
use wasmtime_unwinder::{Frame, ThrowAction};
77

8-
use super::{VMContext, VMExnRef};
9-
use crate::{
10-
store::AutoAssertNoGc,
11-
vm::{TrapReason, catch_unwind_and_record_trap, raise_preexisting_trap},
12-
};
8+
use super::{UnwindReason, UnwindState, VMContext, VMExnRef};
9+
use crate::store::AutoAssertNoGc;
1310

1411
/// Implementation of exception throw.
1512
///
1613
/// # Safety
1714
///
1815
/// Must be invoked when Wasm is in the stack and control has
1916
/// re-entered the runtime.
20-
pub unsafe fn throw(nogc: &mut AutoAssertNoGc, exnref: VMExnRef) -> ! {
17+
pub unsafe fn compute_throw(nogc: &mut AutoAssertNoGc, exnref: VMExnRef) -> UnwindState {
2118
// Get the tag identity relative to the store.
2219
let (throwing_tag_instance_id, throwing_tag_defined_tag_index) =
2320
exnref.tag(nogc).expect("cannot read tag");
@@ -115,23 +112,18 @@ pub unsafe fn throw(nogc: &mut AutoAssertNoGc, exnref: VMExnRef) -> ! {
115112
log::trace!("throw action: {action:?}");
116113

117114
match action {
118-
ThrowAction::Handler { pc, sp, fp } => unsafe {
119-
wasmtime_unwinder::resume_to_exception_handler(
120-
pc,
121-
sp,
122-
fp,
123-
usize::try_from(exnref.as_gc_ref().as_raw_u32())
124-
.expect("gcref does not fit in usize"),
125-
0,
126-
);
115+
ThrowAction::Handler { pc, sp, fp } => UnwindState::UnwindIntoWasm {
116+
pc,
117+
sp,
118+
fp,
119+
payload1: usize::try_from(exnref.as_gc_ref().as_raw_u32())
120+
.expect("gcref does not fit in usize"),
121+
payload2: 0,
122+
},
123+
ThrowAction::None => UnwindState::UnwindPastWasm {
124+
reason: UnwindReason::Exception(exnref),
125+
backtrace: None,
126+
coredump_stack: None,
127127
},
128-
ThrowAction::None => {
129-
catch_unwind_and_record_trap(|| -> Result<(), TrapReason> {
130-
Err(TrapReason::Wasm(Trap::ExceptionToHost))
131-
});
132-
unsafe {
133-
raise_preexisting_trap();
134-
}
135-
}
136128
}
137129
}

0 commit comments

Comments
 (0)