mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-26 11:41:13 +08:00
feat: ShadowRealm evaluate 与 importValue 真实现落地
This commit is contained in:
@@ -6,14 +6,14 @@ use std::sync::{Arc, OnceLock};
|
||||
|
||||
use oxide_bytecode::module::CompiledModule;
|
||||
use oxide_bytecode::opcode::{self, OpCode};
|
||||
use oxide_runtime_api::CompilerService;
|
||||
use oxide_runtime_api::{CompilerService, ModuleSourceLoader};
|
||||
use oxide_types::object::PropAttributes;
|
||||
use oxide_types::value::JsValue;
|
||||
|
||||
use super::Vm;
|
||||
use crate::vm_support::FunctionFlags;
|
||||
|
||||
/// 缺省 no-op 编译服务:两方法均返 `Err`(错误消息指向「未安装编译服务」)。
|
||||
/// 缺省 no-op 编译服务:三方法均返 `Err`(错误消息指向「未安装编译服务」)。
|
||||
///
|
||||
/// 供不需要动态编译的 `Vm` 实例(构造器缺省值);生产 entry points 与
|
||||
/// 动态编译测试经 `set_compiler_service` 注入真实实现。
|
||||
@@ -27,6 +27,12 @@ impl CompilerService for NoopCompilerService {
|
||||
fn compile_eval_script(&self, _source: &str) -> Result<CompiledModule, String> {
|
||||
Err("dynamic compilation unavailable: no compiler service installed".to_string())
|
||||
}
|
||||
|
||||
fn compile_module(
|
||||
&self, _source: &str, _module_path: &str, _loader: &mut dyn ModuleSourceLoader,
|
||||
) -> Result<CompiledModule, String> {
|
||||
Err("dynamic compilation unavailable: no compiler service installed".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl Vm {
|
||||
@@ -90,6 +96,13 @@ impl Vm {
|
||||
// 子树重编号 + 追加:base = 当前代际平表长度,DFS 前序压入,push 序即新
|
||||
// flat_id。make_mut 彼时平表 Arc 强引用唯一持有者是本表,原地扩展不分叉。
|
||||
let table = self.current_table_mut();
|
||||
// 空表(新 Vm / full_reset 后首个动态函数)补占位模块:函数对象落 index 0
|
||||
// 会被 sub_module_index()==0 守卫误判为无本体函数对象。
|
||||
if table.modules.is_empty() {
|
||||
Arc::make_mut(&mut table.modules).insert(0, Arc::new(CompiledModule::new()));
|
||||
table.immutables.insert(0, OnceLock::new());
|
||||
table.si_tables.insert(0, OnceLock::new());
|
||||
}
|
||||
let base = table.modules.len() as u32;
|
||||
let mut added = Vec::new();
|
||||
rehome_subtree(&anonymous, base, &mut added);
|
||||
@@ -150,6 +163,13 @@ impl Vm {
|
||||
// 根模块 flat_id=0 传 base+1,重编号后落 base(避开 sub_module_index()==0
|
||||
// 守卫)。make_mut 彼时平表 Arc 强引用唯一持有者是本表,原地扩展不分叉。
|
||||
let table = self.current_table_mut();
|
||||
// 空表(新 Vm / full_reset 后首段动态脚本)补占位模块:首个动态脚本的根
|
||||
// 落 index 0 会被 sub_module_index()==0 守卫误判为无本体函数对象。
|
||||
if table.modules.is_empty() {
|
||||
Arc::make_mut(&mut table.modules).insert(0, Arc::new(CompiledModule::new()));
|
||||
table.immutables.insert(0, OnceLock::new());
|
||||
table.si_tables.insert(0, OnceLock::new());
|
||||
}
|
||||
let base = table.modules.len() as u32;
|
||||
let mut added = Vec::new();
|
||||
rehome_subtree(&module, base + 1, &mut added);
|
||||
@@ -189,6 +209,13 @@ impl Vm {
|
||||
// 根模块 flat_id=0 传 base+1,重编号后落 base(避开 sub_module_index()==0
|
||||
// 守卫)。make_mut 彼时平表 Arc 强引用唯一持有者是本表,原地扩展不分叉。
|
||||
let table = self.current_table_mut();
|
||||
// 空表(新 Vm / full_reset 后首段动态脚本)补占位模块:首个动态脚本的根
|
||||
// 落 index 0 会被 sub_module_index()==0 守卫误判为无本体函数对象。
|
||||
if table.modules.is_empty() {
|
||||
Arc::make_mut(&mut table.modules).insert(0, Arc::new(CompiledModule::new()));
|
||||
table.immutables.insert(0, OnceLock::new());
|
||||
table.si_tables.insert(0, OnceLock::new());
|
||||
}
|
||||
let base = table.modules.len() as u32;
|
||||
let mut added = Vec::new();
|
||||
rehome_subtree(&module, base + 1, &mut added);
|
||||
|
||||
@@ -45,11 +45,13 @@ pub(crate) enum RootGroup {
|
||||
DisposeStack,
|
||||
EventTargets,
|
||||
ModuleEvalStates,
|
||||
ShadowKeepalive,
|
||||
WrappedFunctionState,
|
||||
}
|
||||
|
||||
impl RootGroup {
|
||||
/// 根组总数(与变体数同源,绑定逐组计数数组的长度)。
|
||||
pub const COUNT: usize = 30;
|
||||
pub const COUNT: usize = 32;
|
||||
}
|
||||
|
||||
impl Vm {
|
||||
@@ -205,6 +207,19 @@ impl Vm {
|
||||
for state in self.module_eval_states.values() {
|
||||
f(RootGroup::ModuleEvalStates, state.namespace);
|
||||
}
|
||||
// WrappedFunction 保活表(影子 realm 侧):原函数是 GC 根,漏根 →
|
||||
// 影子 GC 回收 → WrappedFunction 持悬垂引用。
|
||||
for &value in &self.shadow_keepalive {
|
||||
f(RootGroup::ShadowKeepalive, value);
|
||||
}
|
||||
// WrappedFunction 状态表(主 realm 侧):键(WrappedFunction 对象)是 GC 根,
|
||||
// 漏根 → sweep 释放 → 调用点反查悬垂。
|
||||
for &wrapped_ptr in self.wrapped_function_state.keys() {
|
||||
if wrapped_ptr.is_null() {
|
||||
continue;
|
||||
}
|
||||
f(RootGroup::WrappedFunctionState, JsValue::from_js_object(wrapped_ptr));
|
||||
}
|
||||
}
|
||||
|
||||
/// GC 根统一枚举入口:遍历的字段清单与 `for_each_value` 相同。
|
||||
|
||||
@@ -481,6 +481,21 @@ pub struct Vm {
|
||||
/// Vm)。实例对象是 GC 根(`for_each_value` 遍历);影子 Vm 不跨线程,
|
||||
/// 随主 Vm 整体迁移,在 `full_reset` / `Drop` 清表时统一释放。
|
||||
pub(crate) shadow_realm_objects: std::collections::HashMap<u64, (JsValue, Vm)>,
|
||||
/// WrappedFunction 保活表:本 Vm 的 GC 根,存放被 WrappedFunction 包装的
|
||||
/// 原函数(本 Vm 堆内对象)。WrappedFunction 持有跨 realm 逻辑边,原函数
|
||||
/// 须在属主 Vm 本表保活防属主 GC 回收;条目随 WrappedFunction 消亡孤儿至
|
||||
/// Vm 收尾(规模有界于包装数)。
|
||||
pub(crate) shadow_keepalive: std::vec::Vec<JsValue>,
|
||||
/// WrappedFunction 状态表:键 = WrappedFunction 对象指针,值 =
|
||||
/// (原函数属主 realm 编号,属主 Vm 保活表下标)。是 GC 根(键保活
|
||||
/// WrappedFunction);值非 GC 边。主 Vm 与影子 Vm 均可持有(包装方向
|
||||
/// 双向:evaluate 结果包装影子函数、包装函数实参包装主 realm 函数)。
|
||||
pub(crate) wrapped_function_state: std::collections::HashMap<*mut JsObject, (u64, usize)>,
|
||||
/// 属主 Vm 指针(影子 realm 侧):影子 Vm 建时指向创建它的属主 Vm,主 Vm
|
||||
/// 恒空。供跨 realm 结算沿属主链上溯解析远端 realm 的属主 Vm(嵌套影子
|
||||
/// realm 包装主 realm 函数场景)。与属主 Vm 同线程、同生命周期(属主 Vm
|
||||
/// 侧表持影子 Vm,先于影子 Vm 存活),指针有效。
|
||||
pub(crate) owner_vm: *mut Vm,
|
||||
}
|
||||
|
||||
impl Drop for Vm {
|
||||
|
||||
Reference in New Issue
Block a user