refactor: 函数体编译链收进 FunctionFlags 与 ClassElementHooks 结构体

This commit is contained in:
2026-10-12 16:01:57 +00:00
parent 591c4f5bce
commit 1ca2149f7e
9 changed files with 191 additions and 273 deletions
Generated
+21 -21
View File
@@ -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
View File
@@ -25,7 +25,7 @@ members = [
]
[workspace.package]
version = "0.17.0"
version = "0.17.1"
edition = "2021"
license = "MIT"
rust-version = "1.80"
+25 -19
View File
@@ -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(
&param_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();
+14 -12
View File
@@ -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(
&param_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;
+1 -1
View File
@@ -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。
+17 -29
View File
@@ -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(
&param_names,
body_stmts,
ctx,
is_expr_body,
true,
arrow.has_use_strict_directive(),
None,
)?
} else {
self.compile_function_body(
&param_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(&param_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(&param_names, body_stmts, ctx, own_strict, fn_name)?
} else if fe.generator {
self.compile_generator_body(&param_names, body_stmts, ctx, own_strict, fn_name)?
} else if fe.r#async {
self.compile_async_body(&param_names, body_stmts, ctx, false, false, own_strict, fn_name)?
} else {
self.compile_function_body(&param_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(&param_names, body_stmts, ctx, FunctionBodyContext::Ordinary, flags)?;
if let Some(id) = &fe.id {
sub_module.function_name = Some(id.name.to_string());
}
+102 -180
View File
@@ -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 对象。
///
+1 -1
View File
@@ -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(&param_names, body_stmts, ctx, own_strict, Some(name))?
} else if fd.generator {
self.compile_generator_body(&param_names, body_stmts, ctx, own_strict, Some(name))?
} else if fd.r#async {
self.compile_async_body(&param_names, body_stmts, ctx, false, false, own_strict, Some(name))?
} else {
self.compile_function_body(&param_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(&param_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));