fix: eval 代码顶层函数声明撞不可写全局内置——sloppy 编译期首指令 TypeError、strict 函数声明不落全局

This commit is contained in:
2026-09-13 09:05:54 +00:00
parent a98d5251e1
commit 1fdb7aca2d
6 changed files with 252 additions and 2 deletions
+20
View File
@@ -1660,6 +1660,26 @@ impl Emitter {
ctx.is_eval_script = is_eval_script;
// 脚本顶层严格模式由源码 "use strict" directive 决定(嵌套函数经父 ctx 继承)。
ctx.is_strict = program.has_use_strict_directive();
// eval 代码顶层函数声明撞不可写全局内置(三常量的全局绑定在任何符合规范的
// 实现中均不可配置,声明实例化无法建立全局绑定):规范在建立全局 var 绑定
// 之前抛 TypeError(step 8 的 abrupt 先于绑定实例化),故 throw 发为程序首
// 指令,其后预声明/序言/声明发射均不可达(寄存器保持良定义,运行期零开销)。
// 严格 eval 代码函数声明绑定 eval 自身 lexical 环境、不触全局、不抛,门禁
// 随 !is_strict 关闭,其写点抑制在声明发射处。
if ctx.is_eval_script && !ctx.is_strict {
for name in self.collect_top_level_function_names(&program.body) {
if NON_WRITABLE_GLOBAL_BUILTINS.contains(&name.as_str()) {
let _ = self.emit_throw_error(
"TypeError",
&format!("Cannot declare function '{name}': global property is not configurable"),
&mut ctx,
)?;
break;
}
}
}
self.predeclare_function_declarations(&program.body, &mut ctx);
// 预注册 builtin 引用(先于任何临时寄存器),builtin 槽不进入临时寄存器池。
@@ -70,7 +70,9 @@ impl Emitter {
}
// 脚本顶层(非块内)函数声明:同步写全局对象,使 globalThis 可反射函数名。
// 块内函数声明是块级绑定,不得落全局对象(作用域隔离,块外不可见)。
if ctx.is_global_scope && ctx.scopes.symbols.scopes.len() == 1 {
// 严格 eval 代码函数声明绑定 eval 自身 lexical 环境、不落全局对象:抑制 A
// 侧写(局部绑定读面未暴露),同时避免不可写全局内置在 0x98 上误抛 strict。
if ctx.is_global_scope && ctx.scopes.symbols.scopes.len() == 1 && !(ctx.is_eval_script && ctx.is_strict) {
self.emit_global_prop_write(&name, var_reg, ctx);
}
Ok(None)