docs: 添加 Rustdoc 注释

This commit is contained in:
2026-08-05 21:46:47 +08:00
parent 7c8f19f61a
commit 263fd255b6
158 changed files with 1440 additions and 15 deletions
@@ -7,6 +7,7 @@ use oxide_types::object::{JsObject, PropAttributes};
use crate::bind_constructor;
use crate::bindings::apply_binding_table;
/// 把 Array 构造器与原型方法绑定到 global。
pub fn bind_array(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) {
let _array_methods = ArrayMethods {
is_array: oxide_builtins::array::array_is_array::<crate::vm::Vm> as *const (),
@@ -5,6 +5,7 @@ use crate::bindings::{apply_binding_table, configure_native_constructor};
use oxide_kernel::kernel::{KernelCore, KernelSession};
use oxide_types::object::JsObject;
/// 把 ArrayBuffer 构造器与原型方法绑定到 global。
pub fn bind_array_buffer(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) {
let ctor_ptr = session.builtin_world().array_buffer_constructor.as_ptr() as *mut JsObject;
let ctor = unsafe { &mut *ctor_ptr };
@@ -5,6 +5,7 @@ use crate::bindings::{apply_binding_table, configure_native_constructor};
use oxide_kernel::kernel::{KernelCore, KernelSession};
use oxide_types::object::JsObject;
/// 把 Boolean 构造器与原型方法绑定到 global。
pub fn bind_boolean(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) {
let ctor_ptr = session.builtin_world().boolean_constructor.as_ptr() as *mut JsObject;
let ctor = unsafe { &mut *ctor_ptr };
@@ -5,6 +5,7 @@ use crate::bindings::{apply_binding_table, configure_native_constructor};
use oxide_kernel::kernel::{KernelCore, KernelSession};
use oxide_types::object::JsObject;
/// 把 DataView 构造器与原型方法绑定到 global。
pub fn bind_data_view(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) {
let ctor_ptr = session.builtin_world().data_view_constructor.as_ptr() as *mut JsObject;
let ctor = unsafe { &mut *ctor_ptr };
@@ -5,6 +5,7 @@ use oxide_kernel::kernel::{KernelCore, KernelSession};
use oxide_types::object::JsObject;
use oxide_types::value::JsValue;
/// 把 Date 构造器与原型方法绑定到 global。
pub fn bind_date(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) {
let ctor_ptr = session.builtin_world().date_constructor.as_ptr() as *mut JsObject;
let ctor = unsafe { &mut *ctor_ptr };
@@ -43,6 +43,7 @@ fn bind_error_subtype_constructor(
global.bump_generation();
}
/// 把 Error 及各子类型(TypeError/ReferenceError/...)构造器与原型方法绑定到 global。
pub fn bind_error(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) {
let error_methods = ErrorMethods {
error: oxide_builtins::error::error_constructor::<crate::vm::Vm> as *const (),
@@ -7,6 +7,7 @@ use oxide_types::value::JsValue;
use super::bind_global_value;
/// 把 Function 构造器与原型方法绑定到 global。
pub fn bind_function(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) {
let function_methods = FunctionMethods {
call: oxide_builtins::function::function_call::<crate::vm::Vm> as *const (),
@@ -5,6 +5,7 @@ use oxide_types::object::JsObject;
use crate::bindings::apply_binding_table;
/// 把普通全局函数(`isNaN`、`parseInt`、`decodeURIComponent` 等)绑定到 global。
pub fn bind_global(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) {
apply_binding_table(
session.builtin_world(),
@@ -7,6 +7,7 @@ use oxide_types::value::JsValue;
use crate::bindings::{apply_binding_table, bind_global_value, configure_native_constructor};
/// 绑定迭代器基础设施:`%IteratorPrototype%` 与 `%ArrayIteratorPrototype%` 等。
pub fn bind_iterator(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) {
let function_proto = session.builtin_world().function_proto.as_ptr() as *mut JsObject;
let mut iterator = Box::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(function_proto)));
@@ -5,6 +5,7 @@ use oxide_kernel::kernel::{KernelCore, KernelSession};
use oxide_types::object::JsObject;
use oxide_types::value::JsValue;
/// 把 JSON 单例对象及其方法(parse/stringify 等)绑定到 global。
pub fn bind_json(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) {
let json_ptr = session.builtin_world().json_object.as_ptr() as *mut JsObject;
let json = unsafe { &mut *json_ptr };
+1
View File
@@ -5,6 +5,7 @@ use crate::bindings::{apply_binding_table, configure_native_constructor};
use oxide_kernel::kernel::{KernelCore, KernelSession};
use oxide_types::object::JsObject;
/// 把 Map 构造器与原型方法绑定到 global。
pub fn bind_map(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) {
let ctor_ptr = session.builtin_world().map_constructor.as_ptr() as *mut JsObject;
let ctor = unsafe { &mut *ctor_ptr };
@@ -5,6 +5,7 @@ use oxide_kernel::kernel::{KernelCore, KernelSession};
use oxide_types::object::JsObject;
use oxide_types::value::JsValue;
/// 把 Math 单例对象及其方法(abs/floor/max/random 等)绑定到 global。
pub fn bind_math(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) {
let math_ptr = session.builtin_world().math_object.as_ptr() as *mut JsObject;
let math = unsafe { &mut *math_ptr };
@@ -6,6 +6,7 @@ use oxide_kernel::kernel::{KernelCore, KernelSession};
use oxide_types::object::{JsObject, PropAttributes};
use oxide_types::value::JsValue;
/// 把 Number 构造器与原型方法绑定到 global(含 NaN/POSITIVE_INFINITY 等常量)。
pub fn bind_number(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) {
let ctor_ptr = session.builtin_world().number_constructor.as_ptr() as *mut JsObject;
let ctor = unsafe { &mut *ctor_ptr };
@@ -7,6 +7,7 @@ use oxide_types::object::{JsObject, PropAttributes};
use crate::bind_constructor;
use crate::bindings::apply_binding_table;
/// 把 Object 构造器与原型方法绑定到 global。
pub fn bind_object(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) {
let methods = ObjectMethods {
keys: oxide_builtins::object::object_keys::<crate::vm::Vm> as *const (),
@@ -6,6 +6,7 @@ use oxide_kernel::shape_forge::EMPTY_SHAPE_ID;
use oxide_types::object::JsObject;
use oxide_types::value::JsValue;
/// 把 Reflect 单例对象及其方法(get/set/construct/defineProperty 等)绑定到 global。
pub fn bind_reflect(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) {
let mut reflect = Box::new(JsObject::new_empty(
EMPTY_SHAPE_ID,
@@ -6,6 +6,7 @@ use oxide_types::object::JsObject;
use crate::bind_constructor;
/// 把 RegExp 构造器与原型方法绑定到 global。
pub fn bind_regexp(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) {
let ctor_ptr = session.builtin_world().regexp_constructor.as_ptr() as *mut JsObject;
let ctor = unsafe { &mut *ctor_ptr };
+1
View File
@@ -5,6 +5,7 @@ use crate::bindings::{apply_binding_table, configure_native_constructor};
use oxide_kernel::kernel::{KernelCore, KernelSession};
use oxide_types::object::JsObject;
/// 把 Set 构造器与原型方法绑定到 global。
pub fn bind_set(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) {
let ctor_ptr = session.builtin_world().set_constructor.as_ptr() as *mut JsObject;
let ctor = unsafe { &mut *ctor_ptr };
@@ -6,6 +6,7 @@ use oxide_kernel::kernel::{KernelCore, KernelSession};
use oxide_types::object::JsObject;
use oxide_types::value::JsValue;
/// 把 String 构造器与原型方法绑定到 global。
pub fn bind_string(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) {
let string_methods = StringMethods {
from_char_code: oxide_builtins::string::string_from_char_code::<crate::vm::Vm> as *const (),
@@ -27,6 +27,8 @@ const STUBS: [(&str, *const (), u8); 8] = [
("Atomics", oxide_builtins::stubs::atomics_stub::<crate::vm::Vm> as *const (), 0),
];
/// 把未实现内置(Proxy/BigInt/WeakMap/WeakSet/WeakRef/FinalizationRegistry/SharedArrayBuffer/Atomics)
/// 的 stub 构造器绑定到 global,并登记到 `stub_objects` 供快照跟踪。
pub fn bind_stubs(core: &Arc<KernelCore>, session: &mut KernelSession, global: &mut JsObject) {
let builtin_world = Arc::get_mut(&mut session.builtin_world)
.expect("BuiltinWorld must be uniquely owned during init_kernel_builtins");
@@ -7,6 +7,7 @@ use oxide_types::value::JsValue;
use crate::bind_constructor;
/// 把 Symbol 构造器与原型方法绑定到 global(含 `Symbol.iterator` 等 well-known symbols)。
pub fn bind_symbol(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) {
let ctor_ptr = session.builtin_world().symbol_constructor.as_ptr() as *mut JsObject;
let ctor = unsafe { &mut *ctor_ptr };
@@ -13,6 +13,7 @@ macro_rules! bind_typed_array_constructor {
}};
}
/// 把所有 TypedArray 家族构造器(Int8Array/Uint8Array/.../BigUint64Array)与其共享原型绑定到 global。
pub fn bind_typed_array(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) {
let shared_proto_ptr = session.builtin_world().typed_array_proto.as_ptr() as *mut JsObject;
let shared_proto = unsafe { &mut *shared_proto_ptr };
+31
View File
@@ -1,23 +1,48 @@
//! 内置对象绑定:把 `oxide_builtins` 中的 native 实现安装到每个 session 的
//! builtin 构造器/原型及 global object 上。绑定在 session 创建(`init_kernel_builtins`)
//! 与 dirty reset(`rebind_dirty_builtins`)两个时机执行。
/// Array 构造器与原型的 native 方法绑定。
pub mod bind_array;
/// ArrayBuffer 构造器与原型的 native 方法绑定。
pub mod bind_array_buffer;
/// Boolean 构造器与原型的 native 方法绑定。
pub mod bind_boolean;
/// DataView 构造器与原型的 native 方法绑定。
pub mod bind_data_view;
/// Date 构造器与原型的 native 方法绑定。
pub mod bind_date;
/// Error 家族构造器与原型的 native 方法绑定(含各子类型构造器创建)。
pub mod bind_error;
/// Function 构造器与原型的 native 方法绑定。
pub mod bind_function;
/// global 对象上的普通全局函数(parseInt、isNaN 等)绑定。
pub mod bind_global;
/// Iterator 相关全局辅助对象(%IteratorPrototype% 等)绑定。
pub mod bind_iterator;
/// JSON 单例对象及其 native 方法绑定。
pub mod bind_json;
/// Map 构造器与原型的 native 方法绑定。
pub mod bind_map;
/// Math 单例对象及其 native 方法绑定。
pub mod bind_math;
/// Number 构造器与原型的 native 方法绑定(含常量属性)。
pub mod bind_number;
/// Object 构造器与原型的 native 方法绑定。
pub mod bind_object;
/// Reflect 单例对象及其 native 方法绑定。
pub mod bind_reflect;
/// RegExp 构造器与原型的 native 方法绑定。
pub mod bind_regexp;
/// Set 构造器与原型的 native 方法绑定。
pub mod bind_set;
/// String 构造器与原型的 native 方法绑定。
pub mod bind_string;
/// 未实现内置(Proxy/BigInt/WeakMap 等)的 stub 构造器绑定。
pub mod bind_stubs;
/// Symbol 构造器与原型的 native 方法绑定。
pub mod bind_symbol;
/// 各 TypedArray 构造器与共享原型的 native 方法绑定。
pub mod bind_typed_array;
use std::sync::Arc;
@@ -256,6 +281,10 @@ fn bind_stub_globals(core: &Arc<KernelCore>, session: &KernelSession, global: &m
}
}
/// 把已有 builtin 构造器的 native 实现与 global 槽位一次性装配完整。
///
/// 在 global 对象重建(dirty reset)后调用:重新配置构造器 native 函数并重绑
/// `Object`/`Array`/`Math` 等全局名、TypedArray 家族、stub 与 `globalThis`。
pub fn bind_global_builtin_slots(core: &Arc<KernelCore>, session: &KernelSession, global: &mut JsObject) {
let world = session.builtin_world();
@@ -464,6 +493,7 @@ pub fn bind_global_builtin_slots(core: &Arc<KernelCore>, session: &KernelSession
/// Maintenance: when adding a `BuiltinDirtySet` group, update this rebind map,
/// `BuiltinSnapshot`, and `BuiltinWorld::rebuild_with_dirty()` together.
/// 按脏标记重绑被污染的内置对象;`dirty` 为 `None` 时绑定全部(初始化路径)。
pub fn rebind_dirty_builtins(core: &Arc<KernelCore>, session: &mut KernelSession, dirty: Option<&BuiltinDirtySet>) {
let global_ptr = session.global_object().as_ptr() as *mut JsObject;
let global = unsafe { &mut *global_ptr };
@@ -524,6 +554,7 @@ pub fn rebind_dirty_builtins(core: &Arc<KernelCore>, session: &mut KernelSession
}
}
/// 完整初始化一个 session 的内置对象(全量绑定 + `globalThis` + 快照记录)。
pub fn init_kernel_builtins(core: &Arc<KernelCore>, session: &mut KernelSession) {
rebind_dirty_builtins(core, session, None);
let global_ptr = session.global_object().as_ptr() as *mut oxide_types::object::JsObject;
+14
View File
@@ -1,18 +1,32 @@
#![doc = "OxideJS - Register-based VM with epoch arena memory"]
//!
//! 字节码执行与运行时内核层:基于寄存器的 VM 负责执行 `CompiledModule` 的
//! bytecode,采用 epoch arena 管理 session 内对象内存,并提供 session 级
//! mark-sweep GC、VM 池、native 函数绑定与内置对象初始化。
//!
//! 核心入口为 [`vm::Vm`];`VmPool` 负责 VM 实例的复用;`session_gc` 提供
//! session 内存回收;`bindings` 把内置对象绑定到每个 session 的 global 上。
/// 内置对象绑定模块:向 session 的 global 对象安装 Object/Array/... 及各原型。
pub mod bindings;
mod dispatch;
mod ic_helper;
/// native 函数签名类型([`native::NativeFn`]),builtin 绑定与 VM 调用约定依赖它。
pub mod native;
mod session_arena;
/// session 级 mark-sweep GC:标记-清扫 session arena 对象与 session 字符串。
pub mod session_gc;
/// 寄存器 VM 主类型([`vm::Vm`])与其执行状态定义。
pub mod vm;
mod vm_dispatch_ctrl;
mod vm_dispatch_misc;
/// VM 层日志宏。
pub mod vm_log;
/// VM 池:多个 VM 实例的创建、复用与归还([`vm_pool::VmPool`] / [`vm_pool::VmGuard`])。
pub mod vm_pool;
mod vm_props;
mod vm_runtime;
mod vm_state;
mod vm_support;
/// JS 值类型再导出(来自 `oxide_types`),作为本 crate 公共 API 的一部分。
pub use oxide_types::value::JsValue;
+4
View File
@@ -1,3 +1,7 @@
use oxide_runtime_api::NativeResult;
/// native 内置函数的函数指针类型。
///
/// `args` 是寄存器下标列表(参数值取自 `Vm` 的寄存器);返回 [`NativeResult`]
/// 表示成功/抛错/尾调用三种结局。绑定层通过 `fn` 项指针构造,保证零开销调用。
pub type NativeFn = fn(&mut crate::vm::Vm, args: &[u8]) -> NativeResult;
+7
View File
@@ -10,6 +10,12 @@ use rustc_hash::FxBuildHasher;
use crate::vm::Vm;
use oxide_builtins::{array_buffer, data_view, map, regexp, set, typed_array};
/// session 级 mark-sweep GC 的状态与统计。
///
/// 回收 session arena 中不再可达的对象与 `Vm::new_string` 分配的 session 字符串:
/// `mark` 从 VM roots 标记存活对象,`sweep` 将存活对象复制进新 arena(移动式)、
/// 更新所有引用,并释放死对象;`sweep_session_strings` 按存活标记回收字符串。
/// 所有统计字段供外部观测 GC 行为。
pub struct SessionGc {
pub total_collections: u64,
pub total_bytes_freed: u64,
@@ -28,6 +34,7 @@ pub struct SessionGc {
}
impl SessionGc {
/// 创建全零统计、空标记栈的空 GC 实例。
pub fn new() -> Self {
Self::default()
}
+35
View File
@@ -6,6 +6,7 @@ use oxide_bytecode::module::{CompiledModule, Constant};
use oxide_bytecode::opcode::{self, OpCode};
use smallvec::SmallVec;
/// 初始化一个 session 的内置对象(global 槽位、各构造器与原型、IC 预热)。
pub use crate::bindings::init_kernel_builtins;
use crate::native::NativeFn;
use crate::session_gc::SessionGc;
@@ -89,6 +90,10 @@ macro_rules! binary_arith {
}}
}
/// 调用帧被挂起后,恢复时需要继续的执行方式。
///
/// `AccessorGet` 表示 accessor getter 返回后需把结果写回 `target_reg`;
/// `AccessorSet` 表示 setter 调用完成;`None` 为普通调用返回。
#[derive(Debug, Clone, Copy)]
pub enum FrameContinuation {
None,
@@ -96,6 +101,10 @@ pub enum FrameContinuation {
AccessorSet,
}
/// 一次函数调用的调用帧:记录返回地址、调用方寄存器窗口与 `this`/`new.target`。
///
/// 调用方寄存器窗口在 `save_stack` 中按 `saved_reg_offset` 保存,返回时由
/// `restore_frame` 恢复;`continuation` 描述 getter/setter 场景的恢复方式。
pub struct CallFrame {
pub return_addr: usize,
pub function_name: u32,
@@ -110,6 +119,9 @@ pub struct CallFrame {
pub continuation: FrameContinuation,
}
/// 一次 `for-in` 迭代的游标:已收集的 key 列表与当前下标。
///
/// 每个 key 与它的 intern id 配对保存,使整型下标 key 无需重新 intern 即可排到字符串 key 之前。
pub struct ForInIter<'bump> {
/// Each key paired with its string-intern id, so for-in can sort
/// integer-index keys ahead of string keys without re-interning.
@@ -117,6 +129,7 @@ pub struct ForInIter<'bump> {
pub index: usize,
}
/// try/catch/finally 处理记录,异常展开时用于定位跳转目标与清理范围。
pub struct TryHandler {
pub catch_pc: Option<usize>,
pub finally_pc: Option<usize>,
@@ -149,6 +162,11 @@ pub(crate) struct InlineSyncState {
pub(crate) cell_stack: Vec<Vec<*mut Cell>>,
}
/// 基于寄存器的 JS 虚拟机:持有执行状态、寄存器文件、调用栈与 session 内存。
///
/// 执行入口为 [`Vm::run`](见 `vm_runtime` 模块);内存模型为 epoch arena +
/// session 对象(可被 `SessionGc` 移动式回收)+ session 字符串。多数内部字段为
/// `pub(crate)`,对外提供统计与内省 getter。
pub struct Vm {
pub(crate) regs: [JsValue; 256],
pub(crate) pc: usize,
@@ -404,38 +422,47 @@ impl Vm {
self.gc_state.session_gc = session_gc;
}
/// 只读访问 session GC 的统计(回收次数、存活/死亡对象数、释放字节等)。
pub fn session_gc_stats(&self) -> &SessionGc {
&self.gc_state.session_gc
}
/// 当前 session arena 中存活(已晋升)的对象数量。
pub fn session_object_count(&self) -> usize {
self.gc_state.session_object_ptrs.len()
}
/// session 当前分配的字节数(对象 + 存活字符串)。
pub fn session_bytes_allocated(&self) -> usize {
self.gc_state.session_bytes_allocated
}
/// 当前 epoch 中已分配并跟踪的对象数量(未晋升到 session 的临时对象)。
pub fn epoch_object_count(&self) -> usize {
self.gc_state.epoch_object_ptrs.len()
}
/// inline cache 命中率(0.0~1.0),用于观测 IC 预热效果。
pub fn ic_hit_rate(&self) -> f64 {
self.profiling.ic_hit_rate()
}
/// 累计执行的指令数(profiling)。
pub fn instruction_count(&self) -> u64 {
self.profiling.instruction_count
}
/// 全局 symbol 注册表中已注册的 key 数量。
pub fn symbol_registry_len(&self) -> usize {
self.symbols.registry_len()
}
/// inline cache 命中次数。
pub fn ic_hit_count(&self) -> u64 {
self.profiling.ic_hits.get()
}
/// inline cache 未命中次数。
pub fn ic_miss_count(&self) -> u64 {
self.profiling.ic_misses.get()
}
@@ -477,6 +504,7 @@ impl Vm {
format_error_message(kind, msg)
}
/// 推进线性同余 RNG 一步(Math.random 用)。首次调用以系统时间纳秒播种。
pub fn step_rng(&mut self) {
if self.math_rng_state == 0 {
self.math_rng_state = std::time::SystemTime::now()
@@ -491,14 +519,17 @@ impl Vm {
.wrapping_add(1442695040888963407);
}
/// 读取当前 RNG 状态生成的 [0,1) 浮点数。
pub fn math_rng_value(&self) -> f64 {
(self.math_rng_state >> 33) as f64 / (1u64 << 31) as f64
}
/// 只读访问 VM 共享的 `KernelCore`。
pub fn kernel_core(&self) -> &Arc<KernelCore> {
&self.kernel_core
}
/// 只读访问当前 session(builtin world 与 global object)。
pub fn session(&self) -> &KernelSession {
&self.session
}
@@ -508,18 +539,22 @@ impl Vm {
std::ptr::eq(ptr, proto_ptr)
}
/// 读取寄存器 `idx` 的值(`VmHost` 与 native 绑定的统一入口)。
pub fn reg(&self, idx: u8) -> JsValue {
self.regs[idx as usize]
}
/// 写入寄存器 `idx` 的值。
pub fn set_reg(&mut self, idx: u8, val: JsValue) {
self.regs[idx as usize] = val;
}
/// 只读访问 VM 的 epoch arena。
pub fn epoch(&self) -> &Epoch {
&self.epoch
}
/// 若 `val` 是字符串,返回其内容的 `String` 副本;否则返回 `None`。
pub fn lookup_str(&self, val: JsValue) -> Option<String> {
if !val.is_string() {
return None;
+12
View File
@@ -12,6 +12,10 @@ struct VmPoolInner {
total_count: usize,
}
/// 共享 `Vm` 实例池:按需创建并复用 VM,避免每次执行重建 kernel 共享状态。
///
/// 空闲 VM 存放在 `available` 队列;达到 `max_size` 上限时 `spawn` 会阻塞等待
/// 归还(带 5 秒超时强制扩容兜底)。线程安全,可供多线程并发领取。
pub struct VmPool {
kernel_core: Arc<KernelCore>,
inner: Mutex<VmPoolInner>,
@@ -19,6 +23,10 @@ pub struct VmPool {
max_size: Option<usize>,
}
/// 从池中借出的 VM 独占句柄(RAII)。
///
/// 持有期间独占访问 [`VmGuard::vm`] / [`VmGuard::vm_mut`];`Drop` 时归还池:
/// 干净 VM 执行 `full_reset` 后复用,被标记 dirty 的 VM 直接丢弃并新建替补。
pub struct VmGuard {
vm: Option<Vm>,
pool: Arc<VmPool>,
@@ -26,6 +34,7 @@ pub struct VmGuard {
}
impl VmPool {
/// 创建空池。`min_size` 当前仅作预热预留(未使用),`max_size` 为池上限,`None` 表示不限。
pub fn new(kernel_core: Arc<KernelCore>, _min_size: usize, max_size: Option<usize>) -> Arc<Self> {
Arc::new(Self {
kernel_core,
@@ -46,6 +55,7 @@ impl VmPool {
Self::new_vm(&self.kernel_core)
}
/// 从池中借出一个 VM:优先复用空闲实例,否则在池未满时新建,池满则阻塞等待归还。
pub fn spawn(self: &Arc<Self>) -> VmGuard {
loop {
let mut inner = self.inner.lock().unwrap();
@@ -94,10 +104,12 @@ impl VmPool {
}
impl VmGuard {
/// 只读访问被借出的 VM。
pub fn vm(&self) -> &Vm {
self.vm.as_ref().expect("VmGuard has no VM")
}
/// 可变访问被借出的 VM。
pub fn vm_mut(&mut self) -> &mut Vm {
self.vm.as_mut().expect("VmGuard has no VM")
}
+5
View File
@@ -142,6 +142,7 @@ impl Vm {
self.pc = frame.return_addr;
}
/// 重新执行当前已加载的 bytecode:清空执行状态并重置 IC 缓存后再次 dispatch。
pub fn rerun(&mut self) -> Result<JsValue, String> {
vm_info!("rerun: clearing IC caches");
self.clear_execution_state();
@@ -150,6 +151,10 @@ impl Vm {
self.dispatch()
}
/// 加载并执行一个已编译模块,返回模块顶层执行结果或未捕获异常消息。
///
/// 内部初始化寄存器/bytecode/immutables 与 builtin 寄存器预绑定,然后进入
/// dispatch 主循环;执行完成或异常展开后返回。
pub fn run(&mut self, module: &CompiledModule) -> Result<JsValue, String> {
vm_debug!("run: starting bytecode execution, {} instructions", module.bytecode.len());
self.clear_execution_state();
+9
View File
@@ -15,6 +15,7 @@ use oxide_types::object::{JsObject, JsString, PropAttributes};
use oxide_types::value::JsValue;
impl Vm {
/// 以最小配置创建独立 VM:新建 `KernelCore` + `KernelSession` 并初始化内置对象。
pub fn new() -> Self {
let core = KernelCore::new(KernelConfig::minimal());
let mut session = KernelSession::new(&core);
@@ -78,6 +79,7 @@ impl Vm {
vm
}
/// 复用共享 `KernelCore` 创建 VM(VM 池路径),共享 intern/shape/code 缓存。
pub fn with_kernel_core(core: Arc<KernelCore>) -> Self {
let mut session = KernelSession::new(&core);
bindings::init_kernel_builtins(&core, &mut session);
@@ -140,6 +142,9 @@ impl Vm {
vm
}
/// 全量隔离重置:仅重建被污染的内置对象与 global,并清空所有执行状态与内存。
///
/// 用于在多次 JS 执行之间达到完全隔离:session 内未被污染的 builtin 保留原指针。
pub fn full_reset(&mut self) {
let dirty = self.session.selective_reset(&self.kernel_core);
if dirty.any_builtin_dirty() {
@@ -156,6 +161,7 @@ impl Vm {
vm_info!("full_reset completed");
}
/// 旧版全量重置:总是丢弃并重建整个 session 与内置对象(benchmark 专用)。
#[doc(hidden)]
pub fn full_reset_legacy_for_bench(&mut self) {
self.session = KernelSession::new(&self.kernel_core);
@@ -216,6 +222,7 @@ impl Vm {
self.native_call_depth = 0;
}
/// 轻量重置:清空执行状态并回收 epoch 内存,但保留 session 字符串与 builtin。
pub fn reset(&mut self) {
self.clear_execution_state();
self.maybe_collect_session_gc();
@@ -229,6 +236,7 @@ impl Vm {
self.active_reg_limit = 0;
}
/// 分配一个可被 session GC 回收的字符串 `JsValue`(session-heap 字符串)。
pub fn new_string(&mut self, s: &str) -> JsValue {
self.new_string_owned(s.to_string())
}
@@ -242,6 +250,7 @@ impl Vm {
JsValue::string(ptr)
}
/// 把字符串 intern 为永久 key id(属性名/方法名),进程生命周期内稳定。
pub fn intern_key(&self, s: &str) -> u32 {
self.kernel_core.perm_interner().intern(s).0
}