Skip to content

Commit ef9c4c7

Browse files
committed
move VMStackState to wasmtime crate
1 parent dbf0b31 commit ef9c4c7

File tree

5 files changed

+125
-90
lines changed

5 files changed

+125
-90
lines changed

crates/cranelift/src/stack_switching/instructions.rs

Lines changed: 86 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -981,31 +981,19 @@ pub(crate) mod stack_switching_helpers {
981981
env: &mut crate::func_environ::FuncEnvironment<'a>,
982982
builder: &mut FunctionBuilder,
983983
) -> ir::Value {
984-
// Let's make sure that we still represent the VMStackState enum as i32.
985-
debug_assert!(
986-
mem::size_of::<super::stack_switching_environ::VMStackState>()
987-
== mem::size_of::<i32>()
988-
);
989-
990984
let mem_flags = ir::MemFlags::trusted();
991985
let state_ptr = self.get_state_ptr(env, builder);
992986

993987
builder.ins().load(I32, mem_flags, state_ptr, 0)
994988
}
995989

996-
pub fn set_state<'a>(
990+
fn set_state_no_payload<'a>(
997991
&self,
998992
env: &mut crate::func_environ::FuncEnvironment<'a>,
999993
builder: &mut FunctionBuilder,
1000-
state: super::stack_switching_environ::VMStackState,
994+
discriminant: u32,
1001995
) {
1002-
// Let's make sure that we still represent the VMStackState enum as i32.
1003-
debug_assert!(
1004-
mem::size_of::<super::stack_switching_environ::VMStackState>()
1005-
== mem::size_of::<i32>()
1006-
);
1007-
1008-
let discriminant = builder.ins().iconst(I32, state.discriminant() as i64);
996+
let discriminant = builder.ins().iconst(I32, discriminant as i64);
1009997
emit_debug_println!(
1010998
env,
1011999
builder,
@@ -1020,34 +1008,95 @@ pub(crate) mod stack_switching_helpers {
10201008
builder.ins().store(mem_flags, discriminant, state_ptr, 0);
10211009
}
10221010

1011+
pub fn set_state_running<'a>(
1012+
&self,
1013+
env: &mut crate::func_environ::FuncEnvironment<'a>,
1014+
builder: &mut FunctionBuilder,
1015+
) {
1016+
let discriminant = wasmtime_environ::stack_switching::STACK_STATE_RUNNING_DISCRIMINANT;
1017+
self.set_state_no_payload(env, builder, discriminant);
1018+
}
1019+
1020+
pub fn set_state_parent<'a>(
1021+
&self,
1022+
env: &mut crate::func_environ::FuncEnvironment<'a>,
1023+
builder: &mut FunctionBuilder,
1024+
) {
1025+
let discriminant = wasmtime_environ::stack_switching::STACK_STATE_PARENT_DISCRIMINANT;
1026+
self.set_state_no_payload(env, builder, discriminant);
1027+
}
1028+
1029+
pub fn set_state_returned<'a>(
1030+
&self,
1031+
env: &mut crate::func_environ::FuncEnvironment<'a>,
1032+
builder: &mut FunctionBuilder,
1033+
) {
1034+
let discriminant = wasmtime_environ::stack_switching::STACK_STATE_RETURNED_DISCRIMINANT;
1035+
self.set_state_no_payload(env, builder, discriminant);
1036+
}
1037+
1038+
pub fn set_state_suspended<'a>(
1039+
&self,
1040+
env: &mut crate::func_environ::FuncEnvironment<'a>,
1041+
builder: &mut FunctionBuilder,
1042+
) {
1043+
let discriminant =
1044+
wasmtime_environ::stack_switching::STACK_STATE_SUSPENDED_DISCRIMINANT;
1045+
self.set_state_no_payload(env, builder, discriminant);
1046+
}
1047+
10231048
pub fn has_state_any_of<'a>(
10241049
&self,
10251050
env: &mut crate::func_environ::FuncEnvironment<'a>,
10261051
builder: &mut FunctionBuilder,
1027-
states: &[super::stack_switching_environ::VMStackState],
1052+
state_discriminants: &[u32],
10281053
) -> ir::Value {
10291054
let actual_state = self.load_state(env, builder);
10301055
let zero = builder.ins().iconst(I8, 0);
10311056
let mut res = zero;
1032-
for state in states {
1057+
for state_discriminant in state_discriminants {
10331058
let eq =
10341059
builder
10351060
.ins()
1036-
.icmp_imm(IntCC::Equal, actual_state, state.discriminant() as i64);
1061+
.icmp_imm(IntCC::Equal, actual_state, *state_discriminant as i64);
10371062
res = builder.ins().bor(res, eq);
10381063
}
10391064
res
10401065
}
10411066

1042-
pub fn has_state<'a>(
1067+
pub fn has_state_returned<'a>(
1068+
&self,
1069+
env: &mut crate::func_environ::FuncEnvironment<'a>,
1070+
builder: &mut FunctionBuilder,
1071+
) -> ir::Value {
1072+
self.has_state_any_of(
1073+
env,
1074+
builder,
1075+
&[wasmtime_environ::stack_switching::STACK_STATE_RETURNED_DISCRIMINANT],
1076+
)
1077+
}
1078+
1079+
pub fn has_state_running<'a>(
10431080
&self,
10441081
env: &mut crate::func_environ::FuncEnvironment<'a>,
10451082
builder: &mut FunctionBuilder,
1046-
state: super::stack_switching_environ::VMStackState,
10471083
) -> ir::Value {
1048-
self.has_state_any_of(env, builder, &[state])
1084+
self.has_state_any_of(
1085+
env,
1086+
builder,
1087+
&[wasmtime_environ::stack_switching::STACK_STATE_RUNNING_DISCRIMINANT],
1088+
)
10491089
}
10501090

