Skip to content

Commit 367d9c1

Browse files
committed
feat: use rust stack for function calls
1 parent 98b5ff1 commit 367d9c1

File tree

3 files changed

+40
-85
lines changed

3 files changed

+40
-85
lines changed

Diff for: Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ codegen-units = 1
1313
panic = "abort"
1414
opt-level = 3
1515
overflow-checks = false
16-
# debug = 1
16+
debug = 1
1717

1818
[profile.dev]
1919
opt-level = 0

Diff for: src/bin/wind.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,13 @@ fn main() -> Result<(), Box<dyn Error>> {
3939

4040
let mut compiler = Compiler::new();
4141
let opcode = value_or_exit(compiler.compile_stmts(ast));
42-
// for op in &opcode {
43-
// println!("{}", op);
44-
// }
45-
// println!("========================");
42+
for op in &opcode {
43+
println!("{}", op);
44+
}
45+
println!("========================");
4646

47-
let mut vm = VM::new(opcode);
48-
value_or_exit(vm.interpret());
47+
let mut vm = VM::new();
48+
value_or_exit(vm.interpret(opcode));
4949
}
5050
}
5151

Diff for: src/vm/mod.rs

+33-78
Original file line numberDiff line numberDiff line change
@@ -98,35 +98,16 @@ impl EnvironmentStack {
9898
}
9999
}
100100

101-
pub struct Frame {
102-
instructions: Vec<Opcode>,
103-
ip: i32,
104-
num_of_blocks: i32,
105-
}
106-
107-
impl Frame {
108-
#[inline(always)]
109-
fn new(instructions: Vec<Opcode>) -> Frame {
110-
Frame {
111-
instructions,
112-
ip: 0,
113-
num_of_blocks: 0,
114-
}
115-
}
116-
}
117-
118101
pub struct VM {
119102
pub stack: Vec<Value>,
120103
env_stack: EnvironmentStack,
121-
frames: Vec<Frame>,
122104
}
123105

