rush_interpreter_vm/
vm.rs1use std::{
2 fmt::{self, Display, Formatter},
3 mem::size_of,
4 thread::sleep,
5 time::Duration,
6};
7
8use crate::{
9 instruction::{Instruction, Program},
10 value::{Pointer, Value},
11};
12
13pub struct Vm {
14 stack: Vec<Value>,
16 mem: Vec<Option<Value>>,
18 mem_ptr: isize,
21 call_stack: Vec<CallFrame>,
23}
24
25#[derive(Debug, Default)]
26struct CallFrame {
27 ip: usize,
29 fp: usize,
31}
32
33const STACK_LIMIT: usize = 1024;
34const CALL_STACK_LIMIT: usize = 1024;
35
36pub type Result<T> = std::result::Result<T, RuntimeError>;
37
38#[derive(Debug)]
39pub struct RuntimeError {
40 pub kind: RuntimeErrorKind,
41 pub msg: String,
42}
43
44impl Display for RuntimeError {
45 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
46 write!(f, "{}: {}", self.kind, self.msg)
47 }
48}
49
50impl RuntimeError {
51 pub fn new(kind: RuntimeErrorKind, msg: String) -> Self {
52 Self { kind, msg }
53 }
54}
55
56#[derive(Debug)]
57pub enum RuntimeErrorKind {
58 StackOverflow,
59 Arithmetic,
60}
61
62impl Display for RuntimeErrorKind {
63 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64 write!(
65 f,
66 "{}",
67 match self {
68 Self::StackOverflow => "StackOverflowError",
69 Self::Arithmetic => "ArithmeticError",
70 }
71 )
72 }
73}
74
75impl Default for Vm {
76 fn default() -> Self {
77 Self::new()
78 }
79}
80
81impl Vm {
82 pub fn new() -> Self {
83 Self {
84 stack: vec![],
85 mem: vec![],
86 mem_ptr: 0,
87 call_stack: vec![CallFrame::default()],
89 }
90 }
91
92 fn push(&mut self, val: Value) -> Result<()> {
95 match self.stack.len() >= STACK_LIMIT {
96 true => Err(RuntimeError::new(
97 RuntimeErrorKind::StackOverflow,
98 format!("maximum stack size of {STACK_LIMIT} exceeded"),
99 )),
100 false => {
101 self.stack.push(val);
102 Ok(())
103 }
104 }
105 }
106
107 #[inline]
108 fn pop(&mut self) -> Value {
110 self.stack.pop().expect("pop is always called safely")
111 }
112
113 #[inline]
114 fn call_frame(&self) -> &CallFrame {
115 self.call_stack
116 .last()
117 .expect("there is always at least one call frame")
118 }
119
120 #[inline]
121 fn call_frame_mut(&mut self) -> &mut CallFrame {
122 self.call_stack
123 .last_mut()
124 .expect("there is always at least one call frame")
125 }
126
127 pub fn debug_run(&mut self, program: Program, clock_hz: u64) -> Result<i64> {
130 while self.call_frame().ip < program.0[self.call_frame().fp].len() {
131 let instruction = &program.0[self.call_frame().fp][self.call_frame().ip];
132
133 println!(
134 "[{fp:02}/{ip:02}] {instr:15} | {stack:>40} | mp = {mp} | used = {used_mem:4}b | {mem}",
135 fp = self.call_frame().fp,
136 ip = self.call_frame().ip,
137 instr = instruction.to_string(),
138 stack = self
139 .stack
140 .iter()
141 .rev()
142 .map(|v| v.to_string())
143 .collect::<Vec<String>>()
144 .join(", "),
145 mp = self.mem_ptr,
146 used_mem = self.mem.len() * size_of::<Value>(),
147 mem = self.mem[self.mem_ptr as usize..]
148 .iter()
149 .map(|v| match v {
150 Some(v) => v.to_string(),
151 None => "NONE".to_string(),
152 })
153 .collect::<Vec<String>>()
154 .join(", ")
155 );
156 sleep(Duration::from_millis(1000 / clock_hz));
157
158 if let Some(code) = self.run_instruction(instruction)? {
160 return Ok(code);
161 };
162 }
163 Ok(0)
164 }
165
166 pub fn run(&mut self, program: Program) -> Result<i64> {
167 while self.call_frame().ip < program.0[self.call_frame().fp].len() {
168 let instruction = &program.0[self.call_frame().fp][self.call_frame().ip];
169
170 if let Some(code) = self.run_instruction(instruction)? {
172 return Ok(code);
173 };
174 }
175
176 Ok(0)
177 }
178
179 fn run_instruction(&mut self, inst: &Instruction) -> Result<Option<i64>> {
180 match inst {
181 Instruction::Nop => {}
182 Instruction::Push(value) => self.push(*value)?,
183 Instruction::Drop => {
184 self.pop();
185 }
186 Instruction::Clone => self
187 .stack
188 .push(*self.stack.last().expect("clone is always called safely")),
189 Instruction::Jmp(idx) => {
190 self.call_frame_mut().ip = *idx;
191 return Ok(None);
192 }
193 Instruction::JmpFalse(idx) => {
194 if !self.pop().unwrap_bool() {
196 self.call_frame_mut().ip = *idx;
197 return Ok(None);
198 }
199 }
200 Instruction::SetVarImm(_) | Instruction::SetVar => {
201 let val = self.pop();
202
203 let addr = match inst {
204 Instruction::SetVarImm(Pointer::Rel(offset)) => {
205 (self.mem_ptr + offset) as usize
206 }
207 Instruction::SetVarImm(Pointer::Abs(addr)) => *addr,
208 _ => match self.pop().unwrap_ptr() {
209 Pointer::Rel(offset) => (self.mem_ptr + offset) as usize,
210 Pointer::Abs(addr) => addr,
211 },
212 };
213
214 match self.mem.get_mut(addr) {
217 Some(var) => *var = Some(val),
218 None => {
219 self.mem.resize(addr + 1, None);
220 self.mem[addr] = Some(val)
221 }
222 }
223 }
224 Instruction::GetVar => {
225 let addr = match self.pop().unwrap_ptr() {
226 Pointer::Rel(offset) => (self.mem_ptr + offset) as usize,
227 Pointer::Abs(addr) => addr,
228 };
229 self.push(self.mem[addr].expect("variables are always initialized"))?
230 }
231 Instruction::Call(idx) => {
232 if self.call_stack.len() >= CALL_STACK_LIMIT {
233 return Err(RuntimeError::new(
234 RuntimeErrorKind::StackOverflow,
235 format!("maximum call-stack size of {CALL_STACK_LIMIT} was exceeded"),
236 ));
237 }
238
239 self.call_stack.push(CallFrame { ip: 0, fp: *idx });
241
242 return Ok(None);
244 }
245 Instruction::SetMp(offset) => {
246 self.mem_ptr += offset;
247 self.mem.resize(self.mem_ptr as usize + 1, None);
248 }
249 Instruction::RelToAddr(offset) => {
250 let addr = (self.mem_ptr + offset) as usize;
251 self.push(Value::Ptr(Pointer::Abs(addr)))?;
252 }
253 Instruction::Ret => {
254 self.call_stack.pop();
255 }
256 Instruction::Cast(to) => {
257 let from = self.pop();
258 self.push(from.cast(*to))?
259 }
260 Instruction::Exit => {
261 return Ok(Some(self.pop().unwrap_int()));
262 }
263 Instruction::Neg => {
264 let top = self.pop();
265 self.push(top.neg())?;
266 }
267 Instruction::Not => {
268 let top = self.pop();
269 self.push(top.not())?;
270 }
271 Instruction::Add => {
272 let rhs = self.pop();
273 let lhs = self.pop();
274 self.push(lhs.add(rhs))?;
275 }
276 Instruction::Sub => {
277 let rhs = self.pop();
278 let lhs = self.pop();
279 self.push(lhs.sub(rhs))?;
280 }
281 Instruction::Mul => {
282 let rhs = self.pop();
283 let lhs = self.pop();
284 self.push(lhs.mul(rhs))?;
285 }
286 Instruction::Pow => {
287 let rhs = self.pop();
288 let lhs = self.pop();
289 self.push(lhs.pow(rhs))?;
290 }
291 Instruction::Div => {
292 let rhs = self.pop();
293 let lhs = self.pop();
294 self.push(lhs.div(rhs)?)?;
295 }
296 Instruction::Rem => {
297 let rhs = self.pop();
298 let lhs = self.pop();
299 self.push(lhs.rem(rhs)?)?;
300 }
301 Instruction::Eq => {
302 let rhs = self.pop();
303 let lhs = self.pop();
304 self.push(lhs.eq(rhs))?;
305 }
306 Instruction::Ne => {
307 let rhs = self.pop();
308 let lhs = self.pop();
309 self.push(lhs.ne(rhs))?;
310 }
311 Instruction::Lt => {
312 let rhs = self.pop();
313 let lhs = self.pop();
314 self.push(lhs.lt(rhs))?;
315 }
316 Instruction::Le => {
317 let rhs = self.pop();
318 let lhs = self.pop();
319 self.push(lhs.le(rhs))?;
320 }
321 Instruction::Gt => {
322 let rhs = self.pop();
323 let lhs = self.pop();
324 self.push(lhs.gt(rhs))?;
325 }
326 Instruction::Ge => {
327 let rhs = self.pop();
328 let lhs = self.pop();
329 self.push(lhs.ge(rhs))?;
330 }
331 Instruction::Shl => {
332 let rhs = self.pop();
333 let lhs = self.pop();
334 self.push(lhs.shl(rhs)?)?;
335 }
336 Instruction::Shr => {
337 let rhs = self.pop();
338 let lhs = self.pop();
339 self.push(lhs.shr(rhs)?)?;
340 }
341 Instruction::BitOr => {
342 let rhs = self.pop();
343 let lhs = self.pop();
344 self.push(lhs.bit_or(rhs))?;
345 }
346 Instruction::BitAnd => {
347 let rhs = self.pop();
348 let lhs = self.pop();
349 self.push(lhs.bit_and(rhs))?;
350 }
351 Instruction::BitXor => {
352 let rhs = self.pop();
353 let lhs = self.pop();
354 self.push(lhs.bit_xor(rhs))?;
355 }
356 }
357 self.call_frame_mut().ip += 1;
358 Ok(None)
359 }
360}