mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-25 19:21:11 +08:00
feat: 符号键编码加 realm 维度并把符号表移入 realm
This commit is contained in:
@@ -19,7 +19,7 @@ use oxide_types::mem::P;
|
||||
use oxide_types::object::JsObject;
|
||||
|
||||
use crate::session_gc::SessionGc;
|
||||
use crate::vm_state::GcState;
|
||||
use crate::vm_state::{GcState, SymbolState};
|
||||
|
||||
/// 每 VM 的 realm 组合:内核会话(builtin world 与 global 对象)、
|
||||
/// session GC 簿记与 10 个内建原型槽。
|
||||
@@ -30,8 +30,12 @@ use crate::vm_state::GcState;
|
||||
/// 透传。
|
||||
///
|
||||
/// 字段顺序按原 `Vm` 声明顺序(session 先、10 个 P 字段次之、gc 最后),
|
||||
/// 保 Drop 相对顺序。
|
||||
/// 保 Drop 相对顺序。`realm_id` 是分配时固化的编号(无 Drop 关切);
|
||||
/// `symbols` 是 per-realm 符号表(经 `RefCell` 内部可变性,与 session/gc 同型)。
|
||||
pub(crate) struct Realm {
|
||||
/// realm 编号:构造时经 `KernelCore::alloc_realm_id` 分配,进程内单调递增,
|
||||
/// 首个 realm 编号为 0(与旧符号编码一致)。符号身份 = (realm 编号, 局部下标)。
|
||||
pub(crate) realm_id: u32,
|
||||
pub(crate) session: RefCell<KernelSession>,
|
||||
/// `%Object.prototype%`:session 的 Object 原型(global 的 `[[Prototype]]` 挂它)。
|
||||
pub(crate) object_prototype: RefCell<P<JsObject>>,
|
||||
@@ -56,6 +60,9 @@ pub(crate) struct Realm {
|
||||
pub(crate) async_generator_function_proto: RefCell<P<JsObject>>,
|
||||
/// session 堆与 GC 簿记(对象/字符串/BigInt/cell 四表 + 水位与账目)。
|
||||
pub(crate) gc: RefCell<GcState>,
|
||||
/// per-realm 符号表:well-known 名表 + 用户符号描述 + `Symbol.for` 全局注册表。
|
||||
/// 只持 Rust `String` 与 `u32` 下标,无 GC 根,移入 realm 后 `Send` 性不变。
|
||||
pub(crate) symbols: RefCell<SymbolState>,
|
||||
}
|
||||
|
||||
impl Drop for Realm {
|
||||
|
||||
@@ -304,7 +304,7 @@ impl Vm {
|
||||
|
||||
/// 全局 symbol 注册表中已注册的 key 数量。
|
||||
pub fn symbol_registry_len(&self) -> usize {
|
||||
self.symbols.registry_len()
|
||||
self.realm.symbols.borrow().registry_len()
|
||||
}
|
||||
|
||||
/// inline cache 命中次数。
|
||||
|
||||
@@ -19,7 +19,7 @@ pub use crate::bindings::init_kernel_builtins;
|
||||
use crate::native::NativeFn;
|
||||
use crate::realm::Realm;
|
||||
use crate::vm_debug;
|
||||
use crate::vm_state::{IterState, ProfilingState, SampleState, SymbolState};
|
||||
use crate::vm_state::{IterState, ProfilingState, SampleState};
|
||||
use oxide_kernel::kernel::{KernelCore, KernelSession};
|
||||
use oxide_types::error::JsErrorKind;
|
||||
use oxide_types::object::{Cell, JsObject, JsString, NativeFnPtr};
|
||||
@@ -341,8 +341,6 @@ pub struct Vm {
|
||||
/// 异步生成器 body `dispatch()` 的 AWAIT 让出信号:置 true 表示挂起在 await,
|
||||
/// 恢复方(异步生成器内嵌 dispatch 循环)据此快照挂起状态。
|
||||
pub(crate) async_gen_suspended: bool,
|
||||
/// 分组保存 `Symbol` intern 状态。
|
||||
pub(crate) symbols: SymbolState,
|
||||
/// 分组保存活跃的 for-in / for-of 迭代器状态。
|
||||
pub(crate) iters: IterState,
|
||||
/// 分组保存 inline cache 与指令计数器。
|
||||
@@ -455,6 +453,11 @@ impl Vm {
|
||||
self.realm.session.borrow()
|
||||
}
|
||||
|
||||
/// 读取本 VM 所属 realm 的编号(符号身份 = (realm 编号, 局部下标) 的 realm 维度)。
|
||||
pub fn realm_id(&self) -> u32 {
|
||||
self.realm.realm_id
|
||||
}
|
||||
|
||||
/// 判定裸指针是否指向当前 session 的 `%Object.prototype%`。
|
||||
pub(crate) fn is_object_prototype(&self, ptr: *const JsObject) -> bool {
|
||||
let proto_ptr = self.realm.session.borrow().builtin_world().object_proto.as_ptr();
|
||||
|
||||
@@ -220,20 +220,23 @@ impl oxide_runtime_api::VmHost for Vm {
|
||||
fn create_dynamic_script(&mut self, code: &str) -> Result<JsValue, String> {
|
||||
self.create_dynamic_script(code)
|
||||
}
|
||||
fn symbol_intern(&mut self, desc: Option<String>) -> u32 {
|
||||
self.symbols.intern(desc)
|
||||
fn realm_id(&self) -> u32 {
|
||||
self.realm_id()
|
||||
}
|
||||
fn symbol_description(&self, idx: u32) -> Option<&str> {
|
||||
self.symbols.description(idx)
|
||||
fn symbol_intern(&mut self, desc: Option<String>) -> u32 {
|
||||
self.realm.symbols.borrow_mut().intern(desc)
|
||||
}
|
||||
fn symbol_description(&self, idx: u32) -> Option<String> {
|
||||
self.realm.symbols.borrow().description(idx).map(|s| s.to_string())
|
||||
}
|
||||
fn symbol_lookup_global(&self, key: &str) -> Option<u32> {
|
||||
self.symbols.lookup_global(key)
|
||||
self.realm.symbols.borrow().lookup_global(key)
|
||||
}
|
||||
fn symbol_register_global(&mut self, key: String, idx: u32) {
|
||||
self.symbols.register_global(key, idx)
|
||||
self.realm.symbols.borrow_mut().register_global(key, idx)
|
||||
}
|
||||
fn symbol_key_for_id(&self, idx: u32) -> Option<String> {
|
||||
self.symbols.key_for_id(idx)
|
||||
self.realm.symbols.borrow().key_for_id(idx)
|
||||
}
|
||||
fn atomics_new_waiter_promise(&mut self) -> JsValue {
|
||||
self.atomics_new_waiter_promise()
|
||||
|
||||
@@ -58,6 +58,8 @@ impl Vm {
|
||||
let obj_proto = P::clone(&session.builtin_world().object_proto);
|
||||
// 提前缓存执行期字符串 GC 初始水位(构造后 config 不再变化)。
|
||||
let gc_threshold = core.config().session_gc_threshold;
|
||||
// realm 编号在构造时分配并固化:首个 realm 编号为 0(与旧符号编码一致)。
|
||||
let realm_id = core.alloc_realm_id();
|
||||
let mut vm = Self {
|
||||
regs: [JsValue::undefined(); 256],
|
||||
pc: 0,
|
||||
@@ -66,6 +68,7 @@ impl Vm {
|
||||
frames: smallvec::SmallVec::new(),
|
||||
kernel_core: core,
|
||||
realm: Arc::new(Realm {
|
||||
realm_id,
|
||||
session: RefCell::new(session),
|
||||
object_prototype: RefCell::new(obj_proto),
|
||||
generator_proto: RefCell::new(P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null()))),
|
||||
@@ -92,6 +95,11 @@ impl Vm {
|
||||
pending_forced_collect: false,
|
||||
gc_pressure_mode: gc_pressure_mode_from_env(),
|
||||
}),
|
||||
symbols: RefCell::new(SymbolState {
|
||||
symbol_counter: 0,
|
||||
symbol_descriptions: Vec::new(),
|
||||
symbol_registry: std::collections::HashMap::new(),
|
||||
}),
|
||||
}),
|
||||
length_si,
|
||||
length_perm_ptr,
|
||||
@@ -153,11 +161,6 @@ impl Vm {
|
||||
async_gen_context: None,
|
||||
async_gen_dispatch: false,
|
||||
async_gen_suspended: false,
|
||||
symbols: SymbolState {
|
||||
symbol_counter: 0,
|
||||
symbol_descriptions: Vec::new(),
|
||||
symbol_registry: std::collections::HashMap::new(),
|
||||
},
|
||||
iters: IterState {
|
||||
for_in_iters: Vec::new(),
|
||||
for_of_iters: Vec::new(),
|
||||
@@ -205,6 +208,8 @@ impl Vm {
|
||||
let obj_proto = P::clone(&session.builtin_world().object_proto);
|
||||
// 提前缓存执行期字符串 GC 初始水位(构造后 config 不再变化)。
|
||||
let gc_threshold = core.config().session_gc_threshold;
|
||||
// realm 编号在构造时分配并固化:首个 realm 编号为 0(与旧符号编码一致)。
|
||||
let realm_id = core.alloc_realm_id();
|
||||
let mut vm = Self {
|
||||
regs: [JsValue::undefined(); 256],
|
||||
pc: 0,
|
||||
@@ -213,6 +218,7 @@ impl Vm {
|
||||
frames: smallvec::SmallVec::new(),
|
||||
kernel_core: core,
|
||||
realm: Arc::new(Realm {
|
||||
realm_id,
|
||||
session: RefCell::new(session),
|
||||
object_prototype: RefCell::new(obj_proto),
|
||||
generator_proto: RefCell::new(P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null()))),
|
||||
@@ -239,6 +245,11 @@ impl Vm {
|
||||
pending_forced_collect: false,
|
||||
gc_pressure_mode: gc_pressure_mode_from_env(),
|
||||
}),
|
||||
symbols: RefCell::new(SymbolState {
|
||||
symbol_counter: 0,
|
||||
symbol_descriptions: Vec::new(),
|
||||
symbol_registry: std::collections::HashMap::new(),
|
||||
}),
|
||||
}),
|
||||
length_si,
|
||||
length_perm_ptr,
|
||||
@@ -300,11 +311,6 @@ impl Vm {
|
||||
async_gen_context: None,
|
||||
async_gen_dispatch: false,
|
||||
async_gen_suspended: false,
|
||||
symbols: SymbolState {
|
||||
symbol_counter: 0,
|
||||
symbol_descriptions: Vec::new(),
|
||||
symbol_registry: std::collections::HashMap::new(),
|
||||
},
|
||||
iters: IterState {
|
||||
for_in_iters: Vec::new(),
|
||||
for_of_iters: Vec::new(),
|
||||
@@ -450,7 +456,7 @@ impl Vm {
|
||||
let threshold = self.realm.gc.borrow().gc_threshold_cached;
|
||||
self.realm.gc.borrow_mut().gc_watermark = threshold;
|
||||
self.realm.gc.borrow_mut().session_gc = crate::session_gc::SessionGc::new();
|
||||
self.symbols.reset();
|
||||
self.realm.symbols.borrow_mut().reset();
|
||||
self.root_reg_limit = 0;
|
||||
self.active_reg_limit = 0;
|
||||
// 步数上限覆盖随池回收清位:执行路径按请求必设覆盖(含 None),
|
||||
|
||||
@@ -1108,13 +1108,13 @@ fn benign_run_does_not_falsely_dirty_builtins() {
|
||||
#[test]
|
||||
fn full_reset_clears_symbol_state() {
|
||||
let mut vm = Vm::new();
|
||||
vm.symbols.intern(Some("shared".to_string()));
|
||||
vm.realm.symbols.borrow_mut().intern(Some("shared".to_string()));
|
||||
|
||||
vm.full_reset();
|
||||
|
||||
assert_eq!(vm.symbols.symbol_counter, 0);
|
||||
assert!(vm.symbols.symbol_descriptions.is_empty());
|
||||
assert!(vm.symbols.symbol_registry.is_empty());
|
||||
assert_eq!(vm.realm.symbols.borrow().symbol_counter, 0);
|
||||
assert!(vm.realm.symbols.borrow().symbol_descriptions.is_empty());
|
||||
assert!(vm.realm.symbols.borrow().symbol_registry.is_empty());
|
||||
}
|
||||
|
||||
/// 编译源文本为模块(供步数上限测试直接 `run` 并检查 `Result`)。
|
||||
|
||||
Reference in New Issue
Block a user