124106
impl VM {
125-
pub fn new(instructions: Vec<Opcode>) -> VM {
107+
pub fn new() -> VM {
126108
Self {
127109
stack: vec![],
128110
env_stack: EnvironmentStack::new(),
129-
frames: vec![Frame::new(instructions)],
130111
}
131112
}
132113

@@ -154,13 +135,11 @@ impl VM {
154135

155136
#[inline(always)]
156137
fn begin_environment(&mut self, var_count: usize) {
157-
self.current_frame_mut().num_of_blocks += 1;
158138
self.env_stack.begin_environment(var_count)
159139
}
160140

161141
#[inline(always)]
162142
fn end_environment(&mut self) {
163-
self.current_frame_mut().num_of_blocks -= 1;
164143
self.env_stack.end_environment()
165144
}
166145

@@ -174,38 +153,13 @@ impl VM {
174153
self.env_stack.set(scope_index, index, value)
175154
}
176155

177-
#[inline(always)]
178-
fn current_frame(&self) -> &Frame {
179-
unsafe { self.frames.get_unchecked(self.frames.len() - 1) }
180-
}
181-
182-
#[inline(always)]
183-
fn current_frame_mut(&mut self) -> &mut Frame {
184-
self.frames.last_mut().unwrap()
185-
}
186-
187-
#[inline(always)]
188-
fn current_frame_instruction(&self) -> Opcode {
189-
let curr_frame = self.current_frame();
190-
191-
curr_frame.instructions[curr_frame.ip as usize].clone()
192-
}
193-
194-
#[inline(always)]
195-
fn push_frame(&mut self, instructions: Vec<Opcode>) {
196-
self.frames.push(Frame::new(instructions));
197-
}
198-
199-
#[inline(always)]
200-
fn pop_frame(&mut self) {
201-
self.frames.pop();
202-
}
203-
204-
pub fn interpret(&mut self) -> Result<(), RuntimeError> {
205-
while self.current_frame().ip < self.current_frame().instructions.len() as i32 {
206-
let instruction = self.current_frame_instruction();
156+
pub fn interpret(&mut self, instructions: Vec<Opcode>) -> Result<Value, RuntimeError> {
157+
let mut ip = 0;
158+
let mut num_of_blocks = 0;
159+
while ip < instructions.len() as i32 {
160+
let instruction = instructions.get(ip as usize).unwrap();
207161
match instruction {
208-
Opcode::Const(val) => self.push(val),
162+
Opcode::Const(val) => self.push(val.clone()),
209163
Opcode::Add => {
210164
let left = self.pop();
211165
let right = self.pop();
@@ -240,36 +194,38 @@ impl VM {
240194
self.push(Value::Bool(!is_equal(left, right)))
241195
}
242196
Opcode::Jmp(offset) => {
243-
self.current_frame_mut().ip += offset;
197+
ip += offset;
244198
continue;
245199
}
246200
Opcode::JmpFalse(offset) => {
247201
let operand = self.pop();
248202

249203
if !is_truthy(operand) {
250-
self.current_frame_mut().ip += offset;
204+
ip += offset;
251205
continue;
252206
}
253207
}
254208
Opcode::Pop => {
255209
self.pop();
256210
}
257211
Opcode::Block(var_count) => {
258-
self.begin_environment(var_count);
212+
num_of_blocks += 1;
213+
self.begin_environment(*var_count);
259214
}
260215
Opcode::EndBlock => {
216+
num_of_blocks -= 1;
261217
self.end_environment();
262218
}
263219
Opcode::Let(index) => {
264220
let value = self.pop();
265221

266-
self.define(index, value);
222+
self.define(*index, value);
267223
}
268224
Opcode::Get {
269225
scope_index: scope,
270226
index,
271227
} => {
272-
let val = self.get(scope, index);
228+
let val = self.get(*scope, *index);
273229

274230
self.push(val);
275231
}
@@ -279,12 +235,12 @@ impl VM {
279235
} => {
280236
let value = self.stack_top();
281237

282-
self.set(scope, index, value.clone());
238+
self.set(*scope, *index, value.clone());
283239
}
284240
Opcode::Array(size) => {
285241
let mut values = vec![];
286242

287-
for _ in 0..size {
243+
for _ in 0..(*size) {
288244
values.push(self.pop());
289245
}
290246

@@ -332,15 +288,15 @@ impl VM {
332288

333289
match operand {
334290
Value::Fn(instructions, param_count) => {
335-
if arg_count != param_count {
291+
if (*arg_count) != param_count {
336292
panic!()
337293
}
338294

339-
self.push_frame(instructions);
340-
continue;
295+
let value = self.interpret(instructions)?;
296+
self.push(value);
341297
}
342298
Value::BuiltInFn(f, param_count) => {
343-
if arg_count != param_count {
299+
if (*arg_count) != param_count {
344300
panic!()
345301
}
346302

@@ -357,35 +313,34 @@ impl VM {
357313
Opcode::Ret => {
358314
let operand = self.pop();
359315

360-
for _ in 0..self.current_frame().num_of_blocks {
316+
for _ in 0..num_of_blocks {
361317
self.end_environment();
362318
}
363319

364-
self.pop_frame();
365-
self.push(operand);
320+
return Ok(operand);
366321
}
367322
Opcode::FnStart(param_count) => {
368-
self.begin_environment(param_count);
323+
num_of_blocks += 1;
324+
self.begin_environment(*param_count);
369325

370-
for i in 0..param_count {
326+
for i in 0..(*param_count) {
371327
let arg = self.pop();
372328
self.define(i, arg);
373329
}
374330
}
375331
Opcode::FnEnd => {
332+
num_of_blocks -= 1;
376333
self.end_environment();
377-
self.pop_frame();
378-
self.push(Value::Nil);
379334
}
380335
Opcode::GetGlobal { index } => {
381-
let val = self.env_stack.stack[0][index].clone();
336+
let val = self.env_stack.stack[0][*index].clone();
382337

383338
self.push(val);
384339
}
385340
Opcode::SetGlobal { index } => {
386341
let value = self.stack_top();
387342

388-
self.env_stack.stack[0][index] = value.clone();
343+
self.env_stack.stack[0][*index] = value.clone();
389344
}
390345
Opcode::Index => {
391346
let value = self.pop();
@@ -402,7 +357,7 @@ impl VM {
402357
}
403358
}
404359
Opcode::Continue => {
405-
let mut current_instruction = self.current_frame_instruction();
360+
let mut current_instruction = instruction;
406361
let mut new_blocks = 0;
407362
while !matches!(current_instruction, Opcode::LoopUpdate) {
408363
// Sync env_stack
@@ -419,8 +374,8 @@ impl VM {
419374
}
420375
_ => {}
421376
}
422-
self.current_frame_mut().ip += 1;
423-
current_instruction = self.current_frame_instruction();
377+
ip += 1;
378+
current_instruction = instructions.get(ip as usize).unwrap();
424379
}
425380
}
426381
// Labels
@@ -429,10 +384,10 @@ impl VM {
429384
Opcode::LoopEnd => {}
430385
}
431386

432-
self.current_frame_mut().ip += 1;
387+
ip += 1;
433388
}
434389

435-
Ok(())
390+
Ok(Value::Nil)
436391
}
437392
}
438393

0 commit comments

Comments
 (0)