docs: 补充注释与格式化

This commit is contained in:
爱特每羊队
2026-08-06 23:10:27 +08:00
parent 4e0fd762c2
commit 328b8a3ddc
156 changed files with 2393 additions and 1687 deletions
+18 -21
View File
@@ -1,8 +1,8 @@
//! 精确 DCE 二轮(D-17/D-19/D-20)运行时等价 + 语义断言。
//! 精确 DCE 二轮运行时等价 + 语义断言。
//!
//! 同一 JS 源码走两条管线:parse → emit → dce(保守恒定)→(precise on/off)→ lower → run,
//! 对比顶层执行结果。**不经 `Compiler::compile`**(测试层直调底层函数)。B008/B012 样例做
//! 字节码/IR 级断言,is_top_level 标志直接断言。
//! 对比顶层执行结果。**不经 `Compiler::compile`**(测试层直调底层函数)。顶层赋值 /
//! escaped 槽样例做字节码/IR 级断言,is_top_level 标志直接断言。
use oxide_bytecode::opcode::OpCode;
use oxide_vm::vm::Vm;
@@ -32,7 +32,7 @@ fn normalize(r: Result<JsValue, String>) -> (bool, String) {
}
}
/// 精确轮 on/off 运行时等价样例集(覆盖 B008/B012/const 抛错/try-catch/双写/纯链)。
/// 精确轮 on/off 运行时等价样例集(覆盖顶层赋值 / escaped 槽 / const 抛错 / try-catch / 双写 / 纯链)。
#[test]
fn precise_dce_semantics_preserved() {
let samples = [
@@ -40,13 +40,13 @@ fn precise_dce_semantics_preserved() {
"function f() { var y = 1; return 5; } f();",
// 死 a 链(a 从未读)
"function f() { var a = 1 + 2; var b = 3 + 4; return b; } f();",
// 顶层 STORE_VAR(B008:is_top_level 保护,不删)
// 顶层 STORE_VAR(is_top_level 保护,不删)
"var x = 1; 2;",
// B008 既有回归样例(顶层赋值全局可观察)
// 顶层赋值全局可观察(回归样例)
"let x = 0; class C { [x = 1]() { return 2; } } new C();",
// B012 回归:k 只被嵌套子模块 LOAD_VAR.a 直读(父 liveness 死、escaped 保活)
// escaped 回归:k 只被嵌套子模块 LOAD_VAR.a 直读(父 liveness 死、escaped 保活)
"function f() { let k = 'a'; class C { [k]() { return 1; } } return Object.keys(new C())[0]; } f();",
// 死 const 声明存储(05-01 后 b=0,删之无害)
// 死 const 声明存储(b=0 无 const guard,删之无害)
"function f() { const c = 5; return 6; } f();",
// const 重赋值抛 TypeError(b=1 保留,两跑同抛)
"const x = 1; x = 2;",
@@ -66,7 +66,7 @@ fn precise_dce_semantics_preserved() {
}
}
/// 字节码级断言:顶层 `var x = 1; 2;` 经 dce+dce_precise 后 STORE_VAR 仍存在(B008)。
/// 字节码级断言:顶层 `var x = 1; 2;` 经 dce+dce_precise 后 STORE_VAR 仍存在(顶层赋值全局可观察)。
#[test]
fn top_level_store_var_survives_precise() {
let allocator = oxide_parser::Allocator::default();
@@ -78,14 +78,17 @@ fn top_level_store_var_survives_precise() {
oxide_dce::dce_precise(&mut ir, &live);
let module = oxide_ir::lower::lower(&ir).expect("lower failed");
assert!(
module.bytecode.iter().any(|&i| OpCode::try_from(i as u8).ok() == Some(OpCode::STORE_VAR)),
module
.bytecode
.iter()
.any(|&i| OpCode::try_from(i as u8).ok() == Some(OpCode::STORE_VAR)),
"顶层 STORE_VAR 必须存活"
);
}
/// IR 级断言:函数内局部死 STORE_VAR 被精确轮删除。
/// dce_precise 按 D-03 不递归 nested,管线(05-09)逐函数处理——此处直接对
/// 嵌套函数本体跑 liveness + dce_precise 证明删除生效。
/// dce_precise 不递归 nested,编译管线逐函数处理——此处直接对嵌套函数本体
/// 跑 liveness + dce_precise 证明删除生效。
#[test]
fn precise_removes_dead_local_store() {
let allocator = oxide_parser::Allocator::default();
@@ -97,21 +100,15 @@ fn precise_removes_dead_local_store() {
let cfg = oxide_cfg::build_cfg(&sub);
let live = oxide_liveness::liveness(&sub, &cfg);
oxide_dce::dce_precise(&mut sub, &live);
assert!(
sub.insts.iter().all(|i| i.op != OpCode::STORE_VAR),
"函数内局部死 STORE_VAR 应被删除"
);
assert!(sub.insts.iter().all(|i| i.op != OpCode::STORE_VAR), "函数内局部死 STORE_VAR 应被删除");
}
/// is_top_level 标志直接断言(D-19):顶层 true / 嵌套 false。
/// is_top_level 标志直接断言:顶层 true / 嵌套 false。
#[test]
fn top_level_flag_filled_by_emit() {
let allocator = oxide_parser::Allocator::default();
let program = oxide_parser::parse(&allocator, "var x = 1; function g() { return 2; }").expect("parse failed");
let ir = oxide_emit::Emitter::new().emit_program(&program).expect("emit failed");
assert!(ir.is_top_level, "顶层脚本 is_top_level 应为 true");
assert!(
ir.nested.iter().any(|sub| !sub.is_top_level),
"嵌套函数 is_top_level 应为 false"
);
assert!(ir.nested.iter().any(|sub| !sub.is_top_level), "嵌套函数 is_top_level 应为 false");
}
+19 -22
View File
@@ -1,8 +1,8 @@
//! 运行时等价对比(D-08):DCE 开/关两份字节码 lower + VM 执行结果一致。
//! 运行时等价对比:DCE 开/关两份字节码 lower + VM 执行结果一致。
//!
//! 同一 JS 源码走两条管线:parse → emit →(dce 开/关)→ lower → `Vm::run`,
//! 对比顶层执行结果。纯表读错 VM handler 也能被此兜底(D-08)。
//! **不经 `Compiler::compile`**(D-10:测试层直调底层函数,不依赖开关)。
//! 对比顶层执行结果。副作用纯表读错 VM handler 也能被此兜底。
//! **不经 `Compiler::compile`**:测试层直调底层函数,不依赖编译器开关。
use oxide_vm::vm::Vm;
use oxide_vm::JsValue;
@@ -29,25 +29,25 @@ fn normalize(r: Result<JsValue, String>) -> (bool, String) {
}
}
/// 死代码样例集(04-RESEARCH.md Pattern 5 清单)。
/// 死代码样例集(覆盖表达式丢弃、死分支、死闭包、coerce 抛错、const 重赋值等路径)。
/// 对每个样例:DCE 开与关分别执行,断言结果一致。
#[test]
fn dead_code_removed_semantics_preserved() {
// 覆盖:表达式语句丢弃结果、重复赋值只读最后值、if(false) 分支、死闭包、
// try/catch 内死代码、对象操作数算术(D-05 coerce 风险兜底)、
// 顶层表达式返回值(HALT reg0 链,Pitfall 2)、先调用后丢弃(CALL 隐式 reg0,Pitfall 1)、
// const 重赋值抛错保留(Pitfall 5)。
// try/catch 内死代码、对象操作数算术(coerce 抛错风险兜底)、
// 顶层表达式返回值(HALT 隐式读 reg0 链)、先调用后丢弃(CALL 隐式写 reg0)、
// const 重赋值抛错保留。
let samples = [
"1+2;3+4", // 语句丢弃结果
"'a'+'b';5;", // 语句丢弃结果(字符串)
"var x=1; x=2; x;", // 重复赋值只读最后值
"function a(){return 1;} if(false){a();} 3;", // if(false) 分支
"function f(){}; 1;", // 死闭包
"try{1+2;}catch(e){3;} 4;", // try/catch 内死代码
"({valueOf(){side=1; return 1}})+2;", // 对象操作数算术(coerce 兜底)
"1+2", // 顶层表达式返回值(Pitfall 2)
"function f(){return 1;} f(); 2+3;", // 先调用后丢弃(Pitfall 1)
"const x=1; x=2;", // const 重赋值(Pitfall 5)
"1+2;3+4", // 语句丢弃结果
"'a'+'b';5;", // 语句丢弃结果(字符串)
"var x=1; x=2; x;", // 重复赋值只读最后值
"function a(){return 1;} if(false){a();} 3;", // if(false) 分支
"function f(){}; 1;", // 死闭包
"try{1+2;}catch(e){3;} 4;", // try/catch 内死代码
"({valueOf(){side=1; return 1}})+2;", // 对象操作数算术(coerce 兜底)
"1+2", // 顶层表达式返回值(HALT 隐式读 reg0 链)
"function f(){return 1;} f(); 2+3;", // 先调用后丢弃(CALL 隐式写 reg0)
"const x=1; x=2;", // const 重赋值(运行时抛错保留)
];
for src in samples {
let a = normalize(run_source(src, true));
@@ -65,7 +65,7 @@ fn single_sample_top_level_return_value() {
assert_eq!(a, (true, "3".to_string()), "顶层 1+2 应返回 3");
}
/// Pitfall 6 回归:脚本顶层变量赋值是全局可观察状态(class 计算属性名里的 `x = 1`
/// 顶层变量赋值是全局可观察状态(class 计算属性名里的 `x = 1`
/// 会被测试 harness 的 `assert.sameValue(x, 1)` 观察),即使本函数内无 use,
/// DCE 也**不得删除**对应 STORE_VAR——删除会改变外部可观察语义。
#[test]
@@ -80,10 +80,7 @@ fn top_level_store_var_kept() {
.bytecode
.iter()
.any(|&i| oxide_bytecode::opcode::opcode(i) == oxide_bytecode::opcode::OpCode::STORE_VAR);
assert!(
has_store_var,
"顶层 x 赋值(全局可观察)不应被 DCE 删除: {src}"
);
assert!(has_store_var, "顶层 x 赋值(全局可观察)不应被 DCE 删除: {src}");
// 运行时兜底:DCE 开/关执行结果一致,且 x 最终值为 1(未被删赋值破坏)
let a = normalize(run_source(src, true));