aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler.rs3
-rw-r--r--src/lib.rs29
-rw-r--r--src/vm.rs4
3 files changed, 28 insertions, 8 deletions
diff --git a/src/compiler.rs b/src/compiler.rs
index c0dacec..c70640d 100644
--- a/src/compiler.rs
+++ b/src/compiler.rs
@@ -923,8 +923,7 @@ impl Compiler {
};
add_op(self, block, Op::Link(slot));
if let Value::Function(_, block) = &self.constants[slot] {
- let needs_linking = block.borrow().upvalues.len() != 0;
- block.borrow_mut().constant = needs_linking;
+ block.borrow_mut().mark_constant();
} else {
unreachable!();
}
diff --git a/src/lib.rs b/src/lib.rs
index 1bdcc00..42a74a0 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -626,17 +626,23 @@ mod op {
}
#[derive(Debug)]
+enum BlockLinkState {
+ Linked,
+ Unlinked,
+ Nothing,
+}
+
+#[derive(Debug)]
pub struct Block {
pub ty: Type,
upvalues: Vec<(usize, bool, Type)>,
+ linking: BlockLinkState,
pub name: String,
pub file: PathBuf,
ops: Vec<Op>,
last_line_offset: usize,
line_offsets: HashMap<usize, usize>,
- linked: bool,
- constant: bool,
}
impl Block {
@@ -644,16 +650,31 @@ impl Block {
Self {
ty: Type::Void,
upvalues: Vec::new(),
+ linking: BlockLinkState::Nothing,
+
name: String::from(name),
file: file.to_owned(),
ops: Vec::new(),
last_line_offset: 0,
line_offsets: HashMap::new(),
- linked: false,
- constant: false,
}
}
+ fn mark_constant(&mut self) {
+ if self.upvalues.is_empty() {
+ return;
+ }
+ self.linking = BlockLinkState::Unlinked;
+ }
+
+ fn link(&mut self) {
+ self.linking = BlockLinkState::Linked;
+ }
+
+ fn needs_linking(&self) -> bool {
+ matches!(self.linking, BlockLinkState::Unlinked)
+ }
+
// Used to create empty functions.
fn stubbed_block(ty: &Type) -> Self {
let mut block = Block::new("/empty/", Path::new(""));
diff --git a/src/vm.rs b/src/vm.rs
index 20125be..5e7810d 100644
--- a/src/vm.rs
+++ b/src/vm.rs
@@ -557,7 +557,7 @@ impl VM {
Value::Function(_, block) => {
self.push(Value::Function(Vec::new(), block.clone()));
- if block.borrow().constant && !block.borrow().linked {
+ if block.borrow().needs_linking() {
error!(self,
ErrorKind::InvalidProgram,
format!("Calling function '{}' before all captured variables are declared.",
@@ -676,7 +676,7 @@ impl VM {
Op::Link(slot) => {
match self.constant(slot).clone() {
Value::Function(_, block) => {
- block.borrow_mut().linked = true;
+ block.borrow_mut().link();
}
value => {
error!(self,