mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-25 03:01:12 +08:00
fix: Vm 增加 Drop 收尾释放全部 session 堆数据消除逐实例泄漏
test262 每测试新建 Vm 直接 drop,此前对象堆数据/串/BigInt/cell 全部 泄漏。新增 teardown 收尾函数(epoch+session 对象堆数据、串、BigInt、 cell 统一释放)供 full_reset 与 Drop 共用。连带补齐 promote 分支的 ArrayBuffer 字节缓冲深拷贝(与 sweep 对齐,消除共享所有权 double-free), 并修正依赖旧泄漏行为跨 Vm 解析字符串的 error 测试。
This commit is contained in:
@@ -16,6 +16,14 @@ fn eval(source: &str) -> Result<JsValue, String> {
|
||||
vm.run(&module)
|
||||
}
|
||||
|
||||
/// 在既有 Vm 内编译执行:结果字符串须在同一 Vm 上下文解析(session 串随 Vm 释放)。
|
||||
fn eval_in(vm: &mut Vm, source: &str) -> Result<JsValue, String> {
|
||||
let allocator = oxide_parser::Allocator::default();
|
||||
let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse: {:?}", e))?;
|
||||
let module = Compiler::new().compile(&program).map_err(|e| format!("Compile: {}", e))?;
|
||||
vm.run(&module)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn error_constructor_creates_object() {
|
||||
let mut vm = make_vm();
|
||||
@@ -286,24 +294,24 @@ fn error_to_string_basic() {
|
||||
|
||||
#[test]
|
||||
fn error_to_string_empty_message() {
|
||||
let result = eval("new Error().toString()").unwrap();
|
||||
let vm = make_vm();
|
||||
let mut vm = make_vm();
|
||||
let result = eval_in(&mut vm, "new Error().toString()").unwrap();
|
||||
let s = vm.lookup_str(result);
|
||||
assert_eq!(s, Some("Error".to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn error_to_string_type_error() {
|
||||
let result = eval("new TypeError('bad').toString()").unwrap();
|
||||
let vm = make_vm();
|
||||
let mut vm = make_vm();
|
||||
let result = eval_in(&mut vm, "new TypeError('bad').toString()").unwrap();
|
||||
let s = vm.lookup_str(result);
|
||||
assert_eq!(s, Some("TypeError: bad".to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn error_to_string_name_only() {
|
||||
let result = eval("Error.prototype.toString.call({name: 'E'})").unwrap();
|
||||
let vm = make_vm();
|
||||
let mut vm = make_vm();
|
||||
let result = eval_in(&mut vm, "Error.prototype.toString.call({name: 'E'})").unwrap();
|
||||
let s = vm.lookup_str(result);
|
||||
assert_eq!(s, Some("E".to_string()));
|
||||
}
|
||||
@@ -355,16 +363,16 @@ fn error_stack_is_string() {
|
||||
|
||||
#[test]
|
||||
fn error_stack_starts_with_header() {
|
||||
let result = eval("new Error().stack()").unwrap();
|
||||
let vm = make_vm();
|
||||
let mut vm = make_vm();
|
||||
let result = eval_in(&mut vm, "new Error().stack()").unwrap();
|
||||
let s = vm.lookup_str(result).unwrap();
|
||||
assert!(s.starts_with("Error"), "stack should start with 'Error', got: {}", s);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn error_stack_frame_format() {
|
||||
let result = eval("(function foo() { return new Error('boom').stack(); })()").unwrap();
|
||||
let vm = make_vm();
|
||||
let mut vm = make_vm();
|
||||
let result = eval_in(&mut vm, "(function foo() { return new Error('boom').stack(); })()").unwrap();
|
||||
let s = vm.lookup_str(result).unwrap();
|
||||
assert!(s.contains(" at "), "stack should have 4-space indent, got: {}", s);
|
||||
}
|
||||
|
||||
@@ -18,8 +18,10 @@ fn compile(source: &str) -> oxide_bytecode::module::CompiledModule {
|
||||
#[test]
|
||||
fn generator_promoted_to_global_survives_full_reset_cleanly() {
|
||||
let mut vm = Vm::new();
|
||||
vm.run(&compile("function* g(){ yield 1; yield 2; } globalThis.it = g(); globalThis.it.next(); 0"))
|
||||
.expect("run1");
|
||||
vm.run(&compile(
|
||||
"function* g(){ yield 1; yield 2; } globalThis.it = g(); globalThis.it.next(); 0",
|
||||
))
|
||||
.expect("run1");
|
||||
assert!(vm.session_object_count() > 0, "生成器挂 global 应被 promote 进 session");
|
||||
|
||||
// global 含 session 对象即强制重建:旧 global 丢弃、it 槽不存在,全程无悬垂访问
|
||||
@@ -31,6 +33,8 @@ fn generator_promoted_to_global_survives_full_reset_cleanly() {
|
||||
let text = vm.lookup_str(result).expect("typeof 应返回字符串").to_string();
|
||||
assert_eq!(text, "undefined");
|
||||
// 新会话可正常创建并推进生成器。
|
||||
let ok = vm.run(&compile("function* h(){ yield 9; } var it2 = h(); it2.next().value")).expect("run3");
|
||||
let ok = vm
|
||||
.run(&compile("function* h(){ yield 9; } var it2 = h(); it2.next().value"))
|
||||
.expect("run3");
|
||||
assert_eq!(format!("{ok}"), "9");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user