1091+
// pub fn has_state<'a>(
1092+
// &self,
1093+
// env: &mut crate::func_environ::FuncEnvironment<'a>,
1094+
// builder: &mut FunctionBuilder,
1095+
// state: super::stack_switching_environ::VMStackState,
1096+
// ) -> ir::Value {
1097+
// self.has_state_any_of(env, builder, &[state])
1098+
// }
1099+
10511100
/// Checks whether the `VMStackState` reflects that the stack has ever been
10521101
/// active (instead of just having been allocated, but never resumed).
10531102
pub fn was_invoked<'a>(
@@ -1056,7 +1105,7 @@ pub(crate) mod stack_switching_helpers {
10561105
builder: &mut FunctionBuilder,
10571106
) -> ir::Value {
10581107
let actual_state = self.load_state(env, builder);
1059-
let allocated: i32 = i32::from(super::stack_switching_environ::VMStackState::Fresh);
1108+
let allocated = wasmtime_environ::stack_switching::STACK_STATE_FRESH_DISCRIMINANT;
10601109
builder
10611110
.ins()
10621111
.icmp_imm(IntCC::NotEqual, actual_state, allocated as i64)
@@ -1224,7 +1273,7 @@ pub(crate) mod stack_switching_helpers {
12241273

12251274
use helpers::VMStackChain;
12261275
use stack_switching_environ::{
1227-
VMStackState, CONTROL_EFFECT_RESUME_DISCRIMINANT, CONTROL_EFFECT_SWITCH_DISCRIMINANT,
1276+
CONTROL_EFFECT_RESUME_DISCRIMINANT, CONTROL_EFFECT_SWITCH_DISCRIMINANT,
12281277
};
12291278
use stack_switching_helpers as helpers;
12301279

@@ -1735,11 +1784,7 @@ pub(crate) fn translate_resume<'a>(
17351784
// This should be impossible due to the linearity check.
17361785
let zero = builder.ins().iconst(I8, 0);
17371786
let csi = vmcontref.common_stack_information(env, builder);
1738-
let has_returned = csi.has_state(
1739-
env,
1740-
builder,
1741-
stack_switching_environ::VMStackState::Returned,
1742-
);
1787+
let has_returned = csi.has_state_returned(env, builder);
17431788
emit_debug_assert_eq!(env, builder, has_returned, zero);
17441789
}
17451790

@@ -1797,8 +1842,8 @@ pub(crate) fn translate_resume<'a>(
17971842
let resume_contref = helpers::VMContRef::new(resume_contref);
17981843
let resume_csi = resume_contref.common_stack_information(env, builder);
17991844
let parent_csi = original_stack_chain.get_common_stack_information(env, builder);
1800-
resume_csi.set_state(env, builder, stack_switching_environ::VMStackState::Running);
1801-
parent_csi.set_state(env, builder, stack_switching_environ::VMStackState::Parent);
1845+
resume_csi.set_state_running(env, builder);
1846+
parent_csi.set_state_parent(env, builder);
18021847

18031848
// We update the `VMStackLimits` of the parent of the continuation to be resumed
18041849
// as well as the `VMRuntimeLimits`.
@@ -1886,7 +1931,7 @@ pub(crate) fn translate_resume<'a>(
18861931

18871932
// Now the parent contref (or initial stack) is active again
18881933
vmctx_store_stack_chain(env, builder, vmctx, &original_stack_chain);
1889-
parent_csi.set_state(env, builder, stack_switching_environ::VMStackState::Running);
1934+
parent_csi.set_state_running(env, builder);
18901935

18911936
// Just for consistency: Clear the handler list.
18921937
handler_list.clear(env, builder, true);
@@ -2055,11 +2100,7 @@ pub(crate) fn translate_resume<'a>(
20552100
parent_csi.write_limits_to_vmcontext(env, builder, vm_runtime_limits_ptr);
20562101

20572102
let returned_csi = returned_contref.common_stack_information(env, builder);
2058-
returned_csi.set_state(
2059-
env,
2060-
builder,
2061-
stack_switching_environ::VMStackState::Returned,
2062-
);
2103+
returned_csi.set_state_returned(env, builder);
20632104

20642105
// Load the values returned by the continuation.
20652106
let return_types: Vec<_> = env
@@ -2133,19 +2174,11 @@ pub(crate) fn translate_suspend<'a>(
21332174
// Set current continuation to suspended and break up handler chain.
21342175
let active_contref_csi = active_contref.common_stack_information(env, builder);
21352176
if cfg!(debug_assertions) {
2136-
let is_running = active_contref_csi.has_state(
2137-
env,
2138-
builder,
2139-
stack_switching_environ::VMStackState::Running,
2140-
);
2177+
let is_running = active_contref_csi.has_state_running(env, builder);
21412178
emit_debug_assert!(env, builder, is_running);
21422179
}
21432180

2144-
active_contref_csi.set_state(
2145-
env,
2146-
builder,
2147-
stack_switching_environ::VMStackState::Suspended,
2148-
);
2181+
active_contref_csi.set_state_suspended(env, builder);
21492182
let absent_chain_link = VMStackChain::absent(env, builder);
21502183
end_of_chain_contref.set_parent_stack_chain(env, builder, &absent_chain_link);
21512184

@@ -2259,9 +2292,9 @@ pub(crate) fn translate_switch<'a>(
22592292
emit_debug_assert!(
22602293
env,
22612294
builder,
2262-
switcher_contref_csi.has_state(env, builder, VMStackState::Running)
2295+
switcher_contref_csi.has_state_running(env, builder)
22632296
);
2264-
switcher_contref_csi.set_state(env, builder, VMStackState::Suspended);
2297+
switcher_contref_csi.set_state_suspended(env, builder);
22652298
// We break off `switcher_contref` from the chain of active
22662299
// continuations, by separating the link between `last_ancestor` and its
22672300
// parent stack.
@@ -2317,10 +2350,13 @@ pub(crate) fn translate_switch<'a>(
23172350
switchee_contref_csi.has_state_any_of(
23182351
env,
23192352
builder,
2320-
&[VMStackState::Fresh, VMStackState::Suspended]
2353+
&[
2354+
wasmtime_environ::stack_switching::STACK_STATE_FRESH_DISCRIMINANT,
2355+
wasmtime_environ::stack_switching::STACK_STATE_SUSPENDED_DISCRIMINANT
2356+
]
23212357
)
23222358
);
2323-
switchee_contref_csi.set_state(env, builder, VMStackState::Running);
2359+
switchee_contref_csi.set_state_running(env, builder);
23242360

