mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-25 03:01:12 +08:00
fix: 调度标志经内联 state-swap 边界泄漏——C 侧无帧 accessor 调用继承属主调度上下文,构造帧弹出后误判提前交付、被调函数构造后字节码被跳过
根因:generator/async/construct 三个调度标志是 VM 全局字段,不经 InlineSyncState 在 state-swap 边界保存/恢复。C 侧路径(builtin 经 ordinary_get 无帧调用 accessor,走 call_bytecode_function_inline 状态 交换、不压边界帧)在生成器/异步属主 dispatch 上下文内运行时继承泄漏 标志;被调函数内 new 字节码构造器() 的构造帧是嵌套 dispatch 帧栈唯一 帧,构造器 RETURN 弹出后帧栈清空,do_return 的 frames.is_empty() && 调度标志 误判为属主 dispatch,提前交付构造残留,被调函数构造点之后 的字节码整体不执行(getter 的 throw 被吞,属性读拿到 undefined)。 上层 FDI rest 绑定循环因此永不见 done,步数上限后初始化/恢复方把 异常折成通用错误。 修复:三标志纳入 InlineSyncState,新增 flag_zero 算子臂(save 快照 属主值并清零 VM 侧、restore 写回)——嵌套内联调用不继承外层调度 上下文。既有置位点全部在 save 之后、属主 dispatch 之前,语义不变; do_return 交付条件注释同步更新。 回归钉:inline_dispatch_scoping_tests——C 侧 accessor 构造后 throw 穿透 instanceof Error、C 侧取值 42、字节码帧边界对照、顶层对照 (修复前两枚 C 侧钉失败)。
This commit is contained in:
@@ -375,6 +375,14 @@ pub(crate) struct InlineSyncState {
|
||||
pub(crate) spill_stack: Vec<JsValue>,
|
||||
pub(crate) cell_stack: Vec<Vec<*mut Cell>>,
|
||||
pub(crate) inline_callee: Option<JsValue>,
|
||||
/// 三个内嵌 dispatch 调度标志(`Vm::generator_dispatch` / `async_dispatch` /
|
||||
/// `construct_dispatch`)的属主快照。save 时记录外层值并清零 VM 侧、restore
|
||||
/// 时写回:嵌套 state-swap 调用不得继承外层调度上下文,否则其内部构造帧
|
||||
/// 弹出后 frames 清空,`do_return` 会把嵌套调用误判为属主内嵌 dispatch 提前
|
||||
/// 交付,跳过被调函数剩余字节码(详见 `do_return` 交付条件注释)。
|
||||
pub(crate) generator_dispatch: bool,
|
||||
pub(crate) async_dispatch: bool,
|
||||
pub(crate) construct_dispatch: bool,
|
||||
/// inline 目标函数的严格模式标志(内联执行期间写路径的 strict/sloppy 判定
|
||||
/// 来源;嵌套内联时随本快照保存/恢复)。
|
||||
pub(crate) inline_strict: bool,
|
||||
@@ -504,6 +512,8 @@ pub struct Vm {
|
||||
pub(crate) delegated_iterator: Option<JsValue>,
|
||||
/// 当前是否处于生成器内嵌 dispatch 循环:生成器帧弹出且 frames 清空时,
|
||||
/// `do_return` 据此把结果交付给恢复方(而非当作普通顶层返回继续执行)。
|
||||
/// 作用域限定于置位处包裹的那次 `dispatch()`:经 `InlineSyncState` 在
|
||||
/// state-swap 边界保存/清零/恢复,嵌套内联调用不继承本标志。
|
||||
pub(crate) generator_dispatch: bool,
|
||||
/// 生成器调用时参数初始化步:body 起点标记(SUSPEND_BODY)据此判定"挂起在 body 前"。
|
||||
pub(crate) generator_init_step: bool,
|
||||
@@ -516,11 +526,13 @@ pub struct Vm {
|
||||
/// 循环)取走并快照挂起状态。false = 正常返回/异常。
|
||||
pub(crate) async_suspended: bool,
|
||||
/// 当前是否处于异步函数内嵌 dispatch 循环:异步帧弹出且 frames 清空时,
|
||||
/// `do_return` 据此把结果交付给恢复方(与 generator_dispatch 同语义)。
|
||||
/// `do_return` 据此把结果交付给恢复方(与 generator_dispatch 同语义,
|
||||
/// 同样经 InlineSyncState 限定作用域于属主 dispatch)。
|
||||
pub(crate) async_dispatch: bool,
|
||||
/// 当前是否处于构造器内嵌 dispatch 循环(`call_constructor_bytecode_inline`):
|
||||
/// 构造帧弹出且 frames 清空时,`do_return` 据此把构造结果(regs[0],
|
||||
/// 已做非对象回退 this)交付给恢复方(与 generator_dispatch 同语义)。
|
||||
/// 已做非对象回退 this)交付给恢复方(与 generator_dispatch 同语义,
|
||||
/// 同样经 InlineSyncState 限定作用域于属主 dispatch)。
|
||||
pub(crate) construct_dispatch: bool,
|
||||
/// 当前正在执行的异步生成器上下文对象(`OBJ_TYPE_ASYNC_GENERATOR`,持有
|
||||
/// `AsyncGeneratorState` 快照)。AWAIT dispatch 据此登记异步生成器恢复反应;
|
||||
|
||||
Reference in New Issue
Block a user