mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-26 19:51:11 +08:00
types/kernel/vm/builtins: JsString UTF-16 载荷层(FlatU16 变体 + 单元入口)——原 UTF-8 载荷只存 well-formed 串、孤立 surrogate lossy 转 U+FFFD 回写,FromCodePoint/属性转义与字符串面码点语义皆破;现载荷直存 [u64;3](Flat well-formed / FlatU16 单元序列 / Cons 拼接),utf16_len 独立 32 位字,32B 布局锚保持;from_units 智能路由(含孤立→FlatU16),as_str 仅限 Flat,units/units_borrowed 单元借用,as_lossy_str 宽容读;string_forge 编解码 surrogate 感知(孤立 surrogate 逃逸 hex4 编码、解码展开 astral 代理对、string_ptr 由单元物化);VmHost 单元物化/分配/查询入口 + runtime_api 单元 API;字符串内置全法单元化(charAt/slice/substr/split/replace/search/match/matchAll 单元定位;空模式边界:search→0、match→[""]、replace 插 0 位、matchAll 游标耗尽守卫;接收者 ToString 错误原样传播);正则内置单元化(exec/test/search/symbol_* 单元文本,替换串 \u{...} 与孤立 surrogate 文本处理,lastIndex 与 matchAll 游标单元化);字符串迭代器码点化(高代理+后续低代理成对产出,astral 值回真实码点);String(Symbol) 抛 TypeError;回归钉更新五处(charAt/split/slice/substr 单元精确语义 + dispose 钉改 TypeError 断言);四 crate 全绿(oxide_vm 98 套件 2403 测)+ clippy/fmt 零新增
This commit is contained in:
@@ -541,7 +541,7 @@ impl SessionGc {
|
||||
/// `ptr` 必须是 `Box::into_raw(Box::new(JsString))` 产生的非空指针,仍存在
|
||||
/// 于 `session_string_ptrs`,且恰好释放一次。
|
||||
unsafe fn drop_dead_session_string(ptr: *mut JsString) -> u64 {
|
||||
let bytes = (size_of::<JsString>() + (*ptr).len()) as u64;
|
||||
let bytes = (size_of::<JsString>() + (*ptr).payload_bytes()) as u64;
|
||||
Self::drop_session_string_box(ptr);
|
||||
bytes
|
||||
}
|
||||
@@ -701,7 +701,7 @@ impl SessionGc {
|
||||
if self.live_strings.contains(&ptr) {
|
||||
// 存活——地址不变,无需重写。
|
||||
// SAFETY: ptr 是仍归 VM 所有的存活 session 字符串 box。
|
||||
live_bytes += unsafe { size_of::<JsString>() + (*ptr).len() };
|
||||
live_bytes += unsafe { size_of::<JsString>() + (*ptr).payload_bytes() };
|
||||
live.push(ptr);
|
||||
} else {
|
||||
// SAFETY: ptr 在 session_string_ptrs 中但不可达,恰好释放一次。
|
||||
@@ -1032,7 +1032,7 @@ impl SessionGc {
|
||||
continue;
|
||||
}
|
||||
// SAFETY: ptr 在字符串表登记,收尾前有效。
|
||||
string_bytes += size_of::<JsString>() + unsafe { (*ptr).len() };
|
||||
string_bytes += size_of::<JsString>() + unsafe { (*ptr).payload_bytes() };
|
||||
}
|
||||
let bigint_bytes = vm.gc_state.session_bigint_ptrs.borrow().len() * size_of::<num_bigint::BigInt>();
|
||||
vm.gc_state.session_bytes_allocated = object_bytes + string_bytes + bigint_bytes;
|
||||
@@ -2311,7 +2311,7 @@ mod tests {
|
||||
vm.maybe_collect_session_strings();
|
||||
|
||||
// 账目 = 对象头 + 存活串(size_of::<JsString>() + len),死串不再计入。
|
||||
let expected = size_of::<JsObject>() + (size_of::<JsString>() + unsafe { (*live_ptr).len() });
|
||||
let expected = size_of::<JsObject>() + (size_of::<JsString>() + unsafe { (*live_ptr).payload_bytes() });
|
||||
assert_eq!(vm.gc_state.session_bytes_allocated, expected);
|
||||
assert!(!vm.gc_state.session_string_ptrs.contains(&dead.as_string_ptr_mut()));
|
||||
}
|
||||
@@ -2349,7 +2349,7 @@ mod tests {
|
||||
assert!(vm.gc_state.session_string_ptrs.contains(&parent_ptr));
|
||||
assert!(vm.gc_state.session_string_ptrs.contains(&l_ptr));
|
||||
assert!(vm.gc_state.session_string_ptrs.contains(&r_ptr));
|
||||
assert_eq!(unsafe { (*parent_ptr).as_str() }, "left-partright-part");
|
||||
assert_eq!(unsafe { (*parent_ptr).as_lossy_str() }, "left-partright-part");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -2373,7 +2373,7 @@ mod tests {
|
||||
let (parent, _, _) = make_cons_pair(&mut vm, "left-part", "right-part");
|
||||
let parent_ptr = parent.as_string_ptr_mut();
|
||||
// 触发扁平化:产物发布到 flat_cache。
|
||||
assert_eq!(unsafe { (*parent_ptr).flat_str() }, "left-partright-part");
|
||||
assert_eq!(unsafe { (*parent_ptr).as_lossy_str() }, "left-partright-part");
|
||||
let flat_ptr = unsafe { (*parent_ptr).flat_cache_ptr() };
|
||||
assert!(!flat_ptr.is_null());
|
||||
|
||||
@@ -2400,7 +2400,7 @@ mod tests {
|
||||
collect(&mut vm);
|
||||
|
||||
assert!(vm.gc_state.session_string_ptrs.contains(&chain_ptr));
|
||||
assert_eq!(unsafe { (*chain_ptr).as_str() }, format!("root{}", "x".repeat(1024)));
|
||||
assert_eq!(unsafe { (*chain_ptr).as_lossy_str() }, format!("root{}", "x".repeat(1024)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -2418,7 +2418,7 @@ mod tests {
|
||||
// perm 子节点永不释放(不在 session 表);session 子节点随父存活。
|
||||
assert!(!vm.gc_state.session_string_ptrs.contains(&perm_ptr));
|
||||
assert!(vm.gc_state.session_string_ptrs.contains(&session_ptr));
|
||||
assert_eq!(unsafe { (*parent.as_string_ptr_mut()).as_str() }, "perm-leafsession-leaf");
|
||||
assert_eq!(unsafe { (*parent.as_string_ptr_mut()).as_lossy_str() }, "perm-leafsession-leaf");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -2426,7 +2426,7 @@ mod tests {
|
||||
let mut vm = Vm::new();
|
||||
let (parent, _, _) = make_cons_pair(&mut vm, "left-part", "right-part");
|
||||
// 触发扁平化(产物挂在父上)。
|
||||
assert_eq!(unsafe { (*parent.as_string_ptr_mut()).flat_str() }, "left-partright-part");
|
||||
assert_eq!(unsafe { (*parent.as_string_ptr_mut()).as_lossy_str() }, "left-partright-part");
|
||||
vm.regs[0] = parent;
|
||||
|
||||
// full_reset 清空全部 session 字符串(连带产物):无泄漏、无 double-free。
|
||||
|
||||
Reference in New Issue
Block a user