mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-25 19:21:11 +08:00
fix: for-in var 头撞既有绑定复用槽位消除顶层编译报错,迭代键写不可写全局内置接只读拦截
This commit is contained in:
@@ -38,8 +38,25 @@ impl Emitter {
|
||||
let is_const = matches!(decl.kind, VariableDeclarationKind::Const);
|
||||
let name = bi.name.as_str();
|
||||
let var_reg = ctx.alloc_reg();
|
||||
ctx.declare(name, var_reg, decl.kind, is_const)?;
|
||||
if let Some(&cell_idx) = ctx.captured_bindings.get(name) {
|
||||
// var 声明:绑定已存在(顶层 var 预声明、GDI 序言预登记
|
||||
// builtin 名、同 scope 先前声明)时复用既有槽位,不重复
|
||||
// 声明;let/const 同 scope 重复声明仍报错。
|
||||
let target_reg = if matches!(decl.kind, VariableDeclarationKind::Var) {
|
||||
match ctx.declare(name, var_reg, decl.kind, is_const) {
|
||||
Ok(()) => var_reg,
|
||||
Err(_) => ctx.lookup(name).unwrap_or(var_reg),
|
||||
}
|
||||
} else {
|
||||
ctx.declare(name, var_reg, decl.kind, is_const)?;
|
||||
var_reg
|
||||
};
|
||||
if ctx.targets_readonly_builtin(name, target_reg) {
|
||||
// 声明撞全局不可写内置:声明不更新既有全局绑定——sloppy
|
||||
// 静默跳过写(槽保留入口预载原值),strict 抛 TypeError。
|
||||
if ctx.is_strict {
|
||||
self.emit_throw_error("TypeError", "cannot assign to read-only property", ctx)?;
|
||||
}
|
||||
} else if let Some(&cell_idx) = ctx.captured_bindings.get(name) {
|
||||
let op = if fresh_cell { OpCode::MAKE_CELL_FRESH } else { OpCode::MAKE_CELL };
|
||||
ctx.inst(Inst::new(
|
||||
op,
|
||||
@@ -50,7 +67,7 @@ impl Emitter {
|
||||
} else {
|
||||
ctx.inst(Inst::new(
|
||||
OpCode::STORE_VAR,
|
||||
Operand::Reg(var_reg),
|
||||
Operand::Reg(target_reg),
|
||||
Operand::Reg(key_reg),
|
||||
Operand::None,
|
||||
));
|
||||
|
||||
Reference in New Issue
Block a user