From 39989e555aabdfdbb6015d103cefcd515e7a98d5 Mon Sep 17 00:00:00 2001 From: liquidev Date: Mon, 2 Sep 2024 21:35:52 +0200 Subject: [PATCH] fix SetLocal not taking into account the stack bottom y'know, when you look for locals relative to the call frame's bottom, but then set locals relative to index 0... boom. closes #78 --- crates/haku/src/vm.rs | 3 ++- crates/haku/tests/language.rs | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/crates/haku/src/vm.rs b/crates/haku/src/vm.rs index 3bb96f9..70b9293 100644 --- a/crates/haku/src/vm.rs +++ b/crates/haku/src/vm.rs @@ -210,6 +210,7 @@ impl Vm { .checked_sub(1) .ok_or_else(|| self.create_exception("code ran for too long"))?; + #[allow(unused)] let pc2 = pc; let opcode = chunk.read_opcode(&mut pc)?; vmtrace!("{pc2:2} {opcode:?}"); @@ -245,7 +246,7 @@ impl Vm { Opcode::SetLocal => { let index = chunk.read_u8(&mut pc)? as usize; let new_value = self.pop()?; - *self.get_mut(index)? = new_value; + *self.get_mut(bottom + index)? = new_value; } Opcode::Capture => { diff --git a/crates/haku/tests/language.rs b/crates/haku/tests/language.rs index ba1501e..5b979bf 100644 --- a/crates/haku/tests/language.rs +++ b/crates/haku/tests/language.rs @@ -266,3 +266,18 @@ fn system_arithmetic() { expect_number("1 + 2 + 3 + 4", 10.0, 0.0001); expect_number("(2 * 1) + 1 + (6 / 2) + (10 - 3)", 13.0, 0.0001); } + +#[test] +fn issue_78() { + let code = r#" + f = \_ -> + let x = 1 + x + x + + [ + f () + f () + ] + "#; + assert_eq!(eval(code).unwrap(), Value::Ref(RefId::from_u32(2))) +}