- 编程语言
- 编译器
- 语言运行时
【免费下载链接】ponyc
Pony is an open-source, actor-model, capabilities-secure, high performance programming language
本文以当前仓库根目录的 CHANGELOG.md(共 2850 行,覆盖 2025-2016 年间的 60 余个版本)为骨架,系统梳理 Pony 语言编译器(ponyc)与标准库在十余个主题维度上的演进脉络:语言特性(iftype、裸函数/裸 lambda、注解、穷尽匹配)、编译流水线(pass 优化、LLVM 升级、运行时 bitcode)、标准库包(crypto、json、uri、http_client、net/lori)、测试工具(PonyTest、PonyCheck、pony-lint、pony-lsp、pony-doc)以及运行时系统(调度器、内存分配器、信号处理、系统化测试)。读完本文,你将掌握如何把 CHANGELOG 当作"版本化源码地图",快速定位某个特性的引入版本、对应的源码文件与回归测试用例,并能准确判断新旧版本间的破坏性变更。
一、CHANGELOG 文档本身:结构与写作规范
1.1 文档定位与采用的标准
CHANGELOG.md 是 ponyc 仓库中唯一一份跨版本的变更总账,其开头明确声明了本项目遵循两条约定:
- Semantic Versioning:语义化版本号
MAJOR.MINOR.PATCH,其中 0.x 阶段以 MINOR 号承载主要演进,PATCH 号承载修复(如 0.72.1、0.63.4 这类小版本均是纯修复/小幅增量版本); - Keep a CHANGELOG:按
Added / Changed / Fixed(偶尔还有Removed)三分类组织每个版本的条目。
当前仓库 VERSION 文件中的版本号为0.74.0,与 CHANGELOG 中最新的已发布版本一致,而文首的[unreleased]段落则记录了 0.74.0 之后已经合入但尚未发版的变更——这是判断"当前主线是否领先于最新 release"的第一手依据。
1.2 条目的信息粒度
每个条目都遵循统一格式:动词短语 + 影响面 + (PR #编号)。例如:
Fix getsockopt_u32 failing on platforms that return sub-4-byte socket options (PR #6229)Add \inline\, \inline(N)\, and \noinline\ annotations (PR #6221)
对读者而言,PR 编号有两个实际用途:
- 追溯实现细节:在仓库中搜索对应源码(如
src/libponyc/pass、src/libponyrt/sched),可以定位该变更的实际落点; - 区分"新增"与"回归":同一主题反复出现在
Fixed段(例如TCPConnection在多个版本被多次修复),说明该模块长期处于演进与加固状态。
二、语言特性演进:从基础语法到高级类型系统
2.1 引用能力(Reference Capabilities)体系的持续加固
Pony 的类型安全根基是引用能力系统,CHANGELOG 中大量Fixed条目都与能力子类型、viewpoint adaptation、类型参数约束相关,例如:
- 0.70.0:修复
#read->trnviewpoint adaptation 边界错误、修复别名类型参数约束的健全性漏洞(soundness bug); - 0.62.0:修复
#share能力约束的交集处理; - 0.57.0:修复一个"允许不安全数据访问模式"的编译器漏洞;
- 0.41.0:切换到 Steed 的 subtyping 模型(PR #3643)。
这些条目表明:能力系统并非一次性完成,而是历经多年、多轮健全性(soundness)修补。从源码结构看,相关实现分布在 src/libponyc/type(能力子类型、约束检查)与 src/libponyc/verify(接收者能力校验)等目录中。
2.2 iftype 条件编译/类型分支
iftype(RFC 26)自 0.13.1(2017-04)引入后,一直是高频修复对象:
- 0.64.0:修复
iftype与as组合时的编译器崩溃; - 0.65.0:修复 iftype 条件在 lambda 与对象字面量中的误拒绝与崩溃;
- 0.70.0:修复 iftype 分支不满足类型参数返回类型、lambda/对象字面量捕获丢失类型参数收窄等问题;
- unreleased 段:新增"针对类型参数上方法重载的 iftype 特化"(PR #6222)。
2.3 模式匹配与穷尽匹配(Exhaustive Match)
穷尽匹配(RFC 40)在 0.15.0 引入后持续演进:
- 0.61.0:新增
\exhaustive\注解(PR #4863),将"穷尽性"从隐式推断扩展为显式声明; - 0.60.5:支持对
Bool的穷尽匹配; - 0.63.4、0.70.0 等版本修复了大量"this pattern can never match / unreachable match"误报问题,涉及类型参数在类型实参、trait/interface 类型实参、union/isect/tuple 类型实参中的各种场景。
仓库中test/full-program-tests/match-*系列目录(如match-exhaustive-all-cases-of-union、match-typeparam-in-typearg-*等)正是这些修复的回归测试佐证。
2.4 泛型与类型推断
- 0.70.0:新增"方法/构造器调用的泛型类型实参推断"(PR #5974);
- 0.70.1:修复消耗型实参的类型实参推断;
- 0.69.0:修复默认类型实参在别名 use 包中的解析失败;
- 0.64.0:允许有限递归类型别名(PR #5246)。
2.5 裸函数与裸 lambda(bare functions/lambdas,RFC 34)
0.15.0 引入后,在 0.51.1 得到扩展:支持void*(Pointer[None])参数。仓库中 test/full-program-tests/bare-function-* 与bare-lambda-*系列测试完整覆盖了裸函数回调、partial application、addressof等场景。
三、注解(Annotations)体系:从 AST 注解到编译器指令
CHANGELOG 中与注解相关的条目横跨语言与工具链:
| 版本 | 新增注解 | 用途 |
|---|---|---|
| 0.11.0 | AST annotations(RFC 27) | 在 AST 上附加元数据的基础机制 |
| 0.22.0 | nosupertype(RFC 54) | 子类型排除 |
| 0.47.0 | nodoc | 阻止文档生成 |
| 0.61.0 | \exhaustive\ | 声明 match 必须穷尽 |
| 0.70.0 | \c_api\(PR #5898) | C-ABI 互操作 |
| 0.73.0 | \by_value\(PR #6062) | 结构体按值传递的 FFI 注解 |
| unreleased | \inline\、\inline(N)\、\noinline\(PR #6221) | 控制内联 |
其中\by_value\的实现可以在 src/libponyc/codegen/gencall.c 中找到:代码生成阶段通过ast_has_annotation(ret_type_node, "by_value", ...)判断返回类型是否携带该注解,从而决定按值还是按引用传递结构体;\inline\则由 src/libponyc/codegen/genfun.c 读取注解值并作用于函数属性,相关语法解析位于 src/libponyc/pass/syntax.c。配套的完整程序测试见 test/full-program-tests/annotation-types、annotation-methods、annotation-inline等目录。
四、编译器流水线与代码生成:性能与可移植性并重
4.1 LLVM 版本演进
CHANGELOG 记录了 ponyc 对 LLVM 的持续跟随:3.9.1 → 7.0.1 → 12.0.1 → 13.0.0 → 14.0.3 → 15 → 17.0.1 → 18.1.8 → 21.1.8 → 22.1.6 → 23.1.2(0.74.0)。依赖的 LLVM 补丁与源码位于仓库 lib/llvm 目录(patches/下有 4 个.diff文件)。LLVM 升级往往伴随链接器策略调整:0.61.1 起在 Linux/macOS/Windows/FreeBSD/DragonFly/OpenBSD 原生构建中全面改用内嵌 LLD。
4.2 编译流水线重构(0.73.0 里程碑)
0.73.0 是一次内部架构大改,值得单独列出:
- 移除
--pass asm与--pass obj,以"per-package codegen"取代原先的 optimize-then-emit 流水线(PR #6109); - 移除
--extfun标志; - 修复 32 位平台编译大程序时的 OOM 与 ILP32 Linux 地址空间碎片化导致的崩溃;
- 修复 debug info 生成,release 构建不再需要额外 strip DWARF 数据(相关
--print_stats也不再报告 heap-to-stack 提升计数)。
4.3 运行时 bitcode 化(0.73.0-0.74.0 主线)
运行时链接策略在近几个版本发生了根本变化:
- 0.73.0:在基于 clang 的平台上默认启用 runtime bitcode,并移除
--runtimebcCLI 标志(PR #6137); - 同时修复 ELF 平台合并运行时 bitcode 后 PONY_API 符号导出、优化器属性在运行时链接后丢失等问题;
- 0.74.0 进一步移除
runtime_tracing构建选项,使运行时追踪标志在所有构建中可用(PR #6182)。
从源码结构看,运行时 bitcode 的生成与合并逻辑与 src/libponyrt 以及 cmake/CheckRuntimeBitcode.cmake 相关。
4.4 编译器 pass 性能优化
多版本持续优化编译性能:
- 0.72.0:加速大程序的可达性分析(reachability pass,PR #6025),并新增
--pass-timings/--pass-timings-json对 pass 计时(PR #6022、0.70.0 的 PR #5792); - unreleased:subtype cache 减少无效工作(PR #6243)、reach pass 增加方法名预过滤(PR #6247)。
五、运行时系统:调度器、内存与 I/O
5.1 调度器(Scheduler)
- 0.33.0:
--ponythreads更名为--ponymaxthreads,并规定所有带值的--pony*选项都做最小值检查; - 0.32.0:新增
--ponynoscale与--ponyhelp; - 0.21.x:引入基于负载的动态调度线程伸缩(PR #2386),并多次修复伸缩逻辑(0.21.2、0.22.6、0.25.0、0.26.0);
- 0.65.0:修复调度线程在半程闲置时间后挂起、调度计时计算错误等问题;
- 0.58.8:新增将 actor 固定到专用调度线程的能力(actor pinning,PR #4547),对应标准库包 packages/actor_pinning。
这些运行时选项的实际解析集中在 src/libponyrt/options/options.c,调度入口与线程管理在 src/libponyrt/sched(如 start.c 定义了ponymaxthreads、ponynoscale、ponypinasio等选项的解析表)。
5.2 内存分配器
- 0.69.0:整体替换运行时分配器(PR #5768),并新增
--ponymemoryprofile运行时选项、改变调度器伸缩方式; - 0.73.0:内联 HeapToStack 无法提升的
pony_alloc/pony_alloc_small调用(PR #6133); - 0.58.7:GC 后回收 actor 堆块而不是归还池;
- 0.66.0、0.59.0:持续改善内存占用与 GC 激进程度。
分配器实现位于 src/libponyrt/mem,其中 POOL_ARENA.md 是 arena 池的配套设计文档,src/libponyrt/mem/pool.h 与pool_arena.c与--ponymemoryprofile的计数逻辑直接相关。
5.3 信号与退出
- 0.68.0:整体替换信号处理系统(PR #4984),
signals包也随之调整; - 0.74.0:在 HandleableSignalValidator 中拒绝运行时保留信号(PR #6188);
- 0.71.0:终端 raw mode 改为 opt-in 且需要授权(PR #5990);
- 0.59.0:pony 程序遇到无法识别的运行时选项时直接退出(PR #4622)。
信号包源码见 packages/signals,测试见test/full-program-tests/signal-*目录。
5.4 系统化测试(Systematic Testing)
0.51.1 引入运行时系统化测试(PR #4140)后持续加固:
- 0.65.0/0.66.0:使回放(replay)不依赖内存布局(分别覆盖普通消息、引用计数消息、循环检测器消息),并修复多个间歇性挂起;
- 0.67.0:修复系统化测试比预期慢得多的问题;
- 0.66.0:系统化测试下不运行 ASIO 线程。
相关文档见 SYSTEMATIC_TESTING.md,测试程序位于 test/rt-systematic。
六、标准库演进:包的新增、移除与替换
CHANGELOG 是观察标准库"增删改"最直接的窗口。下表汇总了显著变更:
| 版本 | 标准库事件 |
|---|---|
| 0.11.0 | 新增promises、itertools、ponybench、serialise、collections/persistent等 |
| 0.16.0 | 新增cli包 |
| 0.30.0 | 移除glob、regex、crypto、net/ssl |
| 0.49.0 | 新增PonyCheck到标准库;移除logger |
| 0.61.1 | 重新加入json与iregex包 |
| 0.64.0 | 移除serialise包 |
| 0.69.0 | 新增流式 JSON 解析器、--ponymemoryprofile;替换运行时分配器 |
| 0.72.1 | 新增uri与http_client包 |
| 0.72.0 | 用ponylang/lori替换 stdlib 的net包 |
| 0.73.0 | 新增crypto包;合并属性测试进 PonyTest |
| 0.74.0 | PonyCheck 新增多失败上报、定向测试 |
注意 0.69.0 的Rename Json prefix to JSON in the json package与 0.61.1 的重新引入是两次独立事件,说明json包经历了"移除→重写→回归"的完整生命周期。当前仓库中相关包源码位于 packages/json、packages/crypto、packages/uri、packages/http_client、packages/collections/persistent。
6.1 网络栈的反复打磨
网络相关条目在 CHANGELOG 中占比极高,且大多集中在 Windows 与 BSD 平台:
- 0.66.0:用就绪通知(readiness notifications)替换 Windows IOCP 套接字 I/O(PR #5556),随后 0.65.0 修复 IOCP 相关 use-after-free(0.62.0/0.62.1 已有多条);
- 0.69.0:修复 TCP/UDP 套接字在系统 socket buffer 不足时被错误关闭的问题;
- 0.67.0:修复 Windows 下 TCP 连接挂起、零字节 UDP 数据报投递、阻塞 fd 上的读写挂起等;
- 0.72.1:修复 BSD 上的 TCP 背压停滞;
- 0.73.0:新增
is_socket_connected到TCPBackendtrait(PR #6094),并要求所有TCPBackend实现必须实现它; - 0.70.0:为 UDPSocket 新增组播便捷方法(PR #6220)与 connected UDP 模式(PR #6227)。
网络实现分布在 packages/net(含大量_test_*单元测试),FFI 层在 src/libponyrt/asio。
七、测试与开发者工具链
7.1 PonyTest 与 PonyCheck:测试框架的合并与强化
0.73.0 完成了一次重要的框架合并:把属性测试(property testing,原 PonyCheck)合并进 PonyTest(PR #6171),并修复属性测试失败不触发 shrinking 的问题。随后 0.74.0 为 PonyCheck 增加多失败上报与定向测试。PonyTest 侧的能力增量包括:
- 0.63.0:
--shuffle选项; - 0.73.0:
Generators.f32/f64、分类 API、状态化属性测试、健康检查告警、回归持久化、Randomness抽取方法改为非 partial、StatefulProperty.step()区分被拒命令与 SUT 失败。
相关源码见 packages/pony_test 与 packages/pony_bench。
7.2 pony-lint:静态检查规则持续扩展
- 0.61.1:新增
safety/exhaustive-match规则; - 0.63.1:新增
style/docstring-leading-blank,并支持分层配置、防护超大配置文件/ignore 文件; - 0.69.0:新增
style/testlist-nodoc,并收紧行宽规则、二进制运算符换行规则; - 0.70.0:修复
style/blank-lines误报。
规则实现位于 tools/pony-lint(97 个.pony文件)。
7.3 pony-lsp:语言服务器的大规模扩展
从 0.60.5 随发行版提供开始,pony-lsp 在 0.63.x 系列集中上线了大量 LSP 能力:documentHighlight、inlayHint、references、signatureHelp、selectionRange、workspace/symbol、declaration、rename/prepareRename、typeDefinition、callHierarchy、typeHierarchy等;0.67.0 起支持--version/--help并拒绝未知参数。实现见 tools/pony-lsp。
7.4 pony-doc:文档生成
- 0.74.0:为生成文档加入暗色模式切换(PR #6239);
- 0.63.0:移除 docgen pass(PR #5097),文档生成迁移到独立工具;
- 0.70.0:修复构造器默认参数值显示与源位置问题。
7.5 回归测试的组织方式
CHANGELOG 中每个"修复编译器崩溃"的条目,几乎都能在 test/full-program-tests 找到对应的regression-<issue>或主题目录(如regression-5329、array-infer-*、type-alias-*、iftype-specialization-*等),由 test/full-program-runner 驱动执行,部分用例还带有.txt期望输出。这种"变更条目 ↔ 回归用例"的对应关系,使 CHANGELOG 成为逆向定位测试覆盖范围的索引。
八、平台支持与构建系统的变迁
8.1 支持平台的新增与移除
- 新增:Alpine 3.16→3.24 系列、Ubuntu 20.04→26.04、Fedora 39/41、OpenBSD 7.8/7.9、FreeBSD 12.1/13.0/15.1、macOS Apple Silicon、arm64 Windows、RISC-V(0.51.2)、DragonFly BSD 6.4.2;
- 移除:Ubuntu 18.04/20.04/22.04、Alpine 3.20/3.21/3.22、FreeBSD(0.56.0 短暂移除后 0.63.4 等版本又重新加入)、32 位 ARM Linux 降级为 best-effort(0.68.0);
- 特殊说明:
ProcessMonitor自 0.69.0 起要求 Linux 5.3+(PR #5770)。
8.2 构建系统
- 0.34.0:改用 CMake 构建(PR #3234),并默认使用 clang;
- 0.61.x:全面切换到内嵌 LLD 链接;
- 0.73.0:vendored LLVM 在 ARM64 Windows 上用 clang-cl 构建(PR #6189);
- 0.67.0:停止安装 Pony 运行时的 C 头文件与静态库(PR #5620)。
构建入口为根目录 CMakeLists.txt 与 CMakePresets.json,平台相关封装见 src/common/platform.h。
九、FFI 与 C 互操作
- 0.41.0:RFC 68 强制 FFI 声明(PR #3739);
- 0.50.0:允许覆盖 FFI 函数返回类型,禁止在默认方法/行为中调用 FFI;
- 0.73.0:新增
\by_value\注解实现结构体按值传递; - 0.70.0:新增
\c_api\注解(PR #5898); - 0.65.0:支持与 Pony 一起编译 C shim(PR #5503);
- 0.15.0:禁止向 FFI 传递/返回元组。
对应测试见 test/full-program-tests/ffi-* 与c-shim-*、export-*系列。
十、破坏性变更速查(升级必读)
对于正在升级 Pony 版本的用户,以下是最需要关注的破坏性变更(均来自 CHANGELOG 的Changed段):
- 0.62.0:
--path不再能覆盖标准库(PR #5040); - 0.63.0:
FloatingPoint.frexp的指数返回类型从U32改为I32;docgen pass 移除; - 0.65.0:移除
--linker与--link-ldcmd命令行选项; - 0.69.0:
HashSet、persistentHashSet、Flags不再提供is Comparable;ForAll构造参数改名;Json*前缀改为JSON*; - 0.70.0:PonyCheck 生成器参数从
(gen, max)改为(gen, min, max),随后又更名为from/to;给元组类型别名应用能力变为编译错误;小于 64 位的机器字不再装箱; - 0.72.0:stdlib
net包被ponylang/lori取代,TCPBackend.connect返回Array[AsioEventID]; - 0.73.0:移除
--extfun、--pass asm、--pass obj、--runtimebc;runtime_tracing构建选项移除;--print_stats不再报告 heap-to-stack 计数;release 构建不再自动 strip; - 0.74.0:属性测试合并进 PonyTest,PonyCheck 相关 API 需按新入口迁移。
十一、如何用这份 CHANGELOG 指导日常开发
- 定位特性引入版本:在 CHANGELOG 中搜索目标关键字(如
iftype、by_value、ponymemoryprofile),找到首次出现的版本号,再去对应版本的源码与测试目录验证; - 评估升级风险:优先阅读目标版本与当前版本之间的所有
Changed条目,它们基本等价于破坏性变更清单; - 索引回归测试:把
Fixed条目中的模块名(如IOCP、persistent Vec、iftype)映射到 test/full-program-tests 的目录名,快速找到可复现的历史 bug 用例; - 关注 unreleased 段:它代表主线的最新状态(当前为 0.74.0 之后的若干 PR),可作为预览下个版本的窗口。
总体来看,CHANGELOG.md 不仅是发布记录,更是串联语言设计、编译器架构、运行时、标准库与工具链的"时间线索引"。结合仓库中的 src/libponyc、src/libponyrt、packages 与 test/full-program-tests 源码阅读,你可以把每一条变更还原为具体的实现与测试,从而获得对 Pony 技术栈从语法到运行时再到生态工具的完整认知。
- 编程语言
- 编译器
- 语言运行时
【免费下载链接】ponyc
Pony is an open-source, actor-model, capabilities-secure, high performance programming language
相关推荐
TEN Framework websocket_server_python:用 Python 扩展示例在 TEN 应用中搭建 WebSocket 服务器
TEN Framework websocket_server_python:用 Python 扩展示例在 TEN 应用中搭建 WebSocket 服务器 本文以
编程语言编译器语言运行时Loki 版本演进全景解读:从 2.8 到 3.8 的 CHANGELOG 深度解析
Loki 版本演进全景解读:从 2.8 到 3.8 的 CHANGELOG 深度解析 导读 本文以 Loki 官方仓库根目录的 CHANGELOG.md htt
可观测性日志分析后端微服务对象存储云原生Nim 0.19.0 更新全解析:语言特性演进、标准库重构与编译器能力升级
Nim 0.19.0 更新全解析:语言特性演进、标准库重构与编译器能力升级 导读 :本文基于仓库内 changelogs/changelog_0_19_0.md
编程语言编译器语言运行时标准库
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考