1 use super::*; 2 use crate::ir; 3 use cranelift_control::ControlPlane; 4 5 /// State carried between emissions of a sequence of instructions. 6 #[derive(Default, Clone, Debug)] 7 pub struct EmitState { 8 /// The user stack map for the upcoming instruction, as provided to 9 /// `pre_safepoint()`. 10 user_stack_map: Option<ir::UserStackMap>, 11 12 /// Only used during fuzz-testing. Otherwise, it is a zero-sized struct and 13 /// optimized away at compiletime. See [cranelift_control]. 14 ctrl_plane: ControlPlane, 15 16 /// A copy of the frame layout, used during the emission of `Inst::ReturnCallKnown` and 17 /// `Inst::ReturnCallUnknown` instructions and exception callsites. 18 pub frame_layout: FrameLayout, 19 } 20 21 impl MachInstEmitState<Inst> for EmitState { new(abi: &Callee<X64ABIMachineSpec>, ctrl_plane: ControlPlane) -> Self22 fn new(abi: &Callee<X64ABIMachineSpec>, ctrl_plane: ControlPlane) -> Self { 23 EmitState { 24 user_stack_map: None, 25 ctrl_plane, 26 frame_layout: abi.frame_layout().clone(), 27 } 28 } 29 pre_safepoint(&mut self, user_stack_map: Option<ir::UserStackMap>)30 fn pre_safepoint(&mut self, user_stack_map: Option<ir::UserStackMap>) { 31 self.user_stack_map = user_stack_map; 32 } 33 ctrl_plane_mut(&mut self) -> &mut ControlPlane34 fn ctrl_plane_mut(&mut self) -> &mut ControlPlane { 35 &mut self.ctrl_plane 36 } 37 take_ctrl_plane(self) -> ControlPlane38 fn take_ctrl_plane(self) -> ControlPlane { 39 self.ctrl_plane 40 } 41 frame_layout(&self) -> &FrameLayout42 fn frame_layout(&self) -> &FrameLayout { 43 &self.frame_layout 44 } 45 } 46 47 impl EmitState { take_stack_map(&mut self) -> Option<ir::UserStackMap>48 pub(crate) fn take_stack_map(&mut self) -> Option<ir::UserStackMap> { 49 self.user_stack_map.take() 50 } 51 clear_post_insn(&mut self)52 pub(crate) fn clear_post_insn(&mut self) { 53 self.user_stack_map = None; 54 } 55 } 56