fix(compiler): 完善闭包捕获(cell 索引稳定、参数遮蔽、函数/类名捕获、b 槽立即数)

This commit is contained in:
爱特每羊队
2026-08-05 19:19:29 +08:00
parent 3390b61453
commit b611e26f11
11 changed files with 87 additions and 70 deletions
+1 -8
View File
@@ -146,14 +146,7 @@ impl Compiler {
return Ok(val_reg);
}
// Check if target is a captured cell
if ctx.captured_bindings.contains(name) {
let cell_idx = ctx
.scopes
.cell_registry
.iter()
.find(|(n, _)| n == name)
.map(|(_, idx)| *idx)
.unwrap_or(0);
if let Some(&cell_idx) = ctx.captured_bindings.get(name) {
ctx.inst(Inst::new(OpCode::CELL_SET, Operand::None, Operand::Reg(val_reg as u32), Operand::Imm(cell_idx as u16)));
return Ok(val_reg);
}
+3 -10
View File
@@ -18,19 +18,12 @@ impl Compiler {
}
}
if ctx.captured_bindings.contains(name) {
let cell_idx = ctx
.scopes
.cell_registry
.iter()
.find(|(n, _)| n == name)
.map(|(_, idx)| *idx)
.unwrap_or(0);
if let Some(&cell_idx) = ctx.captured_bindings.get(name) {
let r = ctx.alloc_reg();
if let Some((binding, _)) = ctx.scopes.symbols.lookup_any_binding(name) {
ctx.inst(Inst::new(OpCode::CELL_GET, Operand::Reg(r as u32), Operand::Reg(binding.reg as u32), Operand::Reg(cell_idx as u32)));
ctx.inst(Inst::new(OpCode::CELL_GET, Operand::Reg(r as u32), Operand::Reg(binding.reg as u32), Operand::Imm(cell_idx as u16)));
} else {
ctx.inst(Inst::new(OpCode::CELL_GET, Operand::Reg(r as u32), Operand::None, Operand::Reg(cell_idx as u32)));
ctx.inst(Inst::new(OpCode::CELL_GET, Operand::Reg(r as u32), Operand::None, Operand::Imm(cell_idx as u16)));
}
return Ok(r);
}
@@ -222,7 +222,7 @@ impl Compiler {
let name = id.name.as_str();
// Check if this is an upvalue or captured cell reference
let uv_idx = ctx.current_upvalue_captures.iter().position(|u| u.name == name);
let is_captured = ctx.captured_bindings.contains(name);
let captured_cell = ctx.captured_bindings.get(name).copied();
if let Some(uv) = uv_idx {
// Upvalue: LOAD_UPVALUE + CONST(1) + ADD/SUB + STORE_UPVALUE
let val_reg = ctx.alloc_reg();
@@ -238,15 +238,8 @@ impl Compiler {
ctx.inst(Inst::new(op, Operand::Reg(val_reg as u32), Operand::Reg(val_reg as u32), Operand::Reg(one_reg as u32)));
ctx.inst(Inst::new(OpCode::STORE_UPVALUE, Operand::None, Operand::Reg(val_reg as u32), Operand::Imm(uv as u16)));
Ok(val_reg)
} else if is_captured {
} else if let Some(cell_idx) = captured_cell {
// Captured cell: CELL_GET + CONST(1) + ADD/SUB + CELL_SET
let cell_idx = ctx
.scopes
.cell_registry
.iter()
.find(|(n, _)| n == name)
.map(|(_, idx)| *idx)
.unwrap_or(0);
let val_reg = ctx.alloc_reg();
if let Some((binding, _)) = ctx.scopes.symbols.lookup_any_binding(name) {
ctx.inst(Inst::new(OpCode::CELL_GET, Operand::Reg(val_reg as u32), Operand::Reg(binding.reg as u32), Operand::Imm(cell_idx as u16)));