23252361
let switchee_contref_last_ancestor = switchee_contref.get_last_ancestor(env, builder);
23262362
let mut switchee_contref_last_ancestor =

crates/environ/src/stack_switching.rs

Lines changed: 15 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -48,42 +48,21 @@ pub const STACK_CHAIN_INITIAL_STACK_DISCRIMINANT: usize = 1;
4848
/// `wasmtime::runtime::vm::stack_switching::VMStackChain`.
4949
pub const STACK_CHAIN_CONTINUATION_DISCRIMINANT: usize = 2;
5050

51-
/// Encodes the life cycle of a `VMContRef`.
52-
#[derive(Debug, Clone, Copy, PartialEq)]
53-
#[repr(i32)]
54-
pub enum VMStackState {
55-
/// The `VMContRef` has been created, but neither `resume` or `switch` has ever been
56-
/// called on it. During this stage, we may add arguments using `cont.bind`.
57-
Fresh,
58-
/// The continuation is running, meaning that it is the one currently
59-
/// executing code.
60-
Running,
61-
/// The continuation is suspended because it executed a resume instruction
62-
/// that has not finished yet. In other words, it became the parent of
63-
/// another continuation (which may itself be `Running`, a `Parent`, or
64-
/// `Suspended`).
65-
Parent,
66-
/// The continuation was suspended by a `suspend` or `switch` instruction.
67-
Suspended,
68-
/// The function originally passed to `cont.new` has returned normally.
69-
/// Note that there is no guarantee that a VMContRef will ever
70-
/// reach this status, as it may stay suspended until being dropped.
71-
Returned,
72-
}
73-
74-
impl VMStackState {
75-
/// Returns i32 discriminant of this variant.
76-
pub fn discriminant(&self) -> i32 {
77-
// This is well-defined for an enum with repr(i32).
78-
unsafe { *(self as *const Self as *const i32) }
79-
}
80-
}
81-
82-
impl From<VMStackState> for i32 {
83-
fn from(st: VMStackState) -> Self {
84-
st.discriminant()
85-
}
86-
}
51+
/// Discriminant of variant `Fresh` in
52+
/// `runtime::vm::stack_switching::VMStackState`.
53+
pub const STACK_STATE_FRESH_DISCRIMINANT: u32 = 0;
54+
/// Discriminant of variant `Running` in
55+
/// `runtime::vm::stack_switching::VMStackState`.
56+
pub const STACK_STATE_RUNNING_DISCRIMINANT: u32 = 1;
57+
/// Discriminant of variant `Parent` in
58+
/// `runtime::vm::stack_switching::VMStackState`.
59+
pub const STACK_STATE_PARENT_DISCRIMINANT: u32 = 2;
60+
/// Discriminant of variant `Suspended` in
61+
/// `runtime::vm::stack_switching::VMStackState`.
62+
pub const STACK_STATE_SUSPENDED_DISCRIMINANT: u32 = 3;
63+
/// Discriminant of variant `Returned` in
64+
/// `runtime::vm::stack_switching::VMStackState`.
65+
pub const STACK_STATE_RETURNED_DISCRIMINANT: u32 = 4;
8766

