mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-23 18:21:13 +08:00
docs: 补充注释与格式化
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
//! B005 复现 + n_registers 汇总断言(REG-04 直接验收)。
|
||||
//! 大函数寄存器收缩复现 + n_registers 汇总断言。
|
||||
//!
|
||||
//! 低层管线直调(不经 Compiler——oxide_regalloc dev-dep oxide_compiler 会构成依赖环):
|
||||
//! parse → emit → dce(保守)→(regalloc on/off)→ lower。on 分支按 RESEARCH 例 6:
|
||||
//! 精确 DCE 后重跑 build_cfg + liveness 再 alloc(D-17 索引位移修正);off 分支 = D-18
|
||||
//! 降级路径(vreg 原样当物理号 → lower Reg>253 抛 RangeError)。
|
||||
//! parse → emit → dce(保守)→(regalloc on/off)→ lower。on 分支按编译管线:
|
||||
//! 精确 DCE 后重跑 build_cfg + liveness 再 alloc(删指令后下标位移,重建避免错位);
|
||||
//! off 分支为降级路径(vreg 原样当物理号 → lower Reg>253 抛 RangeError)。
|
||||
|
||||
use oxide_bytecode::module::CompiledModule;
|
||||
|
||||
@@ -23,7 +23,7 @@ fn compile_source(src: &str, regalloc: bool) -> Result<CompiledModule, String> {
|
||||
oxide_ir::lower::lower(&ir)
|
||||
}
|
||||
|
||||
/// B005 样例生成器:n 个逐语句独立 vreg(各值立即死)→ vreg 总数 ≈ 2n ≫ 253,
|
||||
/// 大函数样例生成器:n 个逐语句独立 vreg(各值立即死)→ vreg 总数 ≈ 2n ≫ 253,
|
||||
/// 但峰值活度极小 → RegAlloc 有充分复用空间。
|
||||
fn gen_big(n: usize) -> String {
|
||||
let mut src = String::from("function f() { ");
|
||||
@@ -43,9 +43,9 @@ fn module_max_n_registers(m: &CompiledModule) -> u8 {
|
||||
max
|
||||
}
|
||||
|
||||
/// B005 前置复现:off 模式(降级路径)250 变量函数报 RangeError。
|
||||
/// 前置复现:off 模式(降级路径)250 变量函数报 RangeError。
|
||||
#[test]
|
||||
fn b005_repro_errors_without_regalloc() {
|
||||
fn large_function_errors_without_regalloc() {
|
||||
let err = match compile_source(&gen_big(250), false) {
|
||||
Err(e) => e,
|
||||
Ok(_) => panic!("off 模式应报 RangeError"),
|
||||
@@ -53,14 +53,14 @@ fn b005_repro_errors_without_regalloc() {
|
||||
assert!(err.contains("RangeError"), "off 模式应报 RangeError: {err}");
|
||||
}
|
||||
|
||||
/// B005 修复达成:on 模式 250 变量函数编译成功,模块树 n_registers ≤ 253。
|
||||
/// 修复达成:on 模式 250 变量函数编译成功,模块树 n_registers ≤ 253。
|
||||
#[test]
|
||||
fn b005_compiles_with_regalloc() {
|
||||
fn large_function_compiles_with_regalloc() {
|
||||
let module = compile_source(&gen_big(250), true).expect("on 模式应编译成功");
|
||||
assert!(module_max_n_registers(&module) <= 253, "模块树 n_registers 应 ≤253");
|
||||
}
|
||||
|
||||
/// 样例集 n_registers on ≤ off 且至少一个严格下降(证明寄存器复用,REG-04 核心)。
|
||||
/// 样例集 n_registers on ≤ off 且至少一个严格下降(证明寄存器复用)。
|
||||
#[test]
|
||||
fn n_registers_on_off_aggregate() {
|
||||
let samples = [
|
||||
@@ -78,7 +78,7 @@ fn n_registers_on_off_aggregate() {
|
||||
"function f() { var [a, b] = [1, 2]; var { c, d } = { c: 3, d: 4 }; return a + b + c + d; } f();",
|
||||
// 箭头函数
|
||||
"var f = (a, b) => a * b; f(6, 7);",
|
||||
// switch+const(B011 回归)
|
||||
// switch+const(const guard 回归)
|
||||
"function f(x) { switch (x) { case 1: break; } const c = 5; return c; } f(1);",
|
||||
// 数组字面量
|
||||
"function f() { var a = [1, 2, 3, 4, 5]; return a[0] + a[4]; } f();",
|
||||
@@ -90,10 +90,7 @@ fn n_registers_on_off_aggregate() {
|
||||
assert!(on_max <= 253, "样例 {i} on n_registers {on_max} 超 253");
|
||||
if let Ok(off) = compile_source(src, false) {
|
||||
let off_max = module_max_n_registers(&off);
|
||||
assert!(
|
||||
on_max <= off_max,
|
||||
"样例 {i} on({on_max}) > off({off_max})——RegAlloc 不应增寄存器窗口"
|
||||
);
|
||||
assert!(on_max <= off_max, "样例 {i} on({on_max}) > off({off_max})——RegAlloc 不应增寄存器窗口");
|
||||
if on_max < off_max {
|
||||
strict_decrease = true;
|
||||
}
|
||||
@@ -102,7 +99,7 @@ fn n_registers_on_off_aggregate() {
|
||||
assert!(strict_decrease, "至少一个样例应严格 on < off(复用证明)");
|
||||
}
|
||||
|
||||
/// 确定性:同一源码 on 模式编译两次字节码逐字节相同(B010,structural_hash 缓存依赖)。
|
||||
/// 确定性:同一源码 on 模式编译两次字节码逐字节相同(确定性排序,缓存 key 依赖)。
|
||||
#[test]
|
||||
fn regalloc_deterministic_output() {
|
||||
let a = compile_source(&gen_big(50), true).expect("on 编译成功");
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//! B013 延伸回归:nested 子模块直接槽引用父槽,RegAlloc on/off 运行时等价。
|
||||
//! 嵌套父槽引用回归:nested 子模块直接槽引用父槽,RegAlloc on/off 运行时等价。
|
||||
//!
|
||||
//! 父侧 collect_escaped 保证父不移动槽;但子模块自身 alloc 时引用父槽的
|
||||
//! LOAD_VAR.a / STORE_VAR.rd 曾被当作子模块自己的 vreg 染色移走(→ 读错物理槽,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//! REG-04 断言:RegAlloc on ≤253 且 < off(寄存器收缩);B005 大函数 on 编译成功。
|
||||
//! 寄存器收缩断言:RegAlloc on ≤253 且 < off(寄存器复用);大函数 on 编译成功。
|
||||
|
||||
fn n_registers(src: &str, regalloc: bool) -> Result<u8, String> {
|
||||
let allocator = oxide_parser::Allocator::default();
|
||||
@@ -70,15 +70,15 @@ fn n_registers_shrinks_with_regalloc() {
|
||||
}
|
||||
}
|
||||
|
||||
/// B005 大函数:on 编译成功 ≤253;off 报 RangeError(B005 解决证据)。
|
||||
/// 大函数:on 编译成功 ≤253;off 报 RangeError(vreg 超上限)。
|
||||
#[test]
|
||||
fn b005_large_function_fits_in_253() {
|
||||
fn large_function_fits_in_253() {
|
||||
let src = gen_sum_function(220);
|
||||
let on = n_registers(&src, true);
|
||||
assert!(on.is_ok(), "B005 样例 on 应编译成功");
|
||||
assert!(on.is_ok(), "大函数样例 on 应编译成功");
|
||||
assert!(on.unwrap() <= 253, "on ≤253");
|
||||
let off = n_registers(&src, false);
|
||||
assert!(off.is_err(), "B005 样例 off 应报 RangeError");
|
||||
assert!(off.is_err(), "大函数样例 off 应报 RangeError");
|
||||
assert!(off.unwrap_err().contains("too many registers"), "off Err 消息");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//! RegAlloc on/off 运行时等价(D-21 主验证)+ B005/spill 样例运行正确(REG-04)。
|
||||
//! RegAlloc on/off 运行时等价(主验证)+ 大函数/spill 样例运行正确。
|
||||
//!
|
||||
//! 同一 JS 源码走两条管线:parse → emit → dce(保守恒定)→(regalloc on/off)→ lower → run,
|
||||
//! 对比顶层执行结果。**不经 Compiler::compile**(测试层直调底层函数)。
|
||||
@@ -38,9 +38,9 @@ fn normalize(r: Result<JsValue, String>) -> (bool, String) {
|
||||
#[test]
|
||||
fn regalloc_preserves_semantics() {
|
||||
let samples = [
|
||||
// switch+const(B011 回归)
|
||||
// switch+const(const guard 回归)
|
||||
"function f(x) { switch (x) { case 1: break; } const c = 5; return c; } f(1);",
|
||||
// 类字段(B012 行为锚)
|
||||
// 类字段(escaped 槽行为锚)
|
||||
"var x = 0; class C { p = (x = 1); } new C(); x;",
|
||||
// try-catch
|
||||
"function f() { try { throw 1; } catch (e) { return e + 1; } } f();",
|
||||
@@ -95,15 +95,16 @@ fn gen_spill_function(n: u32) -> String {
|
||||
src
|
||||
}
|
||||
|
||||
/// B005 大函数(200+ 变量)与 spill 压力样例 on 运行正确。
|
||||
/// off 路径 lower 失败(B005 上限)——不能做 on/off 相等,on 运行正确即 REG-04 证据。
|
||||
/// 大函数(200+ 变量)与 spill 压力样例 on 运行正确。
|
||||
/// off 路径 lower 失败(vreg 超 253 上限)——不能做 on/off 相等,on 运行正确即
|
||||
/// 寄存器复用与 spill 的证据。
|
||||
#[test]
|
||||
fn b005_and_spill_samples_run_correctly() {
|
||||
// B005:220 变量 → vreg 数远超 253,但同时存活 < 253 → RegAlloc 复用解决
|
||||
let src_b005 = gen_sum_function(220);
|
||||
let expected_b005 = 220 * 219 / 2;
|
||||
let out = run_source(&src_b005, true).expect("B005 样例 on 应编译成功");
|
||||
assert_eq!(out.to_string(), expected_b005.to_string(), "B005 样例结果错误");
|
||||
fn large_and_spill_samples_run_correctly() {
|
||||
// 220 变量 → vreg 数远超 253,但同时存活 < 253 → RegAlloc 复用解决
|
||||
let src_large = gen_sum_function(220);
|
||||
let expected_large = 220 * 219 / 2;
|
||||
let out = run_source(&src_large, true).expect("大函数样例 on 应编译成功");
|
||||
assert_eq!(out.to_string(), expected_large.to_string(), "大函数样例结果错误");
|
||||
|
||||
// spill 压力:长活 L + 254 短活 → L 溢出,验证 SPILL/UNSPILL 真实发生且结果正确
|
||||
let src_spill = gen_spill_function(254);
|
||||
@@ -124,7 +125,10 @@ fn b005_and_spill_samples_run_correctly() {
|
||||
let module = oxide_ir::lower::lower(&ir).expect("lower");
|
||||
// 递归扫描模块树(spill 发生在嵌套函数 f 中,非顶层 f(1) 调用)
|
||||
fn has_op(m: &oxide_bytecode::module::CompiledModule, target: OpCode) -> bool {
|
||||
if m.bytecode.iter().any(|&instr| OpCode::try_from(instr as u8).ok() == Some(target)) {
|
||||
if m.bytecode
|
||||
.iter()
|
||||
.any(|&instr| OpCode::try_from(instr as u8).ok() == Some(target))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
m.sub_modules.iter().any(|s| has_op(s, target))
|
||||
|
||||
Reference in New Issue
Block a user