mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-25 19:21:11 +08:00
feat: 搭建闭包捕获基础设施
This commit is contained in:
@@ -32,13 +32,21 @@ impl Compiler {
|
||||
self.count_expression(&assign.right, ctx);
|
||||
ctx.count_load_const(); // private id
|
||||
ctx.count_instr(); // SET_PRIVATE
|
||||
} else if let oxide_parser::AssignmentTarget::AssignmentTargetIdentifier(_) = &assign.left {
|
||||
} else if let oxide_parser::AssignmentTarget::AssignmentTargetIdentifier(ati) = &assign.left {
|
||||
let name = ati.name.as_str();
|
||||
// Check if target is an upvalue or captured cell
|
||||
let is_upvalue = ctx.current_upvalue_captures.iter().any(|u| u.name == name);
|
||||
let is_captured = ctx.scopes.symbols.lookup_is_captured(name);
|
||||
if let Some(logical_op) = assign.operator.to_logical_operator() {
|
||||
self.count_identifier_logical_assignment(logical_op, &assign.right, ctx);
|
||||
} else {
|
||||
self.count_expression(&assign.right, ctx);
|
||||
if assign.operator != AssignmentOperator::Assign {
|
||||
ctx.projected_pc += 1; // COMPOUND_* on var
|
||||
} else if is_upvalue {
|
||||
ctx.count_instr(); // STORE_UPVALUE
|
||||
} else if is_captured {
|
||||
ctx.count_instr(); // CELL_SET
|
||||
} else {
|
||||
ctx.alloc_reg();
|
||||
ctx.projected_pc += 1; // STORE_VAR
|
||||
|
||||
@@ -21,8 +21,26 @@ impl Compiler {
|
||||
let Expression::Identifier(ident) = expr else {
|
||||
return;
|
||||
};
|
||||
if CompileCtx::is_known_builtin(ident.name.as_str()) {
|
||||
let _ = ctx.lookup_or_builtin(ident.name.as_str());
|
||||
let name = ident.name.as_str();
|
||||
|
||||
// Check if this is an upvalue reference (nested closure)
|
||||
for up in &ctx.current_upvalue_captures {
|
||||
if up.name == name {
|
||||
ctx.alloc_reg();
|
||||
ctx.count_instr(); // LOAD_UPVALUE
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the owner's binding is captured (cell access)
|
||||
if ctx.scopes.symbols.lookup_is_captured(name) {
|
||||
ctx.alloc_reg();
|
||||
ctx.count_instr(); // CELL_GET
|
||||
return;
|
||||
}
|
||||
|
||||
if CompileCtx::is_known_builtin(name) {
|
||||
let _ = ctx.lookup_or_builtin(name);
|
||||
}
|
||||
ctx.alloc_reg();
|
||||
ctx.projected_pc += 1; // LOAD_VAR
|
||||
|
||||
Reference in New Issue
Block a user