xxc

可编译可解释的系统级语言 - 确定性 ARC 无 GC / 全自举工具链 / 三后端逐字节一致

📂 开发工具#编程语言#编译器#自举#跨平台#无GC#并发#开发工具📅 2026-10-9

实现与自举

📅 2026-10-9

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 翻译文本 |