mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-24 18:51:13 +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:
@@ -100,6 +100,21 @@ macro_rules! inline_save_field {
|
||||
($recv:ident, $window_regs:ident, inline_callee, opt_copy) => {
|
||||
$recv.inline_callee
|
||||
};
|
||||
($recv:ident, $window_regs:ident, generator_dispatch, flag_zero) => {{
|
||||
let prev = $recv.generator_dispatch;
|
||||
$recv.generator_dispatch = false;
|
||||
prev
|
||||
}};
|
||||
($recv:ident, $window_regs:ident, async_dispatch, flag_zero) => {{
|
||||
let prev = $recv.async_dispatch;
|
||||
$recv.async_dispatch = false;
|
||||
prev
|
||||
}};
|
||||
($recv:ident, $window_regs:ident, construct_dispatch, flag_zero) => {{
|
||||
let prev = $recv.construct_dispatch;
|
||||
$recv.construct_dispatch = false;
|
||||
prev
|
||||
}};
|
||||
($recv:ident, $window_regs:ident, inline_strict, copy) => {
|
||||
$recv.inline_strict
|
||||
};
|
||||
@@ -189,6 +204,15 @@ macro_rules! inline_restore_field {
|
||||
($recv:ident, $saved:ident, inline_callee, opt_copy) => {
|
||||
$recv.inline_callee = $saved.inline_callee
|
||||
};
|
||||
($recv:ident, $saved:ident, generator_dispatch, flag_zero) => {
|
||||
$recv.generator_dispatch = $saved.generator_dispatch
|
||||
};
|
||||
($recv:ident, $saved:ident, async_dispatch, flag_zero) => {
|
||||
$recv.async_dispatch = $saved.async_dispatch
|
||||
};
|
||||
($recv:ident, $saved:ident, construct_dispatch, flag_zero) => {
|
||||
$recv.construct_dispatch = $saved.construct_dispatch
|
||||
};
|
||||
($recv:ident, $saved:ident, inline_strict, copy) => {
|
||||
$recv.inline_strict = $saved.inline_strict
|
||||
};
|
||||
@@ -240,6 +264,9 @@ macro_rules! inline_core_fields {
|
||||
(spill_stack, move_field), // V M
|
||||
(cell_stack, move_field), // V M
|
||||
(inline_callee, opt_copy), // V M
|
||||
(generator_dispatch, flag_zero), // M 调度标志:快照属主值,嵌套期间清零
|
||||
(async_dispatch, flag_zero), // M 调度标志:快照属主值,嵌套期间清零
|
||||
(construct_dispatch, flag_zero), // M 调度标志:快照属主值,嵌套期间清零
|
||||
(inline_strict, copy), // M
|
||||
(inline_frames_base, copy), // M
|
||||
(inline_args_base, copy), // M
|
||||
|
||||
Reference in New Issue
Block a user