mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-25 11:11:11 +08:00
fix: 被捕获词法绑定入口建 TDZ 占位 cell 并跳过陈旧静态守卫
This commit is contained in:
@@ -14,8 +14,8 @@ use oxide_ir::IRFunction;
|
||||
use oxide_parser::{Expression, Statement, VariableDeclarationKind};
|
||||
|
||||
use crate::capture::{
|
||||
collect_binding_pattern_names, collect_captured_bindings, collect_own_binding_names, collect_upvalue_names,
|
||||
collect_var_binding_names,
|
||||
collect_binding_pattern_names, collect_captured_bindings, collect_direct_lexical_names, collect_own_binding_names,
|
||||
collect_upvalue_names, collect_var_binding_names,
|
||||
};
|
||||
use crate::compile_ctx::{CompileCtx, FieldBuffer};
|
||||
use crate::symbol_table::{Binding, ScopeKind};
|
||||
@@ -783,6 +783,33 @@ impl Emitter {
|
||||
}
|
||||
}
|
||||
|
||||
// 被捕获函数作用域词法(let/const/class)入口 TDZ 占位 cell:函数声明
|
||||
// hoisting 先于声明语句执行时,闭包指向此未初始化 cell,声明前读写经
|
||||
// 运行时抛真 TDZ;声明语句的 MAKE_CELL 按占位更新语义原位翻转。名集只取
|
||||
// 直接子级(块级名不提升到函数作用域,与块内重执行 cell 族零交集),
|
||||
// 排序保证发射序跨进程稳定。
|
||||
let mut lex_names: Vec<String> = collect_direct_lexical_names(body_stmts)
|
||||
.into_iter()
|
||||
.filter(|n| !param_names.contains(&n.as_str()) && n != "arguments")
|
||||
.filter(|n| ctx.captured_bindings.contains_key(n))
|
||||
.collect();
|
||||
lex_names.sort();
|
||||
if !lex_names.is_empty() {
|
||||
let undef_reg = self.emit_undefined(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,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(param_base)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user