This repository has been archived on 2026-09-15. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
OxideJS/crates/oxide_emit/src/expr/function/mod.rs
T
爱特每羊队 6da248872b feat: emit 模块编译(快照式链接:依赖子模块闭包 + import/export 域)
- emit_program_module:模块顶层编译(is_global_scope=false,顶层 this undefined 由 VM 按标志绑定)
- emit_module_into_ctx:预声明/闭包分析识别 export 包裹声明与 import 绑定
- 依赖收集:import/re-export/star 的 source 去重、循环检测、json/text 数据模块
- 导入绑定初始化:__moduleLinkGet 链接期检查;self-import 别名语义(export 处回写)
- export 域:声明/重导出/export */export default 就地注册命名空间
- re-export 链接检查移至 prelude(先于 body 求值)
- emit_module_call 参数打包连续寄存器(CALL_NATIVE 契约)
- CompileCtx 增 module_ns_reg/module_dep_ns_regs/self-import 映射
- 拆分 declaration helper(export 声明复用);function/class 表达式 emitter 提升可见性
2026-08-12 17:37:33 +08:00

138 lines
5.8 KiB
Rust

//! 函数表达式域:箭头/普通函数/类表达式/`new` 表达式的 emit 与分发。
//! 函数:`emit_arrow_function_expression`、`emit_function_expression`、
//! `emit_class_expression`、`emit_new_expression`、`emit_function_domain`。
use crate::expr::call::pack_arg_regs;
use crate::{CompileCtx, Emitter, ParamSpec};
use oxide_ir::inst::Inst;
use oxide_ir::operand::Operand;
use oxide_parser::{Class, Expression, Statement};
impl Emitter {
fn emit_arrow_function_expression(
&self, arrow: &oxide_parser::ArrowFunctionExpression, ctx: &mut CompileCtx,
) -> Result<u32, String> {
// 提取形参名(与函数表达式相同的形态)
let mut param_names = Vec::new();
for (idx, param) in arrow.params.items.iter().enumerate() {
match &param.pattern {
oxide_parser::BindingPattern::BindingIdentifier(bi) => {
param_names.push(ParamSpec::Identifier {
name: bi.name.to_string(),
initializer: param.initializer.as_deref(),
});
}
pattern => {
param_names.push(ParamSpec::Pattern {
synthetic_name: format!("@@param_{idx}"),
pattern,
initializer: param.initializer.as_deref(),
});
}
}
}
if let Some(rest) = &arrow.params.rest {
self.push_rest_param(&rest.rest.argument, &mut param_names)?;
}
// 表达式体:以 is_expression_body=true 编译;语句体:以 false 编译。
let body_stmts = &arrow.body.statements;
let is_expr_body = arrow.expression;
let mut sub_module = if arrow.r#async {
self.compile_async_body(&param_names, body_stmts, ctx, is_expr_body, true)?
} else {
self.compile_function_body(&param_names, body_stmts, ctx, is_expr_body, true)?
};
sub_module.is_arrow = true;
ctx.nested.push(sub_module);
// 子模块下标 1 起始:0 保留为无子模块哨兵
let sub_idx = ctx.nested.len() as u16;
let r = ctx.alloc_reg();
ctx.inst(Inst::create_closure(Operand::Reg(r), sub_idx));
Ok(r)
}
pub(crate) fn emit_function_expression(&self, fe: &oxide_parser::Function, ctx: &mut CompileCtx) -> Result<u32, String> {
// 函数表达式:编译函数体为子模块,create_closure 实例化闭包
let mut param_names = Vec::new();
for (idx, param) in fe.params.items.iter().enumerate() {
match &param.pattern {
oxide_parser::BindingPattern::BindingIdentifier(bi) => {
param_names.push(ParamSpec::Identifier {
name: bi.name.to_string(),
initializer: param.initializer.as_deref(),
});
}
pattern => {
param_names.push(ParamSpec::Pattern {
synthetic_name: format!("@@param_{idx}"),
pattern,
initializer: param.initializer.as_deref(),
});
}
}
}
if let Some(rest) = &fe.params.rest {
self.push_rest_param(&rest.rest.argument, &mut param_names)?;
}
let body_stmts: &[Statement] = if let Some(body) = &fe.body { &body.statements } else { &[] };
let mut sub_module = if fe.generator && fe.r#async {
self.compile_async_generator_body(&param_names, body_stmts, ctx)?
} else if fe.generator {
self.compile_generator_body(&param_names, body_stmts, ctx)?
} else if fe.r#async {
self.compile_async_body(&param_names, body_stmts, ctx, false, false)?
} else {
self.compile_function_body(&param_names, body_stmts, ctx, false, false)?
};
if let Some(id) = &fe.id {
sub_module.function_name = Some(id.name.to_string());
}
ctx.nested.push(sub_module);
// 子模块下标 1 起始:0 保留为无子模块哨兵
let sub_idx = ctx.nested.len() as u16;
let r = ctx.alloc_reg();
ctx.inst(Inst::create_closure(Operand::Reg(r), sub_idx));
Ok(r)
}
pub(crate) fn emit_class_expression(&self, class: &Class, ctx: &mut CompileCtx) -> Result<u32, String> {
self.emit_class(class, ctx)
}
fn emit_new_expression(&self, ne: &oxide_parser::NewExpression, ctx: &mut CompileCtx) -> Result<u32, String> {
let constructor_reg = self.emit_expression(&ne.callee, ctx)?;
let words = self.emit_call_args(&ne.arguments, ctx)?;
let r = ctx.alloc_reg();
if words.iter().any(|w| w >> 31 == 1) {
ctx.inst(Inst::new_expression_spread(Operand::Reg(r), Operand::Reg(constructor_reg), &words));
} else {
let mut static_regs = words;
let first_arg_reg = if static_regs.is_empty() { 0u32 } else { pack_arg_regs(&mut static_regs, ctx) };
ctx.inst(Inst::new_expression(
Operand::Reg(r),
Operand::Reg(constructor_reg),
Operand::Reg(first_arg_reg),
static_regs.len() as u8,
));
}
Ok(r)
}
pub(crate) fn emit_function_domain(&self, expr: &Expression, ctx: &mut CompileCtx) -> Result<u32, String> {
match expr {
Expression::ArrowFunctionExpression(arrow) => self.emit_arrow_function_expression(arrow, ctx),
Expression::FunctionExpression(fe) => self.emit_function_expression(fe, ctx),
Expression::ClassExpression(class) => self.emit_class_expression(class, ctx),
Expression::NewExpression(ne) => self.emit_new_expression(ne, ctx),
_ => self.emit_unsupported_expression(expr, ctx),
}
}
}