refactor(compiler): remove class count helpers

This commit is contained in:
爱特每羊队
2026-08-05 01:41:51 +08:00
parent fd4172203e
commit 0f78f341fa
12 changed files with 2 additions and 323 deletions
-10
View File
@@ -1,11 +1 @@
use crate::compiler::{CompileCtx, Compiler};
impl Compiler {
pub(crate) fn count_class(&self, class: &oxide_parser::Class, ctx: &mut CompileCtx) {
self.count_class_header(class, ctx);
self.count_class_prototype(class.super_class.is_some(), ctx);
self.count_class_methods(&class.body.body, ctx);
self.count_class_static_fields(&class.body.body, ctx);
self.count_class_static_blocks(&class.body.body, ctx);
}
}
+2 -28
View File
@@ -66,20 +66,7 @@ impl Compiler {
false,
&self_binding,
FunctionBodyContext::ClassElement,
Some(|compiler: &Compiler, field_ctx: &mut CompileCtx| {
for field in &instance_fields {
if matches!(field.key, PropertyKey::PrivateIdentifier(_)) {
compiler.count_private_field_init(field.value.as_ref(), field_ctx);
} else {
compiler.count_public_field_init(
&field.key,
field.computed,
field.value.as_ref(),
field_ctx,
);
}
}
}),
None::<fn(&Compiler, &mut CompileCtx)>,
Some(|compiler: &Compiler, field_ctx: &mut CompileCtx| -> Result<(), String> {
for field in &instance_fields {
if let PropertyKey::PrivateIdentifier(private) = &field.key {
@@ -111,20 +98,7 @@ impl Compiler {
false,
&self_binding,
FunctionBodyContext::ClassElement,
Some(|compiler: &Compiler, field_ctx: &mut CompileCtx| {
for field in &instance_fields {
if matches!(field.key, PropertyKey::PrivateIdentifier(_)) {
compiler.count_private_field_init(field.value.as_ref(), field_ctx);
} else {
compiler.count_public_field_init(
&field.key,
field.computed,
field.value.as_ref(),
field_ctx,
);
}
}
}),
None::<fn(&Compiler, &mut CompileCtx)>,
Some(|compiler: &Compiler, field_ctx: &mut CompileCtx| -> Result<(), String> {
for field in &instance_fields {
if let PropertyKey::PrivateIdentifier(private) = &field.key {
-17
View File
@@ -2,23 +2,6 @@ use crate::compiler::{CompileCtx, Compiler};
use oxide_parser::{ClassElement, PropertyKey};
impl Compiler {
pub(crate) fn count_class_static_fields(&self, elements: &[ClassElement], ctx: &mut CompileCtx) {
for element in elements {
if let ClassElement::PropertyDefinition(prop) = element {
let prop = prop.as_ref();
if prop.r#static {
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();
}
}
}
}
pub(crate) fn emit_class_static_fields(
&self, elements: &[ClassElement], ctor_reg: u8, ctx: &mut CompileCtx,
) -> Result<(), String> {
@@ -1,14 +1,6 @@
use crate::compiler::{CompileCtx, Compiler};
impl Compiler {
pub(crate) fn count_class_header(&self, class: &oxide_parser::Class, ctx: &mut CompileCtx) {
ctx.alloc_reg();
ctx.alloc_reg();
if let Some(super_class) = &class.super_class {
self.count_expression(super_class, ctx);
}
}
pub(crate) fn emit_class_header(
&self, class: &oxide_parser::Class, ctx: &mut CompileCtx,
) -> Result<(u8, u8, Option<u8>), String> {
-34
View File
@@ -4,40 +4,6 @@ use oxide_bytecode::opcode::{self, OpCode};
use oxide_parser::{ClassElement, MethodDefinitionKind, PropertyKey};
impl Compiler {
pub(crate) fn count_class_methods(&self, elements: &[ClassElement], ctx: &mut CompileCtx) {
for element in elements {
match element {
ClassElement::MethodDefinition(method) => {
let method = method.as_ref();
if matches!(method.kind, MethodDefinitionKind::Constructor) {
continue;
}
if matches!(method.key, PropertyKey::PrivateIdentifier(_)) {
ctx.count_load_const();
ctx.count_load_const();
ctx.count_instr();
ctx.count_instr();
continue;
}
self.count_class_key(&method.key, method.computed, ctx);
ctx.count_load_const();
ctx.count_instr();
match method.kind {
MethodDefinitionKind::Method => {
ctx.count_instr();
}
MethodDefinitionKind::Get | MethodDefinitionKind::Set => {
ctx.count_load_const();
ctx.count_define_accessor();
}
MethodDefinitionKind::Constructor => {}
}
}
_ => {}
}
}
}
pub(crate) fn emit_class_methods(
&self, elements: &[ClassElement], ctor_reg: u8, proto_reg: u8, self_binding: &[(&str, u8)],
ctx: &mut CompileCtx,
@@ -3,25 +3,6 @@ use oxide_bytecode::module::Constant;
use oxide_bytecode::opcode::{self, OpCode};
impl Compiler {
pub(crate) fn count_class_prototype(&self, has_super: bool, ctx: &mut CompileCtx) {
ctx.count_instr();
ctx.count_instr();
if has_super {
ctx.alloc_reg();
ctx.count_instr();
ctx.alloc_reg();
ctx.count_instr();
ctx.alloc_reg();
ctx.count_instr();
ctx.count_instr();
ctx.count_instr();
}
ctx.count_load_const();
ctx.count_instr();
ctx.count_load_const();
ctx.count_instr();
}
pub(crate) fn emit_class_prototype(
&self, ctor_reg: u8, proto_reg: u8, super_reg: Option<u8>, sub_idx: u32, ctx: &mut CompileCtx,
) -> Result<(), String> {
@@ -2,16 +2,6 @@ use crate::compiler::{CompileCtx, Compiler};
use oxide_parser::ClassElement;
impl Compiler {
pub(crate) fn count_class_static_blocks(&self, elements: &[ClassElement], ctx: &mut CompileCtx) {
for element in elements {
if let ClassElement::StaticBlock(block) = element {
for stmt in &block.body {
self.count_statement(stmt, ctx);
}
}
}
}
pub(crate) fn emit_class_static_blocks(
&self, elements: &[ClassElement], ctor_reg: u8, ctx: &mut CompileCtx,
) -> Result<(), String> {
-63
View File
@@ -170,10 +170,6 @@ pub(crate) struct CompileCtx {
pub(crate) static_block_this_reg: Option<u8>,
pub(crate) after_super_insert: Option<Vec<opcode::Instr>>,
pub(crate) after_super_inserted: bool,
/// Count-pass mirror of `after_super_insert`: the instruction count of a derived
/// constructor's instance-field code, added at the super() call site during body
/// counting so projected_pc matches where the emit pass splices the field bytecode.
pub(crate) after_super_count_words: Option<usize>,
pub(crate) current_upvalue_captures: Vec<UpvalueCapture>,
/// Set when alloc_reg() overflows into the reserved this/new.target range (≥254).
/// Checked after each emit phase to produce a compile error rather than silent corruption.
@@ -250,7 +246,6 @@ impl CompileCtx {
static_block_this_reg: None,
after_super_insert: None,
after_super_inserted: false,
after_super_count_words: None,
current_upvalue_captures: Vec::new(),
reg_overflow: false,
const_overflow: false,
@@ -342,50 +337,6 @@ impl CompileCtx {
});
}
pub(crate) fn count_word(&mut self) {
self.projected_pc += 1;
}
pub(crate) fn count_words(&mut self, words: usize) {
self.projected_pc += words;
}
pub(crate) fn count_instr(&mut self) {
self.count_word();
}
pub(crate) fn count_instr_with_ext(&mut self, ext_words: usize) {
self.count_words(1 + ext_words);
}
pub(crate) fn count_load_const(&mut self) {
self.alloc_reg();
self.count_instr();
}
pub(crate) fn count_load_var(&mut self) {
self.alloc_reg();
self.count_instr();
}
pub(crate) fn count_ic_instr_with_ext(&mut self) {
self.count_instr_with_ext(3);
}
pub(crate) fn count_call_instr_with_arg_ext(&mut self) {
self.count_instr_with_ext(1);
}
pub(crate) fn count_define_accessor(&mut self) {
self.count_instr_with_ext(1);
}
pub(crate) fn count_private_access(&mut self) {
self.count_load_const();
self.alloc_reg();
self.count_instr();
}
pub(crate) fn alloc_reg(&mut self) -> u8 {
let r = self.next_reg;
// Registers 254 (this) and 255 (new.target) are reserved by the VM.
@@ -1273,20 +1224,6 @@ impl Compiler {
})
}
pub(crate) fn count_statement(&self, stmt: &Statement, ctx: &mut CompileCtx) {
let _ = (stmt, ctx);
}
pub(crate) fn count_expression(&self, expr: &Expression, ctx: &mut CompileCtx) {
match expr {
Expression::CallExpression(_) | Expression::NewExpression(_) => self.count_call_domain(expr, ctx),
Expression::ArrowFunctionExpression(_)
| Expression::FunctionExpression(_)
| Expression::ClassExpression(_) => self.count_function_domain(expr, ctx),
_ => {}
}
}
pub(crate) fn emit_statement(&self, stmt: &Statement, ctx: &mut CompileCtx) -> Result<Option<u8>, String> {
match stmt {
Statement::ExpressionStatement(_) | Statement::ReturnStatement(_) | Statement::EmptyStatement(_) => {
-72
View File
@@ -4,70 +4,6 @@ use oxide_bytecode::opcode::{self, OpCode};
use oxide_parser::Expression;
impl Compiler {
fn count_call_expression(&self, expr: &Expression, ctx: &mut CompileCtx) {
let Expression::CallExpression(call) = expr else {
return;
};
if matches!(&call.callee, Expression::Super(_)) {
for arg in &call.arguments {
if let Some(expr) = arg.as_expression() {
self.count_expression(expr, ctx);
}
}
ctx.alloc_reg();
ctx.count_call_instr_with_arg_ext();
if let Some(words) = ctx.after_super_count_words.take() {
ctx.projected_pc += words;
}
return;
}
match &call.callee {
Expression::PrivateFieldExpression(member) => {
self.count_expression(&member.object, ctx);
ctx.count_private_access();
}
Expression::StaticMemberExpression(member) => {
if matches!(&member.object, Expression::Super(_)) {
ctx.count_load_var();
ctx.count_load_const();
ctx.alloc_reg();
ctx.count_instr();
} else {
self.count_expression(&member.object, ctx);
ctx.count_load_const();
ctx.count_load_var();
ctx.count_ic_instr_with_ext();
}
}
_ => {
self.count_expression(&call.callee, ctx);
ctx.alloc_reg();
ctx.projected_pc += 1;
}
}
for arg in &call.arguments {
if let Some(expr) = arg.as_expression() {
self.count_expression(expr, ctx);
}
}
ctx.count_call_instr_with_arg_ext();
ctx.count_load_var();
}
fn count_new_expression(&self, expr: &Expression, ctx: &mut CompileCtx) {
let Expression::NewExpression(ne) = expr else {
return;
};
self.count_expression(&ne.callee, ctx);
for arg in &ne.arguments {
if let Some(expr) = arg.as_expression() {
self.count_expression(expr, ctx);
}
}
ctx.alloc_reg();
ctx.count_instr_with_ext(1);
}
fn emit_call_expression(&self, call: &oxide_parser::CallExpression, ctx: &mut CompileCtx) -> Result<u8, String> {
if matches!(&call.callee, Expression::Super(_)) {
if !ctx.in_derived_constructor {
@@ -158,14 +94,6 @@ impl Compiler {
Ok(result_reg)
}
pub(crate) fn count_call_domain(&self, expr: &Expression, ctx: &mut CompileCtx) {
match expr {
Expression::CallExpression(_) => self.count_call_expression(expr, ctx),
Expression::NewExpression(_) => self.count_new_expression(expr, ctx),
_ => {}
}
}
pub(crate) fn emit_call_domain(&self, expr: &Expression, ctx: &mut CompileCtx) -> Result<u8, String> {
match expr {
Expression::CallExpression(call) => self.emit_call_expression(call, ctx),
@@ -2,34 +2,6 @@ use crate::compiler::{CompileCtx, Compiler, ParamSpec};
use oxide_bytecode::opcode::{self, OpCode};
use oxide_parser::{Class, Expression, Statement};
impl Compiler {
fn count_arrow_function_expression(&self, ctx: &mut CompileCtx) {
ctx.alloc_reg();
ctx.projected_pc += 1; // LOAD_CONST
}
fn count_function_expression(&self, ctx: &mut CompileCtx) {
ctx.alloc_reg();
ctx.projected_pc += 1; // LOAD_CONST
}
fn count_class_expression(&self, expr: &Expression, ctx: &mut CompileCtx) {
let Expression::ClassExpression(class) = expr else {
return;
};
self.count_class(class, ctx);
}
pub(crate) fn count_function_domain(&self, expr: &Expression, ctx: &mut CompileCtx) {
match expr {
Expression::ArrowFunctionExpression(_) => self.count_arrow_function_expression(ctx),
Expression::FunctionExpression(_) => self.count_function_expression(ctx),
Expression::ClassExpression(_) => self.count_class_expression(expr, ctx),
_ => {}
}
}
}
impl Compiler {
fn emit_arrow_function_expression(
&self, arrow: &oxide_parser::ArrowFunctionExpression, ctx: &mut CompileCtx,
@@ -45,29 +45,4 @@ impl Compiler {
ctx.emit(opcode::encode(OpCode::INIT_PRIVATE, target_reg, method_reg, key_reg));
Ok(())
}
pub(crate) fn count_public_field_init(
&self, key: &PropertyKey, computed: bool, value: Option<&Expression>, ctx: &mut CompileCtx,
) {
self.count_class_key(key, computed, ctx);
if let Some(expr) = value {
self.count_expression(expr, ctx);
} else {
ctx.alloc_reg();
ctx.projected_pc += 1;
}
ctx.projected_pc += 1;
}
pub(crate) fn count_private_field_init(&self, value: Option<&Expression>, ctx: &mut CompileCtx) {
ctx.alloc_reg();
ctx.projected_pc += 1;
if let Some(expr) = value {
self.count_expression(expr, ctx);
} else {
ctx.alloc_reg();
ctx.projected_pc += 1;
}
ctx.projected_pc += 1;
}
}
@@ -36,15 +36,6 @@ impl Compiler {
self.emit_expression(key.to_expression(), ctx)
}
pub(crate) fn count_class_key(&self, key: &PropertyKey, computed: bool, ctx: &mut CompileCtx) {
if computed {
self.count_expression(key.to_expression(), ctx);
} else {
ctx.alloc_reg();
ctx.projected_pc += 1;
}
}
pub(crate) fn static_property_name(&self, key: &PropertyKey) -> Result<String, String> {
match key {
PropertyKey::StaticIdentifier(ident) => Ok(ident.name.as_str().to_string()),