refactor: 写路径契约与压帧与异步标志组收结构体并删死参

This commit is contained in:
2026-10-12 19:12:11 +00:00
parent 2dc5e1fb9e
commit 05b9b280cf
16 changed files with 339 additions and 274 deletions
+39 -12
View File
@@ -12,6 +12,29 @@ use super::{native_fn_ptr_to_fn, Vm};
use crate::native::NativeFn;
use crate::{vm_debug, vm_trace};
/// 压帧构造三元组:构造结果寄存器、构造出的 this、new.target。
///
/// 按值传递的 Copy 结构体,字段数三;非构造调用方统一传 `none()`,
/// 构造调用方传 `new(...)` 三值,避免三元组散参样板。
#[derive(Clone, Copy)]
pub(crate) struct ConstructArgs {
result_reg: Option<u8>,
constructed_this: Option<JsValue>,
new_target: JsValue,
}
impl ConstructArgs {
/// 非构造调用:无结果寄存器、无构造 this,new.target 为 undefined。
pub(crate) fn none() -> Self {
Self { result_reg: None, constructed_this: None, new_target: JsValue::undefined() }
}
/// 构造调用:携带结果寄存器、构造 this 与 new.target。
pub(crate) fn new(result_reg: u8, constructed_this: JsValue, new_target: JsValue) -> Self {
Self { result_reg: Some(result_reg), constructed_this: Some(constructed_this), new_target }
}
}
impl Vm {
fn pack_sync_native_call_args(&mut self, receiver: JsValue, callee: JsValue, args: &[JsValue]) -> Vec<u8> {
self.regs[253] = receiver;
@@ -219,10 +242,14 @@ impl Vm {
/// # 副作用
/// - 压入调用帧与各类保存栈,改写 pc / bytecode / 活动寄存器上限与镜像槽;
/// `continuation` 决定返回后的续行方式。
#[expect(clippy::too_many_arguments)]
pub(crate) fn push_bytecode_frame(
&mut self, callee: JsValue, this_value: JsValue, args: FrameArgs, construct_result_reg: Option<u8>,
constructed_this: Option<JsValue>, new_target: JsValue, continuation: FrameContinuation, call_window: u8,
&mut self,
callee: JsValue,
this_value: JsValue,
args: FrameArgs,
construct: ConstructArgs,
continuation: FrameContinuation,
call_window: u8,
) -> Result<(), String> {
vm_trace!(
"push_bytecode_frame: depth={}, args={}, continuation={:?}",
@@ -312,7 +339,7 @@ impl Vm {
} else {
oxide_runtime_api::to_object(this_value, self)?
};
self.regs[255] = new_target;
self.regs[255] = construct.new_target;
self.saved_bytecode_stack.push(std::mem::take(&mut self.bytecode));
self.saved_immutables_stack.push(self.active_immutables);
@@ -350,8 +377,8 @@ impl Vm {
saved_new_target,
callee,
arguments_obj: JsValue::undefined(),
construct_result_reg,
constructed_this,
construct_result_reg: construct.result_reg,
constructed_this: construct.constructed_this,
is_derived_constructor: obj.is_derived_constructor(),
super_called: false,
strict: sub_is_strict,
@@ -382,6 +409,8 @@ mod tests {
use oxide_runtime_api::VmHost;
use oxide_types::object::NativeFnPtr;
use crate::vm_support::FunctionFlags;
fn native_return_last_arg(vm: &mut Vm, args: &[u8]) -> NativeResult {
let reg = *args.last().expect("receiver + args");
NativeResult::Ok(vm.reg(reg))
@@ -510,7 +539,7 @@ mod tests {
vm.active_reg_limit = 254;
vm.regs[253] = JsValue::int(42);
let callee = vm.create_function_object(1, vm.current_gen, false, false, false, false);
let callee = vm.create_function_object(1, vm.current_gen, FunctionFlags::none());
let callee_obj = unsafe { &*callee.as_js_object_ptr() };
let result = vm
.call_bytecode_function_inline(callee, callee_obj, JsValue::undefined(), &[])
@@ -534,7 +563,7 @@ mod tests {
vm.regs[253] = JsValue::int(7);
vm.regs[254] = JsValue::int(8);
let inner_callee = vm.create_function_object(1, vm.current_gen, false, false, false, false);
let inner_callee = vm.create_function_object(1, vm.current_gen, FunctionFlags::none());
let outer_native = native_function(&mut vm, native_nested_inline_254);
let result = vm
.call_function_sync(outer_native, JsValue::int(99), &[inner_callee])
@@ -563,14 +592,12 @@ mod tests {
vm.regs[1] = JsValue::int(10);
vm.regs[2] = JsValue::int(20);
let callee = vm.create_function_object(1, vm.current_gen, false, false, false, false);
let callee = vm.create_function_object(1, vm.current_gen, FunctionFlags::none());
vm.push_bytecode_frame(
callee,
JsValue::undefined(),
super::FrameArgs::RegRange { first: 1, count: 2 },
None,
None,
JsValue::undefined(),
ConstructArgs::none(),
super::FrameContinuation::None,
0,
)
+4 -3
View File
@@ -11,6 +11,7 @@ use oxide_types::object::PropAttributes;
use oxide_types::value::JsValue;
use super::Vm;
use crate::vm_support::FunctionFlags;
/// 缺省 no-op 编译服务:两方法均返 `Err`(错误消息指向「未安装编译服务」)。
///
@@ -97,7 +98,7 @@ impl Vm {
table.immutables.resize(table.modules.len(), OnceLock::new());
table.si_tables.resize(table.modules.len(), OnceLock::new());
let func_val = self.create_function_object(base, self.current_gen, false, false, false, false);
let func_val = self.create_function_object(base, self.current_gen, FunctionFlags::none());
let func_obj = unsafe { &mut *func_val.as_js_object_ptr() };
let length_si = self.kernel_core.perm_interner().intern("length").0;
let name_si = self.kernel_core.perm_interner().intern("name").0;
@@ -156,7 +157,7 @@ impl Vm {
// 平表变长后同步扩容常量缓存与 si 侧表,否则激活新模块常量时越界 panic。
table.immutables.resize(table.modules.len(), OnceLock::new());
table.si_tables.resize(table.modules.len(), OnceLock::new());
Ok(self.create_function_object(base, self.current_gen, false, false, false, false))
Ok(self.create_function_object(base, self.current_gen, FunctionFlags::none()))
}
/// 动态编译脚本(普通脚本模式):顶层 var/function 声明落全局对象
@@ -195,7 +196,7 @@ impl Vm {
// 平表变长后同步扩容常量缓存与 si 侧表,否则激活新模块常量时越界 panic。
table.immutables.resize(table.modules.len(), OnceLock::new());
table.si_tables.resize(table.modules.len(), OnceLock::new());
Ok(self.create_function_object(base, self.current_gen, false, false, false, false))
Ok(self.create_function_object(base, self.current_gen, FunctionFlags::none()))
}
}
+1
View File
@@ -37,6 +37,7 @@ mod props;
mod tables;
mod vmhost;
pub(crate) use call::ConstructArgs;
pub(crate) use dynamic::NoopCompilerService;
pub(crate) use frames::FrameArgs;
pub use frames::{CallFrame, Completion, ForInIter, FrameContinuation, TryHandler};