fix: 块级 let/const/class 预声明 + TDZ 读取运行时抛 ReferenceError
This commit is contained in:
@@ -18,8 +18,14 @@ impl Emitter {
|
||||
.as_ref()
|
||||
.map(|id| id.name.to_string())
|
||||
.ok_or_else(|| "ClassDeclaration without name".to_string())?;
|
||||
let var_reg = ctx.alloc_reg();
|
||||
ctx.declare(&name, var_reg, VariableDeclarationKind::Let, false)?;
|
||||
let var_reg = match ctx.scopes.symbols.consume_predeclared_slot(&name) {
|
||||
Some(reg) => reg,
|
||||
None => {
|
||||
let reg = ctx.alloc_reg();
|
||||
ctx.declare(&name, reg, VariableDeclarationKind::Let, false)?;
|
||||
reg
|
||||
}
|
||||
};
|
||||
ctx.init_var(&name);
|
||||
let ctor_reg = self.emit_class(class, ctx)?;
|
||||
if let Some(&cell_idx) = ctx.captured_bindings.get(&name) {
|
||||
|
||||
@@ -47,7 +47,16 @@ impl Emitter {
|
||||
Err(_) => ctx.lookup(bi.name.as_str()).unwrap_or(var_reg),
|
||||
}
|
||||
} else {
|
||||
ctx.declare(bi.name.as_str(), var_reg, decl.kind, is_const)?;
|
||||
// let/const 无初始化器:复用本块预声明槽位,否则新声明
|
||||
// (for 头等未预声明路径)。
|
||||
let var_reg =
|
||||
if let Some(reg) = ctx.scopes.symbols.consume_predeclared_slot(bi.name.as_str()) {
|
||||
reg
|
||||
} else {
|
||||
let r = ctx.alloc_reg();
|
||||
ctx.declare(bi.name.as_str(), r, decl.kind, is_const)?;
|
||||
r
|
||||
};
|
||||
var_reg
|
||||
};
|
||||
if let Some(&cell_idx) = ctx.captured_bindings.get(bi.name.as_str()) {
|
||||
|
||||
Reference in New Issue
Block a user