cranelift_interpreter/
state.rs1use crate::address::{Address, AddressSize};
4use crate::frame::Frame;
5use crate::interpreter::LibCallHandler;
6use cranelift_codegen::data_value::DataValue;
7use cranelift_codegen::ir::{
8 types, ExternalName, FuncRef, Function, GlobalValue, LibCall, MemFlags, Signature, StackSlot,
9 Type, Value,
10};
11use cranelift_codegen::isa::CallConv;
12use smallvec::SmallVec;
13use thiserror::Error;
14
15pub trait State<'a> {
24 fn get_function(&self, func_ref: FuncRef) -> Option<&'a Function>;
26 fn get_current_function(&self) -> &'a Function;
28 fn get_libcall_handler(&self) -> LibCallHandler;
30
31 fn push_frame(&mut self, function: &'a Function);
33 fn pop_frame(&mut self);
35
36 fn current_frame_mut(&mut self) -> &mut Frame<'a>;
37 fn current_frame(&self) -> &Frame<'a>;
38
39 fn collect_values(&self, names: &[Value]) -> SmallVec<[DataValue; 1]> {
41 let frame = self.current_frame();
42 names.into_iter().map(|n| frame.get(*n).clone()).collect()
43 }
44
45 fn stack_address(
47 &self,
48 size: AddressSize,
49 slot: StackSlot,
50 offset: u64,
51 ) -> Result<Address, MemoryError>;
52 fn checked_load(
55 &self,
56 address: Address,
57 ty: Type,
58 mem_flags: MemFlags,
59 ) -> Result<DataValue, MemoryError>;
60 fn checked_store(
63 &mut self,
64 address: Address,
65 v: DataValue,
66 mem_flags: MemFlags,
67 ) -> Result<(), MemoryError>;
68
69 fn function_address(
71 &self,
72 size: AddressSize,
73 name: &ExternalName,
74 ) -> Result<Address, MemoryError>;
75
76 fn get_function_from_address(&self, address: Address) -> Option<InterpreterFunctionRef<'a>>;
78
79 fn resolve_global_value(&self, gv: GlobalValue) -> Result<DataValue, MemoryError>;
82
83 fn get_pinned_reg(&self) -> DataValue;
85 fn set_pinned_reg(&mut self, v: DataValue);
87}
88
89pub enum InterpreterFunctionRef<'a> {
90 Function(&'a Function),
91 LibCall(LibCall),
92}
93
94impl<'a> InterpreterFunctionRef<'a> {
95 pub fn signature(&self) -> Signature {
96 match self {
97 InterpreterFunctionRef::Function(f) => f.stencil.signature.clone(),
98 InterpreterFunctionRef::LibCall(lc) => lc.signature(CallConv::SystemV, types::I64),
101 }
102 }
103}
104
105impl<'a> From<&'a Function> for InterpreterFunctionRef<'a> {
106 fn from(f: &'a Function) -> Self {
107 InterpreterFunctionRef::Function(f)
108 }
109}
110
111impl From<LibCall> for InterpreterFunctionRef<'_> {
112 fn from(lc: LibCall) -> Self {
113 InterpreterFunctionRef::LibCall(lc)
114 }
115}
116
117#[derive(Error, Debug)]
118pub enum MemoryError {
119 #[error("Invalid DataValue passed as an address: {0}")]
120 InvalidAddress(DataValue),
121 #[error("Invalid type for address: {0}")]
122 InvalidAddressType(Type),
123 #[error("Requested an the entry {entry} but only {max} entries are allowed")]
124 InvalidEntry { entry: u64, max: u64 },
125 #[error("Requested an offset of {offset} but max was {max}")]
126 InvalidOffset { offset: u64, max: u64 },
127 #[error("Load of {load_size} bytes is larger than available size at address {addr:?}")]
128 OutOfBoundsLoad {
129 addr: Address,
130 load_size: usize,
131 mem_flags: MemFlags,
132 },
133 #[error("Store of {store_size} bytes is larger than available size at address {addr:?}")]
134 OutOfBoundsStore {
135 addr: Address,
136 store_size: usize,
137 mem_flags: MemFlags,
138 },
139 #[error("Load of {load_size} bytes is misaligned at address {addr:?}")]
140 MisalignedLoad { addr: Address, load_size: usize },
141 #[error("Store of {store_size} bytes is misaligned at address {addr:?}")]
142 MisalignedStore { addr: Address, store_size: usize },
143}