fix: 类构造器寄存器放宽 u8 守卫并消除 this 槽 254 特判碰撞

This commit is contained in:
2026-10-16 17:01:17 +00:00
parent a791a312ec
commit 77782f01a5
6 changed files with 63 additions and 29 deletions
+2 -4
View File
@@ -14,10 +14,8 @@ impl Emitter {
&self, elements: &[ClassElement], ctor_reg: u32, key_slots: &[Option<u8>], ctx: &mut CompileCtx,
) -> Result<(), String> {
let saved_static_this = ctx.static_block_this_reg;
// static_block_this_reg 保留 u8(this 槽语义,254 特判),ctor_reg 超 u8 界时报错而非静默截断。
ctx.static_block_this_reg = Some(
u8::try_from(ctor_reg).map_err(|_| format!("class constructor register {ctor_reg} exceeds u8 limit"))?,
);
// ctor_reg 是 vreg 号(RegAlloc 期压缩到物理域),直接存 u32,不截断。
ctx.static_block_this_reg = Some(ctor_reg);
for (element, &key_slot) in elements.iter().zip(key_slots) {
match element {
ClassElement::PropertyDefinition(prop) => {
+3 -1
View File
@@ -66,7 +66,9 @@ pub struct CompileCtx {
/// 源码是否为 `source_escape` 产物(动态编译入口):正则字面量源文本切片
/// 的池键形态据此选择(见 [`Emitter::source_encoded`])。
pub(crate) source_encoded: bool,
pub(crate) static_block_this_reg: Option<u8>,
/// 静态块内 `this` 的构造器寄存器(vreg 号,无 u8 上限,RegAlloc 期压缩到物理域)。
/// None 表示非静态块上下文,`this` 走常规 this 槽。
pub(crate) static_block_this_reg: Option<u32>,
pub(crate) field_buffer: Option<FieldBuffer>,
/// 类构造器模块中 `@@field_keys` upvalue 下标(实例字段 computed key 数组)。
/// 类定义期求值一次存入 cell,构造器经此 upvalue 读取。
+6 -2
View File
@@ -8,8 +8,12 @@ use oxide_ir::operand::Operand;
impl Emitter {
pub(crate) fn emit_this_expression(&self, ctx: &mut CompileCtx) -> Result<u32, String> {
let r = ctx.alloc_reg();
let src = ctx.static_block_this_reg.unwrap_or(254);
let src_op = if src == 254 { Operand::This } else { Operand::Reg(src as u32) };
// None 是常规 this 槽;Some(reg) 是类构造器 vreg(vreg 号可越过 254,
// 按寄存器处理,不与 this 槽特判混淆)。
let src_op = match ctx.static_block_this_reg {
None => Operand::This,
Some(reg) => Operand::Reg(reg),
};
ctx.inst(Inst::new(OpCode::LOAD_VAR, Operand::Reg(r), src_op, Operand::None));
Ok(r)
}