Hotdry.

Article

Blaise 编译器:零遗留 Object Pascal 的现代编译实践

解析 Blaise 编译器的零遗留设计哲学,探讨其 QBE 后端选择、自托管能力与现代化语言特性。

2026-05-08compilers

在编译器领域,遗留代码与历史包袱往往成为技术迭代的重大阻碍。Blaise 作为一款从零构建的现代 Object Pascal 编译器,以「零遗留」(Zero Legacy)为核心设计理念,试图为 Pascal 语言开辟一条全新的演进路径。本文将从架构设计、后端选择、自托管能力三个维度,解析 Blaise 的技术实践与工程价值。

零遗留设计:打破三十年技术债务

Object Pascal 生态长期面临两难选择:Embarcadero Delphi 作为商业闭源方案,以 Windows 为首要目标平台;Free Pascal 作为开源替代,虽支持多平台,却背负了约三十年的累积复杂性 —— 五种语言模式、五种字符串类型、数千个头文件,这种复杂性直接导致维护成本攀升与开发者体验下降。

Blaise 的回应是彻底抛弃兼容性枷锁。在语言层面,项目仅保留一种统一语言模式,彻底移除 {$mode} 切换开关;在类型系统层面,统一为单一的 UTF-8 引用计数字符串类型,原有的 ShortStringAnsiStringWideStringUnicodeString 全部下架,仅保留 RawBytes 用于二进制数据处理;在内存模型层面,自动引用计数(Automatic Reference Counting,ARC)uniformly 应用于字符串、类和接口,消除了 TObjectTInterfacedObject 之间的手动 / 自动内存管理分裂,引入 [Weak] 属性解决循环引用问题。

这种设计选择体现了清晰的工程判断:一种 dialect 精心维护,胜过五种 dialect 粗糙维持。语言层面的极简主义直接降低了编译器的实现复杂度,为后续功能扩展留出空间。

现代化语言特性的工程实现

Blaise 在语言特性层面进行了系统性现代化改造。废弃 with 语句的原因极具代表性:该特性是难以诊断的符号解析错误的根源,且破坏静态分析能力 —— 这种取舍体现了现代编译器设计对可预测性的追求。

在接口设计上,Blaise 移除了 COM 风格的 GUID 需求,转而通过编译时 vtable 映射实现接口分发。这一改变简化了语言核心,同时不损失面向对象编程的表达能力。泛型方面采用具体化(reified)策略,在编译期进行单态化(monomorphization),避免类型擦除带来的运行时开销 —— 这与 Rust 的 monomorphization 模型异曲同工。

调试信息格式的选择同样体现了独立思考。OPDF(Object Pascal Debug Format)被确立为默认调试信息格式,项目方认为 DWARF 并非必须。这一决策的背后是对调试体验的深度考量:专用格式可针对 Pascal 语义提供更精确的调试信息,而非依赖通用格式的折中支持。

QBE 后端:轻量与性能的平衡艺术

Blaise 选择 QBE 作为首要编译后端,这一决策蕴含着对编译器架构的深刻理解。QBE 是由 MIT 开发者 Michael Forney 创建的轻量级编译器后端,以「可 hack」为核心设计目标,代码量远小于 LLVM 等工业级编译器。

从性能角度,QBE 在多数 CPU 密集型任务中可达 LLVM 约百分之七十的性能水平。这一数字常被社区引述为「百分之七十的性能,百分之十的代码量」。对于新兴语言项目或特定领域编译器而言,这一取舍极为理性:QBE 提供足够的优化能力,同时大幅降低后端维护与学习门槛,使团队得以聚焦于语言前端与中间表示的设计迭代。

Blaise 目前已实现自托管(Self-Hosting):编译器能够使用自身进行编译,且支持字节级精确匹配(byte-for-byte exact matches)的引导过程。这一里程碑验证了编译器的完整性与可靠性 —— 没有自托管能力的编译器,其正确性难以获得充分信任。项目当前拥有超过一千二百个测试用例,采用测试驱动开发模式从第一天起贯彻,确保每个语言特性都有对应的回归测试覆盖。

构建系统与开发者体验

项目弃用传统 Makefile,转而采用自研的 PasBuild 构建系统,以 project.xml 作为项目描述文件。PasBuild 支持多模块布局,每个含 project.xml 的子目录构成独立模块,根目录 project.xml 作为聚合器。构建输出位于各模块的 target/ 子目录,且构建产物不提交至版本库,保持仓库整洁。

构建配置支持 Debug 与 Release 两种 profile。Debug 包含调试符号、栈帧、全量运行时检查;Release 启用二级优化、链接时优化与符号 stripping。这种开箱即用的配置简化了开发工作流,开发者无需手动管理繁杂的编译器开关。

实践启示

Blaise 的设计哲学为现代编译器项目提供了若干可参考原则。首先,零遗留并非口号,而是需要系统性评估并果断移除历史特性的决策勇气的结晶。其次,后端选择应根据项目阶段与团队能力权衡:QBE 适合快速迭代与学习目的,LLVM 适合追求极致性能与广泛目标平台支持。第三,自托管能力是编译器成熟度的重要标志,它既是测试策略,也是对编译器自身正确性的最强背书。

对于希望构建新编程语言或改造现有语言的团队,Blaise 示范了一条可行路径:从第一天重视测试、从第一天规划自托管、用清晰的语言设计原则驱动技术决策。

资料来源:Blaise 编译器 GitHub 仓库(https://github.com/graemeg/blaise)

compilers

内容声明:本文无广告投放、无付费植入。

如有事实性问题,欢迎发送勘误至 i@hotdrydog.com