Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/cranelift/codegen/src/isa/x64/inst/stack_switch.rs
1693 views
1
use crate::{isa::x64::inst::regs, machinst::Reg};
2
3
/// The `stack_switch` instruction loads information about the stack to switch
4
/// to and stores information about the current stack by receiving pointers to
5
/// memory laid out as in the struct `ControlContext` below.
6
///
7
/// The instruction is only supported on x64 Linux at the moment.
8
///
9
/// ```
10
/// #[repr(C)]
11
/// pub struct ControlContext {
12
/// pub stack_pointer: *mut u8,
13
/// pub frame_pointer: *mut u8,
14
/// pub instruction_pointer: *mut u8,
15
/// }
16
/// ```
17
///
18
/// Note that this layout is deliberately chosen to make frame pointer walking
19
/// possible, if desired: The layout enables stack layouts where a
20
/// `ControlContext` is part of a frame pointer chain, putting the frame pointer
21
/// next to the corresponding IP.
22
///
23
/// We never actually interact with values of that type in Cranelift, but are
24
/// only interested in its layout for the purposes of generating code.
25
pub struct ControlContextLayout {
26
pub stack_pointer_offset: usize,
27
pub frame_pointer_offset: usize,
28
pub ip_offset: usize,
29
}
30
31
pub fn control_context_layout() -> ControlContextLayout {
32
ControlContextLayout {
33
stack_pointer_offset: 0,
34
frame_pointer_offset: 8,
35
ip_offset: 16,
36
}
37
}
38
39
/// The register used for handing over the payload when switching stacks.
40
///
41
/// We must use a fixed register for sending and receiving the payload: When
42
/// switching from one stack to another using two matching``stack_switch``
43
/// instructions, they must agree on the register where the payload is, similar
44
/// to a calling convention. The same holds when `stack_switch`-ing to a newly
45
/// initialized stack, where the entry trampoline must know which register the
46
/// payload is in.
47
pub fn payload_register() -> Reg {
48
regs::rdi()
49
}
50
51