-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Use EntryStoreContext to manage state when entering and exiting Wasm #10626
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
cfa0033
70a2ddc
bfb44d8
b6d78d7
f8a558f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,11 +15,11 @@ mod signals; | |
| #[cfg(all(has_native_signals))] | ||
| pub use self::signals::*; | ||
|
|
||
| use crate::prelude::*; | ||
| use crate::runtime::module::lookup_code; | ||
| use crate::runtime::store::{ExecutorRef, StoreOpaque}; | ||
| use crate::runtime::vm::sys::traphandlers; | ||
| use crate::runtime::vm::{InterpreterRef, VMContext, VMStoreContext}; | ||
| use crate::{prelude::*, EntryStoreContext}; | ||
| use crate::{StoreContextMut, WasmBacktrace}; | ||
| use core::cell::Cell; | ||
| use core::num::NonZeroU32; | ||
|
|
@@ -365,14 +365,15 @@ impl From<wasmtime_environ::Trap> for TrapReason { | |
| /// longjmp'd over and none of its destructors on the stack may be run. | ||
| pub unsafe fn catch_traps<T, F>( | ||
| store: &mut StoreContextMut<'_, T>, | ||
| old_state: &EntryStoreContext, | ||
| mut closure: F, | ||
| ) -> Result<(), Box<Trap>> | ||
| where | ||
| F: FnMut(NonNull<VMContext>, Option<InterpreterRef<'_>>) -> bool, | ||
| { | ||
| let caller = store.0.default_caller(); | ||
|
|
||
| let result = CallThreadState::new(store.0).with(|cx| match store.0.executor() { | ||
| let result = CallThreadState::new(store.0, old_state).with(|cx| match store.0.executor() { | ||
| // In interpreted mode directly invoke the host closure since we won't | ||
| // be using host-based `setjmp`/`longjmp` as that's not going to save | ||
| // the context we want. | ||
|
|
@@ -424,6 +425,7 @@ where | |
| mod call_thread_state { | ||
| use super::*; | ||
| use crate::runtime::vm::Unwind; | ||
| use crate::EntryStoreContext; | ||
|
|
||
| /// Temporary state stored on the stack which is registered in the `tls` | ||
| /// module below for calls into wasm. | ||
|
|
@@ -462,39 +464,34 @@ mod call_thread_state { | |
| #[cfg(all(has_native_signals, unix))] | ||
| pub(crate) async_guard_range: Range<*mut u8>, | ||
|
|
||
| // The values of `VMStoreContext::last_wasm_{exit_{pc,fp},entry_sp}` for | ||
| // the *previous* `CallThreadState` for this same store/limits. Our | ||
| // *current* last wasm PC/FP/SP are saved in `self.vm_store_context`. We | ||
| // save a copy of the old registers here because the `VMStoreContext` | ||
| // typically doesn't change across nested calls into Wasm (i.e. they are | ||
| // typically calls back into the same store and `self.vm_store_context | ||
| // == self.prev.vm_store_context`) and we must to maintain the list of | ||
| // contiguous-Wasm-frames stack regions for backtracing purposes. | ||
| old_last_wasm_exit_fp: Cell<usize>, | ||
| old_last_wasm_exit_pc: Cell<usize>, | ||
| old_last_wasm_entry_fp: Cell<usize>, | ||
| // The state of the runtime for the *previous* `CallThreadState` for | ||
| // this same store. Our *current* state is saved in `self.vm_store_context`, | ||
| // etc. We need access to the old values of these | ||
| // fields because the `VMStoreContext` typically doesn't change across | ||
| // nested calls into Wasm (i.e. they are typically calls back into the | ||
| // same store and `self.vm_store_context == self.prev.vm_store_context`) and we must to | ||
| // maintain the list of contiguous-Wasm-frames stack regions for | ||
| // backtracing purposes. | ||
| // FIXME(frank-emrich) Does this need to be an (Unsafe)Cell? | ||
|
||
| old_state: *const EntryStoreContext, | ||
| } | ||
|
|
||
| impl Drop for CallThreadState { | ||
| fn drop(&mut self) { | ||
| // Unwind information should not be present as it should have | ||
| // already been processed. | ||
| debug_assert!(self.unwind.replace(None).is_none()); | ||
|
|
||
| unsafe { | ||
| let cx = self.vm_store_context.as_ref(); | ||
| *cx.last_wasm_exit_fp.get() = self.old_last_wasm_exit_fp.get(); | ||
| *cx.last_wasm_exit_pc.get() = self.old_last_wasm_exit_pc.get(); | ||
| *cx.last_wasm_entry_fp.get() = self.old_last_wasm_entry_fp.get(); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl CallThreadState { | ||
| pub const JMP_BUF_INTERPRETER_SENTINEL: *mut u8 = 1 as *mut u8; | ||
|
|
||
| #[inline] | ||
| pub(super) fn new(store: &mut StoreOpaque) -> CallThreadState { | ||
| pub(super) fn new( | ||
| store: &mut StoreOpaque, | ||
| old_state: *const EntryStoreContext, | ||
| ) -> CallThreadState { | ||
| // Don't try to plumb #[cfg] everywhere for this field, just pretend | ||
| // we're using it on miri/windows to silence compiler warnings. | ||
| let _: Range<_> = store.async_guard_range(); | ||
|
|
@@ -512,31 +509,23 @@ mod call_thread_state { | |
| #[cfg(all(has_native_signals, unix))] | ||
| async_guard_range: store.async_guard_range(), | ||
| prev: Cell::new(ptr::null()), | ||
| old_last_wasm_exit_fp: Cell::new(unsafe { | ||
| *store.vm_store_context().last_wasm_exit_fp.get() | ||
| }), | ||
| old_last_wasm_exit_pc: Cell::new(unsafe { | ||
| *store.vm_store_context().last_wasm_exit_pc.get() | ||
| }), | ||
| old_last_wasm_entry_fp: Cell::new(unsafe { | ||
| *store.vm_store_context().last_wasm_entry_fp.get() | ||
| }), | ||
| old_state, | ||
| } | ||
| } | ||
|
|
||
| /// Get the saved FP upon exit from Wasm for the previous `CallThreadState`. | ||
| pub fn old_last_wasm_exit_fp(&self) -> usize { | ||
| self.old_last_wasm_exit_fp.get() | ||
| pub unsafe fn old_last_wasm_exit_fp(&self) -> usize { | ||
| (&*self.old_state).last_wasm_exit_fp | ||
| } | ||
|
|
||
| /// Get the saved PC upon exit from Wasm for the previous `CallThreadState`. | ||
| pub fn old_last_wasm_exit_pc(&self) -> usize { | ||
| self.old_last_wasm_exit_pc.get() | ||
| pub unsafe fn old_last_wasm_exit_pc(&self) -> usize { | ||
| (&*self.old_state).last_wasm_exit_pc | ||
| } | ||
|
|
||
| /// Get the saved FP upon entry into Wasm for the previous `CallThreadState`. | ||
| pub fn old_last_wasm_entry_fp(&self) -> usize { | ||
| self.old_last_wasm_entry_fp.get() | ||
| pub unsafe fn old_last_wasm_entry_fp(&self) -> usize { | ||
| (&*self.old_state).last_wasm_entry_fp | ||
| } | ||
|
|
||
| /// Get the previous `CallThreadState`. | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.