mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-23 18:21:13 +08:00
refactor: 函数体编译链收进 FunctionFlags 与 ClassElementHooks 结构体
This commit is contained in:
Generated
+21
-21
@@ -1160,7 +1160,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_builtins"
|
||||
version = "0.17.0"
|
||||
version = "0.17.1"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"fast-float",
|
||||
@@ -1185,7 +1185,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_bytecode"
|
||||
version = "0.17.0"
|
||||
version = "0.17.1"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"oxide_log",
|
||||
@@ -1193,7 +1193,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_cfg"
|
||||
version = "0.17.0"
|
||||
version = "0.17.1"
|
||||
dependencies = [
|
||||
"oxide_bytecode",
|
||||
"oxide_emit",
|
||||
@@ -1204,7 +1204,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_cli"
|
||||
version = "0.17.0"
|
||||
version = "0.17.1"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"bumpalo",
|
||||
@@ -1228,7 +1228,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_code_cache"
|
||||
version = "0.17.0"
|
||||
version = "0.17.1"
|
||||
dependencies = [
|
||||
"lru",
|
||||
"oxide_bytecode",
|
||||
@@ -1237,7 +1237,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_compiler"
|
||||
version = "0.17.0"
|
||||
version = "0.17.1"
|
||||
dependencies = [
|
||||
"oxide_bytecode",
|
||||
"oxide_cfg",
|
||||
@@ -1258,7 +1258,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_dce"
|
||||
version = "0.17.0"
|
||||
version = "0.17.1"
|
||||
dependencies = [
|
||||
"oxide_bytecode",
|
||||
"oxide_cfg",
|
||||
@@ -1272,7 +1272,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_emit"
|
||||
version = "0.17.0"
|
||||
version = "0.17.1"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"oxc_allocator",
|
||||
@@ -1288,7 +1288,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_engine"
|
||||
version = "0.17.0"
|
||||
version = "0.17.1"
|
||||
dependencies = [
|
||||
"oxide_bytecode",
|
||||
"oxide_compiler",
|
||||
@@ -1300,7 +1300,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_fold"
|
||||
version = "0.17.0"
|
||||
version = "0.17.1"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"oxide_bytecode",
|
||||
@@ -1312,7 +1312,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_ir"
|
||||
version = "0.17.0"
|
||||
version = "0.17.1"
|
||||
dependencies = [
|
||||
"oxide_bytecode",
|
||||
"oxide_log",
|
||||
@@ -1321,7 +1321,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_kernel"
|
||||
version = "0.17.0"
|
||||
version = "0.17.1"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"dashmap",
|
||||
@@ -1335,7 +1335,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_liveness"
|
||||
version = "0.17.0"
|
||||
version = "0.17.1"
|
||||
dependencies = [
|
||||
"oxide_bytecode",
|
||||
"oxide_cfg",
|
||||
@@ -1347,7 +1347,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_log"
|
||||
version = "0.17.0"
|
||||
version = "0.17.1"
|
||||
dependencies = [
|
||||
"tracing",
|
||||
"tracing-appender",
|
||||
@@ -1356,11 +1356,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_net"
|
||||
version = "0.17.0"
|
||||
version = "0.17.1"
|
||||
|
||||
[[package]]
|
||||
name = "oxide_parser"
|
||||
version = "0.17.0"
|
||||
version = "0.17.1"
|
||||
dependencies = [
|
||||
"oxc_allocator",
|
||||
"oxc_ast",
|
||||
@@ -1375,7 +1375,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_regalloc"
|
||||
version = "0.17.0"
|
||||
version = "0.17.1"
|
||||
dependencies = [
|
||||
"oxide_bytecode",
|
||||
"oxide_cfg",
|
||||
@@ -1391,7 +1391,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_runtime_api"
|
||||
version = "0.17.0"
|
||||
version = "0.17.1"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-traits",
|
||||
@@ -1404,7 +1404,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_test262"
|
||||
version = "0.17.0"
|
||||
version = "0.17.1"
|
||||
dependencies = [
|
||||
"oxide_bytecode",
|
||||
"oxide_compiler",
|
||||
@@ -1424,7 +1424,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_types"
|
||||
version = "0.17.0"
|
||||
version = "0.17.1"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"dashmap",
|
||||
@@ -1437,7 +1437,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_vm"
|
||||
version = "0.17.0"
|
||||
version = "0.17.1"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"chrono",
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ members = [
|
||||
]
|
||||
|
||||
[workspace.package]
|
||||
version = "0.17.0"
|
||||
version = "0.17.1"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
rust-version = "1.80"
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
//!
|
||||
//! 函数:`emit_class`。
|
||||
|
||||
use crate::{symbol_table::ScopeKind, CompileCtx, Emitter, FunctionBodyContext};
|
||||
use crate::{
|
||||
symbol_table::ScopeKind, ClassElementHooks, CompileCtx, Emitter, FunctionBodyContext, FunctionFlags,
|
||||
};
|
||||
use oxide_bytecode::module::Constant;
|
||||
use oxide_bytecode::opcode::OpCode;
|
||||
use oxide_ir::inst::Inst;
|
||||
@@ -270,36 +272,40 @@ impl Emitter {
|
||||
Ok(())
|
||||
};
|
||||
|
||||
// 构造器(显式与隐式派生)共用同一组标志与钩子:恒 strict、无表达式体、
|
||||
// 字段发射钩子按派生与否在 super() 前后执行。
|
||||
let ctor_flags = FunctionFlags {
|
||||
is_expression_body: false,
|
||||
is_generator: false,
|
||||
is_async: false,
|
||||
own_strict: true,
|
||||
name: None,
|
||||
};
|
||||
let ctor_hooks = ClassElementHooks {
|
||||
extra_bindings: &self_binding,
|
||||
emit_fields: Some(emit_instance_fields),
|
||||
fields_after_super: is_derived,
|
||||
extra_capture_exprs: &field_value_exprs,
|
||||
extra_upvalue_names: &extra_upvalue_names,
|
||||
};
|
||||
let mut ctor_module = if let Some(method) = constructor_method {
|
||||
let (param_names, body_stmts) = self.extract_function_parts(method.value.as_ref())?;
|
||||
self.compile_function_body_with_field_hooks(
|
||||
self.compile_function_body(
|
||||
¶m_names,
|
||||
body_stmts,
|
||||
ctx,
|
||||
false,
|
||||
&self_binding,
|
||||
FunctionBodyContext::ClassElement,
|
||||
Some(&emit_instance_fields),
|
||||
is_derived,
|
||||
&field_value_exprs,
|
||||
&extra_upvalue_names,
|
||||
true,
|
||||
None,
|
||||
ctor_flags,
|
||||
ctor_hooks,
|
||||
)?
|
||||
} else {
|
||||
let mut module = self.compile_function_body_with_field_hooks(
|
||||
let mut module = self.compile_function_body(
|
||||
&[],
|
||||
&[],
|
||||
ctx,
|
||||
false,
|
||||
&self_binding,
|
||||
FunctionBodyContext::ClassElement,
|
||||
Some(&emit_instance_fields),
|
||||
is_derived,
|
||||
&field_value_exprs,
|
||||
&extra_upvalue_names,
|
||||
true,
|
||||
None,
|
||||
ctor_flags,
|
||||
ctor_hooks,
|
||||
)?;
|
||||
if is_derived {
|
||||
module.insts.clear();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! 类方法 emit:`emit_class_methods` 逐方法构造,`emit_class_method_function`
|
||||
//! 负责单个方法函数体(含 `super` 与 home object)。
|
||||
|
||||
use crate::{CompileCtx, Emitter, FunctionBodyContext};
|
||||
use crate::{ClassElementHooks, CompileCtx, Emitter, FunctionBodyContext, FunctionFlags};
|
||||
use oxide_bytecode::module::Constant;
|
||||
use oxide_bytecode::opcode::OpCode;
|
||||
use oxide_ir::inst::Inst;
|
||||
@@ -125,21 +125,23 @@ impl Emitter {
|
||||
// 生成器/异步/异步生成器方法与普通方法统一走带标志入口:`*m` 置 is_generator,
|
||||
// `async *m` 同时置 is_generator 与 is_async,VM 据此按生成器协议创建对象并
|
||||
// 处理 body 内 SUSPEND/YIELD/异常边界。
|
||||
let mut method_module = self.compile_function_body_with_field_hooks_gen(
|
||||
// 方法无字段发射钩子:以空钩子为基底,注入类名自绑定与 brand upvalue。
|
||||
let mut hooks = ClassElementHooks::none();
|
||||
hooks.extra_bindings = self_binding;
|
||||
hooks.extra_upvalue_names = &extra_uv;
|
||||
let mut method_module = self.compile_function_body(
|
||||
¶m_names,
|
||||
body_stmts,
|
||||
ctx,
|
||||
false,
|
||||
self_binding,
|
||||
FunctionBodyContext::ClassElement,
|
||||
None::<fn(&Emitter, &mut CompileCtx) -> Result<(), String>>,
|
||||
false,
|
||||
&[],
|
||||
&extra_uv,
|
||||
method_value.generator,
|
||||
method_value.r#async,
|
||||
true,
|
||||
None,
|
||||
FunctionFlags {
|
||||
is_expression_body: false,
|
||||
is_generator: method_value.generator,
|
||||
is_async: method_value.r#async,
|
||||
own_strict: true,
|
||||
name: None,
|
||||
},
|
||||
hooks,
|
||||
)?;
|
||||
ctx.in_instance_method = saved_instance;
|
||||
ctx.in_static_method = saved_static;
|
||||
|
||||
@@ -47,7 +47,7 @@ pub struct CompileCtx {
|
||||
/// 本函数是否为异步函数体(`async function` / async 箭头),`assemble_ir` 回写到 IR。
|
||||
pub(crate) is_async: bool,
|
||||
/// 本函数是否为严格模式函数体:自身 directive ‖ 外层严格继承(编译入口设置 +
|
||||
/// 嵌套继承,见 compile_function_body_with_field_hooks_gen),`assemble_ir` 回写到 IR。
|
||||
/// 嵌套继承,见 compile_function_body),`assemble_ir` 回写到 IR。
|
||||
pub(crate) is_strict: bool,
|
||||
/// 是否为脚本顶层模块(emit_program 的根上下文)。顶层 var/function 声明需
|
||||
/// 同步写全局对象属性(脚本环境记录的 var 可经 globalThis 反射);函数体为 false。
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//! `emit_class_expression`、`emit_new_expression`、`emit_function_domain`。
|
||||
|
||||
use crate::expr::call::pack_arg_regs;
|
||||
use crate::{CompileCtx, Emitter, ParamSpec};
|
||||
use crate::{CompileCtx, Emitter, FunctionBodyContext, FunctionFlags, ParamSpec};
|
||||
use oxide_ir::inst::Inst;
|
||||
use oxide_ir::operand::Operand;
|
||||
use oxide_parser::{Class, Expression, Statement};
|
||||
@@ -39,27 +39,15 @@ impl Emitter {
|
||||
let body_stmts = &arrow.body.statements;
|
||||
let is_expr_body = arrow.expression;
|
||||
|
||||
let mut sub_module = if arrow.r#async {
|
||||
self.compile_async_body(
|
||||
¶m_names,
|
||||
body_stmts,
|
||||
ctx,
|
||||
is_expr_body,
|
||||
true,
|
||||
arrow.has_use_strict_directive(),
|
||||
None,
|
||||
)?
|
||||
} else {
|
||||
self.compile_function_body(
|
||||
¶m_names,
|
||||
body_stmts,
|
||||
ctx,
|
||||
is_expr_body,
|
||||
true,
|
||||
arrow.has_use_strict_directive(),
|
||||
None,
|
||||
)?
|
||||
let flags = FunctionFlags {
|
||||
is_expression_body: is_expr_body,
|
||||
is_generator: false,
|
||||
is_async: arrow.r#async,
|
||||
own_strict: arrow.has_use_strict_directive(),
|
||||
name: None,
|
||||
};
|
||||
let mut sub_module =
|
||||
self.compile_simple_function_body(¶m_names, body_stmts, ctx, FunctionBodyContext::Arrow, flags)?;
|
||||
sub_module.is_arrow = true;
|
||||
// 箭头函数词法继承 super 上下文:父带任一 super 标志时,本箭头须挂
|
||||
// home object(运行期从外层函数继承,见 CREATE_CLOSURE 分发)。
|
||||
@@ -106,15 +94,15 @@ impl Emitter {
|
||||
|
||||
let own_strict = fe.has_use_strict_directive();
|
||||
let fn_name = fe.id.as_ref().map(|id| id.name.as_str());
|
||||
let mut sub_module = if fe.generator && fe.r#async {
|
||||
self.compile_async_generator_body(¶m_names, body_stmts, ctx, own_strict, fn_name)?
|
||||
} else if fe.generator {
|
||||
self.compile_generator_body(¶m_names, body_stmts, ctx, own_strict, fn_name)?
|
||||
} else if fe.r#async {
|
||||
self.compile_async_body(¶m_names, body_stmts, ctx, false, false, own_strict, fn_name)?
|
||||
} else {
|
||||
self.compile_function_body(¶m_names, body_stmts, ctx, false, false, own_strict, fn_name)?
|
||||
let flags = FunctionFlags {
|
||||
is_expression_body: false,
|
||||
is_generator: fe.generator,
|
||||
is_async: fe.r#async,
|
||||
own_strict,
|
||||
name: fn_name,
|
||||
};
|
||||
let mut sub_module =
|
||||
self.compile_simple_function_body(¶m_names, body_stmts, ctx, FunctionBodyContext::Ordinary, flags)?;
|
||||
if let Some(id) = &fe.id {
|
||||
sub_module.function_name = Some(id.name.to_string());
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
//! 函数体编译域:`FunctionBodyContext` / `ParamSpec` 类型与函数体编译链
|
||||
//! (参数 prologue、参数默认值与闭包捕获分析、双 sub-pass 语句发射)。
|
||||
//! 函数体编译域:`FunctionBodyContext` / `ParamSpec` / `FunctionFlags` /
|
||||
//! `ClassElementHooks` 类型与函数体编译链(参数 prologue、参数默认值与闭包
|
||||
//! 捕获分析、双 sub-pass 语句发射)。
|
||||
//!
|
||||
//! 两类型经 lib.rs 重导出供各语法域构造实参;编译链为 `Emitter` 方法,
|
||||
//! 捕获分析经自由函数调用 capture 族,与所在文件无关。
|
||||
//! 上下文与参数规格两类型经 lib.rs 重导出供各语法域构造实参;标志与钩子结构体
|
||||
//! 供 crate 内各语法域整体传参;编译链为 `Emitter` 方法,捕获分析经自由函数
|
||||
//! 调用 capture 族,与所在文件无关。
|
||||
|
||||
use std::collections::{BTreeMap, HashSet};
|
||||
|
||||
@@ -58,6 +60,57 @@ impl ParamSpec<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
/// 函数体编译标志:函数体种类与严格性,随函数体编译核心入口整体传入。
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct FunctionFlags<'a> {
|
||||
/// 表达式体(箭头表达式体):体返回最后一个表达式的值,否则返回 undefined。
|
||||
pub is_expression_body: bool,
|
||||
/// 生成器函数(`function*`):VM 按生成器协议创建对象并执行。
|
||||
pub is_generator: bool,
|
||||
/// 异步函数(`async function`):VM 按异步函数协议执行。
|
||||
pub is_async: bool,
|
||||
/// 本函数自身的 strict 指令(类元素恒 strict,不在此传递)。
|
||||
pub own_strict: bool,
|
||||
/// 函数名(具名函数声明/表达式传名,箭头与匿名传 `None`),用于函数名不可写绑定登记。
|
||||
pub name: Option<&'a str>,
|
||||
}
|
||||
|
||||
/// 类元素钩子:类元素函数(构造器/方法/字段)的额外绑定、字段发射与捕获组,
|
||||
/// 非类元素函数传 `ClassElementHooks::none()`。
|
||||
///
|
||||
/// `E` 为字段发射闭包类型(`FnMut(&Emitter, &mut CompileCtx) -> Result<(), String>`),
|
||||
/// 非类元素函数用 `NoFieldsHook` 占位(`emit_fields` 恒为 `None`,永不被调用)。
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct ClassElementHooks<'a, E> {
|
||||
/// 注入函数作用域的额外绑定(类名自绑定等)。
|
||||
pub extra_bindings: &'a [(&'a str, u32)],
|
||||
/// 字段发射钩子(非类元素函数为 `None`)。
|
||||
pub emit_fields: Option<E>,
|
||||
/// 字段在 `super()` 之后发射(派生构造器)。
|
||||
pub fields_after_super: bool,
|
||||
/// 额外捕获表达式(字段值表达式等)。
|
||||
pub extra_capture_exprs: &'a [&'a Expression<'a>],
|
||||
/// 额外 upvalue 名(`@@field_keys` 等合成捕获)。
|
||||
pub extra_upvalue_names: &'a [(String, u8)],
|
||||
}
|
||||
|
||||
/// 无字段发射钩子的占位类型:仅用于 `ClassElementHooks::none()`,`emit_fields`
|
||||
/// 恒为 `None`,永不被调用。
|
||||
type NoFieldsHook = Box<dyn FnMut(&Emitter, &mut CompileCtx) -> Result<(), String>>;
|
||||
|
||||
impl<'a> ClassElementHooks<'a, NoFieldsHook> {
|
||||
/// 非类元素函数的空钩子。
|
||||
pub(crate) fn none() -> Self {
|
||||
Self {
|
||||
extra_bindings: &[],
|
||||
emit_fields: None,
|
||||
fields_after_super: false,
|
||||
extra_capture_exprs: &[],
|
||||
extra_upvalue_names: &[],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Emitter {
|
||||
/// 遍历解构 pattern 收集内嵌默认值表达式(AssignmentPattern.right)与
|
||||
/// 计算键表达式(`{[k]: a}` 的键,运行时求值)——二者都会在参数绑定期被
|
||||
@@ -136,188 +189,38 @@ impl Emitter {
|
||||
Ok((param_specs, body_stmts))
|
||||
}
|
||||
|
||||
/// 编译函数体(函数声明/函数表达式/箭头函数共用),单 pass 完成发码。
|
||||
/// 编译函数体(函数声明/函数表达式/箭头函数/类元素共用核心入口),单 pass 完成发码。
|
||||
///
|
||||
/// `is_expression_body` 为 true(箭头表达式体)时返回最后一个表达式的值,
|
||||
/// 否则返回 undefined。`is_arrow` 控制 super 相关标志的继承:箭头函数词法
|
||||
/// 继承外层 super,普通函数重置 super 作用域。`name` 为函数名(具名函数
|
||||
/// 声明/表达式传名,箭头与匿名传 `None`),用于函数名不可写绑定登记。
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) fn compile_function_body<'a>(
|
||||
&self, param_specs: &[ParamSpec<'a>], body_stmts: &[Statement<'a>], parent_ctx: &CompileCtx,
|
||||
is_expression_body: bool, is_arrow: bool, own_strict: bool, name: Option<&str>,
|
||||
) -> Result<IRFunction, String> {
|
||||
self.compile_function_body_with_flags(
|
||||
param_specs,
|
||||
body_stmts,
|
||||
parent_ctx,
|
||||
is_expression_body,
|
||||
is_arrow,
|
||||
false,
|
||||
false,
|
||||
own_strict,
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
/// 编译函数体并显式指定生成器标志(`function*` 走此入口)。
|
||||
pub(crate) fn compile_generator_body<'a>(
|
||||
&self, param_specs: &[ParamSpec<'a>], body_stmts: &[Statement<'a>], parent_ctx: &CompileCtx, own_strict: bool,
|
||||
name: Option<&str>,
|
||||
) -> Result<IRFunction, String> {
|
||||
self.compile_function_body_with_flags(
|
||||
param_specs,
|
||||
body_stmts,
|
||||
parent_ctx,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
own_strict,
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
/// 编译异步生成器函数体(`async function*` / async 生成器表达式走此入口):
|
||||
/// 同时标记 `is_generator` 与 `is_async`,VM 调用时按异步生成器协议执行
|
||||
/// (next 返回 Promise,yield 挂起与 await 挂起共存)。
|
||||
pub(crate) fn compile_async_generator_body<'a>(
|
||||
&self, param_specs: &[ParamSpec<'a>], body_stmts: &[Statement<'a>], parent_ctx: &CompileCtx, own_strict: bool,
|
||||
name: Option<&str>,
|
||||
) -> Result<IRFunction, String> {
|
||||
self.compile_function_body_with_flags(
|
||||
param_specs,
|
||||
body_stmts,
|
||||
parent_ctx,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
own_strict,
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
/// 编译异步函数体(`async function` / async 箭头走此入口):`is_async` 使
|
||||
/// `assemble_ir` 标记模块,VM 调用时按异步函数协议执行。
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) fn compile_async_body<'a>(
|
||||
&self, param_specs: &[ParamSpec<'a>], body_stmts: &[Statement<'a>], parent_ctx: &CompileCtx,
|
||||
is_expression_body: bool, is_arrow: bool, own_strict: bool, name: Option<&str>,
|
||||
) -> Result<IRFunction, String> {
|
||||
self.compile_function_body_with_flags(
|
||||
param_specs,
|
||||
body_stmts,
|
||||
parent_ctx,
|
||||
is_expression_body,
|
||||
is_arrow,
|
||||
false,
|
||||
true,
|
||||
own_strict,
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn compile_function_body_with_flags<'a>(
|
||||
&self, param_specs: &[ParamSpec<'a>], body_stmts: &[Statement<'a>], parent_ctx: &CompileCtx,
|
||||
is_expression_body: bool, is_arrow: bool, is_generator: bool, is_async: bool, own_strict: bool,
|
||||
name: Option<&str>,
|
||||
) -> Result<IRFunction, String> {
|
||||
let body_context = if is_arrow {
|
||||
FunctionBodyContext::Arrow
|
||||
} else {
|
||||
FunctionBodyContext::Ordinary
|
||||
};
|
||||
self.compile_function_body_with_bindings_gen(
|
||||
param_specs,
|
||||
body_stmts,
|
||||
parent_ctx,
|
||||
is_expression_body,
|
||||
&[],
|
||||
body_context,
|
||||
is_generator,
|
||||
is_async,
|
||||
own_strict,
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) fn compile_function_body_with_bindings_gen<'a>(
|
||||
&self, param_specs: &[ParamSpec<'a>], body_stmts: &[Statement<'a>], parent_ctx: &CompileCtx,
|
||||
is_expression_body: bool, extra_bindings: &[(&str, u32)], body_context: FunctionBodyContext,
|
||||
is_generator: bool, is_async: bool, own_strict: bool, name: Option<&str>,
|
||||
) -> Result<IRFunction, String> {
|
||||
self.compile_function_body_with_field_hooks_gen(
|
||||
param_specs,
|
||||
body_stmts,
|
||||
parent_ctx,
|
||||
is_expression_body,
|
||||
extra_bindings,
|
||||
body_context,
|
||||
None::<fn(&Emitter, &mut CompileCtx) -> Result<(), String>>,
|
||||
false,
|
||||
&[],
|
||||
&[],
|
||||
is_generator,
|
||||
is_async,
|
||||
own_strict,
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
/// 预注册 builtin 引用并编译函数体(普通/箭头/类元素方法共用入口)。
|
||||
/// `flags` 携带函数体种类与严格性(表达式体、生成器、异步、自身 strict、函数名);
|
||||
/// `hooks` 携带类元素钩子(额外绑定、字段发射、捕获组),非类元素函数传
|
||||
/// `ClassElementHooks::none()`。`body_context` 决定 `this`/`super` 绑定与参数
|
||||
/// 前导形态:箭头词法继承外层 super,普通函数重置 super 作用域,类元素按类语义。
|
||||
///
|
||||
/// 本函数体内任意位置(表达式、成员对象、调用实参、类字段等)引用的内置全局
|
||||
/// 标识符,其寄存器槽都先于任何临时寄存器登记。
|
||||
///
|
||||
/// vreg 化后临时值不复用(独立 vreg),但 builtin 槽预注册仍保证分配序稳定:
|
||||
/// builtin 槽先于临时值池,嵌套函数继承边界不受扰。
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) fn compile_function_body_with_field_hooks<'a, E>(
|
||||
&self, param_specs: &[ParamSpec<'a>], body_stmts: &[Statement<'a>], parent_ctx: &CompileCtx,
|
||||
is_expression_body: bool, extra_bindings: &[(&str, u32)], body_context: FunctionBodyContext,
|
||||
emit_fields: Option<E>, fields_after_super: bool, extra_capture_exprs: &[&'a Expression<'a>],
|
||||
extra_upvalue_names: &[(String, u8)], own_strict: bool, name: Option<&str>,
|
||||
) -> Result<IRFunction, String>
|
||||
where
|
||||
E: FnMut(&Emitter, &mut CompileCtx) -> Result<(), String>,
|
||||
{
|
||||
self.compile_function_body_with_field_hooks_gen(
|
||||
param_specs,
|
||||
body_stmts,
|
||||
parent_ctx,
|
||||
is_expression_body,
|
||||
extra_bindings,
|
||||
body_context,
|
||||
emit_fields,
|
||||
fields_after_super,
|
||||
extra_capture_exprs,
|
||||
extra_upvalue_names,
|
||||
false,
|
||||
false,
|
||||
own_strict,
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) fn compile_function_body_with_field_hooks_gen<'a, E>(
|
||||
&self, param_specs: &[ParamSpec<'a>], body_stmts: &[Statement<'a>], parent_ctx: &CompileCtx,
|
||||
is_expression_body: bool, extra_bindings: &[(&str, u32)], body_context: FunctionBodyContext,
|
||||
mut emit_fields: Option<E>, fields_after_super: bool, extra_capture_exprs: &[&'a Expression<'a>],
|
||||
extra_upvalue_names: &[(String, u8)], is_generator: bool, is_async: bool, own_strict: bool, name: Option<&str>,
|
||||
pub(crate) fn compile_function_body<'a, E>(
|
||||
&self,
|
||||
param_specs: &[ParamSpec<'a>],
|
||||
body_stmts: &[Statement<'a>],
|
||||
parent_ctx: &CompileCtx,
|
||||
body_context: FunctionBodyContext,
|
||||
flags: FunctionFlags<'a>,
|
||||
hooks: ClassElementHooks<'a, E>,
|
||||
) -> Result<IRFunction, String>
|
||||
where
|
||||
E: FnMut(&Emitter, &mut CompileCtx) -> Result<(), String>,
|
||||
{
|
||||
let mut ctx = CompileCtx::new();
|
||||
ctx.is_generator = is_generator;
|
||||
ctx.is_async = is_async;
|
||||
ctx.is_generator = flags.is_generator;
|
||||
ctx.is_async = flags.is_async;
|
||||
// 函数 strict = 自身 directive ‖ 外层严格(规范不可解除);
|
||||
// 类元素方法/构造器恒 strict(ClassBody 是严格模式代码)。
|
||||
ctx.is_strict = own_strict || matches!(body_context, FunctionBodyContext::ClassElement) || parent_ctx.is_strict;
|
||||
ctx.is_strict = flags.own_strict
|
||||
|| matches!(body_context, FunctionBodyContext::ClassElement)
|
||||
|| parent_ctx.is_strict;
|
||||
|
||||
// 形参名集(含解构叶子与 rest):块级函数名同名的 web-compat 守卫查此集。
|
||||
let mut param_names = HashSet::new();
|
||||
@@ -412,7 +315,7 @@ impl Emitter {
|
||||
// eval 起源随作用域继承:eval 顶层 var/函数名在嵌套函数内同样可删(物化
|
||||
// c:true 全局属性),delete 分类判定读此标志。
|
||||
ctx.is_eval_origin = parent_ctx.is_eval_origin;
|
||||
for (name, reg) in extra_bindings {
|
||||
for (name, reg) in hooks.extra_bindings {
|
||||
ctx.scopes.symbols.scopes[0].bindings.insert(
|
||||
(*name).to_string(),
|
||||
Binding {
|
||||
@@ -452,9 +355,9 @@ impl Emitter {
|
||||
parent_ctx,
|
||||
&mut ctx,
|
||||
body_context,
|
||||
extra_capture_exprs,
|
||||
extra_upvalue_names,
|
||||
name,
|
||||
hooks.extra_capture_exprs,
|
||||
hooks.extra_upvalue_names,
|
||||
flags.name,
|
||||
&scope_names,
|
||||
)?;
|
||||
// 实例字段 computed key 数组所在 upvalue 下标,供字段初始化 emit 定位。
|
||||
@@ -524,7 +427,7 @@ impl Emitter {
|
||||
let has_using = Self::scope_contains_using(body_stmts);
|
||||
// 生成器:body 起点标记——调用时参数初始化(emit_params_prologue)结束后挂起于此,
|
||||
// 参数副作用/异常在 `g()` 调用时刻生效,首次 next() 从这继续执行 body。
|
||||
if is_generator {
|
||||
if flags.is_generator {
|
||||
ctx.inst(Inst::suspend_body());
|
||||
// 生成器体环境在 `g()` 调用时建立、首次 next() 从挂起点后继续:水位登记
|
||||
// 在挂起点之后,体声明的资源只在体尾(生成器完成)释放。
|
||||
@@ -536,8 +439,8 @@ impl Emitter {
|
||||
ctx.emit_dispose_mark();
|
||||
}
|
||||
|
||||
if let Some(emit) = emit_fields.as_mut() {
|
||||
if fields_after_super {
|
||||
if let Some(mut emit) = hooks.emit_fields {
|
||||
if hooks.fields_after_super {
|
||||
let mut parent_insts = Vec::new();
|
||||
let mut parent_label_pos = Vec::new();
|
||||
std::mem::swap(&mut ctx.insts, &mut parent_insts);
|
||||
@@ -568,7 +471,7 @@ impl Emitter {
|
||||
if has_using {
|
||||
ctx.emit_dispose_pop();
|
||||
}
|
||||
if is_expression_body {
|
||||
if flags.is_expression_body {
|
||||
if let Some(reg) = last_result_reg {
|
||||
ctx.inst(Inst::ret(Operand::Reg(reg), 0, 0, 0));
|
||||
} else {
|
||||
@@ -599,6 +502,25 @@ impl Emitter {
|
||||
Ok(ir)
|
||||
}
|
||||
|
||||
/// 非类元素函数体便捷入口:空钩子,等价于核心入口传 `ClassElementHooks::none()`。
|
||||
pub(crate) fn compile_simple_function_body<'a>(
|
||||
&self,
|
||||
param_specs: &[ParamSpec<'a>],
|
||||
body_stmts: &[Statement<'a>],
|
||||
parent_ctx: &CompileCtx,
|
||||
body_context: FunctionBodyContext,
|
||||
flags: FunctionFlags<'a>,
|
||||
) -> Result<IRFunction, String> {
|
||||
self.compile_function_body(
|
||||
param_specs,
|
||||
body_stmts,
|
||||
parent_ctx,
|
||||
body_context,
|
||||
flags,
|
||||
ClassElementHooks::none(),
|
||||
)
|
||||
}
|
||||
|
||||
/// 规范 `argumentsObjNeeded` 的引擎判据:函数作用域是否声明 `arguments`
|
||||
/// 从而抑制自动 arguments 对象。
|
||||
///
|
||||
|
||||
@@ -25,6 +25,6 @@ pub use compile_ctx::CompileCtx;
|
||||
pub use emit::Emitter;
|
||||
pub use emit::{is_anonymous_function_definition, is_int_literal, is_side_effect_free};
|
||||
pub use emit_ctx::LabelScope;
|
||||
pub use function_body::{FunctionBodyContext, ParamSpec};
|
||||
pub use function_body::{ClassElementHooks, FunctionBodyContext, FunctionFlags, ParamSpec};
|
||||
pub use oxide_bytecode::module::Constant;
|
||||
pub use oxide_parser::{AssignmentOperator, BinaryOperator, UnaryOperator};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! 函数声明语句 emit:`emit_function_declaration_statement` 创建闭包并绑定函数名。
|
||||
|
||||
use crate::symbol_table::ScopeKind;
|
||||
use crate::{CompileCtx, Emitter, ParamSpec};
|
||||
use crate::{CompileCtx, Emitter, FunctionBodyContext, FunctionFlags, ParamSpec};
|
||||
use oxide_bytecode::opcode::OpCode;
|
||||
use oxide_ir::inst::Inst;
|
||||
use oxide_ir::operand::Operand;
|
||||
@@ -151,15 +151,15 @@ impl Emitter {
|
||||
}
|
||||
let body_stmts: &[Statement] = if let Some(body) = &fd.body { &body.statements } else { &[] };
|
||||
let own_strict = fd.has_use_strict_directive();
|
||||
let mut sub_module = if fd.generator && fd.r#async {
|
||||
self.compile_async_generator_body(¶m_names, body_stmts, ctx, own_strict, Some(name))?
|
||||
} else if fd.generator {
|
||||
self.compile_generator_body(¶m_names, body_stmts, ctx, own_strict, Some(name))?
|
||||
} else if fd.r#async {
|
||||
self.compile_async_body(¶m_names, body_stmts, ctx, false, false, own_strict, Some(name))?
|
||||
} else {
|
||||
self.compile_function_body(¶m_names, body_stmts, ctx, false, false, own_strict, Some(name))?
|
||||
let flags = FunctionFlags {
|
||||
is_expression_body: false,
|
||||
is_generator: fd.generator,
|
||||
is_async: fd.r#async,
|
||||
own_strict,
|
||||
name: Some(name),
|
||||
};
|
||||
let mut sub_module =
|
||||
self.compile_simple_function_body(¶m_names, body_stmts, ctx, FunctionBodyContext::Ordinary, flags)?;
|
||||
sub_module.function_name = Some(name.to_string());
|
||||
ctx.nested.push(sub_module);
|
||||
ctx.inst(Inst::create_closure(Operand::Reg(reg), ctx.nested.len() as u16));
|
||||
|
||||
Reference in New Issue
Block a user