refactor(compiler): remove class count helpers
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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(_) => {
|
||||
|
||||
@@ -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()),
|
||||
|
||||
Reference in New Issue
Block a user