fix: RegExp source/flags 原型访问器与 GC 根追踪

This commit is contained in:
2026-09-21 14:56:19 +00:00
parent fea24b6d26
commit 8e22c48b70
6 changed files with 190 additions and 24 deletions
@@ -36,6 +36,22 @@ pub fn bind_regexp(core: &Arc<KernelCore>, session: &KernelSession, global: &mut
],
);
// source/flags 只读访问器(set 恒 undefined,getter 读实例字段)。
bind_accessor_getter(
core,
session,
proto,
"source",
oxide_builtins::regexp::regexp_get_source::<crate::vm::Vm> as *const (),
);
bind_accessor_getter(
core,
session,
proto,
"flags",
oxide_builtins::regexp::regexp_get_flags::<crate::vm::Vm> as *const (),
);
// 8 个单 flag 只读访问器(set 恒 undefined,getter 读实例 flags 串判码元)。
bind_accessor_getter(
core,
+14
View File
@@ -222,6 +222,11 @@ impl SessionGc {
Self::mark_string_live(live_strings, ptr);
}
}
// RegExp 实例 source/flags 字段持有字符串边。
if obj.is_regexp_obj() {
Self::process_edge(obj.get_regexp_source(), vm, stack, live_strings, live_bigints);
Self::process_edge(obj.get_regexp_flags(), vm, stack, live_strings, live_bigints);
}
// 遍历 upvalue cell 中的引用。
for cell_ptr in obj.upvalues_slice() {
if cell_ptr.is_null() {
@@ -393,6 +398,15 @@ impl SessionGc {
Self::mark_string_live(live, ptr);
}
}
// RegExp 实例 source/flags 字段持有字符串边。
if obj.is_regexp_obj() {
if obj.get_regexp_source().is_string() {
Self::mark_string_live(live, obj.get_regexp_source().as_string_ptr_mut());
}
if obj.get_regexp_flags().is_string() {
Self::mark_string_live(live, obj.get_regexp_flags().as_string_ptr_mut());
}
}
}
/// 从 VM roots 标记存活的 session/epoch 对象、字符串与 BigInt,供 `sweep` 判定。
@@ -534,8 +534,9 @@ fn regexp_flag_accessor_descriptor_and_identity() {
#[test]
fn regexp_instance_has_no_own_flag_props() {
let mut vm = Vm::new();
// source/flags 是原型访问器,非实例自身属性;仅 lastIndex 为自身数据属性。
let result = eval(&mut vm, "Object.getOwnPropertyNames(new RegExp('a', 'g')).sort().join(',')").unwrap();
assert_eq!(to_str(&vm, result), "flags,lastIndex,source");
assert_eq!(to_str(&vm, result), "lastIndex");
}
#[test]