aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/vm.rs20
1 files changed, 13 insertions, 7 deletions
diff --git a/src/vm.rs b/src/vm.rs
index bfb5ce4..59e5585 100644
--- a/src/vm.rs
+++ b/src/vm.rs
@@ -1,7 +1,6 @@
use std::cell::RefCell;
use std::collections::hash_map::Entry;
use std::collections::HashMap;
-use std::fmt::Debug;
use std::rc::Rc;
use owo_colors::OwoColorize;
@@ -49,6 +48,7 @@ struct Frame {
stack_offset: usize,
block: Rc<RefCell<Block>>,
ip: usize,
+ has_upvalue: bool,
}
pub struct VM {
@@ -239,6 +239,7 @@ impl VM {
Value::Function(_, block) => {
let mut ups = Vec::new();
for (slot, is_up, _) in block.borrow().upvalues.iter() {
+ self.frame_mut().has_upvalue = true;
let up = if *is_up {
if let Value::Function(local_ups, _) = &self.stack[offset] {
Rc::clone(&local_ups[*slot])
@@ -445,6 +446,7 @@ impl VM {
stack_offset: new_base,
block: Rc::clone(&block),
ip: 0,
+ has_upvalue: false,
});
return Ok(OpResult::Continue);
}
@@ -473,10 +475,12 @@ impl VM {
return Ok(OpResult::Done);
} else {
self.stack[last.stack_offset] = self.pop();
- for slot in last.stack_offset+1..self.stack.len() {
- if self.upvalues.contains_key(&slot) {
- let value = self.stack[slot].clone();
- self.drop_upvalue(slot, value);
+ if last.has_upvalue {
+ for slot in last.stack_offset+1..self.stack.len() {
+ if self.upvalues.contains_key(&slot) {
+ let value = self.stack[slot].clone();
+ self.drop_upvalue(slot, value);
+ }
}
}
self.stack.truncate(last.stack_offset + 1);
@@ -520,7 +524,8 @@ impl VM {
self.frames.push(Frame {
stack_offset: 0,
block,
- ip: 0
+ ip: 0,
+ has_upvalue: false,
});
}
@@ -769,7 +774,8 @@ impl VM {
self.frames.push(Frame {
stack_offset: 0,
block,
- ip: 0
+ ip: 0,
+ has_upvalue: false,
});
if self.print_blocks {