jazz/
frame.rs

1use crate::{opcodes::Instruction, value::Value};
2
3///CallFrame
4/// Stores register values, Blocks of code, registers and arguments stack
5#[derive(Clone, Debug)]
6pub struct CallFrame
7{
8    /// pointer to current block
9    pub ip: usize,
10    /// blocks
11    pub code: Vec<Instruction>,
12    /// registers stored in stack, default size of `stack` is 4096
13    pub stack: Vec<Value>,
14    /// arguments stack, used by Call instruction
15    pub arg_stack: Vec<Value>,
16}
17
18/// CallStack
19/// Stores frames
20#[derive(Clone, Debug)]
21pub struct CallStack
22{
23    pub frames: Vec<CallFrame>,
24    pub n_frames: usize,
25    pub limit: Option<usize>,
26}
27
28impl CallStack
29{
30    pub fn new(len: usize) -> CallStack
31    {
32        let mut frames = Vec::with_capacity(len);
33        for _ in 0..len {
34            frames.push(CallFrame::new());
35        }
36
37        CallStack {
38            frames,
39            n_frames: 1,
40            limit: None,
41        }
42    }
43
44    pub fn push(&mut self)
45    {
46        if self.n_frames >= self.frames.len() {
47            panic!("Virtual stack overflow");
48        }
49        if let Some(limit) = self.limit {
50            if self.n_frames >= limit {
51                panic!("Maximum stack depth exceeded");
52            }
53        }
54
55        self.n_frames += 1;
56    }
57
58    /// Reset last frame
59    pub fn pop(&mut self)
60    {
61        if self.n_frames <= 0 {
62            panic!("Virtual stack underflow");
63        }
64        self.frames[self.n_frames - 1].reset();
65        self.n_frames -= 1;
66    }
67    /// Get top frame
68    pub fn top(&self) -> &CallFrame
69    {
70        if self.n_frames <= 0 {
71            panic!("Virtual stack underflow");
72        }
73        &self.frames[self.n_frames - 1]
74    }
75    /// Get &mut CallFrame
76    pub fn top_mut(&mut self) -> &mut CallFrame
77    {
78        if self.n_frames <= 0 {
79            panic!("Virtual stack underflow");
80        }
81        &mut self.frames[self.n_frames - 1]
82    }
83}
84
85///Fiber
86/// Should be used in future
87///
88/// Fiber must need to store upvalues and have a object pool
89#[derive(Clone, Debug)]
90pub struct Fiber
91{
92    pub frames: Vec<CallFrame>,
93}
94
95impl CallFrame
96{
97    pub fn new() -> CallFrame
98    {
99        let mut vec = Vec::with_capacity(256);
100        for _ in 0..256 {
101            vec.push(Value::Null);
102        }
103
104        CallFrame {
105            ip: 0,
106
107            code: vec![],
108            stack: vec,
109            arg_stack: vec![],
110        }
111    }
112
113    pub fn get(&self, r: usize) -> Value
114    {
115        self.stack[r]
116    }
117
118    pub fn set(&mut self, r: usize, v: Value)
119    {
120        self.stack[r] = v;
121    }
122
123    pub fn init_with_args(&mut self, args: &[Value])
124    {
125        for arg in args {
126            self.arg_stack.push(*arg);
127        }
128    }
129
130    pub fn reset(&mut self)
131    {
132        for i in 0..self.stack.len() {
133            self.stack[i] = Value::Null;
134        }
135        self.arg_stack.clear();
136        self.code.clear();
137    }
138
139    pub fn jit_run(&mut self) -> Value
140    {
141        Value::Null
142    }
143}