Skip to content

Commit fc7c306

Browse files
committed
update: fix some bugs
Signed-off-by: yjhmelody <[email protected]>
1 parent f487873 commit fc7c306

File tree

5 files changed

+78
-47
lines changed

5 files changed

+78
-47
lines changed

src/binary/mod.rs

+15-8
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ pub mod chunk;
44
pub mod reader;
55
pub mod writer;
66

7+
78
/// decode Lua binary chunk to prototype structure
89
pub fn decode(data: Vec<u8>) -> Rc<chunk::Prototype> {
910
let mut r = reader::Reader::new(data);
@@ -12,11 +13,11 @@ pub fn decode(data: Vec<u8>) -> Rc<chunk::Prototype> {
1213
r.read_proto()
1314
}
1415

15-
pub fn encode(proto: Rc<chunk::Prototype>) -> Vec<u8> {
16+
pub fn encode(proto: Rc<chunk::Prototype>, src: Option<String>) -> Vec<u8> {
1617
let mut writer = writer::Writer::new();
1718
writer.write_header();
18-
writer.write_byte(4);
19-
writer.write_proto(proto);
19+
writer.write_byte(1);
20+
writer.write_proto(proto, src);
2021
writer.as_bytes()
2122
}
2223

@@ -46,12 +47,18 @@ mod tests {
4647

4748
#[test]
4849
fn test_encode() {
49-
let s = fs::read("D:/code/Rust/lua-rs/tests/luac.out").expect("error");
50-
let proto = encode(decode(s));
51-
// println!("{:#?}", proto);
50+
let chunk = fs::read("D:/code/Rust/lua-rs/tests/luac.out").expect("error");
51+
let proto = encode(decode(chunk.clone()), Some("@example.lua".to_string()));
52+
let proto = encode(decode(chunk.clone()), Some("@hello.lua".to_string()));
5253

53-
let s = unsafe { String::from_utf8_unchecked(proto) };
54+
let s = unsafe { String::from_utf8_unchecked(proto.clone()) };
5455
fs::write("D:/code/Rust/lua-rs/tests/test.out", s);
55-
assert_eq!(2, 0);
56+
let mut i = 0;
57+
for (a, b) in chunk.iter().zip(proto.iter()) {
58+
println!("{}", i);
59+
assert_eq!(*a, *b);
60+
i += 1;
61+
}
62+
assert_eq!(chunk[33..], proto[33..]);
5663
}
5764
}

src/binary/reader.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,12 @@ impl Reader {
6464

6565
fn read_string0(&mut self) -> Option<String> {
6666
let mut size = self.read_byte() as usize;
67+
dbg!(&size);
6768
if size == 0 {
6869
return None;
6970
}
7071
if size == 0xFF {
71-
size = self.read_u64() as usize; // size_t
72+
size = self.read_u32() as usize; // size_t
7273
}
7374
let bytes = self.read_bytes(size - 1);
7475
let string = String::from_utf8(bytes);
@@ -88,6 +89,7 @@ impl Reader {
8889
}
8990

9091
pub fn check_header(&mut self) {
92+
// 17 + 16 = 33
9193
assert_eq!(self.read_bytes(4), LUA_SIGNATURE, "not a precompiled chunk!");
9294
assert_eq!(self.read_byte(), LUAC_VERSION, "version mismatch!");
9395
assert_eq!(self.read_byte(), LUAC_FORMAT, "format mismatch!");

src/binary/writer.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,10 @@ impl Writer {
6868

6969
fn write_string0(&mut self, s: &String) -> Option<()> {
7070
if s.len() == 0 {
71+
self.write_byte(0);
7172
None
7273
} else if s.len() < 0xFF {
73-
self.write_byte(s.len() as u8 - 1);
74+
self.write_byte(s.len() as u8 + 1);
7475
self.write_bytes(s.as_bytes().to_vec());
7576
Some(())
7677
} else {
@@ -93,8 +94,9 @@ impl Writer {
9394
self.write_lua_number(LUAC_NUM);
9495
}
9596

96-
pub fn write_proto(&mut self, proto: Rc<Prototype>) {
97-
self.write_string0(&proto.source.clone().unwrap());
97+
pub fn write_proto(&mut self, proto: Rc<Prototype>, parent_source: Option<String>) {
98+
self.write_string0(&parent_source.clone().unwrap_or_default());
99+
98100
self.write_u32(proto.line_defined);
99101
self.write_u32(proto.last_line_defined);
100102
self.write_byte(proto.num_params);
@@ -118,7 +120,7 @@ impl Writer {
118120

119121
self.write_u32(proto.prototypes.len() as u32);
120122
for prototype in proto.prototypes.iter() {
121-
self.write_proto(prototype.clone());
123+
self.write_proto(prototype.clone(), None);
122124
}
123125

124126
self.write_u32(proto.line_info.len() as u32);

src/compiler/codegen2.rs

+51-32
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,12 @@ pub fn gen_prototype(block: Box<Block>) -> Result<Rc<Prototype>> {
6060
let last_line = block.last_line;
6161
let fn_def = FnDef::new(ParList::default(), block, 0, last_line);
6262
let mut fn_info = FnInfo::new(None, ParList::default(), 0, last_line);
63-
fn_info.add_local_var("_ENV".to_string(), 0)?;
63+
// fn_info.add_local_var("_ENV".to_string(), 0)?;
64+
fn_info.up_values.insert(
65+
"_ENV".to_string(),
66+
UpValueInfo::new(Some(0), Some(0), 0),
67+
);
68+
6469
fn_info.codegen_fn_def_exp(&fn_def, 0)?;
6570

6671
Ok(fn_info.to_prototype())
@@ -192,7 +197,7 @@ impl FnInfo {
192197
used_regs: 0,
193198
max_regs: 0,
194199
scope_level: 0,
195-
local_vars: Vec::new(),
200+
local_vars: vec![HashMap::new()],
196201
breaks: Vec::new(),
197202
// parent_index,
198203
// current_index,
@@ -208,17 +213,6 @@ impl FnInfo {
208213
}
209214
}
210215

211-
fn find_fn_info_by_index(mut fn_info: Rc<RefCell<FnInfo>>, index: usize) -> Option<Rc<RefCell<FnInfo>>> {
212-
unimplemented!();
213-
// if fn_info.borrow_mut().current_index == index {
214-
// Some(fn_info)
215-
// } else {
216-
// for sub_fn in fn_info.borrow_mut().sub_fns.iter() {
217-
// return Self::find_fn_info_by_index(sub_fn.0.clone(), index);
218-
// }
219-
// None
220-
// }
221-
}
222216

223217
fn constant_index(&mut self, k: &Constant) -> usize {
224218
match self.constants.get(k) {
@@ -335,10 +329,10 @@ impl FnInfo {
335329
}));
336330
let slot = new_var.borrow_mut().slot;
337331
if self.local_vars.len() <= self.scope_level {
338-
self.local_vars.resize(self.local_vars.len() + 2, HashMap::new());
332+
self.local_vars.resize(self.local_vars.len() * 2, HashMap::new());
339333
}
340-
self.local_vars[self.scope_level].insert(name, new_var);
341334

335+
self.local_vars[self.scope_level].insert(name, new_var);
342336
Ok(slot)
343337
}
344338

@@ -455,6 +449,7 @@ impl FnInfo {
455449
})
456450
}
457451
}
452+
458453
res
459454
}
460455

@@ -744,7 +739,7 @@ impl FnInfo {
744739
// clear sBx Op
745740
ins = ins << 18 >> 18;
746741
// reset sBx op
747-
ins = ins | (sBx as u32 + MAXARG_SBX as u32) << 14;
742+
ins = ins | ((sBx + MAXARG_SBX) as u32) << 14;
748743
self.instructions[pc] = ins;
749744
}
750745
}
@@ -984,9 +979,6 @@ impl FnInfo {
984979
self.exit_scope()
985980
}
986981

987-
fn remove_tail_nils(exps: &Vec<Exp>) -> Result<Vec<Exp>> {
988-
unimplemented!()
989-
}
990982

991983
fn codegen_assign_stat(&mut self, names: &Vec<Exp>, vals: &Vec<Exp>, line: Line) -> Result<()> {
992984
let old_regs = self.used_regs;
@@ -1065,7 +1057,6 @@ impl FnInfo {
10651057
self.emit_set_table(last_line, a as isize, k_regs[i], v_regs[i]);
10661058
}
10671059
} else {
1068-
dbg!();
10691060
let a = self.up_value_index(&"_ENV".to_string())
10701061
.ok_or(Error::NotUpValue {
10711062
line: last_line,
@@ -1125,14 +1116,13 @@ impl FnInfo {
11251116
let a = self.alloc_registers(n)?;
11261117
self.emit_load_nil(last_line, a as isize, n as isize);
11271118
}
1119+
}
11281120

1129-
self.used_regs = old_regs;
1130-
let start_pc = self.pc() + 1;
1131-
for name in names {
1132-
self.add_local_var(name.clone(), start_pc)?;
1133-
}
1121+
self.used_regs = old_regs;
1122+
let start_pc = self.pc() + 1;
1123+
for name in names {
1124+
self.add_local_var(name.clone(), start_pc)?;
11341125
}
1135-
dbg!();
11361126

11371127
Ok(())
11381128
}
@@ -1172,12 +1162,11 @@ impl FnInfo {
11721162
let a = self.alloc_registers(n)?;
11731163
self.emit_load_nil(last_line, a as isize, n as isize);
11741164
}
1175-
1176-
self.used_regs = old_regs;
1177-
let start_pc = self.pc() + 1;
1178-
for name in names {
1179-
self.add_local_var(name.clone(), start_pc)?;
1180-
}
1165+
}
1166+
self.used_regs = old_regs;
1167+
let start_pc = self.pc() + 1;
1168+
for name in names {
1169+
self.add_local_var(name.clone(), start_pc)?;
11811170
}
11821171

11831172
Ok(())
@@ -1449,6 +1438,9 @@ fn is_vararg_or_fn_call(exp: &Exp) -> bool {
14491438

14501439

14511440
mod tests {
1441+
use std::fs;
1442+
1443+
use crate::binary::encode;
14521444
use crate::compiler::lexer::*;
14531445
use crate::compiler::parser::*;
14541446

@@ -1507,4 +1499,31 @@ mod tests {
15071499
let proto = gen_prototype(Box::new(block));
15081500
println!("{:#?}", proto);
15091501
}
1502+
1503+
#[test]
1504+
fn test_codegen2() {
1505+
let s = r##"
1506+
local g = {
1507+
a = 1,
1508+
b = {}
1509+
}
1510+
1511+
print(g.a)
1512+
print(g.b)
1513+
1514+
local a = 1
1515+
while a < 1 do
1516+
a = a + 1
1517+
end
1518+
print(a)
1519+
"##.to_string();
1520+
1521+
let mut lexer = Lexer::from_iter(s.into_bytes(), "test".to_string());
1522+
let block = parse_block(&mut lexer).expect("parse error");
1523+
let proto = gen_prototype(Box::new(block));
1524+
1525+
let bytes = encode(proto.unwrap(), Some("@hello2.lua".to_string()));
1526+
fs::write("D:/code/Rust/lua-rs/tests/test.out", bytes);
1527+
assert_eq!(1, 2);
1528+
}
15101529
}

src/compiler/parser.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,7 @@ fn _parse_var_list(lexer: &mut impl Lex, var0: Exp) -> Result<Vec<Exp>> {
358358
fn _parse_name_list(lexer: &mut impl Lex, name0: String) -> Result<Vec<String>> {
359359
let mut name_list = vec![name0];
360360
while let Ok(Token::SepComma) = lexer.look_ahead() {
361+
lexer.skip_next_token();
361362
let name = lexer.next_ident()?;
362363
name_list.push(name);
363364
}
@@ -628,6 +629,7 @@ fn parse_table_constructor_exp(lexer: &mut impl Lex) -> Result<Exp> {
628629
if !lexer.check_next_token(Token::SepLcurly) {
629630
return Err(Error::IllegalExpression { line: lexer.current_line() });
630631
}
632+
let line = lexer.current_line();
631633
// [fieldlist]
632634
let fields = _parse_field_list(lexer)?;
633635

@@ -636,8 +638,7 @@ fn parse_table_constructor_exp(lexer: &mut impl Lex) -> Result<Exp> {
636638
return Err(Error::IllegalExpression { line: lexer.current_line() });
637639
}
638640

639-
let last_line = lexer.current_line();
640-
Ok(Exp::TableConstructor(fields, last_line))
641+
Ok(Exp::TableConstructor(fields, line))
641642
}
642643

643644
fn parse_fn_def_exp(lexer: &mut impl Lex) -> Result<Exp> {

0 commit comments

Comments
 (0)