refactor: CompileCtx 拆分为 LabelCtx/ScopeCtx,字面量域改用注册表入口

This commit is contained in:
2026-06-25 19:46:35 +08:00
parent d195d7615c
commit f7bcfd3846
17 changed files with 180 additions and 113 deletions
@@ -72,7 +72,7 @@ impl Compiler {
self.count_expression(right, ctx);
ctx.count_ic_set_with_ext(); // IC_SET_PROP + 3 ext
ctx.projected_pc += 1; // LOAD_VAR result <- rhs
ctx.label_map.insert(Label::TernaryEnd(id), ctx.projected_pc);
ctx.labels.label_map.insert(Label::TernaryEnd(id), ctx.projected_pc);
}
fn count_computed_member_logical_assignment(
@@ -88,7 +88,7 @@ impl Compiler {
self.count_expression(right, ctx);
ctx.projected_pc += 1; // SET_PROP_DYNAMIC
ctx.projected_pc += 1; // LOAD_VAR result <- rhs
ctx.label_map.insert(Label::TernaryEnd(id), ctx.projected_pc);
ctx.labels.label_map.insert(Label::TernaryEnd(id), ctx.projected_pc);
}
fn count_identifier_logical_assignment(
@@ -101,6 +101,6 @@ impl Compiler {
self.count_expression(right, ctx);
ctx.projected_pc += 1; // STORE_VAR
ctx.projected_pc += 1; // LOAD_VAR result <- rhs
ctx.label_map.insert(Label::TernaryEnd(id), ctx.projected_pc);
ctx.labels.label_map.insert(Label::TernaryEnd(id), ctx.projected_pc);
}
}
@@ -10,8 +10,8 @@ impl Compiler {
ctx.alloc_reg();
ctx.projected_pc += 1; // LOAD_VAR result <- chain value
ctx.projected_pc += 1; // JMP over short-circuit writer
ctx.label_map.insert(Label::TernaryElse(id), ctx.projected_pc);
ctx.labels.label_map.insert(Label::TernaryElse(id), ctx.projected_pc);
ctx.projected_pc += 1; // LOAD_CONST undefined
ctx.label_map.insert(Label::TernaryEnd(id), ctx.projected_pc);
ctx.labels.label_map.insert(Label::TernaryEnd(id), ctx.projected_pc);
}
}
@@ -15,10 +15,10 @@ impl Compiler {
ctx.alloc_reg(); // result register
ctx.projected_pc += 1; // LOAD_VAR result <- consequent
ctx.projected_pc += 1; // JMP to end
ctx.label_map.insert(else_label, ctx.projected_pc);
ctx.labels.label_map.insert(else_label, ctx.projected_pc);
self.count_expression(&cond.alternate, ctx);
ctx.projected_pc += 1; // LOAD_VAR result <- alternate
ctx.label_map.insert(end_label, ctx.projected_pc);
ctx.labels.label_map.insert(end_label, ctx.projected_pc);
}
pub(in crate::counter) fn count_sequence_expression(&self, expr: &Expression, ctx: &mut CompileCtx) {
@@ -49,7 +49,7 @@ impl Compiler {
ctx.projected_pc += 1; // JMP_IF_FALSE, JMP_IF_TRUE, or JMP_IF_NULLISH
if matches!(log.operator, LogicalOperator::Coalesce) {
ctx.projected_pc += 1; // JMP over RHS on non-nullish
ctx.label_map.insert(Label::TernaryElse(id), ctx.projected_pc);
ctx.labels.label_map.insert(Label::TernaryElse(id), ctx.projected_pc);
}
self.count_expression(&log.right, ctx);
ctx.projected_pc += 1; // LOAD_VAR (overwrite)
@@ -58,7 +58,7 @@ impl Compiler {
LogicalOperator::Or => Label::TernaryElse(id),
LogicalOperator::Coalesce => Label::TernaryEnd(id),
};
ctx.label_map.insert(skip_label, ctx.projected_pc);
ctx.labels.label_map.insert(skip_label, ctx.projected_pc);
}
}
}
@@ -1,6 +1,17 @@
use super::*;
impl Compiler {
/// Domain entry point: count any literal expression. The central
/// `count_expression` match delegates all literal variants here in one arm.
/// Numeric/String/Boolean/Null share the default single-`LOAD_CONST` shape;
/// RegExp emits three instructions.
pub(in crate::counter) fn count_literal(&self, expr: &Expression, ctx: &mut CompileCtx) {
match expr {
Expression::RegExpLiteral(_) => self.count_regexp_literal(ctx),
_ => self.count_default_expression(ctx),
}
}
pub(in crate::counter) fn count_this_expression(&self, ctx: &mut CompileCtx) {
ctx.alloc_reg();
ctx.projected_pc += 1; // LOAD_VAR from reg 254
@@ -38,7 +38,11 @@ impl Compiler {
Expression::ThisExpression(_) => self.count_this_expression(ctx),
Expression::Identifier(_) => self.count_identifier_expression(expr, ctx),
Expression::UpdateExpression(_) => self.count_update_expression(expr, ctx),
Expression::RegExpLiteral(_) => self.count_regexp_literal(ctx),
Expression::NumericLiteral(_)
| Expression::StringLiteral(_)
| Expression::BooleanLiteral(_)
| Expression::NullLiteral(_)
| Expression::RegExpLiteral(_) => self.count_literal(expr, ctx),
_ => self.count_default_expression(ctx),
}
}
@@ -166,7 +166,7 @@ impl Compiler {
LogicalOperator::Coalesce => {
ctx.projected_pc += 1; // JMP_IF_NULLISH to store body
ctx.projected_pc += 1; // JMP to end on non-nullish
ctx.label_map.insert(Label::TernaryElse(id), ctx.projected_pc);
ctx.labels.label_map.insert(Label::TernaryElse(id), ctx.projected_pc);
}
}
}
@@ -43,7 +43,7 @@ impl Compiler {
// LabeledEnd target right after the body for `break label`.
let id = ctx.next_label_id();
self.count_statement(&stmt.body, ctx);
ctx.label_map.insert(Label::LabeledEnd(id), ctx.projected_pc);
ctx.labels.label_map.insert(Label::LabeledEnd(id), ctx.projected_pc);
}
}
}
@@ -14,11 +14,11 @@ impl Compiler {
if stmt.alternate.is_some() {
ctx.projected_pc += 1; // JMP (skip else)
}
ctx.label_map.insert(else_label, ctx.projected_pc);
ctx.labels.label_map.insert(else_label, ctx.projected_pc);
if let Some(alt_stmt) = &stmt.alternate {
self.count_statement(alt_stmt, ctx);
ctx.projected_pc += 1; // LOAD_VAR result <- alternate
}
ctx.label_map.insert(end_label, ctx.projected_pc);
ctx.labels.label_map.insert(end_label, ctx.projected_pc);
}
}
@@ -39,7 +39,7 @@ impl Compiler {
ctx.projected_pc += 1; // JMP
}
ctx.label_map.insert(catch_label, ctx.projected_pc);
ctx.labels.label_map.insert(catch_label, ctx.projected_pc);
if let Some(catch) = &stmt.handler {
ctx.push_scope();
if let Some(_param) = &catch.param {
@@ -55,7 +55,7 @@ impl Compiler {
if let Some(finally) = &stmt.finalizer {
let finally_label = Label::FinallyBody(id);
ctx.label_map.insert(finally_label, ctx.projected_pc);
ctx.labels.label_map.insert(finally_label, ctx.projected_pc);
for fs in &finally.body {
self.count_statement(fs, ctx);
}
@@ -63,6 +63,6 @@ impl Compiler {
ctx.projected_pc += 1; // TRY_FINALLY_END
}
ctx.label_map.insert(try_end_label, ctx.projected_pc);
ctx.labels.label_map.insert(try_end_label, ctx.projected_pc);
}
}
@@ -8,12 +8,12 @@ impl Compiler {
let start_label = Label::WhileStart(id);
let end_label = Label::WhileEnd(id);
ctx.label_map.insert(start_label, ctx.projected_pc);
ctx.labels.label_map.insert(start_label, ctx.projected_pc);
self.count_expression(&stmt.test, ctx);
ctx.projected_pc += 1; // JMP_IF_FALSE
self.count_statement(&stmt.body, ctx);
ctx.projected_pc += 1; // JMP (backward)
ctx.label_map.insert(end_label, ctx.projected_pc);
ctx.labels.label_map.insert(end_label, ctx.projected_pc);
}
pub(in crate::counter) fn count_do_while_statement(
@@ -23,11 +23,11 @@ impl Compiler {
let start_label = Label::DoWhileStart(id);
let end_label = Label::DoWhileEnd(id);
ctx.label_map.insert(start_label, ctx.projected_pc);
ctx.labels.label_map.insert(start_label, ctx.projected_pc);
self.count_statement(&stmt.body, ctx);
self.count_expression(&stmt.test, ctx);
ctx.projected_pc += 1; // JMP_IF_TRUE (backward)
ctx.label_map.insert(end_label, ctx.projected_pc);
ctx.labels.label_map.insert(end_label, ctx.projected_pc);
}
pub(in crate::counter) fn count_for_statement(&self, stmt: &oxide_parser::ForStatement<'_>, ctx: &mut CompileCtx) {
@@ -51,18 +51,18 @@ impl Compiler {
}
}
}
ctx.label_map.insert(start_label, ctx.projected_pc);
ctx.labels.label_map.insert(start_label, ctx.projected_pc);
if let Some(test) = &stmt.test {
self.count_expression(test, ctx);
ctx.projected_pc += 1; // JMP_IF_FALSE
}
self.count_statement(&stmt.body, ctx);
ctx.label_map.insert(update_label, ctx.projected_pc);
ctx.labels.label_map.insert(update_label, ctx.projected_pc);
if let Some(update) = &stmt.update {
self.count_expression(update, ctx);
}
ctx.projected_pc += 1; // JMP (backward)
ctx.label_map.insert(end_label, ctx.projected_pc);
ctx.labels.label_map.insert(end_label, ctx.projected_pc);
}
pub(in crate::counter) fn count_for_in_statement(
@@ -75,7 +75,7 @@ impl Compiler {
self.count_expression(&stmt.right, ctx);
ctx.count_instr(); // FOR_IN_INIT
ctx.label_map.insert(start_label, ctx.projected_pc);
ctx.labels.label_map.insert(start_label, ctx.projected_pc);
ctx.count_instr(); // FOR_IN_DONE
ctx.count_jump(); // JMP_IF_FALSE
ctx.count_jump(); // JMP cleanup
@@ -98,7 +98,7 @@ impl Compiler {
self.count_statement(&stmt.body, ctx);
ctx.count_jump(); // JMP back to start
ctx.label_map.insert(end_label, ctx.projected_pc);
ctx.labels.label_map.insert(end_label, ctx.projected_pc);
ctx.count_instr(); // FOR_IN_CLEANUP
}
@@ -111,7 +111,7 @@ impl Compiler {
self.count_expression(&stmt.right, ctx);
ctx.count_instr(); // FOR_OF_INIT
ctx.label_map.insert(start_label, ctx.projected_pc);
ctx.labels.label_map.insert(start_label, ctx.projected_pc);
ctx.alloc_reg(); // has_reg
ctx.count_instr(); // FOR_OF_DONE
ctx.count_jump(); // JMP_IF_FALSE
@@ -137,7 +137,7 @@ impl Compiler {
}
self.count_statement(&stmt.body, ctx);
ctx.count_jump(); // JMP back
ctx.label_map.insert(end_label, ctx.projected_pc);
ctx.labels.label_map.insert(end_label, ctx.projected_pc);
ctx.count_instr(); // FOR_OF_CLOSE
}
}
@@ -29,13 +29,13 @@ impl Compiler {
for (case_idx, case) in cases.iter().enumerate() {
let case_label = Label::SwitchCase(id, case_idx as u32);
ctx.label_map.insert(case_label, ctx.projected_pc);
ctx.labels.label_map.insert(case_label, ctx.projected_pc);
for s in &case.consequent {
self.count_statement(s, ctx);
}
}
ctx.label_map.insert(end_label, ctx.projected_pc);
ctx.labels.label_map.insert(end_label, ctx.projected_pc);
ctx.pop_switch();
}
}