fix: class 类名绑定经 dedicated cell 捕获(C===Cv 恒等)+ upvalue 写入 const guard(getter 赋值抛 TypeError)

This commit is contained in:
2026-08-12 17:30:28 +08:00
parent 0a4e42334d
commit 0c22a0e968
10 changed files with 60 additions and 31 deletions
+4 -2
View File
@@ -28,6 +28,7 @@ impl Emitter {
}
let uv_idx = ctx.current_upvalue_captures.iter().position(|u| u.name == name);
let captured_cell = ctx.captured_bindings.get(name).copied();
let const_flag = if ctx.lookup_const_flag(name) { 1 } else { 0 };
if let Some(uv) = uv_idx {
let val_reg = ctx.alloc_reg();
ctx.inst(Inst::new(
@@ -39,7 +40,7 @@ impl Emitter {
ctx.inst(Inst::new(op, Operand::Reg(val_reg), Operand::Reg(rhs), Operand::None));
ctx.inst(Inst::new(
OpCode::STORE_UPVALUE,
Operand::None,
Operand::Imm(const_flag),
Operand::Reg(val_reg),
Operand::Imm(uv as u16),
));
@@ -266,10 +267,11 @@ impl Emitter {
self.emit_logical_assign_test(logical_op, result_reg, store_label, end_label, ctx)?;
ctx.labels.set_label_pos(store_label, ctx.insts.len());
let val_reg = self.emit_expression(&assign.right, ctx)?;
let const_flag = if ctx.lookup_const_flag(name) { 1 } else { 0 };
if let Some(uv) = uv_idx {
ctx.inst(Inst::new(
OpCode::STORE_UPVALUE,
Operand::None,
Operand::Imm(const_flag),
Operand::Reg(val_reg),
Operand::Imm(uv as u16),
));
+3 -3
View File
@@ -116,8 +116,8 @@ impl Emitter {
/// 静态标识符写入:upvalue / 被捕获 cell / 普通槽(含 const guard)。
///
/// # 边界与前提
/// - `const_flag` 为 1 时走 STORE_VAR 运行时 const guard(对 const 再赋值报错)。
/// - upvalue 与 cell 写穿共享单元,不设 guard。
/// - `const_flag` 为 1 时走 STORE_VAR / STORE_UPVALUE 运行时 const guard(对 const 再赋值报错)。
/// - cell 写穿共享单元,不设 guard(类名/闭包捕获的初始化写入路径);upvalue 按 const_flag 设 guard。
pub(crate) fn emit_identifier_store(&self, name: &str, val_reg: u32, const_flag: u16, ctx: &mut CompileCtx) {
// 循环 update 段:被捕获绑定走寄存器而非 cell(C 风格 for 每迭代 fresh,
// update 写寄存器供下一迭代 fresh 拷贝,不污染本迭代闭包捕获的 cell)。
@@ -136,7 +136,7 @@ impl Emitter {
if let Some(uv_idx) = ctx.current_upvalue_captures.iter().position(|u| u.name == name) {
ctx.inst(Inst::new(
OpCode::STORE_UPVALUE,
Operand::None,
Operand::Imm(const_flag),
Operand::Reg(val_reg),
Operand::Imm(uv_idx as u16),
));
+2 -1
View File
@@ -455,9 +455,10 @@ impl Emitter {
};
let new_reg = ctx.alloc_reg();
ctx.inst(Inst::new(op, Operand::Reg(new_reg), Operand::Reg(old_reg), Operand::Reg(one_reg)));
let const_flag = if ctx.lookup_const_flag(name) { 1 } else { 0 };
ctx.inst(Inst::new(
OpCode::STORE_UPVALUE,
Operand::None,
Operand::Imm(const_flag),
Operand::Reg(new_reg),
Operand::Imm(uv as u16),
));