🐛 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.main
parent
f29eaac1d0
commit
e87265373c
|
@ -70,8 +70,10 @@ pub fn parse_inst (buf: [u8; 4]) -> Option <Inst>
|
|||
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),
|
||||
|
|
65
src/state.rs
65
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 <Value>,
|
||||
}
|
||||
|
||||
#[derive (Clone, Debug, PartialEq)]
|
||||
pub enum Value {
|
||||
Nil,
|
||||
Boolean (bool),
|
||||
Float (f64),
|
||||
String (String),
|
||||
String (Rc <String>),
|
||||
|
||||
// These are all bogus, I haven't figured out how to implement
|
||||
// tables and function pointers yet
|
||||
|
||||
BogusArg (Vec <String>),
|
||||
BogusClosure {
|
||||
idx: usize,
|
||||
upvalues: Vec <Value>,
|
||||
},
|
||||
BogusEnv (BTreeMap <String, Value>),
|
||||
BogusArg (Rc <Vec <String>>),
|
||||
BogusClosure (Rc <BogusClosure>),
|
||||
BogusEnv (Rc <BTreeMap <String, Value>>),
|
||||
BogusPrint,
|
||||
}
|
||||
|
||||
|
@ -89,7 +95,7 @@ impl Default for Value {
|
|||
|
||||
impl From <String> 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 <I: Iterator <Item = String>> (args: I) -> Vec <Value>
|
||||
{
|
||||
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 {
|
||||
|
|
13
src/tests.rs
13
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::<Box <()>> () <= 8);
|
||||
assert! (size_of::<std::rc::Rc <()>> () <= 8);
|
||||
|
||||
pub enum Value {
|
||||
enum Value {
|
||||
Nil,
|
||||
Boolean (bool),
|
||||
Float (f64),
|
||||
String (Rc <String>),
|
||||
}
|
||||
|
||||
assert_eq! (size_of::<Value> (), 16);
|
||||
assert_eq! (size_of::<crate::state::Value> (), 16);
|
||||
let sz = size_of::<Value> ();
|
||||
let expected = 16;
|
||||
assert! (sz <= expected, "{sz} > {expected}");
|
||||
|
||||
let sz = size_of::<crate::state::Value> ();
|
||||
let expected = 16;
|
||||
assert! (sz <= expected, "{sz} > {expected}");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue