Skip to content

Commit

Permalink
test: add more test case
Browse files Browse the repository at this point in the history
  • Loading branch information
sbwtw committed May 25, 2024
1 parent 196d275 commit 91309c1
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 87 deletions.
35 changes: 17 additions & 18 deletions lib/src/backend/lua/bytecode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use std::hash::{Hash, Hasher};

use crate::parser::StString;

use super::register::{Register, RK};
use super::{ConstantIndex, LuaType, LuaVarKind, UpValueIndex};
use super::register::{Reg, RK};
use super::{ConstIdx, LuaType, LuaVarKind};

macro_rules! excess_k {
($v: expr, $k: expr) => {
Expand Down Expand Up @@ -204,34 +204,34 @@ impl Display for LuaConstants {
#[derive(Debug)]
pub enum LuaByteCode {
/// A B: R[A] := R[B]
Move(Register, Register),
Move(Reg, Reg),
/// A sBx: R[A] := sBx
LoadI(Register, i32),
LoadI(Reg, i32),
/// A B: R[A] := K[Bx]
LoadK(Register, ConstantIndex),
LoadK(Reg, ConstIdx),

/// A B C: R[A] := UpValue[B][K[C]:string]
GetTabUp(Register, u8, ConstantIndex),
GetTabUp(Reg, u8, ConstIdx),
/// A B C: UpValue[A][K[B]:string] := RK(C)
SetTabUp(Register, UpValueIndex, RK),
SetTabUp(Reg, u8, RK),

/// A B C: R[A] := R[B] + R[C]
Add(Register, Register, Register),
Add(Reg, Reg, Reg),

/// A B k: if ((R[A] == R[B]) ~= k) then pc++
Eq(Register, Register, u8),
Eq(Reg, Reg, u8),

/// A sB k: if ((R[A] > sB) ~= k) then pc++
Gti(Register, u8, u8),
Gti(Reg, u8, u8),
/// A sB k: if ((R[A] >= sB) ~= k) then pc++
Gei(Register, u8, u8),
Gei(Reg, u8, u8),

/// A B C: return R[A], ... ,R[A+B-2]
Return(u8, u8, u8),

/// Call k, v: k is callee symbol position, v is argument count, return value not included
/// A B C: R[A], ... ,R[A+C-2] := R[A](R[A+1], ... ,R[A+B-1])
Call(Register, u8, u8),
Call(Reg, u8, u8),

/// A (adjust vararg parameters)
VarArgPrep(u8),
Expand Down Expand Up @@ -291,7 +291,7 @@ impl LuaByteCode {
// A B RK
LuaByteCode::SetTabUp(a, upv, rk) => {
let c = match rk {
RK::R(Register::RealRegister(r)) => r as u32,
RK::R(Reg::R(r)) => r as u32,
RK::K(k) => (k as u32) << 17 | 1u32 << 8,
_ => unreachable!(),
};
Expand Down Expand Up @@ -396,8 +396,7 @@ impl LuaCompiledCode {
write!(s, " ; K[{}] = {}", bx, self.constants[*bx as usize]).unwrap();
}
LuaByteCode::GetTabUp(a, b, k) => {
let (name, _upv) = self.upvalues.get_index(*k as usize).unwrap();
write!(s, " ; _ENV \"{}\"", name).unwrap()
write!(s, " ; _ENV \"{}\"", self.constants[*k as usize]).unwrap()
}
LuaByteCode::Call(a, b, c) => {
if *b == 0 {
Expand Down Expand Up @@ -453,14 +452,14 @@ impl Display for LuaCompiledCode {
#[cfg(test)]
mod test {
use super::LuaByteCode;
use super::Register;
use super::Reg;

#[test]
fn test_encoding() {
let code = LuaByteCode::LoadI(Register::from_raw(0), 2);
let code = LuaByteCode::LoadI(Reg::from_raw(0), 2);
assert_eq!(code.encode(), 0x80008001);

let code = LuaByteCode::LoadI(Register::from_raw(3), -65535);
let code = LuaByteCode::LoadI(Reg::from_raw(3), -65535);
assert_eq!(code.encode(), 0x00000181);

let code = LuaByteCode::Return(0, 1, 1);
Expand Down
79 changes: 32 additions & 47 deletions lib/src/backend/lua/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,9 @@ use log::*;
use smallvec::{smallvec, SmallVec};
use std::mem;
use std::rc::Rc;
use crate::backend::lua::register::Register::RealRegister;
use crate::backend::lua::register::Reg::R;

type ConstantIndex = u8;
type UpValueIndex = u8;
type ConstIdx = u8;

bitflags! {
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
Expand Down Expand Up @@ -62,7 +61,7 @@ bitflags! {
enum LuaAccessMode {
None,
Call(usize),
ReadUpValue,
ReadSymbol,
WriteRegister,
// Read value into register or literal
LoadNewRegister,
Expand All @@ -76,9 +75,8 @@ enum LuaAccessMode {
#[derive(Clone)]
pub struct LuaBackendStates {
variable: Option<Rc<Variable>>,
registers: SmallVec8<Register>,
constant_index: Option<ConstantIndex>,
upvalue: Option<(u8, LuaUpValue)>,
registers: SmallVec8<Reg>,
const_idx: Option<ConstIdx>,
scope: Option<Scope>,
error: bool,
access_mode: LuaAccessMode,
Expand All @@ -91,9 +89,8 @@ impl Default for LuaBackendStates {
registers: smallvec![],
scope: None,
error: false,
upvalue: None,
access_mode: LuaAccessMode::None,
constant_index: None,
const_idx: None,
}
}
}
Expand All @@ -114,21 +111,21 @@ pub struct LuaBackend {

impl LuaBackend {
#[inline]
fn code_gettabup(&mut self, dst: Register, k: ConstantIndex) {
fn code_gettabup(&mut self, dst: Reg, k: ConstIdx) {
self.push_code(LuaByteCode::GetTabUp(dst, 0, k));
}

#[inline]
fn code_settabup(&mut self, up_idx: u8, rk: RK) {
self.push_code(LuaByteCode::SetTabUp(RealRegister(0), up_idx, rk));
self.push_code(LuaByteCode::SetTabUp(R(0), up_idx, rk));
}

#[inline]
fn code_move(&mut self, from: Register, to: Register) {
fn code_move(&mut self, from: Reg, to: Reg) {
self.push_code(LuaByteCode::Move(to, from))
}

fn code_load(&mut self, r: Register, v: &LiteralValue) {
fn code_load(&mut self, r: Reg, v: &LiteralValue) {
// if literal can use LoadI instructions
if let Some(v) = try_fit_sbx(v) {
self.push_code(LuaByteCode::LoadI(r, v));
Expand All @@ -140,28 +137,18 @@ impl LuaBackend {
}

#[inline]
fn code_load_constant(&mut self, r: Register, k: ConstantIndex) {
fn code_load_constant(&mut self, r: Reg, k: ConstIdx) {
self.push_code(LuaByteCode::LoadK(r, k))
}

#[inline]
fn push_code(&mut self, code: LuaByteCode) {
debug!("LuaBackend: Push Code {:?}", code);
trace!("Code-Lua: {:?}", code);
self.byte_codes.push(code)
}

fn lookup_symbol(&mut self, sym: &StString) -> Option<(u8, LuaUpValue)> {
if !self.upvalue_table.contains_key(sym) {
let constant = self.add_constant(&LiteralValue::String(sym.origin_string().clone()));
self.upvalue_table.insert_full(sym.clone(), LuaUpValue { stack: 0, index: constant, kind: LuaVarKind::RDKCONST });
}

let (idx, _key, val) = self.upvalue_table.get_full(sym).unwrap();
Some((idx as u8, *val))
}

#[inline]
fn add_constant(&mut self, v: &LiteralValue) -> ConstantIndex {
fn add_constant(&mut self, v: &LiteralValue) -> ConstIdx {
match v {
LiteralValue::String(s) => self.add_string_constant(s),
LiteralValue::DInt(i) => self.add_integer_constant(*i as i64),
Expand Down Expand Up @@ -224,24 +211,24 @@ impl LuaBackend {
}

#[inline]
fn add_string_constant<S: AsRef<str>>(&mut self, s: S) -> ConstantIndex {
fn add_string_constant<S: AsRef<str>>(&mut self, s: S) -> ConstIdx {
let constant = LuaConstants::String(s.as_ref().to_owned());
let (idx, _inserted) = self.constants.insert_full(constant);
idx as ConstantIndex
idx as ConstIdx
}

#[inline]
fn add_integer_constant(&mut self, i: i64) -> ConstantIndex {
fn add_integer_constant(&mut self, i: i64) -> ConstIdx {
let constant = LuaConstants::Integer(i);
let (idx, _inserted) = self.constants.insert_full(constant);
idx as ConstantIndex
idx as ConstIdx
}

#[inline]
fn add_float_constant(&mut self, f: f64) -> ConstantIndex {
fn add_float_constant(&mut self, f: f64) -> ConstIdx {
let constant = LuaConstants::Float(f);
let (idx, _inserted) = self.constants.insert_full(constant);
idx as ConstantIndex
idx as ConstIdx
}
}

Expand Down Expand Up @@ -356,7 +343,7 @@ impl AstVisitorMut for LuaBackend {

self.code_load(r, literal.literal());
} else {
self.top_attribute().constant_index = Some(self.add_constant(literal.literal()))
self.top_attribute().const_idx = Some(self.add_constant(literal.literal()))
}
}

Expand All @@ -378,18 +365,16 @@ impl AstVisitorMut for LuaBackend {

let arg_regs = self.reg_mgr.alloc_hard_batch(arg_cnt);
self.top_attribute().registers = arg_regs.into();
self.top_attribute().upvalue = self.lookup_symbol(var_expr.name());
// self.top_attribute().constant_index =
// Some(self.add_string_constant(var_expr.org_name()));
self.top_attribute().const_idx = Some(self.add_string_constant(var_expr.org_name()));
}
// Read UpValue
LuaAccessMode::ReadUpValue => {
self.top_attribute().upvalue = self.lookup_symbol(var_expr.name());
// Read Symbol
LuaAccessMode::ReadSymbol => {
self.top_attribute().const_idx = Some(self.add_string_constant(var_expr.org_name()));
}
LuaAccessMode::WriteRegister => {
let dst = self.top_attribute().registers[0];
let upv = self.lookup_symbol(var_expr.name());
self.code_gettabup(dst, upv.unwrap().0);
let constant_index = self.add_string_constant(var_expr.org_name());
self.code_gettabup(dst, constant_index);
}
// Write register into stack
LuaAccessMode::Write => {}
Expand Down Expand Up @@ -429,8 +414,8 @@ impl AstVisitorMut for LuaBackend {
let arg_regs = callee_attr.registers;
let callee_reg = arg_regs[0];

// TODO:
self.push_code(LuaByteCode::GetTabUp(callee_reg, 0, callee_attr.upvalue.unwrap().0));
// Load Callee from constant table into callee_reg
self.push_code(LuaByteCode::GetTabUp(callee_reg, 0, callee_attr.const_idx.unwrap()));

// visit all arguments
for (idx, arg) in call.arguments_mut().iter_mut().enumerate() {
Expand Down Expand Up @@ -524,15 +509,15 @@ impl AstVisitorMut for LuaBackend {
let rhs = self.pop_attribute();

// Get lhs register
self.push_access_attribute(LuaAccessMode::ReadUpValue);
self.push_access_attribute(LuaAccessMode::ReadSymbol);
assign.left_mut().accept_mut(self);
let lhs_upv = self.pop_attribute().upvalue.unwrap();
let lhs_constant_index = self.pop_attribute().const_idx.unwrap();
// let lhs_reg = self.pop_attribute().registers[0];

if let Some(constant_index) = rhs.constant_index {
if let Some(constant_index) = rhs.const_idx {
assert_eq!(rhs.registers.len(), 0);
// self.code_load_constant(lhs_reg, constant_index)
self.code_settabup(lhs_upv.0, RK::K(constant_index));
self.code_settabup(lhs_constant_index, RK::K(constant_index));
} else {
assert_eq!(1, rhs.registers.len());
// assert_ne!(lhs_reg, rhs.registers[0]);
Expand Down
Loading

0 comments on commit 91309c1

Please sign in to comment.