实现与自举
xxc 实现与自举
> xxc 的终极目标是 Go 式完全自举:编译 xxc 源码直出原生机器码,且
> 整个工具链(词法、语法、类型检查、代码生成、汇编器、链接器)全部用
> xxc 自己编写。这一目标已达成。相关页:
> 语言指南 ·
> 快速开始。
三后端架构
| 后端 | 命令 | 角色 |
|---|---|---|
| 树遍历解释器 | xxc run | 语义基准(oracle) |
| 扁平栈字节码 VM | xxc vm | 中间性能档(约 2.8×) |
| 原生编译器 | xxc build | 直出机器码 |
三个后端共享同一前端(lexer → parser → typeck),由差分门矩阵钉死
一致性——每个测试程序在三条管线上输出逐字节相同:
| 门 | 覆盖 | 现状 |
|---|---|---|
| Windows 三管线 | interp = native-PE = VM,ARC 关门+开门 | 58/58 × 2 |
| aarch64 原生三管线 | 同上(aarch64 主机) | 60/60 × 2 |
| Linux x86-64 | 原生 + VM | 61/61 |
| qemu 过渡腿 | aarch64 主机上 interp vs x86 ELF | 59/59 |
| 并发门 | w=1 字节 parity;w≥2 契约;行原子多重集 | 全绿 |
| 差分 fuzz | mix/containers/closures/arc/oop 轮转,三管线 | 50 冒烟 / 250 深跑 0 败 |
| reltest | x86 .bss rip-rel 重定位仲裁器 | CLEAN |
原生编译:零外部工具链
xxc build 不经过 C 编译器、不调用 binutils——xxc 自带进程内汇编器
(assembler.rs)与链接器(pelinker.rs 出 Windows PE,
elflinker.rs 出静态 Linux ELF),三个目标:
- Windows x86-64:PE,VEH 诊断 + 保护页;
- Linux x86-64:静态 ELF,纯 syscall,无 libc、无 PT_INTERP(Go 式
单文件发行);
- Linux aarch64:AArch64 ELF——生成代码经 a64 后端(x86→a64 虚拟翻译 +
真实 AArch64 编码器)落地,LL/SC 原子操作按数据寄存器宽度诚实编码。
交叉编译:Windows 上 XXC_TARGET=linux;aarch64 主机默认即原生。
自举工具链
selfhost/ 目录是 xxc 写的完整编译器:
lexer.xxc → parser.xxc → typeck → gen.xxc → xas.xxc(汇编器)→ xld(链接器)
└──────────── 合并为 xxcc_full.xxc ────────────┘
- gen1 = Rust 种子编译出的自举编译器;gen2 = gen1 编译
xxcc_full.xxc 的产物;
- 不动点:gen2 再编译 xxcc_full.xxc 的输出 == gen1 的输出(字节级),
build_selfhost.sh 每次链刷新都验证,且在 ARC 关门/开门双态下成立;
- Rust 种子扮演 Go 语境里"上一个编译器"的角色:语言扩展先进种子,
不动点证明自举编译器在其余一切上语义等价;
- 自举侧 xas/xld 与 Rust 侧 assembler/pelinker 的产物字节级对拍。
运行时语义(四份派生,一套语义)
| 派生 | 用途 |
|---|---|
| rt/runtime.s(正本) | Windows PE 直译;承载行原子 print 与分配器记账 |
| rt/runtime_new.s | 自举链变体(无 guard 导入) |
| linux/runtime_linux.s | mk_runtime.py 生成(勿手改) |
| a64 转译 | aarch64 构建时从 runtime 文本翻译 |
核心性质(全部经门验证):
- 确定性 ARC:原子引用计数(x86
lock/ a64 独占对,64 位诚实宽度),
归零即释放;XXC_ARC_FREE=1 开真释放路径;
- 精确记账:
alloc_live= 当前持有的用户字节(free 剥 16 字节头、
grow 按增量记账),恒非负;XXC_ALLOC_LIMIT(严格十进制)为失控护栏;
- 行原子打印:语句级所有者令牌锁 + 单次写出,并发任务永不撕行;
- 跨平台 ARC 等价:Windows PE / x86-linux / a64 三方事件序列差分
58/58 三方 MATCH(tools/trace3.py)。
质量纪律
家规一条:往完美了做,往正确了做——发现的每个问题都根修,不做
绕行。近年案例:a64 编码器 LL/SC 宽度缺陷(潜伏五会话,根因后全臂
宽度法则扫清 17 处同类似缺陷)、分配器记账不对称(两处"良性评估"
改为根修)、行原子 print 正本治愈(canonical 脚本恢复单源双后端)。
完整实现史见仓库 ROADMAP.md。
环境变量总表
| 变量 | 作用 |
|---|---|
| XXC_ALLOC_LIMIT | 分配护栏(严格十进制字节,默认 2GiB;8e9 会解析成 8) |
| XXC_ARC_FREE | 1 = 真释放路径(门开态差分的被测路径) |
| XXC_HEAPGUARD | 1 = 页保护分配(野写检测,Windows 强化) |
| XXC_ARC_TRACE | 1 = ARC retain/release 轨迹 |
| XXC_CONC_WORKERS | 并发 worker 数 |
| XXC_TARGET | linux = 交叉编译 Linux ELF |
| XXC_PRINT_ATOMIC | 并发梯子的原子门选择器(历史门环境) |
| XXC_A64_DUMP | 1 = 落出 a64 翻译文本 |