From e87265373c70251df2c3a7d1c9c950d018437faf Mon Sep 17 00:00:00 2001 From: _ <_@_> Date: Tue, 26 Sep 2023 14:10:57 -0500 Subject: [PATCH] :bug: bug: shrank the Value size to 16 bytes This is a little pre-mature, since it's still in the "make it work" phase of "make it work, make it fast, make it pretty". But it was bugging me, and I'd have to ditch the raw strings and vecs some day to add a GC anyway. --- src/loader.rs | 2 ++ src/state.rs | 65 +++++++++++++++++++++++++++------------------------ src/tests.rs | 13 +++++++---- 3 files changed, 46 insertions(+), 34 deletions(-) diff --git a/src/loader.rs b/src/loader.rs index a761dd2..55d0cc0 100644 --- a/src/loader.rs +++ b/src/loader.rs @@ -70,8 +70,10 @@ pub fn parse_inst (buf: [u8; 4]) -> Option 0x22 => Inst::Add (a, b, c), 0x24 => Inst::Mul (a, b, c), 0x2e => Inst::MmBin (a, b, c), + 0x33 => Inst::Not (a, b), 0x3c => Inst::EqK (a, b, c), 0x38 => Inst::Jmp (s_j), + 0x42 => Inst::Test (a, k), 0x44 => Inst::Call (a, b, c), 0x45 => Inst::TailCall (a, b, c, k), 0x46 => Inst::Return (a, b, c, k), diff --git a/src/state.rs b/src/state.rs index b48e71a..2f9c713 100644 --- a/src/state.rs +++ b/src/state.rs @@ -1,4 +1,7 @@ -use std::collections::BTreeMap; +use std::{ + collections::BTreeMap, + rc::Rc, +}; #[derive (Debug, PartialEq)] pub enum Instruction { @@ -57,27 +60,30 @@ pub enum Instruction { TailCall (u8, u8, u8, bool), - Test (u8, i32), + Test (u8, bool), VarArgPrep (i32), } +#[derive (Clone, Debug, PartialEq)] +pub struct BogusClosure { + idx: usize, + upvalues: Vec , +} + #[derive (Clone, Debug, PartialEq)] pub enum Value { Nil, Boolean (bool), Float (f64), - String (String), + String (Rc ), // These are all bogus, I haven't figured out how to implement // tables and function pointers yet - BogusArg (Vec ), - BogusClosure { - idx: usize, - upvalues: Vec , - }, - BogusEnv (BTreeMap ), + BogusArg (Rc >), + BogusClosure (Rc ), + BogusEnv (Rc >), BogusPrint, } @@ -89,7 +95,7 @@ impl Default for Value { impl From for Value { fn from (x: String) -> Self { - Self::String (x) + Self::String (x.into ()) } } @@ -196,15 +202,15 @@ impl Default for State { impl State { pub fn upvalues_from_args > (args: I) -> Vec { - let arg = args.map (|s| s.to_string ()).collect (); + let arg: Vec <_> = args.map (|s| s.to_string ()).collect (); let env = BTreeMap::from_iter ([ - ("arg", Value::BogusArg (arg)), + ("arg", Value::BogusArg (arg.into ())), ("print", Value::BogusPrint), ].map (|(k, v)| (k.to_string (), v))); vec! [ - Value::BogusEnv (env), + Value::BogusEnv (env.into ()), ] } @@ -262,7 +268,7 @@ impl State { r [a] = (v_b + v_c).into (); }, - Instruction::Call (a, b, c) => { + Instruction::Call (a, _b, c) => { // Take arguments from registers [a + 1, a + b) // Call the function in register [a] // Return values in registers [a, a + c - 1) @@ -278,12 +284,11 @@ impl State { let v_a = r.get (a).unwrap (); match v_a { - Value::BogusClosure { - idx, - upvalues, - }=> { + Value::BogusClosure (rc) => { + let idx = rc.idx; + let block_idx = frame.block_idx; - let target_block = *idx; + let target_block = idx; let current_frame = self.stack.last ().unwrap (); @@ -310,7 +315,7 @@ impl State { assert_eq! (*c, 1); let value = r.get (a + 1).unwrap (); - let s = match value { + match value { Value::Nil => println! ("nil"), Value::Boolean (false) => println! ("false"), Value::Boolean (true) => println! ("true"), @@ -336,10 +341,10 @@ impl State { } let r = self.register_window_mut (); - r [a] = Value::BogusClosure { + r [a] = Value::BogusClosure (BogusClosure { idx: b + frame.block_idx + 1, upvalues: vec! [], - }; + }.into ()); }, Instruction::EqK (a, b, c_k) => { let a = usize::try_from (*a).unwrap (); @@ -365,7 +370,7 @@ impl State { }; let key = match k.get (c).unwrap () { - Value::String (s) => s, + Value::String (s) => s.as_ref (), _ => panic! ("GetTabUp only supports string keys"), }; @@ -393,7 +398,7 @@ impl State { Instruction::GetUpVal (a, b) => { let this_func = self.stack.last ().unwrap ().register_offset - 1; let upvalues = match &self.registers [this_func] { - Value::BogusClosure { idx, upvalues } => upvalues, + Value::BogusClosure (rc) => &rc.upvalues, _ => panic! ("Can't do GetUpVal outside a closure"), }; @@ -461,7 +466,7 @@ impl State { Instruction::Return (a, b, c, k) => { let a = usize::try_from (*a).unwrap (); let b = usize::try_from (*b).unwrap (); - let c = usize::try_from (*c).unwrap (); + let _c = usize::try_from (*c).unwrap (); let popped_frame = self.stack.pop ().unwrap (); @@ -469,20 +474,20 @@ impl State { if *k { let closure_idx = match &self.registers [popped_frame.register_offset + a] { - Value::BogusClosure { idx, upvalues } => idx, + Value::BogusClosure (rc) => rc.idx, _ => panic! ("Impossible"), }; - let upvalue_count = chunk.blocks [*closure_idx].upvalue_count; + let upvalue_count = chunk.blocks [closure_idx].upvalue_count; let start_reg = a + popped_frame.register_offset - upvalue_count; let upvalues = self.registers [start_reg..start_reg+upvalue_count].iter ().cloned ().collect (); - self.registers [a + popped_frame.register_offset] = Value::BogusClosure { - idx: *closure_idx, + self.registers [a + popped_frame.register_offset] = Value::BogusClosure (BogusClosure { + idx: closure_idx, upvalues, - }; + }.into ()); } if self.debug_print { diff --git a/src/tests.rs b/src/tests.rs index 9be3e9b..db2a4ca 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -56,7 +56,7 @@ fn bools () { }, Block { instructions: vec! [ - Inst::Test (0, 0), + Inst::Test (0, false), Inst::Jmp (3), Inst::LoadI (1, 99), Inst::Return1 (1), @@ -211,13 +211,18 @@ fn value_size () { assert! (size_of::> () <= 8); assert! (size_of::> () <= 8); - pub enum Value { + enum Value { Nil, Boolean (bool), Float (f64), String (Rc ), } - assert_eq! (size_of:: (), 16); - assert_eq! (size_of:: (), 16); + let sz = size_of:: (); + let expected = 16; + assert! (sz <= expected, "{sz} > {expected}"); + + let sz = size_of:: (); + let expected = 16; + assert! (sz <= expected, "{sz} > {expected}"); }