mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-25 03:01:12 +08:00
fix: 被捕获词法绑定入口建 TDZ 占位 cell 并跳过陈旧静态守卫
This commit is contained in:
@@ -17,8 +17,8 @@ use oxide_ir::IRFunction;
|
||||
use oxide_parser::Statement;
|
||||
|
||||
use crate::capture::{
|
||||
collect_captured_bindings, collect_own_binding_names, collect_top_level_function_names,
|
||||
collect_top_level_function_names_ordered, collect_var_binding_names,
|
||||
collect_captured_bindings, collect_direct_lexical_names, collect_own_binding_names,
|
||||
collect_top_level_function_names, collect_top_level_function_names_ordered, collect_var_binding_names,
|
||||
};
|
||||
use crate::compile_ctx::CompileCtx;
|
||||
use crate::Emitter;
|
||||
@@ -377,6 +377,31 @@ impl Emitter {
|
||||
}
|
||||
}
|
||||
|
||||
// 被捕获顶层词法(let/const/class)入口 TDZ 占位 cell:声明语句执行前
|
||||
// 创建的闭包指向此未初始化 cell,声明前读写经运行时抛真 TDZ;声明语句
|
||||
// 的 MAKE_CELL 按占位更新语义原位翻转为已初始化。名集取捕获集交集
|
||||
// (直接子级词法名,块级名不提升到顶层),排序保证发射序跨进程稳定。
|
||||
let mut lex_names: Vec<String> = collect_direct_lexical_names(&program.body)
|
||||
.into_iter()
|
||||
.filter(|n| ctx.captured_bindings.contains_key(n))
|
||||
.collect();
|
||||
lex_names.sort();
|
||||
if !lex_names.is_empty() {
|
||||
let undef_reg = self.emit_undefined(&mut ctx);
|
||||
for name in lex_names {
|
||||
if let Some(&cell_idx) = ctx.captured_bindings.get(&name) {
|
||||
// 未初始化标志折入 16 位立即数高字节(0x0100),dispatch 侧
|
||||
// 按字节拆回两字段。
|
||||
ctx.inst(Inst::new(
|
||||
OpCode::MAKE_CELL,
|
||||
Operand::Reg(undef_reg),
|
||||
Operand::Imm(cell_idx as u16 | 0x0100),
|
||||
Operand::None,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 全局声明实例化序言:脚本求值前为顶层 var 名创建全局对象属性(值 undefined),
|
||||
// 使声明语句执行前的读取(typeof、反射、自引用)可经全局对象见绑定。
|
||||
// 顶层函数声明名不进序言:函数值是编译闭包,编译期不可得,其全局对象属性值
|
||||
|
||||
Reference in New Issue
Block a user