Skip to content

Commit dd4a50c

Browse files
committed
pass test
1 parent 3dfec8d commit dd4a50c

File tree

25 files changed

+579
-343
lines changed

25 files changed

+579
-343
lines changed

crates/luars/src/compiler/expr.rs

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,19 @@ use emmylua_parser::{
2020
LuaNameExpr, LuaUnaryExpr, LuaVarExpr,
2121
};
2222

23+
//======================================================================================
24+
// Helper functions
25+
//======================================================================================
26+
27+
/// Check if an expression is a vararg (...) literal
28+
fn is_vararg_expr(expr: &LuaExpr) -> bool {
29+
if let LuaExpr::LiteralExpr(lit) = expr {
30+
matches!(lit.get_literal(), Some(LuaLiteralToken::Dots(_)))
31+
} else {
32+
false
33+
}
34+
}
35+
2336
//======================================================================================
2437
// NEW API: ExpDesc-based expression compilation (Lua 5.4 compatible)
2538
//======================================================================================
@@ -585,11 +598,14 @@ fn compile_binary_expr_desc(c: &mut Compiler, expr: &LuaBinaryExpr) -> Result<Ex
585598
let concat_base = c.freereg;
586599
alloc_register(c); // for left operand copy
587600
alloc_register(c); // for right operand
588-
601+
589602
emit_move(c, concat_base, left_reg);
590603
emit_move(c, concat_base + 1, right_reg);
591-
emit(c, Instruction::encode_abc(OpCode::Concat, concat_base, 1, 0));
592-
604+
emit(
605+
c,
606+
Instruction::encode_abc(OpCode::Concat, concat_base, 1, 0),
607+
);
608+
593609
result_reg = concat_base;
594610
// Reset freereg to result_reg + 1 (concat consumes right operand)
595611
c.freereg = result_reg + 1;
@@ -1676,10 +1692,10 @@ fn compile_binary_expr_to(
16761692
emit_move(c, concat_reg, left_reg);
16771693
emit_move(c, concat_reg + 1, right_reg);
16781694
emit(c, Instruction::encode_abc(OpCode::Concat, concat_reg, 1, 0));
1679-
1695+
16801696
// Reset freereg (concat consumes right operand)
16811697
c.freereg = concat_reg + 1;
1682-
1698+
16831699
if let Some(d) = dest {
16841700
if d != concat_reg {
16851701
emit_move(c, d, concat_reg);
@@ -2618,8 +2634,7 @@ fn compile_table_expr_to(
26182634
if field.is_value_field() {
26192635
// Check if it's a simple value (not ... or call as last element)
26202636
if let Some(value_expr) = field.get_value_expr() {
2621-
let is_dots = matches!(&value_expr, LuaExpr::LiteralExpr(lit)
2622-
if matches!(lit.get_literal(), Some(LuaLiteralToken::Dots(_))));
2637+
let is_dots = is_vararg_expr(&value_expr);
26232638
let is_call = matches!(&value_expr, LuaExpr::CallExpr(_));
26242639
let is_last = i == fields.len() - 1;
26252640

@@ -2684,8 +2699,7 @@ fn compile_table_expr_to(
26842699
if field.is_value_field() {
26852700
// Array element or special case (vararg/call at end)
26862701
if let Some(value_expr) = field.get_value_expr() {
2687-
let is_dots = matches!(&value_expr, LuaExpr::LiteralExpr(lit)
2688-
if matches!(lit.get_literal(), Some(LuaLiteralToken::Dots(_))));
2702+
let is_dots = is_vararg_expr(&value_expr);
26892703
let is_call = matches!(&value_expr, LuaExpr::CallExpr(_));
26902704

26912705
if is_last_field && is_dots {

crates/luars/src/compiler/helpers.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,13 @@ pub fn emit_set_global(c: &mut Compiler, name: &str, src_reg: u32) {
409409
// k=false means C is a register index (not constant)
410410
emit(
411411
c,
412-
Instruction::create_abck(OpCode::SetTabUp, env_index as u32, const_idx, src_reg, false),
412+
Instruction::create_abck(
413+
OpCode::SetTabUp,
414+
env_index as u32,
415+
const_idx,
416+
src_reg,
417+
false,
418+
),
413419
);
414420
}
415421

crates/luars/src/compiler/stmt.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,15 @@ use emmylua_parser::{
1717
LuaRepeatStat, LuaReturnStat, LuaStat, LuaVarExpr, LuaWhileStat,
1818
};
1919

20+
/// Check if an expression is a vararg (...) literal
21+
fn is_vararg_expr(expr: &LuaExpr) -> bool {
22+
if let LuaExpr::LiteralExpr(lit) = expr {
23+
matches!(lit.get_literal(), Some(LuaLiteralToken::Dots(_)))
24+
} else {
25+
false
26+
}
27+
}
28+
2029
/// Check if a block contains only a single unconditional jump statement (break/return only)
2130
/// Note: goto is NOT optimized by luac, so we don't include it here
2231
#[allow(dead_code)]
@@ -641,11 +650,7 @@ fn compile_return_stat(c: &mut Compiler, stat: &LuaReturnStat) -> Result<(), Str
641650

642651
// Check if last expression is varargs (...) or function call - these can return multiple values
643652
let last_is_multret = if let Some(last_expr) = exprs.last() {
644-
matches!(last_expr, LuaExpr::CallExpr(_))
645-
|| matches!(last_expr, LuaExpr::LiteralExpr(lit) if matches!(
646-
lit.get_literal(),
647-
Some(emmylua_parser::LuaLiteralToken::Dots(_))
648-
))
653+
matches!(last_expr, LuaExpr::CallExpr(_)) || is_vararg_expr(last_expr)
649654
} else {
650655
false
651656
};

crates/luars/src/gc/mod.rs

Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,11 @@
55
mod object_pool;
66

77
// Use ObjectPoolV2 as the main ObjectPool
8+
use crate::lua_value::LuaValue;
89
pub use object_pool::{
9-
ObjectPoolV2 as ObjectPool,
10-
StringId, TableId, FunctionId, UpvalueId, UserdataId, ThreadId,
11-
Arena, GcHeader, GcTable, GcFunction, GcUpvalue, GcString, GcThread, UpvalueState,
10+
Arena, FunctionId, GcFunction, GcHeader, GcString, GcTable, GcThread, GcUpvalue,
11+
ObjectPoolV2 as ObjectPool, StringId, TableId, ThreadId, UpvalueId, UpvalueState, UserdataId,
1212
};
13-
use crate::lua_value::LuaValue;
1413
use std::collections::{HashMap, HashSet};
1514

1615
/// GC Generation
@@ -269,11 +268,7 @@ impl GC {
269268

270269
/// Perform garbage collection (chooses minor or major)
271270
/// Takes root set (stack, globals, etc.) and marks reachable objects
272-
pub fn collect(
273-
&mut self,
274-
roots: &[LuaValue],
275-
object_pool: &mut ObjectPool,
276-
) -> usize {
271+
pub fn collect(&mut self, roots: &[LuaValue], object_pool: &mut ObjectPool) -> usize {
277272
// For public API, determine which to run based on state
278273
if self.minor_gc_count >= 10 {
279274
self.major_collect_internal(roots, object_pool)
@@ -514,16 +509,12 @@ impl GC {
514509
// Mark children
515510
match key.0 {
516511
GcObjectType::Table => {
517-
if let Some(table) =
518-
object_pool.get_table(TableId(key.1))
519-
{
512+
if let Some(table) = object_pool.get_table(TableId(key.1)) {
520513
self.mark_table(table, &mut worklist);
521514
}
522515
}
523516
GcObjectType::Function => {
524-
if let Some(func) =
525-
object_pool.get_function(FunctionId(key.1))
526-
{
517+
if let Some(func) = object_pool.get_function(FunctionId(key.1)) {
527518
self.mark_function(func, object_pool, &mut worklist);
528519
}
529520
}
@@ -545,7 +536,12 @@ impl GC {
545536
}
546537

547538
/// Mark function upvalues
548-
fn mark_function(&self, func: &GcFunction, object_pool: &ObjectPool, worklist: &mut Vec<LuaValue>) {
539+
fn mark_function(
540+
&self,
541+
func: &GcFunction,
542+
object_pool: &ObjectPool,
543+
worklist: &mut Vec<LuaValue>,
544+
) {
549545
for upval_id in &func.upvalues {
550546
// Only mark closed upvalues (open ones are on the stack already)
551547
if let Some(upval) = object_pool.get_upvalue(*upval_id) {
@@ -594,7 +590,7 @@ impl GC {
594590
}
595591
}
596592
}
597-
593+
598594
/// Check if a value is collectable (needs GC barrier)
599595
#[inline(always)]
600596
pub fn is_collectable(value: &LuaValue) -> bool {
@@ -696,11 +692,7 @@ impl GC {
696692

697693
/// Check if table has weak mode (__mode metamethod)
698694
/// Returns: None if no weak mode, Some("k") for weak keys, Some("v") for weak values, Some("kv") for both
699-
pub fn get_weak_mode(
700-
&self,
701-
table_id: TableId,
702-
object_pool: &ObjectPool,
703-
) -> Option<String> {
695+
pub fn get_weak_mode(&self, table_id: TableId, object_pool: &ObjectPool) -> Option<String> {
704696
if let Some(table) = object_pool.get_table(table_id) {
705697
if let Some(meta_value) = table.get_metatable() {
706698
if let Some(meta_id) = meta_value.as_table_id() {
@@ -745,15 +737,19 @@ impl GC {
745737

746738
// First pass: collect keys to remove (immutable borrow)
747739
let keys_to_remove: Vec<LuaValue> = if let Some(table) = object_pool.get_table(table_id) {
748-
table.iter_all()
740+
table
741+
.iter_all()
749742
.into_iter()
750743
.filter(|(key, value)| {
751744
let mut should_remove = false;
752-
745+
753746
// Check if weak key was collected
754747
if has_weak_keys {
755748
if let Some(key_table_id) = key.as_table_id() {
756-
if !self.objects.contains_key(&(GcObjectType::Table, key_table_id.0)) {
749+
if !self
750+
.objects
751+
.contains_key(&(GcObjectType::Table, key_table_id.0))
752+
{
757753
should_remove = true;
758754
}
759755
}
@@ -762,12 +758,15 @@ impl GC {
762758
// Check if weak value was collected
763759
if has_weak_values && !should_remove {
764760
if let Some(val_table_id) = value.as_table_id() {
765-
if !self.objects.contains_key(&(GcObjectType::Table, val_table_id.0)) {
761+
if !self
762+
.objects
763+
.contains_key(&(GcObjectType::Table, val_table_id.0))
764+
{
766765
should_remove = true;
767766
}
768767
}
769768
}
770-
769+
771770
should_remove
772771
})
773772
.map(|(key, _)| key)

0 commit comments

Comments
 (0)