44 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 | 5c133ed2 |
2026-07-21 | 已批准:增加语法能力组 TDD、CPython 逐字节脚本回归、严格 ISO C99 硬门禁和扁平 C 源目录合同。 |
| v0.4 | cd0004b9 |
2026-07-21 | 已批准:固定 Python 3 .pyi C 模块声明、C callback 边界、原生实例生命周期和 binding 回归合同。 |
| v0.5 | 13187182 |
2026-07-21 | 冻结嵌入式操作符矩阵、纯内置函数统计分母和 90% 验收口径。 |
修改历史只记录规格语义变更,不记录实现进度、阶段基线或一次性证据。
v0.4 及其引用的 PIKA-CAP v0.3 已批准生效,作为当前实现合同。
正文
PJ2026-0501 V2内核需求规格
1. 文档控制
| 字段 | 内容 |
|---|---|
| 编号 | PJ2026-0501 |
| 短名 | V2内核 |
| 层级 | L1 方向 |
| 规格状态 | 已生效 |
| 当前生效版本 | v0.4 |
| 实现引用版本 | v0.4 |
| 需求规格模板 | 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 模块绑定、平台抽象和可预测错误合同。
- Python 3
.pyiC 模块声明、主机侧归一化和目标侧 C callback 边界。 - 实现文件和代码标识符的职责化命名合同。
- 项目自有 C 源码的严格 ISO C99 编译合同。
- 项目自有 C 源码和头文件在单一
src/目录中的扁平集成合同。 - 分层内部测试和与 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 C binding SDK、生成器、
PikaObj*ABI、具体.pyi文件和 C 符号命名的内部兼容。 - 将 V1 parser、V1 runtime 或 MicroPython fork 设为 V2 目标运行时的长期依赖。
- 由本规格预先固定宽度寄存器 VM、紧凑栈 VM 或字节码编码形态。
- 为提升 parser 性能牺牲 runtime 性能或内核资源;parser 可在 PC 端一次性运行。
- 仅通过 C 模块 binding 替代通用脚本 VM。
2.4 操作符与内置函数统计边界
本规格对“完整操作符”和“90% 内置函数”使用可复核的嵌入式子集口径:
- 完整操作符矩阵覆盖已启用标量、字符串、字节序列和容器的全部声明操作;
- 矩阵包括一元正号、一元负号、按位取反、逻辑非、幂、乘法、矩阵乘法、
除法、整除、取模、加法、减法、左移、右移、按位与、按位异或、按位或、
小于、小于等于、大于、大于等于、等于、不等于、
in、not in、is、is not、and、or、条件表达式、订阅、切片和对应增强赋值; - 操作符的类型错误、除零、越界和不支持组合必须返回稳定错误,不得静默转换;
- 内置函数分母固定为 45 个确定性、无文件系统、无交互输入、无动态代码执行
依赖的嵌入式纯内置:
abs、all、any、ascii、bin、bool、bytes、bytearray、chr、dict、divmod、enumerate、float、format、getattr、hasattr、hash、hex、id、int、isinstance、len、list、max、min、oct、ord、pow、print、range、repr、reversed、round、set、slice、sorted、str、sum、tuple、type、zip; eval、exec、compile、input、open、动态导入、调试交互和宿主环境 查询不进入分母,也不因未实现而降低覆盖率;- 内置函数覆盖率按“具有正向语义测试、错误路径测试和 CPython 输出/结果对照的 函数数 / 45”计算,阶段目标为至少 41/45(91.1%);仅注册名称或返回占位值 不计入已实现数。
3. 术语表
| 术语 | 定义 |
|---|---|
| 重写优先 | 当热点或资源债务来自内核结构时,重新设计结构优先于围绕旧结构继续局部优化。 |
| 动态子集 | 不要求静态类型注解,在运行时保持对象类型语义,但只承诺明确列出的 Python 语法和对象能力。 |
| 快速路径 | 对高频类型和 opcode 使用无堆分配、少分支或专用表示的执行路径。 |
| 慢速路径 | 处理通用对象、异常、边界转换或低频语义的共享路径。 |
| 主机预编译 | 在 PC 端完成解析、语义检查和字节码生成,目标设备只加载或执行产物。 |
| capability | 可独立标识、声明依赖、测试语义和报告资源成本的语言或 runtime 能力。 |
| profile | 有稳定名称和产品意图的 capability 根集合,不表示线性兼容等级。 |
| V1 前端适配器 | 仅在主机侧把 V1 parser 的输出转换为 V2 中性类型化 IR 的可替换引导组件。 |
| 中性类型化 V2 IR | V2 前端与后端之间版本化、结构节点和操作数类别显式、无 V1 对象和 ABI 依赖的唯一长期合同;不表示静态类型证明。 |
| 能力等价配置 | 所需 capability 闭包、被测语义和必需平台模块一致的比较配置。 |
| 职责化命名 | 文件名和代码标识符表达内核职责、数据语义或生命周期,不携带路线代际缩写。 |
| 语法能力组 | 一次 TDD 迭代选择的 capability 根集合、依赖闭包、正负测试和资源比较单元。 |
| 逐字节脚本回归 | 对相同受支持源码比较目标运行时与 CPython 的退出状态和 stdout 原始字节,不做空白或换行归一化。 |
.pyi 声明 |
使用 Python 3 stub 语法描述 C 模块 Python 可见名称、签名和原生类的主机侧输入;不表示目标设备上的源文件。 |
| binding descriptor | 从 .pyi 归一化得到的模块、成员、签名、类型转换和 callback 元数据。 |
| C callback | 由 C 模块实现提供、在目标 runtime 调用边界内执行并通过 tagged value 传递参数和结果的函数。 |
| 原生实例 | 由 C 模块创建、由 runtime 持有不透明载荷并可绑定 C 方法的 Python 可见对象。 |
4. 系统边界和接口
| 边界项 | 内容 |
|---|---|
| 外部使用者 | 嵌入式应用开发者、V1 迁移者、模块开发者和平台移植者。 |
| 外部输入 | 受支持 Python 源码或 V2 字节码、.pyi 声明、C callback 模块、裁剪配置和平台端口。 |
| 受控资源 | 编译器、字节码、VM 状态、调用帧、对象、堆、binding descriptor、模块表和错误状态。 |
| 外部输出 | 执行结果、异常、停机诊断、静态库或固件、字节码和资源指标。 |
| 用户接口 | V2 Python 子集、字节码格式、Python 3 .pyi 声明、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: 结果、异常或致命停机诊断
5.7 C 模块声明与调用数据流
.pyi 绑定必须采用主机生成、目标执行的两段式数据流:
flowchart LR
PYI[Python 3 .pyi 声明] --> N[主机解析与归一化]
N --> D[版本化 binding descriptor]
D --> G[描述符校验与 C99 glue 生成]
G --> R[目标模块注册表]
C[C callback 实现] --> R
APP[Python import 与调用] --> R
R --> OUT[返回值或明确错误]
该数据流必须满足以下稳定边界:
.pyi只在主机侧参与解析、归一化、校验和 glue 生成;- 目标产物只包含已选 capability 所需的 descriptor、注册表和 callback glue;
- descriptor 必须独立于 V1 对象布局、调用栈、生成头文件和符号命名;
- descriptor 必须携带可校验的 schema 版本和记录尺寸,未知版本或非法尺寸必须在注册前拒绝;
- C 模块只能通过公开 C99 binding API 使用不透明上下文和值,不得直接读取 VM、调用帧或对象内部结构;
- 模块可以通过静态注册或显式初始化加入 registry,但 Python 可见的查找、重复注册和调用错误语义必须一致;
- 模块名、类名和成员名在 registry 生命周期内保持稳定,并拒绝重复定义;
- tagged value 的语义标签至少包括:
none、bool、int、float、str、bytes和opaque;- 具体 C 结构布局不属于本合同;
- callback 边界必须满足:
- 位置参数的数量和类型转换在进入 callback 前完成;
- callback 失败通过稳定错误结果返回,不得以未定义跳转或隐式全局状态传递异常;
- 语义接口包含调用上下文、只读参数序列、结果输出和错误输出;
- 不得通过 C
longjmp或未定义异常跨越边界;
- callback 接收的
str、bytes和其他输入视为调用期间借用值,除非 descriptor 明确声明更长生命周期; - callback 产生的字符串或字节结果必须在 runtime 接管前完成复制,或使用 descriptor 明确声明的静态只读存储;
- 原生实例的载荷是不透明的:
- 构造失败不得产生可见实例;
- 已成功构造的实例在销毁时最多执行一次清理 callback;
- 目标 runtime 不得因为支持
.pyi绑定而链接.pyiparser、主机工具或 V1 binding SDK。
Python 可见调用路径必须覆盖:
import module后调用模块级 C 函数;module.Type(...)创建 C-backed 原生实例;instance.method(...)调用 C 实例方法;- 标量参数和返回值在 Python 值与 tagged value 之间进行确定转换;
- 缺模块、缺成员、参数数量、参数类型、callback 和资源错误分别产生可测试诊断。
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.2.1 V2-L1-REQ-002A 操作符矩阵
| 编号 | 短名 | 主责模块 | 关联模块 |
|---|---|---|---|
| V2-L1-REQ-002A | 操作符矩阵 | PJ2026-050101 语言编译 | PJ2026-050102 VM执行、PJ2026-050103 对象内存 |
已选操作符矩阵必须满足以下合同:
- lexer 为每个多字符和关键字操作符产生独立 token,最长匹配不得拆分成不同语义;
- parser 按 Python 优先级和结合性生成确定 IR,短路操作不得提前求值右操作数;
- verifier 校验每种操作的结果槽、操作数槽和容器索引/切片描述边界;
- VM 为整数和布尔快速路径提供无堆执行,并为已启用对象类型提供统一慢速路径;
- 增强赋值必须等价于读取、操作和写回,且只求值一次左侧目标;
- 订阅、切片、成员和身份操作必须覆盖正向、类型错误、越界和空值边界;
- 矩阵乘法对一维数值序列执行点积,对不满足该合同的输入返回稳定类型错误;
- 每个矩阵项必须有 lexer/parser/IR/verifier/VM 细粒度测试和至少一个 CPython 逐字节脚本回归。
6.2.2 V2-L1-REQ-002B 嵌入式纯内置目录
| 编号 | 短名 | 主责模块 | 关联模块 |
|---|---|---|---|
| V2-L1-REQ-002B | 纯内置目录 | PJ2026-050101 语言编译 | PJ2026-050102 VM执行、PJ2026-050103 对象内存、PJ2026-050105 验证基准 |
嵌入式纯内置目录必须满足以下合同:
- 目录分母固定为本规格 2.4 列出的 45 个名称,注册表必须暴露名称、签名、 支持状态和所需 capability;
- 至少 41 个名称必须有真实实现,覆盖整数、布尔、浮点、字符串、字节、 列表、元组、字典、集合和 range 的已声明语义;
- 参数数量、参数类型、空序列、不可迭代对象、不可哈希对象和数值边界必须 返回稳定错误;
print、repr、str、ascii和容器格式化必须与 CPython 对照值的 stdout 原始字节一致;- 目录内置调用必须经统一 builtin registry 和 verifier,不得由 parser 为每个 名称复制一套隐藏执行分支;
- 未进入分母的宿主相关函数必须明确拒绝,不能返回假成功;
- 覆盖率报告必须列出分母、已实现数、未实现名称和测试用例,不得只报告百分比。
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 的依赖。
6.13 V2-L1-REQ-013 扁平 C 源目录
| 编号 | 短名 | 主责模块 | 关联模块 |
|---|---|---|---|
| V2-L1-REQ-013 | 扁平源码 | PJ2026-050104 裁剪移植 | PJ2026-050101 语言编译、PJ2026-050102 VM执行、PJ2026-050103 对象内存 |
版本控制内全部项目自有 .c 和 .h 文件必须直接平铺在单一 src/ 目录中:
- 不设置独立
include/目录; - 不按 parser、VM、runtime 或平台职责建立存放
.c和.h的子目录; - 文件职责通过职责化文件名表达;
- 公开头文件和内部头文件通过构建及打包清单区分,不通过物理目录区分;
- 嵌入式项目必须能够把
src/作为唯一项目头文件搜索目录; - 包管理器必须能够从同一目录枚举待集成源码和公开头文件。
以下对象不属于项目自有 C 源码平铺范围:
- 明确隔离的第三方 vendored 文件;
- 构建目录内生成且不进入版本控制的 C 中间产物。
6.14 V2-L1-REQ-014 Python 3 .pyi C 模块绑定
| 编号 | 短名 | 主责模块 | 关联模块 |
|---|---|---|---|
| V2-L1-REQ-014 | C 模块绑定 | PJ2026-050104 裁剪移植 | PJ2026-050101 语言编译、PJ2026-050102 VM执行、PJ2026-050103 对象内存、PJ2026-050105 验证基准 |
V2 必须提供面向用户的 C 模块接口,并遵循
PIKA-CAP .pyi C 模块声明合同。
该接口必须满足以下稳定要求:
.pyi是主机侧 Python 3 stub 声明输入,不是目标 runtime 的解释脚本;- 声明必须归一化为版本化 binding descriptor,再生成目标侧注册表和 C99 callback glue;
- Python 用户必须能够导入 C 模块、调用模块函数、构造 C-backed 原生实例并调用实例方法;
- 目标侧 C API 必须使用不透明模块、类和实例描述,以及带类型标签的参数和返回值边界;
- 公开 binding header 必须能被模块以严格 ISO C99 独立包含,不得要求 C++、GNU 扩展或内部 runtime header;
- callback 生命周期、字符串和字节的借用/复制规则、原生实例清理规则必须是确定的;
- 缺模块、缺成员、重复注册、参数数量错误、参数类型错误、callback 失败和资源耗尽必须分别可观察和可测试;
- V1 的
PikaObj*、内部 SDK、生成头文件、符号命名和对象 ABI 不属于 V2 兼容合同; .pyi的兼容目标是声明方式和 Python 可见调用语义,不是某个具体XXX.pyi文件或 V1 生成结果;- 未启用
binding.c或binding.c-object时,相关声明必须在主机生成阶段被拒绝,不能依赖目标运行时临时失败。
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 测试或内部行为;
- 不支持能力必须有负向测试,验证明确拒绝和错误可见性;
- 模块裁剪组合必须验证功能依赖和最终链接结果。
- 操作符矩阵必须逐项验证,内置函数覆盖率必须按 45 个固定名称计算且至少达到 41 个真实实现;
- 每组语法能力必须保存先失败后通过的 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 分析。
- 每份资源对比表必须同时披露 Flash 和 RAM 的:
- 绝对值;
- 相对于对应 profile 预算的占比;
- 相对于比较对象的变化百分比或节省百分比。
- 高频整数算术、局部控制流和已优化函数调用路径应保持零堆分配:
- 该结论必须由分配器计数或等价 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 扩展、C11 语法或漏检 C 编译单元都必须使测试失败。
7.8 C 源目录验收
- 版本控制内项目自有
.c和.h文件必须全部是src/的直接子项; - 仓库不得存在项目自有
include/目录; - 构建和打包清单必须从
src/显式选择源码与公开头文件; - 使用者只增加
src/头文件搜索路径即可构建受支持的内核配置。
7.9 C 模块绑定验收
.pyi主机工具必须对最小 Python 3 stub 子集执行 lexer、parser、归一化和签名校验;- 范围外语法、V1 专用宏和 V1 私有类型必须产生稳定诊断,不得生成部分绑定;
- binding descriptor 必须能确定性表达模块函数、C 类、构造函数、实例方法、参数类型和返回类型;
- C 模块 fixture 必须只包含公开 binding header,并在
-std=c99 -pedantic-errors条件下独立编译; - registry 必须覆盖注册、查找、重复定义、缺模块和缺成员路径;
- VM 必须分别覆盖模块函数、C 类构造和实例方法的参数绑定、callback 返回和错误传播;
- 回归 fixture 必须使用目标 C 模块和 CPython 侧同名纯 Python 语义参考模块,比较退出状态和 stdout 原始字节;
- 目标固件或静态库不得包含
.pyiparser、主机生成器或 V1 binding SDK; - 冷启动必须单独报告注册和首次调用成本,warm benchmark 只计入已完成注册和加载后的调用;
- 模块函数和实例方法的调用开销必须分别测量,并同时披露:
- Flash、RAM;
- profile 预算占比;
- 相对比较对象的变化百分比。
- callback 失败、输入借用值失效、结果复制失败和实例清理必须各有负向或生命周期测试。
8. 过程控制
- V2 新增或修改的手写内核源码应标注
SPEC: PJ2026-0501 V2内核 v0.4和文件职责。 - 自动生成、vendored、配置和二进制产物可不加源码头,但生成器或配置入口必须能追溯本规格。
- 架构选择必须记录候选方案、适用前提、benchmark 热点和资源影响;当前结果进入 TaskTree 或 issue,不进入 SPEC。
- 任何实现若让 V1 内部结构越过中性类型化 V2 IR 边界,必须先更新本规格或作为偏离停止合并。
- capability 和 profile 实现引用
PIKA-CAP v0.3。 - 语法能力组的红测例、通过证据和 benchmark 数值进入 TaskTree 或 issue,不进入 SPEC。
- 若后续决定引入 strict type、LLVM、JIT 或 native emitter,应归入独立静态加速规格,不得直接修改 V2 默认路线。