1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
use std::fmt::{Display, Write};
use crate::object::ClosureFunction;
use super::super::bytecode::errors::FrameError;
use super::super::bytecode::instruction::Instruction;
/// Stack Frame of function.
///
/// * cf - Compiled function closure
/// * bp - base pointer aka bp (stack index of return)
/// * ic - instruction counter (same as program counter) aka ic
pub struct Frame {
/// * cf - Compiled function closure
cf: ClosureFunction,
/// * bp - base pointer aka bp (stack index of return)
bp: usize,
/// * ic - instruction counter (same as program counter) aka ic
ic: usize,
}
impl Frame {
/// Creates a new [`Frame`].
/// * `fun`- Compiled function closure
/// * `base_ptr` - base pointer aka bp (stack index of return)
pub fn new(fun: ClosureFunction, base_ptr: usize) -> Self {
Self {
cf: fun,
bp: base_ptr,
ic: 0,
}
}
/// Returns the rext instruction of this [`Frame`]
/// by reading instruction from [`Self::cf`],
///
/// # Errors [`FrameError::InnerError`]
///
/// This function will return an error if failed to read instruction
pub fn rext_instruction(&self) -> Result<Instruction, FrameError> {
Ok(self.cf.fun.instructions.read_instruction(self.ic)?)
}
/// Sets the ic of this [`Frame`].
pub fn set_ic(&mut self, tgt: usize) {
self.ic = tgt
}
/// Add ic with given `offset`
pub fn add_ic(&mut self, offset: usize) {
self.ic += offset
}
/// Returns the ic of this [`Frame`]
pub fn ic(&self) -> usize {
#![allow(dead_code)]
self.ic
}
/// Returns the bp of this [`Frame`].
pub fn bp(&self) -> usize {
self.bp
}
/// Returns the is runnable of this [`Frame`].
pub fn is_runnable(&self) -> bool {
self.ic < self.cf.fun.instructions.length()
}
/// Returns a reference to the get closure ref of this [`Frame`].
pub fn get_closure_ref(&self) -> &ClosureFunction {
&self.cf
}
}
impl Display for Frame {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut buf = String::new();
buf += &format!("<FRAME> IC : {}, BP : {}\n", self.ic, self.bp);
buf += "\nINSTRUCTIONS\n";
buf += &self.cf.fun.instructions.to_string_with_highlight(self.ic);
f.write_str(buf.as_str())
}
}