8867
/// Discriminant of variant `Return` in
8968
/// `runtime::vm::stack_switching::ControlEffect`.

crates/wasmtime/src/runtime/store.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1645,7 +1645,7 @@ impl StoreOpaque {
16451645
// continuations below.
16461646
// - For `Fresh` continuations, we know that there are no GC values
16471647
// on their stack, yet.
1648-
if state == wasmtime_environ::stack_switching::VMStackState::Suspended {
1648+
if state == crate::vm::stack_switching::VMStackState::Suspended {
16491649
Backtrace::trace_suspended_continuation(self, continuation.deref(), |frame| {
16501650
self.trace_wasm_stack_frame(gc_roots_list, frame);
16511651
core::ops::ControlFlow::Continue(())

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

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
use core::{cell::UnsafeCell, marker::PhantomPinned, ptr::NonNull};
55

66
use stack::VMContinuationStack;
7-
use wasmtime_environ::stack_switching::VMStackState;
87
#[allow(unused)]
98
use wasmtime_environ::{debug_println, stack_switching::ENABLE_DEBUG_PRINTING};
109

@@ -682,6 +681,28 @@ unsafe impl Sync for VMStackChainCell {}
682681
/// FIXME(frank-emrich) Justify why this is safe
683682
unsafe impl crate::vm::VmSafe for VMStackChainCell {}
684683

684+
/// Encodes the life cycle of a `VMContRef`.
685+
#[derive(Debug, Clone, Copy, PartialEq)]
686+
#[repr(u32)]
687+
pub enum VMStackState {
688+
/// The `VMContRef` has been created, but neither `resume` or `switch` has ever been
689+
/// called on it. During this stage, we may add arguments using `cont.bind`.
690+
Fresh = wasmtime_environ::stack_switching::STACK_STATE_FRESH_DISCRIMINANT,
691+
/// The continuation is running, meaning that it is the one currently
692+
/// executing code.
693+
Running = wasmtime_environ::stack_switching::STACK_STATE_RUNNING_DISCRIMINANT,
694+
/// The continuation is suspended because it executed a resume instruction
695+
/// that has not finished yet. In other words, it became the parent of
696+
/// another continuation (which may itself be `Running`, a `Parent`, or
697+
/// `Suspended`).
698+
Parent = wasmtime_environ::stack_switching::STACK_STATE_PARENT_DISCRIMINANT,
699+
/// The continuation was suspended by a `suspend` or `switch` instruction.
700+
Suspended = wasmtime_environ::stack_switching::STACK_STATE_SUSPENDED_DISCRIMINANT,
701+
/// The function originally passed to `cont.new` has returned normally.
702+
/// Note that there is no guarantee that a VMContRef will ever
703+
/// reach this status, as it may stay suspended until being dropped.
704+
Returned = wasmtime_environ::stack_switching::STACK_STATE_RETURNED_DISCRIMINANT,
705+
}
685706

686707
/// Universal control effect. This structure encodes return signal, resume
687708
/// signal, suspension signal, and the handler to suspend to in a single variant

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,8 @@ use crate::runtime::vm::{
2828
traphandlers::{tls, CallThreadState},
2929
Unwind, VMRuntimeLimits,
3030
};
31-
use crate::vm::stack_switching::VMContRef;
31+
use crate::vm::stack_switching::{VMContRef, VMStackState};
3232
use core::ops::ControlFlow;
33-
use wasmtime_environ::stack_switching::VMStackState;
3433

3534
/// A WebAssembly stack trace.
3635
#[derive(Debug)]

0 commit comments

Comments
 (0)