diff --git a/02-type-system.md b/02-type-system.md index b61561b..b6a050b 100644 --- a/02-type-system.md +++ b/02-type-system.md @@ -520,22 +520,6 @@ class Node: next: Node* # struct Node* next ``` -### 匿名结构体成员(❌) - -> WARNING: **警告:** 由于 Viper 在声明结构体,枚举等处不需要关键字,因此 `t.Anonymouse` 是不需要使用的。此关键字不再维护,强行使用可能导致未定义行为。 - -继承 `t.Anonymous` 的类作为匿名成员嵌入: - -```python -class Header(t.Anonymous): - magic: uint32 - version: uint32 - -class Packet: - Header # 匿名嵌入,可直接访问 Packet.magic - length: uint32 -``` - ### 字节序标记 > WARNING: **警告:** 此关键字是实验性的。未经充分测试,不当使用可能导致未定义行为。 diff --git a/05-classes.md b/05-classes.md index fe1b27e..cac7c0f 100644 --- a/05-classes.md +++ b/05-classes.md @@ -85,22 +85,6 @@ class Config: obj_ptr: MyClass* = &MyClass(arg1, arg2) ``` -### 匿名结构体成员(❌) - -> WARNING: **警告:** `t.Anonymous` 已废弃。由于 Viper 在声明结构体,枚举等处不需要关键字,因此 `t.Anonymouse` 是不需要使用的。此关键字不再维护,强行使用可能导致未定义行为。 - -继承 `t.Anonymous` 的类作为匿名成员嵌入: - -```python -class Header(t.Anonymous): - magic: uint32 - version: uint32 - -class Packet: - Header # 匿名嵌入,可直接访问 Packet.magic - length: uint32 -``` - ### 字节序标记 > 待实现(尚无字节序处理代码)。 diff --git a/07-control-flow.md b/07-control-flow.md index bd9a724..3147d03 100644 --- a/07-control-flow.md +++ b/07-control-flow.md @@ -240,6 +240,7 @@ match value: ## assert 语句 > 避免使用此语句,此语句未经充分测试,在多数情况下,编译器不知道如何展示结果。 +> 需要断言时**推荐使用 `testcheck` 库的断言**(`import testcheck`,核心断言为 `testcheck.check(cond, ok_msg, fail_msg)`,另有 `begin`/`section`/`ok`/`fail`/`info`/`end`/`summary`)。 > 期望实现——当前语句分派无 assert 分支 ```python diff --git a/14-oo-refactor.md b/14-oo-refactor.md deleted file mode 100644 index 4ab65ad..0000000 --- a/14-oo-refactor.md +++ /dev/null @@ -1,231 +0,0 @@ -# TPV 对象化重构方案 - -> 基线:TPV `f63dcd7` / TransPyC `e1cb560`(对象化前最后稳定版本,2026-08-09) -> 状态:已实施(落地形态与方案存在偏差,见下) - -## 1. 背景与目标 - -### 1.1 现状问题 - -TPV 编译器当前是"**数据对象 + 行为函数式**"架构: - -- `includes/llvmlite/`:19 个数据结构类已对象化(`IRBuilder`/`LLVMModule`/`Value`/`LLVMType`…),但**所有操作是"首参传 self"的顶层函数**(`build_load(builder, ...)`、`module_add_function(mod, ...)`),与 C 风格 API 一致 -- `TransPyV/App/lib/core/Handles/`:**纯函数模块**(`translate_call(pool, builder, mod, node, funcs, count, trans)` 六参连传),且存在严重膨胀: - -| 文件 | 大小 | 行数 | -|---|---|---| -| HandlesExprCall.vp | 362KB | 7043 | -| HandlesExpr.vp | 181KB | 3715 | -| HandlesClassDef.vp | 172KB | 4010 | -| HandlesType.vp | 102KB | 2360 | - -*注:表中 Handles*.vp 行数为历史基线(TransPyV/App/lib/core/Handles 已删除);迁移去向:HandlesExprCall → Gen/Call(12 文件)、HandlesExpr → Gen/Expr、HandlesClassDef → Gen/Class、HandlesType → Gen/Type(位于 TransPyV/App/lib/core/Gen/)。* - -### 1.2 重构目标 - -1. **对象化**:引入 `Generator` 生成器对象(Mixin 组合),状态集中于 `self`,与 TPC 的 `Translator + LlvmCodeGenerator` 架构对齐 -2. **膨胀治理**:`translate_call` 7043 行 God Function 按职责拆散为 `CallGen` 的方法簇 -3. **不引入 TPC 代码**:基于 TPC 设计理念 + Viper 约束自研;TPC 的 LLVMCG 仅作参考 -4. **每阶段可验证**:bootstrap 编译 + 全 Test 回归,IR 输出零变化 - -## 2. 现状盘点(已实测) - -### 2.1 llvmlite 模块(`includes/llvmlite/`,7 文件) - -| 文件 | 内容 | 对象化程度 | -|---|---|---| -| `__init__.vp` (422行) | 10 工厂函数 + `LLVMModuleCore`(27 个薄封装方法) | **已有方法化先例** | -| `__builder.vp` (1336行) | **60+ 个 `build_*` 顶层函数** + `IRBuilder`(4 字段:Pool/Func/CurBlock/Counter) | **IRBuilder 是天然状态对象,签名已按 self 优先** | -| `__types.vp` (748行) | 34 类型工厂/打印/深拷贝 + `LLVMType`(**REnum tagged union**)+ `LLVMTypeCore`(19 方法) | REnum 应保留,Core 是方法化先例 | -| `__module.vp` (565行) | 19 函数 + `LLVMModule`(12 字段容器,含 NamedType 链表) | 纯数据容器,可平移 | -| `__function.vp` (798行) | 35 函数 + `Line/BasicBlock/Param/Function`(GSListNode 链) | 纯数据结构 | -| `__values.vp` (230行) | 14 函数 + `Value`(5 字段) | 纯数据结构 | -| `__verify.vp` (399行) | 15 验证函数 + `VerifyResult` | 独立,最后迁移 | - -**关键结论**: -- **IRBuilder 对象化零状态迁移成本**:4 字段已齐,60+ 顶层函数改方法只需 `self` 替代首参,签名一一对应 -- **LLVMModule 对象化有先例**:`LLVMModuleCore`/`LLVMTypeCore` 已证明"方法化封装"可行(但仍为薄壳,核心 `module_add_named_type`/打印仍是顶层函数) -- **LLVMType 保持 REnum**:变体即"子类",不应转继承层次 - -### 2.2 演进阻力点 - -1. `novirtual` + 硬编码 SIZE(`BUILDER_SIZE=32`/`pool.alloc(96)`)强耦合——**方法化不改布局则无影响**;若转 `virtual` 需全量重写 -2. 16 个跨模块 stub 访问器(`value_get_ty`/`paramnode_get_ty`…)是规避 TransPyC stub 限制的产物——方法化后可逐步消除(**依赖编译器缺陷修复,非本方案范围**) -3. `LLVMType` 的 `pool.alloc(__sizeof__)` + `*p = v`(旧 `c.DerefAs`)构造模式——保留为构造方法 - -## 3. 目标架构 - -``` -includes/llvmlite/ # ① 方法化平移(P0) - ├── __builder.vp # IRBuilder + 60 方法(build_load → self.load) - ├── __module.vp # LLVMModule + 方法 + 命名类型注册 - ├── __types.vp # LLVMType(REnum) + 构造方法 - ├── __values.vp / __function.vp / __verify.vp - └── __init__.vp # 薄兼容层:旧顶层函数委托新方法(调用方零改动) - -TransPyV/App/lib/core/ - ├── Gen/ # ② 生成器对象(P1-P6) - │ ├── Generator.vp # 入口:实际落地为组合:novirtual class Generator 持 46 个 GenMixin 子对象,非 Mixin 多继承 - │ ├── BaseGenMixin.vp # 状态/Pool/Module/Builder/SymTab + 错误/trace - │ ├── TypeGenMixin.vp # 类型映射/注解解析(← HandlesType) - │ ├── StructGenMixin.vp # struct 注册/字段/继承/vtable(← HandlesStruct+ClassDef 布局) - │ ├── ExprGenMixin.vp # 表达式/二元/一元(← HandlesExpr+ExprOps) - │ ├── CallGenMixin.vp # 调用分派/方法/类型转换/c.*/stdarg(← HandlesExprCall 拆解) - │ ├── FuncGenMixin.vp # 函数/方法声明与翻译(← HandlesFunctions) - │ ├── ClassGenMixin.vp # 类定义/泛型特化(← HandlesClassDef) - │ ├── StmtGenMixin.vp # 语句(← Body/If/While/For/Assign/AnnAssign/Return/Match/Nonlocal) - │ └── ImportsGenMixin.vp # 导入(← HandlesImports) - └── Handles/ # ③ 迁移完成后:删除或保留为薄壳(P6 决定) -``` - -## 4. P0:llvmlite 方法化(双轨过渡) - -> **落地状态**:未实施/已放弃,保留顶层函数调用(build_load → self.load 方法化未落地)。 - -### 4.1 原则 - -**纯方法化平移,不改布局、不改语义**:顶层函数 → 类方法,`self` 替代首参;类保持 `novirtual` + 硬编码 SIZE(不引入 vtable 继承)。 - -### 4.2 方法映射示例 - -```python -# 现状(__builder.vp) -def build_load(builder, ty, ptr): ... -def build_gep_struct(builder, struct_ty, field_ty, ptr, field_idx): ... - -# 目标(同文件,类方法) -novirtual class IRBuilder: - Pool, Func, CurBlock, Counter - def load(self, ty, ptr): ... # 原函数体,builder → self - def gep_struct(self, struct_ty, field_ty, ptr, field_idx): ... - -# 兼容层(__init__.vp):旧函数保留为薄包装 -def build_load(builder, ty, ptr): - return builder.load(ty, ptr) -``` - -### 4.3 覆盖清单(60+ 方法) - -| 类别 | 方法 | -|---|---| -| 内存 | alloca / alloca_aligned / alloca_at_entry / load / store | -| 整数二元 | add/sub/mul/sdiv/udiv/srem/urem/and/or/xor/shl/lshr/ashr | -| 浮点 | fadd/fsub/fmul/fdiv/frem/fneg | -| 比较 | icmp / fcmp | -| 控制流 | br / cond_br / ret / ret_void / unreachable / switch / select | -| 调用 | call / call_indirect | -| 转换 | bitcast/sext/trunc/zext/ptrtoint/inttoptr/fpext/fptrunc/fp2si/si2fp/fp2ui/ui2fp | -| GEP | gep / gep_array / gep_struct | -| Phi/原子/杂项 | phi / atomicrmw / cmpxchg / va_arg / inline_asm | - -### 4.4 Module 方法化 - -```python -def add_function(self, func): ... -def add_global(self, gv): ... -def add_named_type(self, ty): ... -def ensure_opaque_for_type(self, ty): ... -def set_target(self, triple): ... -def print_ir(self, mode): ... -``` - -### 4.5 验证 - -- bootstrap 编译 TPV(自举)通过 -- 全 Test 回归:编译产物 `.text.ll` 与基线**逐字节一致**(兼容层保证行为不变) -- 兼容层在 P6 确认无调用方后删除 - -## 5. P1-P6:Generator 对象迁移 - -### 5.1 Generator 骨架(P1) - -```python -# 采用 virtual(多态 Mixin 继承,与现有 ReturnHandle(HandlesBase.Mixin) 模式一致, -# 符合"多态类不用 novirtual"约定;数据类 llvmlite 仍为 novirtual) -virtual class Generator(BaseGenMixin, TypeGenMixin, StructGenMixin, - ExprGenMixin, CallGenMixin, FuncGenMixin, - ClassGenMixin, StmtGenMixin, ImportsGenMixin): - pass -``` - -*注:本骨架为原始方案;实际落地为组合架构(novirtual class Generator 持 46 个 GenMixin 子对象),见 §3 图注。* - -BaseGenMixin 状态字段(迁移自 HandlesTranslator): -`Pool` / `Module` / `Builder` / `SymTab` / `FuncTable` / `FuncCount` / `StructTable` / `VTableCache` / `ImportedModules` / `FromImports` / `ModuleSha1` / `CurFunc` / `CurBuilder` / `CurClassName` / 错误 trace 栈 - -### 5.2 Mixin 方法映射表(P2-P5) - -| Mixin | 来源(现状函数) | 迁移后方法 | -|---|---|---| -| TypeGenMixin | `HandlesType.map_t_type` / `resolve_annotation_type` / CDefine 表 | `self.map_type(name)` / `self.resolve_annotation(node)` | -| StructGenMixin | `HandlesStruct.register_struct` / `find_struct` / `lookup_field`;`HandlesClassDef` 布局/vtable | `self.register_struct(...)` / `self.lookup_field(...)` / `self.gen_vtable(cls)` | -| ExprGenMixin | `HandlesExpr.translate_value` / `translate_name_value` / 属性访问;`HandlesExprOps.translate_binop` / `try_unary_operator_overload` | `self.visit_value(node)` / `self.visit_binop(node)` / `self.visit_attr(node)` | -| CallGenMixin | `HandlesExprCall.translate_call`(**拆解**)+ `_translate_method_call` / `_translate_t_type_cast` / `translate_c_addr` 等 | `self.visit_call(node)` → `self._call_method(...)` / `self._call_t_cast(...)` / `self._call_c_addr(...)` | -| FuncGenMixin | `HandlesFunctions.translate_function_def` / `_mangle_name` | `self.translate_func(node)` / `self.mangle_name(name)` | -| ClassGenMixin | `HandlesClassDef.translate_class_def` / `_specialize_generic_class` | `self.translate_class(node)` / `self.specialize_generic(...)` | -| StmtGenMixin | `HandlesBody.translate_stmt` + If/While/For/Assign/AnnAssign/Return/Match/Nonlocal 各 Handle | `self.visit_stmt(node)` | -| ImportsGenMixin | `HandlesImports` Import/ImportFrom | `self.import_module(...)` | - -### 5.3 签名瘦身规则 - -```python -# 现状:六参连传 -translate_call(pool, builder, mod, node, funcs_ptr, func_count, trans) - -# 目标:self 持状态 -self.visit_call(node) # 内部用 self.Pool/self.Builder/self.Module/self.FuncTable -``` - -- 中间态:`self.visit_call(node, funcs_ptr, func_count)`(表引用局部化后去参) -- 迁移顺序**从叶子到根**(先无依赖者),每迁移一个 Mixin 立即 bootstrap - -> **落地状态**:未完全落地:pool/builder/mod/funcs 仍显式连传(CallGenMixin.translate_call),GenApi 保留模块级兼容壳。 - -### 5.4 CallGen 拆解(P4,膨胀治理重点) - -`translate_call` 7043 行按分支簇拆为方法(**纯移动,逻辑零改动**): - -| 方法簇 | 对应分支 | -|---|---| -| `_call_generic_ctor(node)` | 泛型类构造 `list[int](pool, n)` | -| `_call_binop_cast(node)` | `(A|t.CPtr)(val)` / 新写法 `T*(val)` BinOp 强转 | -| `_call_c_special(node)` | `c.Deref/Addr/Set/Load/Asm/LLVMIR/CIf/CIfdef` 系列 | -| `_call_stdarg(node)` | `va_arg/arg/va_start/va_end` | -| `_call_builtin_cast(node)` | `str/bytes/int/bool(x)` | -| `_call_t_cast(node)` | `t.CInt(x)` / `t.CVoid(x, CPtr)` / 裸名 typedef | -| `_call_class_sizeof(node)` | `ClassName.__sizeof__()` | -| `_call_method(node)` | `self.field.method(...)` / `(expr).method(...)` | -| `_call_plain(node)` | 普通函数/跨模块调用 | - -## 6. 迁移计划总表 - -| 阶段 | 内容 | 产出 | 验证 | -|---|---|---|---| -| P0 | llvmlite 方法化 + 兼容层 | Builder/Module 方法化 | bootstrap + 全回归(IR 零差异) | -| P1 | Generator 骨架 + trans 字段迁入 | `Gen/Generator.vp` 空状态对象 | bootstrap | -| P2 | TypeGen / StructGen | 2 个 Mixin 文件 | bootstrap | -| P3 | ExprGen(含 ExprOps) | 1-2 个 Mixin | bootstrap | -| P4 | CallGen(拆 7043 行) | 9 个方法簇 | bootstrap | -| P5 | FuncGen / ClassGen / StmtGen / ImportsGen | 4 个 Mixin | bootstrap | -| P6 | 删除 Handles 壳 / 兼容层 / ast visitor(可选) | 收尾 | bootstrap + 全回归 | - -**每阶段验收**:bootstrap 编译通过 → 全 Test 项目编译通过 → `.text.ll` 与基线 diff 为空(或仅行号差异)。 - -## 7. 风险与对策 - -| 风险 | 对策 | -|---|---| -| `novirtual` + 硬编码 SIZE 布局 | 方法化不改布局;Generator 用 `virtual`(数据类保持 novirtual) | -| 跨模块 stub 访问器 | 方法化后保留访问器(消除依赖编译器缺陷修复,延后) | -| Viper 循环 import | 保持现有"延迟 import"模式 | -| 迁移引入行为差异 | 每阶段 `.text.ll` 基线 diff 校验 | -| REnum LLVMType 误转继承 | 明确保持 REnum 构造模式 | -| 工作量/回归风险 | 纯移动优先(P0-P5),语义重构仅 P6(可选) | - -## 8. 验收标准(最终) - -1. TPV bootstrap 编译通过(三重编译流程) -2. 全部 Test 项目编译 + 运行通过 -3. IR 输出与基线一致(无行为变化) -4. `HandlesExprCall.vp` 7043 行 → `CallGen` 各方法簇 < 1500 行 -5. 所有 Handles 调用不再六参连传(`self` 持状态)