fix: 修复嵌套函数调用并接通闭包捕获链路
This commit is contained in:
@@ -1089,10 +1089,13 @@ impl Compiler {
|
||||
is_class_constructor: false,
|
||||
is_derived_constructor: false,
|
||||
needs_home_object: false,
|
||||
upvalue_captures: Vec::new(),
|
||||
cells_needed: ctx.scopes.symbols.scopes[0]
|
||||
.bindings
|
||||
.values()
|
||||
upvalue_captures: ctx.current_upvalue_captures.clone(),
|
||||
cells_needed: ctx
|
||||
.scopes
|
||||
.symbols
|
||||
.scopes
|
||||
.iter()
|
||||
.flat_map(|s| s.bindings.values())
|
||||
.filter(|b| b.is_captured.get())
|
||||
.count() as u8,
|
||||
})
|
||||
@@ -1193,10 +1196,13 @@ impl Compiler {
|
||||
is_class_constructor: false,
|
||||
is_derived_constructor: false,
|
||||
needs_home_object: false,
|
||||
upvalue_captures: Vec::new(),
|
||||
cells_needed: ctx.scopes.symbols.scopes[0]
|
||||
.bindings
|
||||
.values()
|
||||
upvalue_captures: ctx.current_upvalue_captures.clone(),
|
||||
cells_needed: ctx
|
||||
.scopes
|
||||
.symbols
|
||||
.scopes
|
||||
.iter()
|
||||
.flat_map(|s| s.bindings.values())
|
||||
.filter(|b| b.is_captured.get())
|
||||
.count() as u8,
|
||||
})
|
||||
|
||||
@@ -356,9 +356,6 @@ impl Compiler {
|
||||
) -> Result<(), String> {
|
||||
let var_reg = ctx.alloc_reg();
|
||||
let target_reg = if matches!(kind, VariableDeclarationKind::Var) {
|
||||
// `var` is hoisted, so the count pass already registered the name. A redeclare
|
||||
// here reuses that existing register instead of erroring; the freshly allocated
|
||||
// reg matches it (count/emit allocate in lock-step) so either resolves the same.
|
||||
match ctx.declare(name, var_reg, kind, is_const) {
|
||||
Ok(()) => var_reg,
|
||||
Err(_) => ctx.lookup(name).unwrap_or(var_reg),
|
||||
@@ -367,7 +364,13 @@ impl Compiler {
|
||||
ctx.declare(name, var_reg, kind, is_const)?;
|
||||
var_reg
|
||||
};
|
||||
ctx.emit(opcode::encode(OpCode::STORE_VAR, target_reg, src_reg, if is_const { 1 } else { 0 }));
|
||||
if ctx.scopes.symbols.lookup_is_captured(name) {
|
||||
let cell_idx = ctx.scopes.cell_registry.len() as u8;
|
||||
ctx.scopes.cell_registry.push((name.to_string(), cell_idx));
|
||||
ctx.emit(opcode::encode(OpCode::MAKE_CELL, src_reg, cell_idx, 0));
|
||||
} else {
|
||||
ctx.emit(opcode::encode(OpCode::STORE_VAR, target_reg, src_reg, if is_const { 1 } else { 0 }));
|
||||
}
|
||||
ctx.init_var(name);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ impl Compiler {
|
||||
if is_captured {
|
||||
let cell_idx = ctx.scopes.cell_registry.len() as u8;
|
||||
ctx.scopes.cell_registry.push((bi.name.to_string(), cell_idx));
|
||||
ctx.emit(opcode::encode(OpCode::MAKE_CELL, var_reg, cell_idx, 0));
|
||||
ctx.emit(opcode::encode(OpCode::MAKE_CELL, tmp, cell_idx, 0));
|
||||
} else {
|
||||
ctx.emit(opcode::encode(OpCode::STORE_VAR, var_reg, tmp, 0));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user