wasmer_compiler_singlepass/
common_decl.rs1use std::collections::BTreeMap;
2
3#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
4pub struct RegisterIndex(pub usize);
5
6#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
8pub enum WasmAbstractValue {
9 Runtime,
11 Const(u64),
13}
14
15#[derive(Clone, Debug)]
17pub struct MachineState {
18 pub stack_values: Vec<MachineValue>,
20 pub register_values: Vec<MachineValue>,
22 pub prev_frame: BTreeMap<usize, MachineValue>,
24 pub wasm_stack: Vec<WasmAbstractValue>,
26 pub wasm_inst_offset: usize,
28}
29
30#[derive(Clone, Debug, Default)]
35#[allow(dead_code)]
36pub struct MachineStateDiff {
37 pub last: Option<usize>,
39
40 pub stack_push: Vec<MachineValue>,
42
43 pub stack_pop: usize,
45
46 pub reg_diff: Vec<(RegisterIndex, MachineValue)>,
48
49 pub prev_frame_diff: BTreeMap<usize, Option<MachineValue>>, pub wasm_stack_push: Vec<WasmAbstractValue>,
54
55 pub wasm_stack_pop: usize,
57
58 pub wasm_inst_offset: usize, }
61
62#[derive(Clone, Debug, Eq, PartialEq, Hash)]
64pub enum MachineValue {
65 Undefined,
67 Vmctx,
69 _VmctxDeref(Vec<usize>),
71 PreserveRegister(RegisterIndex),
73 CopyStackBPRelative(i32), ExplicitShadow, WasmStack(usize),
79 WasmLocal(usize),
81 _TwoHalves(Box<(MachineValue, MachineValue)>), }
84
85#[derive(Clone, Debug)]
87#[allow(dead_code)]
88pub struct FunctionStateMap {
89 pub initial: MachineState,
91 pub local_function_id: usize,
93 pub locals: Vec<WasmAbstractValue>,
95 pub shadow_size: usize, pub diffs: Vec<MachineStateDiff>,
99 pub wasm_function_header_target_offset: Option<SuspendOffset>,
101 pub wasm_offset_to_target_offset: BTreeMap<usize, SuspendOffset>,
103 pub loop_offsets: BTreeMap<usize, OffsetInfo>, pub call_offsets: BTreeMap<usize, OffsetInfo>, pub trappable_offsets: BTreeMap<usize, OffsetInfo>, }
110
111#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
112pub enum Size {
113 S8,
114 S16,
115 S32,
116 S64,
117}
118
119#[allow(dead_code)]
121#[derive(Clone, Copy, Debug)]
122pub enum SuspendOffset {
123 _Loop(usize),
125 Call(usize),
127 Trappable(usize),
129}
130
131#[allow(dead_code)]
133#[derive(Clone, Debug)]
134pub struct OffsetInfo {
135 pub end_offset: usize,
137 pub diff_id: usize,
139 pub activate_offset: usize,
141}
142
143impl FunctionStateMap {
144 pub fn new(
146 initial: MachineState,
147 local_function_id: usize,
148 shadow_size: usize,
149 locals: Vec<WasmAbstractValue>,
150 ) -> FunctionStateMap {
151 FunctionStateMap {
152 initial,
153 local_function_id,
154 shadow_size,
155 locals,
156 diffs: vec![],
157 wasm_function_header_target_offset: None,
158 wasm_offset_to_target_offset: BTreeMap::new(),
159 loop_offsets: BTreeMap::new(),
160 call_offsets: BTreeMap::new(),
161 trappable_offsets: BTreeMap::new(),
162 }
163 }
164}
165
166impl MachineState {
167 pub fn diff(&self, old: &MachineState) -> MachineStateDiff {
169 let first_diff_stack_depth: usize = self
170 .stack_values
171 .iter()
172 .zip(old.stack_values.iter())
173 .enumerate()
174 .find(|&(_, (a, b))| a != b)
175 .map(|x| x.0)
176 .unwrap_or_else(|| old.stack_values.len().min(self.stack_values.len()));
177 assert_eq!(self.register_values.len(), old.register_values.len());
178 let reg_diff: Vec<_> = self
179 .register_values
180 .iter()
181 .zip(old.register_values.iter())
182 .enumerate()
183 .filter(|&(_, (a, b))| a != b)
184 .map(|(i, (a, _))| (RegisterIndex(i), a.clone()))
185 .collect();
186 let prev_frame_diff: BTreeMap<usize, Option<MachineValue>> = self
187 .prev_frame
188 .iter()
189 .filter(|(k, v)| {
190 if let Some(ref old_v) = old.prev_frame.get(k) {
191 v != old_v
192 } else {
193 true
194 }
195 })
196 .map(|(&k, v)| (k, Some(v.clone())))
197 .chain(
198 old.prev_frame
199 .iter()
200 .filter(|(k, _)| !self.prev_frame.contains_key(k))
201 .map(|(&k, _)| (k, None)),
202 )
203 .collect();
204 let first_diff_wasm_stack_depth: usize = self
205 .wasm_stack
206 .iter()
207 .zip(old.wasm_stack.iter())
208 .enumerate()
209 .find(|&(_, (a, b))| a != b)
210 .map(|x| x.0)
211 .unwrap_or_else(|| old.wasm_stack.len().min(self.wasm_stack.len()));
212 MachineStateDiff {
213 last: None,
214 stack_push: self.stack_values[first_diff_stack_depth..].to_vec(),
215 stack_pop: old.stack_values.len() - first_diff_stack_depth,
216 reg_diff,
217
218 prev_frame_diff,
219
220 wasm_stack_push: self.wasm_stack[first_diff_wasm_stack_depth..].to_vec(),
221 wasm_stack_pop: old.wasm_stack.len() - first_diff_wasm_stack_depth,
222
223 wasm_inst_offset: self.wasm_inst_offset,
224 }
225 }
226}
227
228impl MachineStateDiff {
229 pub fn _build_state(&self, m: &FunctionStateMap) -> MachineState {
231 let mut chain: Vec<&MachineStateDiff> = vec![self];
232 let mut current = self.last;
233 while let Some(x) = current {
234 let that = &m.diffs[x];
235 current = that.last;
236 chain.push(that);
237 }
238 chain.reverse();
239 let mut state = m.initial.clone();
240 for x in chain {
241 for _ in 0..x.stack_pop {
242 state.stack_values.pop().unwrap();
243 }
244 for v in &x.stack_push {
245 state.stack_values.push(v.clone());
246 }
247 for &(index, ref v) in &x.reg_diff {
248 state.register_values[index.0] = v.clone();
249 }
250 for (index, ref v) in &x.prev_frame_diff {
251 if let Some(x) = v {
252 state.prev_frame.insert(*index, x.clone());
253 } else {
254 state.prev_frame.remove(index).unwrap();
255 }
256 }
257 for _ in 0..x.wasm_stack_pop {
258 state.wasm_stack.pop().unwrap();
259 }
260 for v in &x.wasm_stack_push {
261 state.wasm_stack.push(*v);
262 }
263 }
264 state.wasm_inst_offset = self.wasm_inst_offset;
265 state
266 }
267}