refactor: 函数 strict 标志入 IR/编译/缓存链(零行为地基)
This commit is contained in:
@@ -58,6 +58,8 @@ pub struct CompiledModule {
|
|||||||
pub sub_modules: Vec<Arc<CompiledModule>>,
|
pub sub_modules: Vec<Arc<CompiledModule>>,
|
||||||
/// 是否为箭头函数体(箭头函数从外围作用域词法捕获 `this`)。
|
/// 是否为箭头函数体(箭头函数从外围作用域词法捕获 `this`)。
|
||||||
pub is_arrow: bool,
|
pub is_arrow: bool,
|
||||||
|
/// 是否为严格模式函数体:VM 帧入口据其判定 sloppy `this` 替换。
|
||||||
|
pub is_strict: bool,
|
||||||
/// 捕获 `this` 的 JsValue 在常量池中的下标;0 表示未捕获,使用标准 this 绑定。
|
/// 捕获 `this` 的 JsValue 在常量池中的下标;0 表示未捕获,使用标准 this 绑定。
|
||||||
pub captured_this_const_idx: u16,
|
pub captured_this_const_idx: u16,
|
||||||
/// 由赋值上下文推断的函数名,在变量声明 / 对象属性赋值点设置。
|
/// 由赋值上下文推断的函数名,在变量声明 / 对象属性赋值点设置。
|
||||||
@@ -96,6 +98,7 @@ impl CompiledModule {
|
|||||||
builtin_reg_map: Vec::new(),
|
builtin_reg_map: Vec::new(),
|
||||||
sub_modules: Vec::new(),
|
sub_modules: Vec::new(),
|
||||||
is_arrow: false,
|
is_arrow: false,
|
||||||
|
is_strict: false,
|
||||||
captured_this_const_idx: 0,
|
captured_this_const_idx: 0,
|
||||||
function_name: None,
|
function_name: None,
|
||||||
function_length: 0,
|
function_length: 0,
|
||||||
@@ -129,6 +132,7 @@ impl Clone for CompiledModule {
|
|||||||
builtin_reg_map: self.builtin_reg_map.clone(),
|
builtin_reg_map: self.builtin_reg_map.clone(),
|
||||||
sub_modules: self.sub_modules.clone(),
|
sub_modules: self.sub_modules.clone(),
|
||||||
is_arrow: self.is_arrow,
|
is_arrow: self.is_arrow,
|
||||||
|
is_strict: self.is_strict,
|
||||||
captured_this_const_idx: self.captured_this_const_idx,
|
captured_this_const_idx: self.captured_this_const_idx,
|
||||||
function_name: self.function_name.clone(),
|
function_name: self.function_name.clone(),
|
||||||
function_length: self.function_length,
|
function_length: self.function_length,
|
||||||
|
|||||||
@@ -56,6 +56,12 @@ fn hash_program(program: &oxide_parser::Program, include_binding_names: bool) ->
|
|||||||
statement::hash_statement(stmt, &mut h, include_binding_names);
|
statement::hash_statement(stmt, &mut h, include_binding_names);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// directives 决定脚本/函数严格模式:不纳入 hash 时 `"use strict"; f()`
|
||||||
|
// 与 `f()` 缓存键相同,复用错误字节码(严格标志随缓存命中错配)。
|
||||||
|
for directive in &program.directives {
|
||||||
|
directive.directive.as_str().hash(&mut h);
|
||||||
|
}
|
||||||
|
|
||||||
h.finish()
|
h.finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,10 @@ impl Emitter {
|
|||||||
pub(crate) fn emit_class_with_binding(
|
pub(crate) fn emit_class_with_binding(
|
||||||
&self, class: &Class, ctx: &mut CompileCtx, binding_reg: Option<u32>,
|
&self, class: &Class, ctx: &mut CompileCtx, binding_reg: Option<u32>,
|
||||||
) -> Result<u32, String> {
|
) -> Result<u32, String> {
|
||||||
|
// 类定义体是严格模式代码:字段初始化/静态块/extends 表达式内嵌套函数以
|
||||||
|
// 本 ctx 为父 ctx,类编译期间强制 strict(函数末尾恢复外层标志)。
|
||||||
|
let saved_strict = ctx.is_strict;
|
||||||
|
ctx.is_strict = true;
|
||||||
let ctor_name = class.id.as_ref().map(|id| id.name.to_string());
|
let ctor_name = class.id.as_ref().map(|id| id.name.to_string());
|
||||||
// 类声明由调用方提供外层绑定槽(binding_reg=Some),类表达式无外部槽
|
// 类声明由调用方提供外层绑定槽(binding_reg=Some),类表达式无外部槽
|
||||||
// (None,类名是类体内独立 const 绑定)。真实名 cell 仅声明路径指向
|
// (None,类名是类体内独立 const 绑定)。真实名 cell 仅声明路径指向
|
||||||
@@ -264,6 +268,7 @@ impl Emitter {
|
|||||||
is_derived,
|
is_derived,
|
||||||
&field_value_exprs,
|
&field_value_exprs,
|
||||||
&extra_upvalue_names,
|
&extra_upvalue_names,
|
||||||
|
true,
|
||||||
)?
|
)?
|
||||||
} else {
|
} else {
|
||||||
let mut module = self.compile_function_body_with_field_hooks(
|
let mut module = self.compile_function_body_with_field_hooks(
|
||||||
@@ -277,6 +282,7 @@ impl Emitter {
|
|||||||
is_derived,
|
is_derived,
|
||||||
&field_value_exprs,
|
&field_value_exprs,
|
||||||
&extra_upvalue_names,
|
&extra_upvalue_names,
|
||||||
|
true,
|
||||||
)?;
|
)?;
|
||||||
if is_derived {
|
if is_derived {
|
||||||
module.insts.clear();
|
module.insts.clear();
|
||||||
@@ -288,6 +294,8 @@ impl Emitter {
|
|||||||
module.insts.push(Inst::super_call_spread(Operand::Reg(0), &[0x8000_0000 | 1]));
|
module.insts.push(Inst::super_call_spread(Operand::Reg(0), &[0x8000_0000 | 1]));
|
||||||
// 字段初始化直接重发:构造器 upvalue/内置槽引用须与首轮编译产物对齐。
|
// 字段初始化直接重发:构造器 upvalue/内置槽引用须与首轮编译产物对齐。
|
||||||
let mut field_ctx = CompileCtx::new();
|
let mut field_ctx = CompileCtx::new();
|
||||||
|
// 字段表达式运行于构造器帧,构造器恒 strict,字段 ctx 同步置位。
|
||||||
|
field_ctx.is_strict = true;
|
||||||
field_ctx.scopes.private_name_map =
|
field_ctx.scopes.private_name_map =
|
||||||
private_names.iter().map(|(n, id, _, _)| (n.clone(), *id)).collect();
|
private_names.iter().map(|(n, id, _, _)| (n.clone(), *id)).collect();
|
||||||
field_ctx.scopes.builtin_reg_map = module.builtin_reg_map.clone();
|
field_ctx.scopes.builtin_reg_map = module.builtin_reg_map.clone();
|
||||||
@@ -427,6 +435,8 @@ impl Emitter {
|
|||||||
ctx.scopes.private_name_map = saved_private_names;
|
ctx.scopes.private_name_map = saved_private_names;
|
||||||
ctx.scopes.private_element_kinds = saved_private_kinds;
|
ctx.scopes.private_element_kinds = saved_private_kinds;
|
||||||
ctx.scopes.private_brand_id = saved_brand_id;
|
ctx.scopes.private_brand_id = saved_brand_id;
|
||||||
|
// 类编译结束恢复外层 strict 标志:类在 sloppy 上下文时不得泄漏 strict 到类后代码。
|
||||||
|
ctx.is_strict = saved_strict;
|
||||||
Ok(ctor_reg)
|
Ok(ctor_reg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,6 +128,7 @@ impl Emitter {
|
|||||||
&extra_uv,
|
&extra_uv,
|
||||||
method_value.generator,
|
method_value.generator,
|
||||||
method_value.r#async,
|
method_value.r#async,
|
||||||
|
true,
|
||||||
)?;
|
)?;
|
||||||
ctx.in_instance_method = saved_instance;
|
ctx.in_instance_method = saved_instance;
|
||||||
ctx.in_static_method = saved_static;
|
ctx.in_static_method = saved_static;
|
||||||
|
|||||||
@@ -172,6 +172,9 @@ pub struct CompileCtx {
|
|||||||
pub(crate) is_generator: bool,
|
pub(crate) is_generator: bool,
|
||||||
/// 本函数是否为异步函数体(`async function` / async 箭头),`assemble_ir` 回写到 IR。
|
/// 本函数是否为异步函数体(`async function` / async 箭头),`assemble_ir` 回写到 IR。
|
||||||
pub(crate) is_async: bool,
|
pub(crate) is_async: bool,
|
||||||
|
/// 本函数是否为严格模式函数体:自身 directive ‖ 外层严格继承(编译入口设置 +
|
||||||
|
/// 嵌套继承,见 compile_function_body_with_field_hooks_gen),`assemble_ir` 回写到 IR。
|
||||||
|
pub(crate) is_strict: bool,
|
||||||
/// 是否为脚本顶层模块(emit_program 的根上下文)。顶层 var/function 声明需
|
/// 是否为脚本顶层模块(emit_program 的根上下文)。顶层 var/function 声明需
|
||||||
/// 同步写全局对象属性(脚本环境记录的 var 可经 globalThis 反射);函数体为 false。
|
/// 同步写全局对象属性(脚本环境记录的 var 可经 globalThis 反射);函数体为 false。
|
||||||
pub(crate) is_global_scope: bool,
|
pub(crate) is_global_scope: bool,
|
||||||
@@ -306,6 +309,7 @@ impl CompileCtx {
|
|||||||
in_static_method: false,
|
in_static_method: false,
|
||||||
is_generator: false,
|
is_generator: false,
|
||||||
is_async: false,
|
is_async: false,
|
||||||
|
is_strict: false,
|
||||||
is_global_scope: false,
|
is_global_scope: false,
|
||||||
static_block_this_reg: None,
|
static_block_this_reg: None,
|
||||||
field_buffer: None,
|
field_buffer: None,
|
||||||
@@ -701,6 +705,7 @@ impl CompileCtx {
|
|||||||
needs_home_object: false,
|
needs_home_object: false,
|
||||||
is_generator: self.is_generator,
|
is_generator: self.is_generator,
|
||||||
is_async: self.is_async,
|
is_async: self.is_async,
|
||||||
|
is_strict: self.is_strict,
|
||||||
captured_this_const_idx: 0,
|
captured_this_const_idx: 0,
|
||||||
function_name: None,
|
function_name: None,
|
||||||
function_length: self.function_length,
|
function_length: self.function_length,
|
||||||
@@ -874,7 +879,7 @@ impl Emitter {
|
|||||||
/// 继承外层 super,普通函数重置 super 作用域。
|
/// 继承外层 super,普通函数重置 super 作用域。
|
||||||
pub(crate) fn compile_function_body<'a>(
|
pub(crate) fn compile_function_body<'a>(
|
||||||
&self, param_specs: &[ParamSpec<'a>], body_stmts: &[Statement<'a>], parent_ctx: &CompileCtx,
|
&self, param_specs: &[ParamSpec<'a>], body_stmts: &[Statement<'a>], parent_ctx: &CompileCtx,
|
||||||
is_expression_body: bool, is_arrow: bool,
|
is_expression_body: bool, is_arrow: bool, own_strict: bool,
|
||||||
) -> Result<IRFunction, String> {
|
) -> Result<IRFunction, String> {
|
||||||
self.compile_function_body_with_flags(
|
self.compile_function_body_with_flags(
|
||||||
param_specs,
|
param_specs,
|
||||||
@@ -884,30 +889,40 @@ impl Emitter {
|
|||||||
is_arrow,
|
is_arrow,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
own_strict,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 编译函数体并显式指定生成器标志(`function*` 走此入口)。
|
/// 编译函数体并显式指定生成器标志(`function*` 走此入口)。
|
||||||
pub(crate) fn compile_generator_body<'a>(
|
pub(crate) fn compile_generator_body<'a>(
|
||||||
&self, param_specs: &[ParamSpec<'a>], body_stmts: &[Statement<'a>], parent_ctx: &CompileCtx,
|
&self, param_specs: &[ParamSpec<'a>], body_stmts: &[Statement<'a>], parent_ctx: &CompileCtx, own_strict: bool,
|
||||||
) -> Result<IRFunction, String> {
|
) -> Result<IRFunction, String> {
|
||||||
self.compile_function_body_with_flags(param_specs, body_stmts, parent_ctx, false, false, true, false)
|
self.compile_function_body_with_flags(
|
||||||
|
param_specs,
|
||||||
|
body_stmts,
|
||||||
|
parent_ctx,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
own_strict,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 编译异步生成器函数体(`async function*` / async 生成器表达式走此入口):
|
/// 编译异步生成器函数体(`async function*` / async 生成器表达式走此入口):
|
||||||
/// 同时标记 `is_generator` 与 `is_async`,VM 调用时按异步生成器协议执行
|
/// 同时标记 `is_generator` 与 `is_async`,VM 调用时按异步生成器协议执行
|
||||||
/// (next 返回 Promise,yield 挂起与 await 挂起共存)。
|
/// (next 返回 Promise,yield 挂起与 await 挂起共存)。
|
||||||
pub(crate) fn compile_async_generator_body<'a>(
|
pub(crate) fn compile_async_generator_body<'a>(
|
||||||
&self, param_specs: &[ParamSpec<'a>], body_stmts: &[Statement<'a>], parent_ctx: &CompileCtx,
|
&self, param_specs: &[ParamSpec<'a>], body_stmts: &[Statement<'a>], parent_ctx: &CompileCtx, own_strict: bool,
|
||||||
) -> Result<IRFunction, String> {
|
) -> Result<IRFunction, String> {
|
||||||
self.compile_function_body_with_flags(param_specs, body_stmts, parent_ctx, false, false, true, true)
|
self.compile_function_body_with_flags(param_specs, body_stmts, parent_ctx, false, false, true, true, own_strict)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 编译异步函数体(`async function` / async 箭头走此入口):`is_async` 使
|
/// 编译异步函数体(`async function` / async 箭头走此入口):`is_async` 使
|
||||||
/// `assemble_ir` 标记模块,VM 调用时按异步函数协议执行。
|
/// `assemble_ir` 标记模块,VM 调用时按异步函数协议执行。
|
||||||
pub(crate) fn compile_async_body<'a>(
|
pub(crate) fn compile_async_body<'a>(
|
||||||
&self, param_specs: &[ParamSpec<'a>], body_stmts: &[Statement<'a>], parent_ctx: &CompileCtx,
|
&self, param_specs: &[ParamSpec<'a>], body_stmts: &[Statement<'a>], parent_ctx: &CompileCtx,
|
||||||
is_expression_body: bool, is_arrow: bool,
|
is_expression_body: bool, is_arrow: bool, own_strict: bool,
|
||||||
) -> Result<IRFunction, String> {
|
) -> Result<IRFunction, String> {
|
||||||
self.compile_function_body_with_flags(
|
self.compile_function_body_with_flags(
|
||||||
param_specs,
|
param_specs,
|
||||||
@@ -917,13 +932,14 @@ impl Emitter {
|
|||||||
is_arrow,
|
is_arrow,
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
|
own_strict,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn compile_function_body_with_flags<'a>(
|
fn compile_function_body_with_flags<'a>(
|
||||||
&self, param_specs: &[ParamSpec<'a>], body_stmts: &[Statement<'a>], parent_ctx: &CompileCtx,
|
&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,
|
is_expression_body: bool, is_arrow: bool, is_generator: bool, is_async: bool, own_strict: bool,
|
||||||
) -> Result<IRFunction, String> {
|
) -> Result<IRFunction, String> {
|
||||||
let body_context = if is_arrow {
|
let body_context = if is_arrow {
|
||||||
FunctionBodyContext::Arrow
|
FunctionBodyContext::Arrow
|
||||||
@@ -939,6 +955,7 @@ impl Emitter {
|
|||||||
body_context,
|
body_context,
|
||||||
is_generator,
|
is_generator,
|
||||||
is_async,
|
is_async,
|
||||||
|
own_strict,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -946,7 +963,7 @@ impl Emitter {
|
|||||||
pub(crate) fn compile_function_body_with_bindings_gen<'a>(
|
pub(crate) fn compile_function_body_with_bindings_gen<'a>(
|
||||||
&self, param_specs: &[ParamSpec<'a>], body_stmts: &[Statement<'a>], parent_ctx: &CompileCtx,
|
&self, param_specs: &[ParamSpec<'a>], body_stmts: &[Statement<'a>], parent_ctx: &CompileCtx,
|
||||||
is_expression_body: bool, extra_bindings: &[(&str, u32)], body_context: FunctionBodyContext,
|
is_expression_body: bool, extra_bindings: &[(&str, u32)], body_context: FunctionBodyContext,
|
||||||
is_generator: bool, is_async: bool,
|
is_generator: bool, is_async: bool, own_strict: bool,
|
||||||
) -> Result<IRFunction, String> {
|
) -> Result<IRFunction, String> {
|
||||||
self.compile_function_body_with_field_hooks_gen(
|
self.compile_function_body_with_field_hooks_gen(
|
||||||
param_specs,
|
param_specs,
|
||||||
@@ -961,6 +978,7 @@ impl Emitter {
|
|||||||
&[],
|
&[],
|
||||||
is_generator,
|
is_generator,
|
||||||
is_async,
|
is_async,
|
||||||
|
own_strict,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -976,7 +994,7 @@ impl Emitter {
|
|||||||
&self, param_specs: &[ParamSpec<'a>], body_stmts: &[Statement<'a>], parent_ctx: &CompileCtx,
|
&self, param_specs: &[ParamSpec<'a>], body_stmts: &[Statement<'a>], parent_ctx: &CompileCtx,
|
||||||
is_expression_body: bool, extra_bindings: &[(&str, u32)], body_context: FunctionBodyContext,
|
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>],
|
emit_fields: Option<E>, fields_after_super: bool, extra_capture_exprs: &[&'a Expression<'a>],
|
||||||
extra_upvalue_names: &[(&str, u8)],
|
extra_upvalue_names: &[(&str, u8)], own_strict: bool,
|
||||||
) -> Result<IRFunction, String>
|
) -> Result<IRFunction, String>
|
||||||
where
|
where
|
||||||
E: FnMut(&Emitter, &mut CompileCtx) -> Result<(), String>,
|
E: FnMut(&Emitter, &mut CompileCtx) -> Result<(), String>,
|
||||||
@@ -994,6 +1012,7 @@ impl Emitter {
|
|||||||
extra_upvalue_names,
|
extra_upvalue_names,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
own_strict,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1002,7 +1021,7 @@ impl Emitter {
|
|||||||
&self, param_specs: &[ParamSpec<'a>], body_stmts: &[Statement<'a>], parent_ctx: &CompileCtx,
|
&self, param_specs: &[ParamSpec<'a>], body_stmts: &[Statement<'a>], parent_ctx: &CompileCtx,
|
||||||
is_expression_body: bool, extra_bindings: &[(&str, u32)], body_context: FunctionBodyContext,
|
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>],
|
mut emit_fields: Option<E>, fields_after_super: bool, extra_capture_exprs: &[&'a Expression<'a>],
|
||||||
extra_upvalue_names: &[(&str, u8)], is_generator: bool, is_async: bool,
|
extra_upvalue_names: &[(&str, u8)], is_generator: bool, is_async: bool, own_strict: bool,
|
||||||
) -> Result<IRFunction, String>
|
) -> Result<IRFunction, String>
|
||||||
where
|
where
|
||||||
E: FnMut(&Emitter, &mut CompileCtx) -> Result<(), String>,
|
E: FnMut(&Emitter, &mut CompileCtx) -> Result<(), String>,
|
||||||
@@ -1010,6 +1029,9 @@ impl Emitter {
|
|||||||
let mut ctx = CompileCtx::new();
|
let mut ctx = CompileCtx::new();
|
||||||
ctx.is_generator = is_generator;
|
ctx.is_generator = is_generator;
|
||||||
ctx.is_async = is_async;
|
ctx.is_async = is_async;
|
||||||
|
// 函数 strict = 自身 directive ‖ 外层严格(规范不可解除);
|
||||||
|
// 类元素方法/构造器恒 strict(ClassBody 是严格模式代码)。
|
||||||
|
ctx.is_strict = own_strict || matches!(body_context, FunctionBodyContext::ClassElement) || parent_ctx.is_strict;
|
||||||
|
|
||||||
// length = 第一个带默认值形参之前的形参数(解构默认与标识符默认同规则);
|
// length = 第一个带默认值形参之前的形参数(解构默认与标识符默认同规则);
|
||||||
// rest 参数不计入 length(以 0 结尾即止)。
|
// rest 参数不计入 length(以 0 结尾即止)。
|
||||||
@@ -1475,6 +1497,8 @@ impl Emitter {
|
|||||||
let mut ctx = CompileCtx::new();
|
let mut ctx = CompileCtx::new();
|
||||||
// 脚本顶层:var/function 声明需落到全局对象,let/const/class 不进全局。
|
// 脚本顶层:var/function 声明需落到全局对象,let/const/class 不进全局。
|
||||||
ctx.is_global_scope = true;
|
ctx.is_global_scope = true;
|
||||||
|
// 脚本顶层严格模式由源码 "use strict" directive 决定(嵌套函数经父 ctx 继承)。
|
||||||
|
ctx.is_strict = program.has_use_strict_directive();
|
||||||
self.predeclare_function_declarations(&program.body, &mut ctx);
|
self.predeclare_function_declarations(&program.body, &mut ctx);
|
||||||
|
|
||||||
// 预注册 builtin 引用(先于任何临时寄存器),builtin 槽不进入临时寄存器池。
|
// 预注册 builtin 引用(先于任何临时寄存器),builtin 槽不进入临时寄存器池。
|
||||||
|
|||||||
@@ -40,9 +40,23 @@ impl Emitter {
|
|||||||
let is_expr_body = arrow.expression;
|
let is_expr_body = arrow.expression;
|
||||||
|
|
||||||
let mut sub_module = if arrow.r#async {
|
let mut sub_module = if arrow.r#async {
|
||||||
self.compile_async_body(¶m_names, body_stmts, ctx, is_expr_body, true)?
|
self.compile_async_body(
|
||||||
|
¶m_names,
|
||||||
|
body_stmts,
|
||||||
|
ctx,
|
||||||
|
is_expr_body,
|
||||||
|
true,
|
||||||
|
arrow.has_use_strict_directive(),
|
||||||
|
)?
|
||||||
} else {
|
} else {
|
||||||
self.compile_function_body(¶m_names, body_stmts, ctx, is_expr_body, true)?
|
self.compile_function_body(
|
||||||
|
¶m_names,
|
||||||
|
body_stmts,
|
||||||
|
ctx,
|
||||||
|
is_expr_body,
|
||||||
|
true,
|
||||||
|
arrow.has_use_strict_directive(),
|
||||||
|
)?
|
||||||
};
|
};
|
||||||
sub_module.is_arrow = true;
|
sub_module.is_arrow = true;
|
||||||
|
|
||||||
@@ -83,14 +97,15 @@ impl Emitter {
|
|||||||
|
|
||||||
let body_stmts: &[Statement] = if let Some(body) = &fe.body { &body.statements } else { &[] };
|
let body_stmts: &[Statement] = if let Some(body) = &fe.body { &body.statements } else { &[] };
|
||||||
|
|
||||||
|
let own_strict = fe.has_use_strict_directive();
|
||||||
let mut sub_module = if fe.generator && fe.r#async {
|
let mut sub_module = if fe.generator && fe.r#async {
|
||||||
self.compile_async_generator_body(¶m_names, body_stmts, ctx)?
|
self.compile_async_generator_body(¶m_names, body_stmts, ctx, own_strict)?
|
||||||
} else if fe.generator {
|
} else if fe.generator {
|
||||||
self.compile_generator_body(¶m_names, body_stmts, ctx)?
|
self.compile_generator_body(¶m_names, body_stmts, ctx, own_strict)?
|
||||||
} else if fe.r#async {
|
} else if fe.r#async {
|
||||||
self.compile_async_body(¶m_names, body_stmts, ctx, false, false)?
|
self.compile_async_body(¶m_names, body_stmts, ctx, false, false, own_strict)?
|
||||||
} else {
|
} else {
|
||||||
self.compile_function_body(¶m_names, body_stmts, ctx, false, false)?
|
self.compile_function_body(¶m_names, body_stmts, ctx, false, false, own_strict)?
|
||||||
};
|
};
|
||||||
if let Some(id) = &fe.id {
|
if let Some(id) = &fe.id {
|
||||||
sub_module.function_name = Some(id.name.to_string());
|
sub_module.function_name = Some(id.name.to_string());
|
||||||
|
|||||||
@@ -136,6 +136,8 @@ impl Emitter {
|
|||||||
let mut ctx = CompileCtx::new();
|
let mut ctx = CompileCtx::new();
|
||||||
// 模块顶层 var/function 不写全局对象(模块作用域绑定)。
|
// 模块顶层 var/function 不写全局对象(模块作用域绑定)。
|
||||||
ctx.is_global_scope = false;
|
ctx.is_global_scope = false;
|
||||||
|
// ES module 顶层恒严格模式(模块代码是严格模式代码,嵌套函数经父 ctx 继承)。
|
||||||
|
ctx.is_strict = true;
|
||||||
let mut path_stack = vec![module_path.to_string()];
|
let mut path_stack = vec![module_path.to_string()];
|
||||||
self.emit_module_into_ctx(program, module_path, loader, &mut path_stack, &mut ctx)?;
|
self.emit_module_into_ctx(program, module_path, loader, &mut path_stack, &mut ctx)?;
|
||||||
Ok(ctx.assemble_ir(ParamLayout { base: 0, count: 0 }, None))
|
Ok(ctx.assemble_ir(ParamLayout { base: 0, count: 0 }, None))
|
||||||
@@ -387,6 +389,8 @@ impl Emitter {
|
|||||||
})?;
|
})?;
|
||||||
let mut ctx = CompileCtx::new();
|
let mut ctx = CompileCtx::new();
|
||||||
ctx.is_global_scope = false;
|
ctx.is_global_scope = false;
|
||||||
|
// 依赖模块经 parse_module 解析,顶层恒严格模式。
|
||||||
|
ctx.is_strict = true;
|
||||||
self.emit_module_into_ctx(&program, &resolved.path, loader, path_stack, &mut ctx)?;
|
self.emit_module_into_ctx(&program, &resolved.path, loader, path_stack, &mut ctx)?;
|
||||||
Ok(ctx.assemble_ir(ParamLayout { base: 0, count: 0 }, None))
|
Ok(ctx.assemble_ir(ParamLayout { base: 0, count: 0 }, None))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,14 +43,15 @@ impl Emitter {
|
|||||||
self.push_rest_param(&rest.rest.argument, &mut param_names)?;
|
self.push_rest_param(&rest.rest.argument, &mut param_names)?;
|
||||||
}
|
}
|
||||||
let body_stmts: &[Statement] = if let Some(body) = &fd.body { &body.statements } else { &[] };
|
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 {
|
let mut sub_module = if fd.generator && fd.r#async {
|
||||||
self.compile_async_generator_body(¶m_names, body_stmts, ctx)?
|
self.compile_async_generator_body(¶m_names, body_stmts, ctx, own_strict)?
|
||||||
} else if fd.generator {
|
} else if fd.generator {
|
||||||
self.compile_generator_body(¶m_names, body_stmts, ctx)?
|
self.compile_generator_body(¶m_names, body_stmts, ctx, own_strict)?
|
||||||
} else if fd.r#async {
|
} else if fd.r#async {
|
||||||
self.compile_async_body(¶m_names, body_stmts, ctx, false, false)?
|
self.compile_async_body(¶m_names, body_stmts, ctx, false, false, own_strict)?
|
||||||
} else {
|
} else {
|
||||||
self.compile_function_body(¶m_names, body_stmts, ctx, false, false)?
|
self.compile_function_body(¶m_names, body_stmts, ctx, false, false, own_strict)?
|
||||||
};
|
};
|
||||||
sub_module.function_name = Some(name.clone());
|
sub_module.function_name = Some(name.clone());
|
||||||
ctx.nested.push(sub_module);
|
ctx.nested.push(sub_module);
|
||||||
|
|||||||
@@ -55,6 +55,8 @@ pub struct IRFunction {
|
|||||||
pub is_generator: bool,
|
pub is_generator: bool,
|
||||||
/// 是否为异步函数体(`async function` / async 箭头)。
|
/// 是否为异步函数体(`async function` / async 箭头)。
|
||||||
pub is_async: bool,
|
pub is_async: bool,
|
||||||
|
/// 是否为严格模式函数体(自身 "use strict" directive 或外层严格继承,不可解除)。
|
||||||
|
pub is_strict: bool,
|
||||||
pub captured_this_const_idx: u16,
|
pub captured_this_const_idx: u16,
|
||||||
pub function_name: Option<String>,
|
pub function_name: Option<String>,
|
||||||
/// 函数 `length` 属性值:第一个带默认值/解构默认的形参之前的形参数(rest 不计)。
|
/// 函数 `length` 属性值:第一个带默认值/解构默认的形参之前的形参数(rest 不计)。
|
||||||
@@ -87,6 +89,7 @@ impl IRFunction {
|
|||||||
needs_home_object: false,
|
needs_home_object: false,
|
||||||
is_generator: false,
|
is_generator: false,
|
||||||
is_async: false,
|
is_async: false,
|
||||||
|
is_strict: false,
|
||||||
captured_this_const_idx: 0,
|
captured_this_const_idx: 0,
|
||||||
function_name: None,
|
function_name: None,
|
||||||
function_length: 0,
|
function_length: 0,
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ pub fn lower(f: &IRFunction) -> Result<CompiledModule, String> {
|
|||||||
builtin_reg_map: f.builtin_reg_map.clone(),
|
builtin_reg_map: f.builtin_reg_map.clone(),
|
||||||
sub_modules,
|
sub_modules,
|
||||||
is_arrow: f.is_arrow,
|
is_arrow: f.is_arrow,
|
||||||
|
is_strict: f.is_strict,
|
||||||
captured_this_const_idx: f.captured_this_const_idx,
|
captured_this_const_idx: f.captured_this_const_idx,
|
||||||
function_name: f.function_name.clone(),
|
function_name: f.function_name.clone(),
|
||||||
function_length: f.function_length,
|
function_length: f.function_length,
|
||||||
|
|||||||
Reference in New Issue
Block a user