refactor: 拆分编译流水线过程以避免逻辑漂移

This commit is contained in:
爱特每羊队
2026-07-05 14:41:08 +08:00
parent a4c13c4f6a
commit ff6de1e4e7
62 changed files with 2190 additions and 1152 deletions
@@ -46,7 +46,7 @@ impl Compiler {
}
}
pub(in crate::counter) fn count_rest_array(&self, ctx: &mut CompileCtx) {
pub(crate) fn count_rest_array(&self, ctx: &mut CompileCtx) {
ctx.alloc_reg(); // rest
ctx.count_instr(); // NEW_ARRAY
ctx.count_load_const(); // idx = 0
@@ -61,9 +61,7 @@ impl Compiler {
ctx.count_jump(); // JMP
}
pub(in crate::counter) fn count_array_assignment(
&self, ap: &oxide_parser::ArrayAssignmentTarget, ctx: &mut CompileCtx,
) {
pub(crate) fn count_array_assignment(&self, ap: &oxide_parser::ArrayAssignmentTarget, ctx: &mut CompileCtx) {
ctx.count_instr(); // FOR_OF_INIT
for elem in &ap.elements {
ctx.alloc_reg();
@@ -86,9 +84,7 @@ impl Compiler {
ctx.count_instr(); // FOR_OF_CLOSE
}
pub(in crate::counter) fn count_object_assignment(
&self, op: &oxide_parser::ObjectAssignmentTarget, ctx: &mut CompileCtx,
) {
pub(crate) fn count_object_assignment(&self, op: &oxide_parser::ObjectAssignmentTarget, ctx: &mut CompileCtx) {
for prop in &op.properties {
match prop {
oxide_parser::AssignmentTargetProperty::AssignmentTargetPropertyIdentifier(id) => {
@@ -118,7 +114,7 @@ impl Compiler {
}
}
pub(in crate::counter) fn count_assignment_maybe_default(
pub(crate) fn count_assignment_maybe_default(
&self, target: &oxide_parser::AssignmentTargetMaybeDefault, ctx: &mut CompileCtx,
) {
match target {
@@ -144,9 +140,7 @@ impl Compiler {
}
}
pub(in crate::counter) fn count_assign_target(
&self, target: &oxide_parser::AssignmentTarget, ctx: &mut CompileCtx,
) {
pub(crate) fn count_assign_target(&self, target: &oxide_parser::AssignmentTarget, ctx: &mut CompileCtx) {
match target {
oxide_parser::AssignmentTarget::AssignmentTargetIdentifier(_) => {
ctx.alloc_reg();
@@ -1,86 +0,0 @@
use super::super::*;
impl Compiler {
pub(in crate::counter) fn count_class(&self, class: &oxide_parser::Class, ctx: &mut CompileCtx) {
ctx.alloc_reg(); // ctor_reg
ctx.alloc_reg(); // proto_reg
if let Some(super_class) = &class.super_class {
self.count_expression(super_class, ctx);
}
ctx.count_instr(); // LOAD_CONST ctor
ctx.count_instr(); // NEW_OBJECT proto
if class.super_class.is_some() {
ctx.alloc_reg(); // parent prototype key
ctx.count_instr(); // LOAD_CONST
ctx.alloc_reg(); // parent prototype value
ctx.count_instr(); // GET_PROP
ctx.alloc_reg(); // __proto__ key
ctx.count_instr(); // LOAD_CONST
ctx.count_instr(); // SET_PROP proto.__proto__
ctx.count_instr(); // SET_PROP ctor.__proto__
}
ctx.count_load_const(); // constructor key
ctx.count_instr(); // SET_PROP proto.constructor = ctor
ctx.count_load_const(); // prototype key
ctx.count_instr(); // SET_PROP ctor.prototype = proto
for element in &class.body.body {
match element {
ClassElement::MethodDefinition(method) => {
let method = method.as_ref();
if matches!(method.kind, MethodDefinitionKind::Constructor) {
continue;
}
if matches!(method.key, oxide_parser::PropertyKey::PrivateIdentifier(_)) {
// Mirror emit_private_method_init for static AND non-static private
// methods: private-id LOAD_CONST + CREATE_CLOSURE + SET_HOME_OBJECT +
// INIT_PRIVATE.
ctx.count_load_const(); // private id reg
ctx.count_load_const(); // method closure (CREATE_CLOSURE)
ctx.count_instr(); // SET_HOME_OBJECT
ctx.count_instr(); // INIT_PRIVATE
continue;
}
// Computed method key emits the full key expression; a plain key is one
// LOAD_CONST. Mirror emit_class_key_reg via the shared count_class_key.
self.count_class_key(&method.key, method.computed, ctx);
ctx.count_load_const(); // method closure (CREATE_CLOSURE)
ctx.count_instr(); // SET_HOME_OBJECT
match method.kind {
MethodDefinitionKind::Method => {
ctx.count_instr(); // SET_PROP
}
MethodDefinitionKind::Get | MethodDefinitionKind::Set => {
ctx.count_load_const(); // undefined placeholder
ctx.count_define_accessor(); // DEFINE_ACCESSOR + ext
}
MethodDefinitionKind::Constructor => {}
}
}
ClassElement::PropertyDefinition(prop) => {
let prop = prop.as_ref();
if prop.r#static {
// Computed static field key emits the full key expression; mirror
// emit_public_field_init via the shared count_class_key.
self.count_class_key(&prop.key, prop.computed, ctx);
if let Some(value) = &prop.value {
self.count_expression(value, ctx);
} else {
ctx.count_load_const();
}
ctx.count_instr(); // SET_PROP
}
}
ClassElement::StaticBlock(block) => {
for stmt in &block.body {
self.count_statement(stmt, ctx);
}
}
ClassElement::AccessorProperty(_) | ClassElement::TSIndexSignature(_) => {}
}
}
}
}
@@ -1,13 +1,13 @@
use super::super::*;
impl Compiler {
pub(in crate::counter) fn count_object_property_read_static(&self, ctx: &mut CompileCtx) {
pub(crate) fn count_object_property_read_static(&self, ctx: &mut CompileCtx) {
ctx.count_load_var(); // prop/object temp
ctx.count_load_const(); // key reg
ctx.count_ic_instr_with_ext(); // IC_GET_PROP + 3 ext words
}
pub(in crate::counter) fn count_object_property_read_key(
pub(crate) fn count_object_property_read_key(
&self, key: &oxide_parser::PropertyKey, computed: bool, ctx: &mut CompileCtx,
) {
if !computed {
@@ -38,12 +38,12 @@ impl Compiler {
ctx.count_instr(); // GET_PROP_DYNAMIC
}
pub(in crate::counter) fn count_optional_guard(&self, ctx: &mut CompileCtx) {
pub(crate) fn count_optional_guard(&self, ctx: &mut CompileCtx) {
ctx.count_load_var(); // dup
ctx.count_jump(); // JMP_IF_NULLISH
}
pub(in crate::counter) fn count_static_member_get_preserve_base(
pub(crate) fn count_static_member_get_preserve_base(
&self, member: &oxide_parser::StaticMemberExpression, short_chain: bool, ctx: &mut CompileCtx,
) {
self.count_chainable_expression(&member.object, short_chain, ctx);
@@ -55,7 +55,7 @@ impl Compiler {
ctx.count_ic_instr_with_ext(); // IC_GET_PROP + 3 ext words
}
pub(in crate::counter) fn count_computed_member_get_preserve_base(
pub(crate) fn count_computed_member_get_preserve_base(
&self, member: &oxide_parser::ComputedMemberExpression, short_chain: bool, ctx: &mut CompileCtx,
) {
self.count_chainable_expression(&member.object, short_chain, ctx);
@@ -67,7 +67,7 @@ impl Compiler {
ctx.count_instr(); // GET_PROP_DYNAMIC
}
pub(in crate::counter) fn count_chain_call(
pub(crate) fn count_chain_call(
&self, call: &oxide_parser::CallExpression, short_chain: bool, ctx: &mut CompileCtx,
) {
match &call.callee {
@@ -113,9 +113,7 @@ impl Compiler {
ctx.count_load_var(); // result <- regs[0]
}
pub(in crate::counter) fn count_chainable_expression(
&self, expr: &Expression, short_chain: bool, ctx: &mut CompileCtx,
) {
pub(crate) fn count_chainable_expression(&self, expr: &Expression, short_chain: bool, ctx: &mut CompileCtx) {
match expr {
Expression::StaticMemberExpression(member) => {
self.count_static_member_get_preserve_base(member, short_chain, ctx)
@@ -136,9 +134,7 @@ impl Compiler {
}
}
pub(in crate::counter) fn count_chain_element(
&self, element: &ChainElement, short_chain: bool, ctx: &mut CompileCtx,
) {
pub(crate) fn count_chain_element(&self, element: &ChainElement, short_chain: bool, ctx: &mut CompileCtx) {
match element {
ChainElement::StaticMemberExpression(member) => {
self.count_static_member_get_preserve_base(member, short_chain, ctx)
@@ -158,7 +154,7 @@ impl Compiler {
}
}
pub(in crate::counter) fn count_logical_assign_test(&self, op: LogicalOperator, id: u32, ctx: &mut CompileCtx) {
pub(crate) fn count_logical_assign_test(&self, op: LogicalOperator, id: u32, ctx: &mut CompileCtx) {
match op {
LogicalOperator::And | LogicalOperator::Or => {
ctx.projected_pc += 1;
@@ -1,3 +1,2 @@
mod binding;
mod class;
mod member;