Skip to content

Commit 668849e

Browse files
committed
WIP.
1 parent fabfe8b commit 668849e

File tree

6 files changed

+34
-9
lines changed

6 files changed

+34
-9
lines changed

crates/wasmtime/src/runtime/gc/enabled/exnref.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,15 @@ impl ExnRef {
630630
}
631631
}
632632

633+
/// Rooted<ExnRef> implements Error so that it can be boxed and
634+
/// returned in an `anyhow::Result` from host-to-Wasm function calls.
635+
impl core::error::Error for Rooted<ExnRef> {}
636+
impl core::fmt::Display for Rooted<ExnRef> {
637+
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
638+
write!(f, "Wasm exception")
639+
}
640+
}
641+
633642
unsafe impl WasmTy for Rooted<ExnRef> {
634643
#[inline]
635644
fn valtype() -> ValType {

crates/wasmtime/src/runtime/store.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,6 @@ mod async_;
123123
#[cfg(all(feature = "async", feature = "call-hook"))]
124124
pub use self::async_::CallHookHandler;
125125

126-
use super::ExnRef;
127126
use super::vm::VMExnRef;
128127
#[cfg(feature = "gc")]
129128
mod gc;
@@ -1793,7 +1792,11 @@ impl StoreOpaque {
17931792
#[cfg(feature = "gc")]
17941793
fn trace_pending_exception_roots(&mut self, gc_roots_list: &mut GcRootsList) {
17951794
log::trace!("Begin trace GC roots :: pending exception");
1796-
gc_roots_list.add_root(self.pending_exception.as_mut().into(), "Pending exception");
1795+
if let Some(pending_exception) = self.pending_exception.as_mut() {
1796+
unsafe {
1797+
gc_roots_list.add_root(pending_exception.into(), "Pending exception");
1798+
}
1799+
}
17971800
log::trace!("End trace GC roots :: pending exception");
17981801
}
17991802

crates/wasmtime/src/runtime/trap.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
use super::ExnRef;
12
#[cfg(feature = "coredump")]
23
use super::coredump::WasmCoreDump;
4+
use super::store::AutoAssertNoGc;
35
use crate::prelude::*;
46
use crate::store::StoreOpaque;
57
use crate::{AsContext, Module};
@@ -110,6 +112,13 @@ pub(crate) fn from_runtime_box(
110112
(err, Some(pc))
111113
}
112114
crate::runtime::vm::TrapReason::Wasm(trap_code) => (trap_code.into(), None),
115+
crate::runtime::vm::TrapReason::Exception => {
116+
let mut nogc = AutoAssertNoGc::new(store);
117+
let exnref = nogc.take_pending_exception();
118+
let exnref = ExnRef::_from_raw(&mut nogc, exnref.as_gc_ref().as_raw_u32())
119+
.expect("Exception should be non-null");
120+
(exnref.into(), None)
121+
}
113122
};
114123

115124
if let Some(bt) = backtrace {

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1533,13 +1533,13 @@ fn trap(
15331533
))
15341534
}
15351535

1536-
fn raise(_store: &mut dyn VMStore, _instance: Pin<&mut Instance>) {
1536+
fn raise(store: &mut dyn VMStore, _instance: Pin<&mut Instance>) {
15371537
// SAFETY: this is only called from compiled wasm so we know that wasm has
15381538
// already been entered. It's a dynamic safety precondition that the trap
15391539
// information has already been arranged to be present.
15401540
#[cfg(has_host_compiler_backend)]
15411541
unsafe {
1542-
crate::runtime::vm::traphandlers::raise_preexisting_trap()
1542+
crate::runtime::vm::traphandlers::raise_preexisting_trap(store)
15431543
}
15441544

15451545
// When Cranelift isn't in use then this is an unused libcall for Pulley, so

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! Exception-throw logic for Wasm exceptions.
22
3+
use core::ptr::NonNull;
4+
35
use wasmtime_environ::TagIndex;
46
use wasmtime_unwinder::{Frame, ThrowAction};
57

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

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,9 @@ fn lazy_per_thread_init() {
9191
/// have been previously called. Additionally no Rust destructors can be on the
9292
/// stack. They will be skipped and not executed.
9393
#[cfg(has_host_compiler_backend)]
94-
pub(super) unsafe fn raise_preexisting_trap() -> ! {
95-
tls::with(|info| unsafe { info.unwrap().unwind() })
94+
pub(super) unsafe fn raise_preexisting_trap(store: &mut dyn crate::vm::VMStore) -> ! {
95+
let mut nogc = AutoAssertNoGc::new(store.store_opaque_mut());
96+
tls::with(|info| unsafe { info.unwrap().unwind(&mut nogc) })
9697
}
9798

9899
/// Invokes the closure `f` and returns a `bool` if it succeeded.
@@ -334,7 +335,8 @@ pub struct Trap {
334335
pub coredumpstack: Option<CoreDumpStack>,
335336
}
336337

337-
/// Enumeration of different methods of raising a trap.
338+
/// Enumeration of different methods of raising a trap (or a sentinel
339+
/// for an exception).
338340
#[derive(Debug)]
339341
pub enum TrapReason {
340342
/// A user-raised trap through `raise_user_trap`.
@@ -756,7 +758,7 @@ impl CallThreadState {
756758
// An unwind due to an already-set pending exception sets
757759
// a special UnwindState that triggers the handler-search
758760
// stack-walk on unwind().
759-
UnwindReason::Exception => {
761+
UnwindReason::Trap(TrapReason::Exception) => {
760762
self.unwind.set(UnwindState::ThrowException);
761763
}
762764
// And if we are just propagating an existing trap that already has
@@ -934,7 +936,7 @@ impl CallThreadState {
934936
) {
935937
let backtrace = self.capture_backtrace(self.vm_store_context.as_ptr(), Some((pc, fp)));
936938
let coredump_stack = self.capture_coredump(self.vm_store_context.as_ptr(), Some((pc, fp)));
937-
self.unwind.set(UnwindState::UnwindPastWasm {
939+
self.unwind.set(UnwindState::UnwindToHost {
938940
reason: UnwindReason::Trap(TrapReason::Jit {
939941
pc,
940942
faulting_addr,

0 commit comments

Comments
 (0)