32 KiB
PJ2026-0501 V2内核需求规格
修改历史
| 版本 | 对应 commit id | 更新日期 | 变更说明 |
|---|---|---|---|
| v0.1 | 205e3a70 |
2026-07-21 | 定义 V2 动态子集重写内核的架构原则、能力边界和量化验收合同。 |
| v0.2 | d72a1f52 |
2026-07-21 | 已批准:明确阶段性 V1 parser 适配器、原子 capability、职责化实现命名、候选内核比较和 cold/warm benchmark 生命周期。 |
| v0.3 | 待追溯 |
2026-07-21 | 已批准:增加语法能力组 TDD、CPython 逐字节脚本回归和严格 ISO C99 硬门禁。 |
修改历史只记录规格语义变更,不记录实现进度、阶段基线或一次性证据。
v0.3 及其引用的 PIKA-CAP v0.2 已批准生效,作为当前实现合同。
正文
PJ2026-0501 V2内核需求规格
1. 文档控制
| 字段 | 内容 |
|---|---|
| 编号 | PJ2026-0501 |
| 短名 | V2内核 |
| 层级 | L1 方向 |
| 规格状态 | 已生效 |
| 当前生效版本 | v0.3 |
| 实现引用版本 | v0.3 |
| 需求规格模板 | ISO/IEC/IEEE 29148 需求规格模板 |
| 上级规格 | PJ2026-05 PikaPython 总规格 |
本文采用 ISO/IEC/IEEE 29148 需求规格模板的项目裁剪版。 正文只定义:
- V2 的预期终态;
- 稳定边界;
- 目标架构;
- 原子需求;
- 验收合同。
2. 目的和范围
2.1 目的
V2 是对 V1 动态 Python 子集路线的全新内核实现。“重写大于优化”表示:
- 保留有价值的用户语义;
- 保留嵌入式定位和可裁剪能力;
- 允许以主机侧、阶段性的 V1 parser 适配器缩短前端引导期;
- 不继承阻碍性能、资源占用或长期演进的 V1 执行内核架构。
V2 的目标是:
- 从内核第一版开始极致优化运行时性能、Flash 和 RAM;
- 通过吸收 Lua、MicroPython、QuickJS 和其他成熟 VM 的可验证技术,提高执行内核质量;
- 在能力等价的代表性 runtime suite 上大幅超越 V1,并相对 MicroPython 取得可解释的 Pareto 优势;
- 以明确的 Python 动态语法子集换取紧凑、确定和可裁剪的嵌入式实现;
- 为 V1 用户提供按能力逐步迁移的后继路线,而不是要求内部二进制兼容。
2.2 范围内
- 动态类型 Python 语法子集和模块语义。
- 可选、主机侧的 V1 lexer/parser 适配器和可迁移前端测试资产。
- 可在 PC 预编译、在微控制器直接执行的紧凑字节码。
- 带稳定 ID、显式依赖和命名 profile 的 capability 配置。
- VM dispatch、调用帧、对象表示、名称访问、容器、异常和内存管理。
- 编译期和构建期的语法、opcode、对象、模块与平台裁剪。
- C 模块绑定、平台抽象和可预测错误合同。
- 实现文件和代码标识符的职责化命名合同。
- 项目自有 C 源码的严格 ISO C99 编译合同。
- 分层内部测试和与 CPython 逐字节对照的脚本回归。
- Linux 快速性能裁决及真实 Cortex-M、RV32 目标的功能、性能、Flash 和 RAM 确认。
2.3 范围外
- strict type、强制 type hint、静态类型证明或类型驱动的语言准入。
- LLVM IR、LLVM 后端、JIT 和目标相关 native emitter 作为 V2 内核依赖。
- 完整 CPython 或 MicroPython 语法兼容。
- V1 字节码、对象布局、调用栈、ABI 或 runtime 源码目录结构的内部兼容。
- 将 V1 parser、V1 runtime 或 MicroPython fork 设为 V2 目标运行时的长期依赖。
- 由本规格预先固定宽度寄存器 VM、紧凑栈 VM 或字节码编码形态。
- 为提升 parser 性能牺牲 runtime 性能或内核资源;parser 可在 PC 端一次性运行。
- 仅通过 C 模块 binding 替代通用脚本 VM。
3. 术语表
| 术语 | 定义 |
|---|---|
| 重写优先 | 当热点或资源债务来自内核结构时,重新设计结构优先于围绕旧结构继续局部优化。 |
| 动态子集 | 不要求静态类型注解,在运行时保持对象类型语义,但只承诺明确列出的 Python 语法和对象能力。 |
| 快速路径 | 对高频类型和 opcode 使用无堆分配、少分支或专用表示的执行路径。 |
| 慢速路径 | 处理通用对象、异常、边界转换或低频语义的共享路径。 |
| 主机预编译 | 在 PC 端完成解析、语义检查和字节码生成,目标设备只加载或执行产物。 |
| capability | 可独立标识、声明依赖、测试语义和报告资源成本的语言或 runtime 能力。 |
| profile | 有稳定名称和产品意图的 capability 根集合,不表示线性兼容等级。 |
| V1 前端适配器 | 仅在主机侧把 V1 parser 的输出转换为 V2 中性类型化 IR 的可替换引导组件。 |
| 中性类型化 V2 IR | V2 前端与后端之间版本化、结构节点和操作数类别显式、无 V1 对象和 ABI 依赖的唯一长期合同;不表示静态类型证明。 |
| 能力等价配置 | 所需 capability 闭包、被测语义和必需平台模块一致的比较配置。 |
| 职责化命名 | 文件名和代码标识符表达内核职责、数据语义或生命周期,不携带路线代际缩写。 |
| 语法能力组 | 一次 TDD 迭代选择的 capability 根集合、依赖闭包、正负测试和资源比较单元。 |
| 逐字节脚本回归 | 对相同受支持源码比较目标运行时与 CPython 的退出状态和 stdout 原始字节,不做空白或换行归一化。 |
4. 系统边界和接口
| 边界项 | 内容 |
|---|---|
| 外部使用者 | 嵌入式应用开发者、V1 迁移者、模块开发者和平台移植者。 |
| 外部输入 | 受支持 Python 源码或 V2 字节码、C 模块、裁剪配置和平台端口。 |
| 受控资源 | 编译器、字节码、VM 状态、调用帧、对象、堆、模块表和错误状态。 |
| 外部输出 | 执行结果、异常、停机诊断、静态库或固件、字节码和资源指标。 |
| 用户接口 | V2 Python 子集、字节码格式、C API、模块绑定和 workspace CLI。 |
| 系统边界 | V2 定义动态子集内核,不定义静态加速路线、板级驱动或应用业务逻辑。 |
5. 目标架构
5.1 内部分工
| 编号 | 课题 | 主责边界 | 上游依赖 | 下游支撑 |
|---|---|---|---|---|
| PJ2026-050101 | 语言编译 | 语法子集、语义检查、常量折叠、字节码生成和产物校验。 | Python 语义需求、裁剪配置。 | VM执行、错误诊断。 |
| PJ2026-050102 | VM执行 | opcode、dispatch、调用帧、控制流、快速路径和异常转移。 | 字节码合同。 | 对象内存、模块调用。 |
| PJ2026-050103 | 对象内存 | 值表示、对象布局、字符串驻留、容器、堆和资源耗尽语义。 | VM 生命周期、平台分配器。 | 全部运行时语义。 |
| PJ2026-050104 | 裁剪移植 | 功能切片、模块绑定、C API、平台抽象和目标构建。 | 语言、VM、对象能力。 | MCU 应用与板级生态。 |
| PJ2026-050105 | 验证基准 | 语义测试、差分测试、benchmark、Flash、RAM 和回归分析。 | 各能力切片。 | 发布决策与性能设计。 |
5.2 目标架构图
flowchart LR
SRC[Python 动态子集源码] --> FE[V2 原生前端]
SRC -. 引导期可选 .-> V1A[V1 parser 适配器,仅主机侧]
V1A --> IR[中性类型化 V2 IR]
FE --> IR
CFG[capability 与 profile 配置] --> FE
CFG --> C[V2 优化与字节码生成]
IR --> C
C --> BC[紧凑 V2 字节码]
BC --> V[验证器与加载器]
V --> VM[高效 VM dispatch]
VM --> F[高频值快速路径]
VM --> O[通用对象慢速路径]
VM --> FR[紧凑调用帧]
F --> M[受控内存与栈]
O --> M
FR --> M
VM --> MOD[可裁剪模块与 C binding]
MOD --> HAL[平台抽象]
5.3 编译与执行数据流
flowchart TD
S[源码] --> P[V2 原生前端或主机侧 V1 parser 适配器]
P --> IR[中性类型化 V2 IR]
CAP[capability 闭包] --> P
IR --> OPT[常量折叠与局部优化]
OPT --> E[字节码编码]
CAP --> E
E --> CHECK[格式和 capability 校验]
CHECK --> LOAD[目标加载]
LOAD --> RUN[VM执行]
RUN --> RESULT[结果或明确错误]
中性类型化 V2 IR 遵循以下边界:
- 只服务 V2 编译器自身,并由版本化 IR 合同定义;
- V1 parser 适配器必须在 IR 边界前终止,V1 的前端容器、对象、VM 状态和 ABI 不得跨越该边界;
- 适配器仅在主机侧使用,目标 runtime 不得依赖 V1 parser、对象、VM、ABI 或模块注册;
- 目标内编译若被支持,必须使用 V2 原生前端;
- 不采用 LLVM IR,也不要求静态类型;
- 编译器可以在 PC 端运行,因此 parser 吞吐不是内核性能优化优先级。
5.4 capability 与 profile 在 V2 中的应用
能力和 profile 的唯一共享合同是 PikaPython 能力与配置档。V2 构建必须从命名 profile 或显式 capability 根集合解析依赖闭包。
V2 对 capability 的应用必须满足以下要求:
- 编译器只接受当前 capability 闭包承诺的源码语义;
- 字节码携带所需 capability 清单,runtime 声明提供 capability 清单;
- profile 选择能力和资源预算,不选择独立 VM 或隐含的能力顺序;
compute-min可用于最小计算和内核上限验证,但不定义其他 profile 的实现继承关系;- V1 parser 即使能识别更多语法,适配器也必须拒绝未启用 capability;
- 定制 profile 必须显式记录根集合、展开后的闭包和资源预算。
5.5 单一内核与证据驱动专用化
V2 的默认实现必须满足以下要求:
- 使用一个共享内核架构;
- 通过 capability 闭包在构建期移除不需要的代码和数据;
- profile 不得默认选择完整独立的 VM。
候选架构包括:
- 固定宽度寄存器 VM;
- 紧凑栈 VM;
- 变长字节码编码;
- 其他适合目标平台的编码或 dispatch 方案。
本规格不预先承诺候选终态。 结构选择必须满足以下要求:
- 在相同 capability 闭包、workload 和资源预算下完成 A/B 验证;
- 同时比较:
- 动态能力等价 suite 的吞吐、延迟和离散度;
- Flash、静态 RAM、峰值堆、VM 栈和宿主栈;
- 热路径动态分配、错误路径和实现复杂度;
- 真实 Cortex-M 或 RV32 目标上的对应结果。
局部专用化只在上述验证证明有稳定收益时允许,并且必须满足:
- 专用化仅覆盖已识别的 opcode、值类型、调用路径或对象操作;
- 保持相同 capability 语义、字节码校验和错误合同;
- 未启用 capability 的代码、数据和注册表仍可从最终产物移除;
- 不得以 profile 或单一整数宏选择整套 VM;
- 不得因局部专用化把 V1 或 MicroPython 内部结构带入 V2 runtime。
flowchart TD
Y[owning YAML] --> R[capability 依赖解析]
R --> M[版本化 capability 清单]
M --> K[共享 V2 内核]
K --> P[构建期裁剪的目标产物]
B[能力等价 A/B 证据] -. 仅局部热点 .-> S[局部专用实现]
S --> K
5.6 关键执行时序
sequenceDiagram
participant A as 应用
participant L as 字节码加载器
participant V as V2 VM
participant M as 内存与模块
A->>L: 提交字节码与能力配置
L->>L: 校验版本、边界和所需能力
L->>V: 创建紧凑执行帧
loop opcode dispatch
V->>V: 执行类型快速路径
V->>M: 必要时访问对象、堆或模块
M-->>V: 值或明确错误
end
V-->>A: 结果、异常或致命停机诊断
6. 原子需求
6.1 V2-L1-REQ-001 重写优先架构
| 编号 | 短名 | 主责模块 | 关联模块 |
|---|---|---|---|
| V2-L1-REQ-001 | 重写优先 | PJ2026-050102 VM执行 | PJ2026-050103 对象内存、PJ2026-050105 验证基准 |
V2 不得以复用 V1 内部架构为默认目标。热点处理顺序如下:
- benchmark 识别对象表示、调用帧或 dispatch 热点;
- profiler 识别名称查找、容器或内存模型热点;
- 优先重新设计对应结构;
- 结构问题解除后再评估局部微优化。
结构选择必须满足以下要求:
- 由可重复 benchmark、资源报告和语义测试共同裁决;
- 吸收先进项目技术前理解其适用前提;
- 重新实现适合 V2 的机制,不复制许可证不兼容代码;
- MicroPython 作为架构参考、语义对照和竞争基线,不得被 fork 后作为 V2 内核底座;
- 不因技术来源先进而跳过本项目验证。
6.2 V2-L1-REQ-002 动态语言子集
| 编号 | 短名 | 主责模块 | 关联模块 |
|---|---|---|---|
| V2-L1-REQ-002 | 动态子集 | PJ2026-050101 语言编译 | PJ2026-050102 VM执行、PJ2026-050105 验证基准 |
动态 Python 子集必须满足以下要求:
- 支持不带 type hint 的源码;
- 类型注解即使被语法接受,也不得成为执行正确性的必要条件;
- 类型注解不得成为性能快速路径或函数准入的必要条件。
V1 lexer/parser 只能作为可选、阶段性的主机侧引导适配器。复用必须满足以下边界:
- V1 前端输出必须经适配器归一化为版本化、中性类型化 V2 IR;
- V1 字节码生成、对象、调用栈、ABI、模块注册和 runtime 语义不得作为 V2 后端输入;
- V1 内部数据结构不得跨越 V2 IR 边界;
- V2 的长期发布工具链必须可在不链接 V1 parser 的条件下生成相同 IR 合同;
- 主机预编译配置必须能从目标固件完全移除 parser 和前端只读数据;
- 目标内编译若被支持,必须使用 V2 原生前端,不得引入 V1 runtime 依赖;
- V1 parser 升级不得静默改变 V2 IR、字节码或目标 runtime 语义。
语法子集要求如下:
- 兼容性可以弱于 MicroPython;
- 已承诺子集必须具备明确语义、专属单元测试和稳定错误;
- 未支持语法必须在编译或加载阶段清晰拒绝;
- 不得静默降级成错误行为。
6.3 V2-L1-REQ-003 高效执行核心
| 编号 | 短名 | 主责模块 | 关联模块 |
|---|---|---|---|
| V2-L1-REQ-003 | 执行核心 | PJ2026-050102 VM执行 | PJ2026-050103 对象内存、PJ2026-050105 验证基准 |
VM 应针对高频动态值建立紧凑表示和快速路径:
- 整数算术、比较和分支避免不必要堆分配;
- 局部变量访问避免字符串查找;
- 已优化函数调用避免通用对象分派。
执行结构要求如下:
- opcode、dispatch 和调用帧共同降低有效语义操作的指令数;
- 热路径减少分支数和内存访问;
- 固定宽度寄存器 VM、紧凑栈 VM、变长编码和其他 dispatch 方案必须以能力等价 A/B 结果选择;
- 可以在保持 capability 语义一致的前提下选择适合平台的 dispatch 实现;
- 不得要求 LLVM、JIT 或 native emitter。
6.4 V2-L1-REQ-004 紧凑对象与内存
| 编号 | 短名 | 主责模块 | 关联模块 |
|---|---|---|---|
| V2-L1-REQ-004 | 对象内存 | PJ2026-050103 对象内存 | PJ2026-050102 VM执行、PJ2026-050104 裁剪移植 |
对象和调用状态必须把 32 位微控制器作为一等目标:
- 值表示、对象头和容器使用紧凑布局;
- 常用不可变值优先使用紧凑立即数;
- 局部变量和调用状态优先使用栈或帧;
- 避免把所有值统一提升为堆对象。
内存故障要求如下:
- 分配、回收和资源上限必须可配置、可观测且确定;
- 普通可恢复错误返回异常;
- 栈耗尽等致命故障必须报告原因后停机;
- 停机后不得继续执行受损状态。
6.5 V2-L1-REQ-005 分层裁剪
| 编号 | 短名 | 主责模块 | 关联模块 |
|---|---|---|---|
| V2-L1-REQ-005 | 分层裁剪 | PJ2026-050104 裁剪移植 | PJ2026-050101 语言编译、PJ2026-050102 VM执行、PJ2026-050103 对象内存 |
V2 必须延续并强化 V1 的可裁剪能力:
- 裁剪由 capability 依赖闭包驱动,并覆盖语法产生、opcode、对象类型和异常;
- 裁剪覆盖模块、C binding 和平台能力;
- 未启用功能的代码、只读数据和注册表能够从最终产物中移除。
每个 capability 必须声明:
- 依赖;
- 测试;
- 资源变化。
裁剪不得产生:
- 无法解释的链接失败;
- 静默行为变化;
- 只在完整配置可见的错误诊断。
6.6 V2-L1-REQ-006 Runtime 性能优先
| 编号 | 短名 | 主责模块 | 关联模块 |
|---|---|---|---|
| V2-L1-REQ-006 | 性能优先 | PJ2026-050105 验证基准 | PJ2026-050101 语言编译、PJ2026-050102 VM执行、PJ2026-050103 对象内存 |
性能优化顺序如下:
- 先由 benchmark 或 profiler 识别热点;
- 再针对热点改变实现;
- runtime 性能优先级远高于 parser 性能;
- 只有 parser 成为目标设备上重复执行且可测量的主导成本时才优化 parser;
- 不得以优化 parser 为由增加 VM 热路径成本。
性能结果必须按以下 suite 分类,且不得混用结论:
- 内核上限 suite:衡量最小 capability 闭包的热点上限,用于候选内核 A/B,不代表完整动态产品性能;
- 动态能力等价 suite:使用相同 capability 闭包和语义,对照 V1 与 MicroPython,是跨动态内核比较的基础;
- 产品代表性 suite:覆盖命名 profile 的调用、容器、属性、模块、C binding 和异常等真实路径,是产品发布结论的基础;
- 静态加速对照:Viper 或其他静态实现仅用于 PJ2026-0502 的独立对照,不参与 V2 动态产品结论。
6.7 V2-L1-REQ-007 错误和字节码安全
| 编号 | 短名 | 主责模块 | 关联模块 |
|---|---|---|---|
| V2-L1-REQ-007 | 错误安全 | PJ2026-050101 语言编译 | PJ2026-050102 VM执行、PJ2026-050103 对象内存 |
编译器和加载器必须完成以下校验:
- 语法、常量和跳转;
- 栈或寄存器边界;
- 能力依赖和字节码版本。
运行时必须区分可恢复异常与致命资源故障,并为两者提供稳定、可测试的可见信息。
非法输入不得导致:
- 未报告崩溃;
- 越界执行;
- 静默退出;
- 无诊断循环。
致命故障允许停机,但停机前必须输出最小可靠诊断。
6.8 V2-L1-REQ-008 原子 capability 与 profile
| 编号 | 短名 | 主责模块 | 关联模块 |
|---|---|---|---|
| V2-L1-REQ-008 | capability 配置 | PJ2026-050101 语言编译 | PJ2026-050102 VM执行、PJ2026-050104 裁剪移植、PJ2026-050105 验证基准 |
V2 必须遵循 PIKA-CAP 能力配置档 的原子 capability、显式依赖和命名 profile 合同:
- 每个已启用 capability 必须有稳定 ID、依赖、语义测试、负向测试和资源报告;
- 编译器从 profile 或显式根集合解析 capability 闭包,并拒绝闭包外源码语义;
- 字节码必须声明所需 capability 清单和格式版本;
- 加载器必须拒绝 runtime 未提供完整 capability 闭包的产物;
compute-min、control-core、embedded-app和dynamic-full是命名 profile,不构成实现成熟度或 VM 选择顺序;- 定制 profile 必须显式记录根集合、展开后的闭包和资源预算。
6.9 V2-L1-REQ-009 共享内核与局部专用化
| 编号 | 短名 | 主责模块 | 关联模块 |
|---|---|---|---|
| V2-L1-REQ-009 | 共享内核 | PJ2026-050102 VM执行 | PJ2026-050101 语言编译、PJ2026-050104 裁剪移植、PJ2026-050105 验证基准 |
V2 必须以一个共享内核作为默认实现,并由 capability 闭包完成构建期裁剪。该要求贯彻“重写大于优化”:
- 未启用 capability 的对象、opcode、模块、错误路径和只读数据不得进入最终产物;
- profile 不得选择完整独立 VM,也不得由单一整数宏成为第二配置真相;
- 局部专用化只在能力等价 A/B benchmark 证明有稳定性能或资源收益时允许;
- 专用化不得改变 capability 语义、字节码验证、错误合同或配置可追溯性;
- 固定宽度寄存器 VM、紧凑栈 VM 和混合实现的选择必须记录适用 profile、候选对照和资源影响;
- owning YAML 是 capability、profile 和资源预算的唯一配置事实源。
6.10 V2-L1-REQ-010 职责化实现命名
| 编号 | 短名 | 主责模块 | 关联模块 |
|---|---|---|---|
| V2-L1-REQ-010 | 职责化命名 | PJ2026-050102 VM执行 | PJ2026-050101 语言编译、PJ2026-050103 对象内存、PJ2026-050104 裁剪移植、PJ2026-050105 验证基准 |
V2 作为路线和规格称谓,不得进入实现仓库的文件名或项目自有代码标识符:
- 文件名、目录内构建 target、函数、变量、类型、枚举、宏和 namespace 必须按职责命名;
- 禁止项按大小写不敏感方式检查,不得通过别名、兼容宏或包装函数保留代际缩写;
- 公开 API 应表达程序、参数、调用方存储、执行结果和运行指标等稳定职责;
- 路线名称可以出现在规格、阶段报告和产品版本元数据中,但不得成为实现结构或 ABI 名称;
- 版本控制内全部实现文件名和项目自有代码标识符必须由自动扫描验证。
6.11 V2-L1-REQ-011 语法能力组 TDD
| 编号 | 短名 | 主责模块 | 关联模块 |
|---|---|---|---|
| V2-L1-REQ-011 | 语法 TDD | PJ2026-050101 语言编译 | PJ2026-050102 VM执行、PJ2026-050105 验证基准 |
每组新增语法必须先冻结 capability 根集合和依赖闭包,再按以下顺序交付:
- 先增加能够因缺失能力而稳定失败的 lexer、parser、IR、verifier 和 VM 细粒度测试;
- 同时增加输入单个
.py文件和输入目录的最终回归,目录默认执行main.py; - 记录红测例的预期失败位置和诊断后,才实现满足该能力组的最小前端和 runtime 语义;
- 内部测试通过后,使用相同工作目录和源码由目标运行时与 CPython 执行;
- 对受支持且成功执行的脚本逐字节比较 stdout,并比较退出状态;
- 最后在相同环境运行实现前后 benchmark,报告性能和资源变化。
脚本回归必须满足以下边界:
- 输入文件必须是单个
.py文件;输入目录必须包含默认入口main.py; - 目录中的其他
.py文件只有在对应模块能力已启用时才可被加载,不得隐式全部执行; - stdout 比较不得裁剪空白、修改换行或忽略末尾字节;
- stderr 和编译诊断必须保持可见,但不得混入 stdout 对照结果;
- 不支持的语法必须由对应负向测试验证稳定拒绝,不得为了通过 CPython 对照而静默接受。
测试组织必须满足以下要求:
- 可以参考稳定 PikaPython 的能力分类和脚本粒度;
- 不得复制其测试实现、内部断言或 runtime 假设。
每个语法能力组必须同时具备:
- lexer、parser 和编译结果的细粒度测试;
- opcode、控制流、存储和错误恢复的 VM 测试;
- 单文件和目录入口的最终脚本回归;
- 禁用 capability 和依赖缺失的负向测试。
6.12 V2-L1-REQ-012 严格 ISO C99
| 编号 | 短名 | 主责模块 | 关联模块 |
|---|---|---|---|
| V2-L1-REQ-012 | C99 合同 | PJ2026-050104 裁剪移植 | PJ2026-050101 语言编译、PJ2026-050102 VM执行、PJ2026-050103 对象内存、PJ2026-050105 验证基准 |
全部项目自有 C 源码和 C 头文件必须符合严格 ISO C99。 本要求是本次唯一新增硬门禁:
- C 编译标准固定为 C99,不得提升到 C11 或更高版本;
- GNU 语言扩展必须关闭,不得使用
gnu99或编译器默认 GNU 方言; - GCC 和 Clang 构建:
- 必须使用
-std=c99或等价参数; - 必须启用
-pedantic-errors;
- 必须使用
- 默认内核、显式候选、smoke 和工具中的每个 C 编译单元都必须进入该检查;
- 构建系统配置和实际编译命令必须同时验证,任一编译单元偏离即构建失败;
- C++ 仅可用于主机测试和 benchmark harness,不得成为目标 runtime 或 C ABI 的依赖。
7. 验收合同
7.1 语义验收
- 每个已支持 capability 必须具备 V2 专属正向、负向和依赖缺失测试;
- 每个命名 profile 必须能确定性展开为完整 capability 闭包;
- V1 parser 测试资产必须映射到明确 capability,不得把全部 V1 语法变成 V2 承诺;
- 相同源码、capability 闭包和编译配置必须产生确定的中性类型化 V2 IR;
- 对共同支持的源码,任意两个已启用前端必须产生语义等价的 V2 IR;
- V1 parser 升级不得静默改变 IR;必要的 IR 变化必须先修改 IR 版本和对应语义测试;
- V2 IR 和目标产物不得包含 V1 对象、VM、ABI 或模块注册依赖;
- 测试粒度参考 V1,但不要求继承 V1 测试或内部行为;
- 不支持能力必须有负向测试,验证明确拒绝和错误可见性;
- 模块裁剪组合必须验证功能依赖和最终链接结果。
- 每组语法能力必须保存先失败后通过的 TDD 证据,并覆盖前端、IR、verifier、VM 和最终脚本五个层次。
- 回归执行器必须接受单个
.py文件或目录;目录未包含main.py时返回明确错误。 - 对受支持的成功脚本,目标运行时和 CPython 的退出状态与 stdout 原始字节必须完全一致。
7.2 性能验收
- 裁决环境:
- Linux 原生执行是快速主裁决环境;
- 涉及 MCU 发布主张时,必须在对应真实 Cortex-M 或 RV32 目标上确认;
- 声称跨 Cortex-M 和 RV32 通用的结论必须分别在至少一个真实目标上确认;
- QEMU 只验证功能、Flash 和静态 RAM,不用于性能结论;
- 所有实现使用固定版本、相同 workload、能力等价配置和公开编译参数。
- 生命周期口径:
- cold-start 分别报告 runtime 或 root 创建、parser 或 compile、首次执行和销毁;
- warm execution 在 fixture setup 完成 runtime 或 root 创建及程序编译,在全部 iteration 结束后统一销毁;
- warm iteration 只执行已加载或已编译程序,不得包含 root 创建、销毁、parser 或 compile;
- V1 生命周期修复前后的原始数据必须同时保留,旧数据不得改写为 warm execution;
- 重复执行必须核对结果、错误状态、活跃对象、峰值堆和 teardown 稳定性。
- suite 分类:
- 内核上限 suite 只裁决候选内核和局部热点,不支撑完整动态产品结论;
- 动态能力等价 suite 对照 V1 与 MicroPython,并绑定完整 capability 闭包;
- 产品代表性 suite 覆盖命名 profile 的真实应用路径;
- Viper 或其他静态实现只进入 PJ2026-0502 静态加速对照。
- 动态能力等价和产品代表性 suite 合计至少覆盖:
- 递归和非递归函数调用;
- 整数算术、比较、分支和循环;
- 局部变量、全局变量和属性访问;
- 字符串、列表、元组和字典的已支持操作;
- Python 到 C 模块边界调用;
- 异常正常路径和异常抛出路径。
- 比较目标:
compute-min必须独立满足最小计算闭环的语义、性能和资源预算;- V2 相对能力等价 V1 的动态能力等价和产品代表性 suite 几何平均吞吐分别至少提升 50%;
- V2 相对能力等价 MicroPython 必须形成预算约束下的 Pareto 优势;
- 性能、Flash 和峰值 RAM 至少一项明确领先 MicroPython,其余项不得越过对应 profile 预算;
- 领先幅度必须大于预先声明的测量噪声或置信区间;
- 相对 MicroPython 的 suite 几何平均吞吐提升 5% 仅作为延伸目标,不作为第一阶段完成条件;
- 单一 workload 不得独立支撑上述结论;
- 报告同时披露每项原始值、样本数、median、p95、标准差、变异系数、几何平均和退化项。
- 每个语法能力组进入默认内核前必须完成实现前后对照:
- 使用相同工具链、环境、CPU 亲和性和 workload;
- 比较热执行、字节码、执行存储、宿主栈、动态分配和二进制尺寸。
- 前端解析和编译成本单独报告,不得混入 warm execution;目标 runtime 不得因主机前端链接而虚增 Flash 结论。
7.3 资源验收
- 对每个可比较配置分别报告:
text与只读数据;- 初始化数据和
bss; - 峰值堆、峰值 VM 栈和宿主栈;
- benchmark 热路径动态分配次数。
- 资源指标:
- 必须来自 allocator、执行存储水位、栈水位或等价 instrumentation;
- 无法测量的字段必须报告 unavailable 和原因;
- 不得填写推测值或手工零值。
- 每个命名或定制 profile 均不得超过 owning YAML 声明的资源预算。
- V2 的可比较配置应满足:
- Flash 不高于 V1 同能力配置;
- 峰值 RAM 不高于 V1 同能力配置;
- 相对 MicroPython 的性能、Flash 和峰值 RAM 按 7.2 的预算约束做 Pareto 分析。
- 高频整数算术、局部控制流和已优化函数调用路径应保持零堆分配:
- 该结论必须由分配器计数或等价 trace 证明;
- 不得使用手工源码计数代替。
- 宿主 C 栈或目标栈上的帧、寄存器数组和临时缓冲必须单独计入峰值栈,不得因“零堆分配”而省略。
- 构建产物必须证明只链接 capability 闭包需要的 opcode、对象、模块和辅助路径。
7.4 可裁剪验收
config/pikapython-capabilities.yaml是 capability、profile、依赖和资源预算的目标事实源;- 构建生成的 capability 清单和细粒度编译开关不得成为第二配置真相;
- 命名 profile 和定制 profile 均必须显式解析完整 capability 闭包;
- 主机预编译的目标配置必须能够完全移除 lexer/parser 代码和前端只读数据;
- 目标 runtime 和固件不得链接 V1 parser、对象、VM、ABI 或模块注册实现;
- 禁用功能后,对应 opcode、对象实现、模块表和只读字符串应能从链接产物移除;
- 配置差异必须能映射到功能、测试和资源差异;
- 任何裁剪配置均不得把资源耗尽或非法字节码变成静默故障。
7.5 内核结构验收
- 固定宽度寄存器 VM、紧凑栈 VM、变长编码或混合候选必须使用相同 capability 闭包、IR 语义、workload 和编译条件比较;
- 候选结论必须同时包含 Linux、对应真实目标、Flash、RAM、栈和动态分配证据;
- 单一 fib 或其他内核上限 workload 不得独立决定产品内核结构;
- profile 默认使用共享 V2 内核,完整 profile 专用 VM 不得作为无证据的预设架构;
- 局部专用实现只有在收益超出测量噪声、未违反 profile 预算且语义回归全部通过时才可进入默认构建。
7.6 实现命名验收
- 扫描版本控制内全部实现文件名,按大小写不敏感方式确认不存在路线代际缩写;
- 对 C、C++、CMake 和项目脚本执行标识符级扫描,并输出命中的路径、行和标识符;
- 公开头文件、链接符号、构建 target 和测试 fixture 不得保留兼容别名;
- 第三方依赖必须位于明确的 vendored 边界,其上游标识符不构成本项目公开 API。
7.7 C99 验收
- 配置阶段必须断言 C 标准为 99 且扩展关闭;
- 编译命令清单必须证明全部项目自有
.c文件使用严格 C99 方言和-pedantic-errors; - 默认构建和显式候选构建都必须通过同一 C99 合同检查;
- 任意 GNU extension、C11 语法或漏检 C 编译单元都必须使测试失败。
8. 过程控制
- V2 新增或修改的手写内核源码应标注
SPEC: PJ2026-0501 V2内核 v0.3和文件职责。 - 自动生成、vendored、配置和二进制产物可不加源码头,但生成器或配置入口必须能追溯本规格。
- 架构选择必须记录候选方案、适用前提、benchmark 热点和资源影响;当前结果进入 TaskTree 或 issue,不进入 SPEC。
- 任何实现若让 V1 内部结构越过中性类型化 V2 IR 边界,必须先更新本规格或作为偏离停止合并。
- capability 和 profile 实现引用
PIKA-CAP v0.2。 - 语法能力组的红测例、通过证据和 benchmark 数值进入 TaskTree 或 issue,不进入 SPEC。
- 若后续决定引入 strict type、LLVM、JIT 或 native emitter,应归入独立静态加速规格,不得直接修改 V2 默认路线。