mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-24 18:51:13 +08:00
fix: 构造帧 super 状态改显式标志修复多层继承与 return 语义
derived 构造器 super 状态改由 CallFrame.super_called 显式标志承载, 取代依赖 regs[254] 值判定:多层继承中间 derived 帧由 SUPER_CALL 压入 this=构造对象,值判定三重失效(未调 super 不报错 / this-before-super 失效 / 合法 super() 误判 more-than-once)。父构造器正常返回经 construct_result_reg==Some(254) 识别置位调用方帧(该 ABI 不变量仅 SUPER_CALL 压帧满足),抛错走 unwind 不置位。 do_return 检查放宽为非对象返回值(含 undefined/null/原始值)且未调 super 时抛 ReferenceError(规范 §9.2.2.2),调过 super 回退构造 this。 super 构造器改取当前帧 callee 原型而非 newTarget 原型:newTarget 跨 SUPER_CALL 压帧保持为最外层类,取其原型在中间 derived 层解析回同一 父类导致无限压帧。
This commit is contained in:
@@ -423,12 +423,14 @@ impl Vm {
|
||||
let construct_result_reg = frame.construct_result_reg;
|
||||
let constructed_this = frame.constructed_this;
|
||||
let is_derived_constructor = frame.is_derived_constructor;
|
||||
let super_called = frame.super_called;
|
||||
let continuation = frame.continuation;
|
||||
let callee_this = self.regs[254];
|
||||
vm_trace!("RETURN frame: continuation={:?}, derived={}", continuation, is_derived_constructor);
|
||||
self.restore_frame(frame);
|
||||
if let (Some(target_reg), Some(constructed_this)) = (construct_result_reg, constructed_this) {
|
||||
if is_derived_constructor && result.is_undefined() && callee_this.is_undefined() {
|
||||
// 规范 §9.2.2.2:derived 构造器返回非对象值(含 undefined/null/原始值)
|
||||
// 且未调用 super() 时抛 ReferenceError;调过 super() 则回退构造 this。
|
||||
if is_derived_constructor && !result.is_object() && !super_called {
|
||||
self.raise_error_kind("ReferenceError", "derived constructor must call super()")?;
|
||||
return Ok(None);
|
||||
}
|
||||
@@ -447,6 +449,17 @@ impl Vm {
|
||||
}
|
||||
}
|
||||
}
|
||||
// 父构造器正常返回:super() 调用完成,置位调用方 derived 帧的 super_called。
|
||||
// 识别依据:construct_result_reg == Some(254) 仅 SUPER_CALL 压帧产生(emit
|
||||
// 从寄存器 ≥1 分配,254 保留给 this);父构造器抛错走 unwind 弹帧不进
|
||||
// 本函数,不置位——后续 this 访问 / 再调 super 仍按未初始化报错。
|
||||
if construct_result_reg == Some(254) {
|
||||
if let Some(caller) = self.frames.last_mut() {
|
||||
if caller.is_derived_constructor {
|
||||
caller.super_called = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 生成器/异步/构造内嵌 dispatch:帧全部弹出后把结果交付恢复方,而非继续执行。
|
||||
if self.frames.is_empty() && (self.generator_dispatch || self.async_dispatch || self.construct_dispatch) {
|
||||
// 构造内嵌:弹帧已把构造结果(非对象回退 this)写入 regs[0],直接交付。
|
||||
|
||||
Reference in New Issue
Block a user