⭐ loading upvalue metadata
parent
b639d02027
commit
05b1d6e1f7
|
@ -251,19 +251,25 @@ pub fn parse_block <R: Read> (rdr: &mut R, blocks: &mut Vec <Block>)
|
||||||
}
|
}
|
||||||
|
|
||||||
let upvalue_count = parse_int (rdr).unwrap () as usize;
|
let upvalue_count = parse_int (rdr).unwrap () as usize;
|
||||||
|
let mut upvalues = Vec::with_capacity (upvalue_count);
|
||||||
for _ in 0..upvalue_count {
|
for _ in 0..upvalue_count {
|
||||||
// Just ignore these
|
let in_stack = parse_byte (rdr).unwrap () == 1;
|
||||||
|
let idx = parse_byte (rdr).unwrap ();
|
||||||
|
let kind = parse_byte (rdr).unwrap ();
|
||||||
|
|
||||||
for _ in 0..3 {
|
let upvalue = crate::state::Upvalue {
|
||||||
parse_byte (rdr).unwrap ();
|
in_stack,
|
||||||
}
|
idx,
|
||||||
|
kind,
|
||||||
|
};
|
||||||
|
|
||||||
|
upvalues.push (upvalue);
|
||||||
}
|
}
|
||||||
|
|
||||||
blocks.push (Block {
|
blocks.push (Block {
|
||||||
constants,
|
constants,
|
||||||
instructions,
|
instructions,
|
||||||
upvalue_count,
|
upvalues,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Recursion
|
// Recursion
|
||||||
|
|
20
src/state.rs
20
src/state.rs
|
@ -8,11 +8,18 @@ use crate::{
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[derive (Debug)]
|
||||||
|
pub struct Upvalue {
|
||||||
|
pub in_stack: bool,
|
||||||
|
pub idx: u8,
|
||||||
|
pub kind: u8,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive (Debug)]
|
#[derive (Debug)]
|
||||||
pub struct Block {
|
pub struct Block {
|
||||||
pub instructions: Vec <Instruction>,
|
pub instructions: Vec <Instruction>,
|
||||||
pub constants: Vec <Value>,
|
pub constants: Vec <Value>,
|
||||||
pub upvalue_count: usize,
|
pub upvalues: Vec <Upvalue>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive (Debug)]
|
#[derive (Debug)]
|
||||||
|
@ -345,7 +352,14 @@ impl State {
|
||||||
|
|
||||||
let b = usize::try_from (*b).unwrap ();
|
let b = usize::try_from (*b).unwrap ();
|
||||||
|
|
||||||
*self.reg_mut (*a) = upvalues [b].clone ();
|
let upvalue = match upvalues.get (b) {
|
||||||
|
Some (x) => x.clone (),
|
||||||
|
None => {
|
||||||
|
dbg! (chunk, &self);
|
||||||
|
panic! ("Missing upvalue");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
*self.reg_mut (*a) = upvalue;
|
||||||
},
|
},
|
||||||
Instruction::Jmp (s_j) => next_pc += s_j,
|
Instruction::Jmp (s_j) => next_pc += s_j,
|
||||||
Instruction::Len (a, b) => {
|
Instruction::Len (a, b) => {
|
||||||
|
@ -420,7 +434,7 @@ impl State {
|
||||||
_ => panic! ("Impossible"),
|
_ => panic! ("Impossible"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let upvalue_count = chunk.blocks [closure_idx].upvalue_count;
|
let upvalue_count = chunk.blocks [closure_idx].upvalues.len ();
|
||||||
|
|
||||||
let start_reg = a + popped_frame.register_offset - upvalue_count;
|
let start_reg = a + popped_frame.register_offset - upvalue_count;
|
||||||
|
|
||||||
|
|
14
src/tests.rs
14
src/tests.rs
|
@ -93,7 +93,7 @@ fn bools () {
|
||||||
"arg".into (),
|
"arg".into (),
|
||||||
"print".into (),
|
"print".into (),
|
||||||
],
|
],
|
||||||
upvalue_count: 1,
|
upvalues: vec! [],
|
||||||
},
|
},
|
||||||
Block {
|
Block {
|
||||||
instructions: vec! [
|
instructions: vec! [
|
||||||
|
@ -107,7 +107,7 @@ fn bools () {
|
||||||
Inst::Return0,
|
Inst::Return0,
|
||||||
],
|
],
|
||||||
constants: vec! [],
|
constants: vec! [],
|
||||||
upvalue_count: 0,
|
upvalues: vec! [],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
@ -164,7 +164,7 @@ fn floats () {
|
||||||
0.5.into (),
|
0.5.into (),
|
||||||
"print".into (),
|
"print".into (),
|
||||||
],
|
],
|
||||||
upvalue_count: 1,
|
upvalues: vec! [],
|
||||||
};
|
};
|
||||||
let chunk = Chunk {
|
let chunk = Chunk {
|
||||||
blocks: vec! [block],
|
blocks: vec! [block],
|
||||||
|
@ -187,8 +187,10 @@ fn floats () {
|
||||||
fn fma () {
|
fn fma () {
|
||||||
let bytecode = include_bytes! ("../test_vectors/fma.luac");
|
let bytecode = include_bytes! ("../test_vectors/fma.luac");
|
||||||
let mut rdr = std::io::Cursor::new (bytecode);
|
let mut rdr = std::io::Cursor::new (bytecode);
|
||||||
let file = crate::loader::parse_chunk (&mut rdr).unwrap ();
|
let chunk = crate::loader::parse_chunk (&mut rdr).unwrap ();
|
||||||
assert_eq! (file.blocks.len (), 4);
|
assert_eq! (chunk.blocks.len (), 4);
|
||||||
|
|
||||||
|
assert_eq! (chunk.blocks [3].upvalues.len (), 2);
|
||||||
|
|
||||||
for (arg, expected) in [
|
for (arg, expected) in [
|
||||||
(vec! ["_exe_name"], vec! [122.into ()]),
|
(vec! ["_exe_name"], vec! [122.into ()]),
|
||||||
|
@ -197,7 +199,7 @@ fn fma () {
|
||||||
let expected: Vec <Value> = expected;
|
let expected: Vec <Value> = expected;
|
||||||
let mut vm = State::default ();
|
let mut vm = State::default ();
|
||||||
let upvalues = State::upvalues_from_args (arg.into_iter ().map (|s| s.to_string ()));
|
let upvalues = State::upvalues_from_args (arg.into_iter ().map (|s| s.to_string ()));
|
||||||
let actual = vm.execute_chunk (&file, &upvalues);
|
let actual = vm.execute_chunk (&chunk, &upvalues);
|
||||||
|
|
||||||
assert_eq! (actual, expected);
|
assert_eq! (actual, expected);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
-- This one fails :( I haven't implemented closures properly yet.
|
-- This one fails :( I haven't implemented closures properly yet.
|
||||||
|
|
||||||
|
local ii = "bogus"
|
||||||
|
|
||||||
local function add (aa, bb)
|
local function add (aa, bb)
|
||||||
return aa + bb
|
return aa + bb
|
||||||
end
|
end
|
||||||
|
@ -12,6 +14,12 @@ local function fma (ee, ff, gg)
|
||||||
return add (mul (ee, ff), gg)
|
return add (mul (ee, ff), gg)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function run ()
|
||||||
local hh = fma (10, 11, 12)
|
local hh = fma (10, 11, 12)
|
||||||
print (hh)
|
print (hh)
|
||||||
|
end
|
||||||
|
|
||||||
|
run ()
|
||||||
|
print (ii)
|
||||||
|
|
||||||
return hh
|
return hh
|
||||||
|
|
Loading…
Reference in New Issue