diff options
| -rw-r--r-- | src/vm.rs | 20 |
1 files changed, 13 insertions, 7 deletions
@@ -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 { |
