fix: 裸 return 物化 undefined,防调用残留值冒充完成值

This commit is contained in:
2026-09-20 18:07:54 +00:00
parent 06cd63c3b0
commit c9e1ee2e09
3 changed files with 76 additions and 2 deletions
+6 -1
View File
@@ -307,10 +307,15 @@ impl Emitter {
.position(|u| u.name == "@@field_keys")
.map(|i| i as u8);
emit_instance_fields(self, &mut field_ctx)?;
// 构造器尾裸 return 须物化 undefined:RETURN 读 rd 槽值,字段初始化器
// 尾表达式为返回对象的调用时,该对象会漏出为构造结果。
let undef_idx = field_ctx.add_constant(Constant::Undefined);
let undef_reg = field_ctx.alloc_reg();
field_ctx.inst(Inst::load_const(Operand::Reg(undef_reg), undef_idx));
module.insts.extend(field_ctx.insts);
module.constants = field_ctx.constants;
module.n_registers = field_ctx.max_regs.max(1);
module.insts.push(Inst::ret(Operand::None, 0, 0));
module.insts.push(Inst::ret(Operand::Reg(undef_reg), 0, 0));
}
module
};
@@ -1,6 +1,7 @@
//! return 语句 emit:`emit_return_statement` 求值返回值并生成返回指令。
use crate::{CompileCtx, Emitter};
use oxide_bytecode::module::Constant;
use oxide_bytecode::opcode::OpCode;
use oxide_ir::inst::Inst;
use oxide_ir::operand::Operand;
@@ -32,7 +33,12 @@ impl Emitter {
if for_of_count == 0 && for_in_count == 0 {
self.emit_return_try_cleanup(ctx);
}
ctx.inst(Inst::ret(Operand::None, for_of_count, for_in_count));
// 裸 return 须显式物化 undefined 为完成值:RETURN 从 rd 槽读值,
// 不物化则交付槽内残留值(如最近一次调用的结果)冒充完成值。
let undef_idx = ctx.add_constant(Constant::Undefined);
let undef_reg = ctx.alloc_reg();
ctx.inst(Inst::load_const(Operand::Reg(undef_reg), undef_idx));
ctx.inst(Inst::ret(Operand::Reg(undef_reg), for_of_count, for_in_count));
}
}
Ok(None)