refactor: realm 与 Vm 生命周期解耦,Vm 持 Arc<Realm>

This commit is contained in:
2026-10-07 01:35:16 +00:00
parent 14ef287a75
commit c6bc93a076
39 changed files with 796 additions and 676 deletions
+19 -12
View File
@@ -67,12 +67,16 @@ pub fn iterator_constructor<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult
/// 重建内置对象族,换新的 `Iterator` 函数对象;缓存旧指针会指向已释放对象。
/// lookup 失败(极端:global 无 `Iterator`)返回 undefined,不 panic。
pub fn iterator_constructor_getter<H: VmHost>(vm: &mut H, _args: &[u8]) -> NativeResult {
let global = vm.session().global_object();
let (shape_id, global_ptr) = {
let session = vm.session();
let global = session.global_object();
(global.shape_id(), global.as_ptr() as *mut JsObject)
};
let si = vm.kernel_core().perm_interner().intern("Iterator").0;
let Some(pos) = vm.kernel_core().shape_forge().lookup_position(global.shape_id(), si) else {
let Some(pos) = vm.kernel_core().shape_forge().lookup_position(shape_id, si) else {
return NativeResult::Ok(JsValue::undefined());
};
NativeResult::Ok(global.get_prop_at(pos))
NativeResult::Ok(unsafe { &*global_ptr }.get_prop_at(pos))
}
/// `%IteratorPrototype%` 上 `Symbol.toStringTag` 访问器的 getter:返回 `"Iterator"`。
@@ -1486,15 +1490,18 @@ fn builtin_iterator_default_intact<H: VmHost>(vm: &mut H, value: JsValue, method
if !method.is_object() {
return false;
}
let world = vm.session().builtin_world();
let (anchor_ptr, anchor_name) = if is_array_value(value) {
(world.array_proto.as_ptr() as *mut JsObject, "values")
} else if is_typed_array_value(value) {
(world.typed_array_proto.as_ptr() as *mut JsObject, "values")
} else if is_map_value(value) {
(world.map_proto.as_ptr() as *mut JsObject, "entries")
} else {
(world.set_proto.as_ptr() as *mut JsObject, "values")
let (anchor_ptr, anchor_name) = {
let session = vm.session();
let world = session.builtin_world();
if is_array_value(value) {
(world.array_proto.as_ptr() as *mut JsObject, "values")
} else if is_typed_array_value(value) {
(world.typed_array_proto.as_ptr() as *mut JsObject, "values")
} else if is_map_value(value) {
(world.map_proto.as_ptr() as *mut JsObject, "entries")
} else {
(world.set_proto.as_ptr() as *mut JsObject, "values")
}
};
let anchor_obj = unsafe { &*anchor_ptr };
let anchor_si = vm.kernel_core().perm_interner().intern(anchor_name).0;
+6 -3
View File
@@ -455,10 +455,11 @@ pub fn map_size<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
pub fn map_entries<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
let this_val = vm.reg(if args.is_empty() { 0 } else { args[0] });
let _inner = native_try!(get_map_inner(vm, this_val));
let proto_ptr = vm.session().builtin_world().map_iterator_proto.as_ptr() as *mut JsObject;
NativeResult::Ok(crate::iterator::make_collection_iterator(
vm,
this_val,
JsValue::from_js_object(vm.session().builtin_world().map_iterator_proto.as_ptr() as *mut JsObject),
JsValue::from_js_object(proto_ptr),
crate::iterator::MapSetMode::MapEntries,
))
}
@@ -467,10 +468,11 @@ pub fn map_entries<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
pub fn map_values<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
let this_val = vm.reg(if args.is_empty() { 0 } else { args[0] });
let _inner = native_try!(get_map_inner(vm, this_val));
let proto_ptr = vm.session().builtin_world().map_iterator_proto.as_ptr() as *mut JsObject;
NativeResult::Ok(crate::iterator::make_collection_iterator(
vm,
this_val,
JsValue::from_js_object(vm.session().builtin_world().map_iterator_proto.as_ptr() as *mut JsObject),
JsValue::from_js_object(proto_ptr),
crate::iterator::MapSetMode::MapValues,
))
}
@@ -479,10 +481,11 @@ pub fn map_values<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
pub fn map_keys<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
let this_val = vm.reg(if args.is_empty() { 0 } else { args[0] });
let _inner = native_try!(get_map_inner(vm, this_val));
let proto_ptr = vm.session().builtin_world().map_iterator_proto.as_ptr() as *mut JsObject;
NativeResult::Ok(crate::iterator::make_collection_iterator(
vm,
this_val,
JsValue::from_js_object(vm.session().builtin_world().map_iterator_proto.as_ptr() as *mut JsObject),
JsValue::from_js_object(proto_ptr),
crate::iterator::MapSetMode::MapKeys,
))
}
+2 -4
View File
@@ -1568,10 +1568,8 @@ pub fn object_from_entries<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
if entries_ptr.is_null() {
return NativeResult::Err(crate::error::create_type_error(vm, "Object.fromEntries: argument must be iterable"));
}
let obj = vm.alloc_object(JsObject::new_empty(
EMPTY_SHAPE_ID,
JsValue::from_js_object(vm.session().builtin_world().object_proto.as_ptr() as *mut JsObject),
));
let proto_ptr = vm.session().builtin_world().object_proto.as_ptr() as *mut JsObject;
let obj = vm.alloc_object(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(proto_ptr)));
let target_val = JsValue::from_js_object(obj);
// entry 数组的元素存元素区(元素区之外才是命名属性区),按元素区长度迭代。
let n: usize = unsafe { (*entries_ptr).array_prop_count } as usize;
+6 -3
View File
@@ -315,10 +315,11 @@ pub fn set_size<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
pub fn set_entries<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
let this_val = vm.reg(if args.is_empty() { 0 } else { args[0] });
let _inner = native_try!(get_set_inner(vm, this_val));
let proto_ptr = vm.session().builtin_world().set_iterator_proto.as_ptr() as *mut JsObject;
NativeResult::Ok(crate::iterator::make_collection_iterator(
vm,
this_val,
JsValue::from_js_object(vm.session().builtin_world().set_iterator_proto.as_ptr() as *mut JsObject),
JsValue::from_js_object(proto_ptr),
crate::iterator::MapSetMode::SetEntries,
))
}
@@ -327,10 +328,11 @@ pub fn set_entries<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
pub fn set_values<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
let this_val = vm.reg(if args.is_empty() { 0 } else { args[0] });
let _inner = native_try!(get_set_inner(vm, this_val));
let proto_ptr = vm.session().builtin_world().set_iterator_proto.as_ptr() as *mut JsObject;
NativeResult::Ok(crate::iterator::make_collection_iterator(
vm,
this_val,
JsValue::from_js_object(vm.session().builtin_world().set_iterator_proto.as_ptr() as *mut JsObject),
JsValue::from_js_object(proto_ptr),
crate::iterator::MapSetMode::SetValues,
))
}
@@ -340,10 +342,11 @@ pub fn set_keys<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
let this_val = vm.reg(if args.is_empty() { 0 } else { args[0] });
let _inner = native_try!(get_set_inner(vm, this_val));
// Set 的 keys() 是 values() 的别名——返回同样的逐元素迭代器。
let proto_ptr = vm.session().builtin_world().set_iterator_proto.as_ptr() as *mut JsObject;
NativeResult::Ok(crate::iterator::make_collection_iterator(
vm,
this_val,
JsValue::from_js_object(vm.session().builtin_world().set_iterator_proto.as_ptr() as *mut JsObject),
JsValue::from_js_object(proto_ptr),
crate::iterator::MapSetMode::SetValues,
))
}
+2 -4
View File
@@ -931,10 +931,8 @@ fn match_all_construct_invoke<H: VmHost>(vm: &mut H, this_val: JsValue, pattern_
// regexp = RegExpCreate(pattern, "g")。
let g_str = vm.new_string("g");
let rx_val = match vm.construct_ctor(
JsValue::from_js_object(vm.session().builtin_world().regexp_constructor.as_ptr() as *mut JsObject),
&[pattern_val, g_str],
) {
let ctor_ptr = vm.session().builtin_world().regexp_constructor.as_ptr() as *mut JsObject;
let rx_val = match vm.construct_ctor(JsValue::from_js_object(ctor_ptr), &[pattern_val, g_str]) {
Ok(v) => v,
Err(e) => return NativeResult::Err(e),
};
+32 -26
View File
@@ -58,19 +58,22 @@ fn to_index<H: VmHost>(vm: &mut H, value: JsValue, msg: &str) -> Result<usize, J
}
fn typed_array_proto_ptr<H: VmHost>(vm: &mut H, kind: TypedArrayKind) -> *mut JsObject {
let world = vm.session().builtin_world();
match kind {
TypedArrayKind::Int8 => world.int8array_proto.as_ptr() as *mut JsObject,
TypedArrayKind::Uint8 => world.uint8array_proto.as_ptr() as *mut JsObject,
TypedArrayKind::Uint8Clamped => world.uint8clampedarray_proto.as_ptr() as *mut JsObject,
TypedArrayKind::Int16 => world.int16array_proto.as_ptr() as *mut JsObject,
TypedArrayKind::Uint16 => world.uint16array_proto.as_ptr() as *mut JsObject,
TypedArrayKind::Int32 => world.int32array_proto.as_ptr() as *mut JsObject,
TypedArrayKind::Uint32 => world.uint32array_proto.as_ptr() as *mut JsObject,
TypedArrayKind::Float32 => world.float32array_proto.as_ptr() as *mut JsObject,
TypedArrayKind::Float64 => world.float64array_proto.as_ptr() as *mut JsObject,
TypedArrayKind::BigInt64 => world.bigint64array_proto.as_ptr() as *mut JsObject,
TypedArrayKind::BigUint64 => world.biguint64array_proto.as_ptr() as *mut JsObject,
{
let session = vm.session();
let world = session.builtin_world();
match kind {
TypedArrayKind::Int8 => world.int8array_proto.as_ptr() as *mut JsObject,
TypedArrayKind::Uint8 => world.uint8array_proto.as_ptr() as *mut JsObject,
TypedArrayKind::Uint8Clamped => world.uint8clampedarray_proto.as_ptr() as *mut JsObject,
TypedArrayKind::Int16 => world.int16array_proto.as_ptr() as *mut JsObject,
TypedArrayKind::Uint16 => world.uint16array_proto.as_ptr() as *mut JsObject,
TypedArrayKind::Int32 => world.int32array_proto.as_ptr() as *mut JsObject,
TypedArrayKind::Uint32 => world.uint32array_proto.as_ptr() as *mut JsObject,
TypedArrayKind::Float32 => world.float32array_proto.as_ptr() as *mut JsObject,
TypedArrayKind::Float64 => world.float64array_proto.as_ptr() as *mut JsObject,
TypedArrayKind::BigInt64 => world.bigint64array_proto.as_ptr() as *mut JsObject,
TypedArrayKind::BigUint64 => world.biguint64array_proto.as_ptr() as *mut JsObject,
}
}
}
@@ -100,19 +103,22 @@ fn ta_gpf_proto<H: VmHost>(vm: &mut H, kind: TypedArrayKind) -> Result<JsValue,
}
fn typed_array_ctor_value<H: VmHost>(vm: &mut H, kind: TypedArrayKind) -> JsValue {
let world = vm.session().builtin_world();
let ctor = match kind {
TypedArrayKind::Int8 => world.int8array_constructor.clone(),
TypedArrayKind::Uint8 => world.uint8array_constructor.clone(),
TypedArrayKind::Uint8Clamped => world.uint8clampedarray_constructor.clone(),
TypedArrayKind::Int16 => world.int16array_constructor.clone(),
TypedArrayKind::Uint16 => world.uint16array_constructor.clone(),
TypedArrayKind::Int32 => world.int32array_constructor.clone(),
TypedArrayKind::Uint32 => world.uint32array_constructor.clone(),
TypedArrayKind::Float32 => world.float32array_constructor.clone(),
TypedArrayKind::Float64 => world.float64array_constructor.clone(),
TypedArrayKind::BigInt64 => world.bigint64array_constructor.clone(),
TypedArrayKind::BigUint64 => world.biguint64array_constructor.clone(),
let ctor = {
let session = vm.session();
let world = session.builtin_world();
match kind {
TypedArrayKind::Int8 => world.int8array_constructor.clone(),
TypedArrayKind::Uint8 => world.uint8array_constructor.clone(),
TypedArrayKind::Uint8Clamped => world.uint8clampedarray_constructor.clone(),
TypedArrayKind::Int16 => world.int16array_constructor.clone(),
TypedArrayKind::Uint16 => world.uint16array_constructor.clone(),
TypedArrayKind::Int32 => world.int32array_constructor.clone(),
TypedArrayKind::Uint32 => world.uint32array_constructor.clone(),
TypedArrayKind::Float32 => world.float32array_constructor.clone(),
TypedArrayKind::Float64 => world.float64array_constructor.clone(),
TypedArrayKind::BigInt64 => world.bigint64array_constructor.clone(),
TypedArrayKind::BigUint64 => world.biguint64array_constructor.clone(),
}
};
JsValue::from_js_object(ctor.as_ptr() as *mut JsObject)
}