From 6869624f097c91b59909ecb34436014f702ce9d4 Mon Sep 17 00:00:00 2001 From: chentianya Date: Mon, 24 Aug 2026 16:00:45 +0800 Subject: [PATCH] =?UTF-8?q?U10=20=E5=AE=9A=E6=A1=88=EF=BC=9A=E5=AF=84?= =?UTF-8?q?=E5=AD=98=E5=99=A8/=E8=B0=83=E7=94=A8=E7=BA=A6=E5=AE=9A?= =?UTF-8?q?=E7=BB=B4=E6=8C=81=20+=20=E6=A0=88=E6=96=B9=E6=A1=88=20C?= =?UTF-8?q?=EF=BC=88=E9=A2=84=E5=88=86=E9=85=8D=E6=A0=88=E5=8C=BA=20+=20ma?= =?UTF-8?q?x=5Fstack=20=E7=BC=96=E8=AF=91=E6=9C=9F=E7=AE=97=20+=20?= =?UTF-8?q?=E5=8F=8C=E6=A3=80=E6=9F=A5=20+=20=E9=80=92=E5=BD=92=E7=BC=96?= =?UTF-8?q?=E8=AF=91=E6=9C=9F=E6=8A=A5=E9=94=99=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - §2.2 修正:256 = 寻址上限(非每帧分配数);帧按 nregs 动态分配 - 新增调用栈设计:max_stack@116(调用图最坏路径)、预分配零分配、 字节/深度双检查、MAIN 帧常驻 - 递归 = 链接层环检测编译期报错(link error: recursive call) - 编译器优化.md:max_stack 计算职责 + Linker 环检测 - §9.2 U10 闭合;影响面/决策历史同步 --- Doc/compiler/编译器优化.md | 8 +++++++- Doc/isa/指令集优化.md | 26 +++++++++++++++++++------- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/Doc/compiler/编译器优化.md b/Doc/compiler/编译器优化.md index bad5742..b0c4868 100644 --- a/Doc/compiler/编译器优化.md +++ b/Doc/compiler/编译器优化.md @@ -51,6 +51,12 @@ - **值段**:紧凑变宽布局,对齐规则 1/2/8 字节(BOOL 1 / INT 2 / TIME·LREAL·LWORD·ULINT·LINT 8 / REAL·DWORD·UDINT·DINT 4),**对齐由编译器保证**,VM 从 type 位段已知宽度 - 初值写值段(编译期 layout);结构体 = 值区连续字段块(元数据段字段表,v1 预留) +### 3.3b 调用栈与递归(U10 方案 C) + +- **递归 = 编译期错误**:链接层对 FUNCTION 调用图做环检测(自调用/循环调用)→ `link error: recursive call`(V1 用例 19 已是负例,V2 明确为编译期错误) +- **max_stack 计算**(链接层/Codegen 职责):无环调用图 → 最坏调用路径 Σ(帧头 12B + 各函数 nregs×8),写入映像头 @116 +- VM 按 max_stack 预分配栈区(运行期零分配);溢出双检查(字节 + 深度 64) + ### 3.4 变长指令对 codegen 的影响 - **跳转回填改字节单位**:`patch_jump` 按字节(off32,相对下一条),pc/code_offset/code_len 全字节化 @@ -84,7 +90,7 @@ | Lexer | 类型关键字扩展(19)、进制前缀 + 浮点字面量 | | Parser | 类型引用、字面量 AST | | Typecheck | 禁隐式转换(严格一致)+ 字面量上下文适配、19 类型元数据 | -| Linker | 槽表条目分配(addr:u32)、FB 实例字段偏移 | +| Linker | 槽表条目分配(addr:u32)、FB 实例字段偏移、**调用图环检测(递归报错)+ max_stack 计算** | | Codegen | E_* 变长发射、字节化回填、槽表+值区 layout、FB 共享体(16B 变体) | | MachineConfig / machine.toml | type 表 19 条(base/width/signed/tag)、前缀分区/func 位段校验 | diff --git a/Doc/isa/指令集优化.md b/Doc/isa/指令集优化.md index 57bfd4a..570ed67 100644 --- a/Doc/isa/指令集优化.md +++ b/Doc/isa/指令集优化.md @@ -52,12 +52,22 @@ - **字段访问统一为 LOAD/STORE 16B 变体**:`LOAD rd, slot, off32`(基槽 + 偏移,编译期算死)——结构体字段与 FB 共享体字段**同一指令**,无单独 LOADF - **跳转偏移字节化**:off32(字节,相对下一条);pc/code_offset/code_len 全字节单位;code 段 16 字节对齐 -### 2.2 寄存器模型(维持现状) +### 2.2 寄存器模型与调用栈(U10 定案) -- **寄存器编号 = 1 字节(8 位)→ 256 个/帧**(定长) -- 编号容量恒定关系:`8bit×256 == 16bit×128 == 32bit×64 == 64bit×32`(编号位宽 × 数量反比,总容量恒定) +- **寄存器编号 = 1 字节(8 位)→ 256 个为寻址上限**(8 位字段能编的最大寄存器号),**不是每帧分配数** +- **每帧按函数头 nregs 动态分配**(编译器按该函数变量+临时峰值算):帧大小 = nregs × 8B(百字节级),栈深 64 上限 +- 编号容量恒定关系:`8bit×256 == 16bit×128 == 32bit×64 == 64bit×32`(指编号位宽 × 数量反比,编号空间,非帧大小) - 寄存器值仍 8 字节(int64);codegen `register overflow (>256)` 检查保留 -- 调用约定不变:r0 结果、r1..r7 参数、r8+ 变量/临时 +- 调用约定不变:r0 结果、r1..r7 参数(≤7)、r8+ 变量/临时;CALL/RET 帧复制 = **r0..r7 全宽(64B)**,类型解释是下游指令按 func 的事 + +#### 调用栈(方案 C:预分配栈区,U10 定案) + +- **无递归**:链接层检测调用图环(FUNCTION 自调用/循环调用)→ **编译期报错**(`link error: recursive call`);无环 → 最坏调用路径编译期可算 +- **max_stack 编译期计算**:最坏调用路径 Σ(帧头 12B + nregs×8),写入映像头(@116) +- **预分配栈区**:Machine 构造时一次性分配 max_stack 字节连续内存,运行期零分配 +- **压帧**:从栈顶取 nregs×8 + 帧头(12B),sp += 帧需求;**弹帧**:sp -= 帧需求 +- **溢出检查双口径**:剩余栈 < 帧需求 → `StackOverflow`(字节主检查)+ 深度 ≤64(双保险) +- **MAIN 帧常驻栈底**(跨周期保留),周期结束回退 sp 到 MAIN 帧顶 ### 2.3 数据模型:槽表(引用)→ 值区(数据) @@ -114,7 +124,8 @@ 104 n_slots ← 槽表条目数(= n_globals + FB 实例/结构体字段槽数) 108 values_size ← 值段字节数(原 n_values,命名修正) 112 offset_meta ← 元数据段偏移(v1 恒 0 = 空段;结构体/字符串类型表预留) -116..127 预留 12 字节 +116 max_stack ← 栈区字节数(编译期按调用图算,U10 方案 C) +120..127 预留 8 字节 ``` 段序:头 → 常量表 → 函数表 → 字节码 → 槽表段 → 值段 → 元数据段(v1 空) → SHA-256 尾 @@ -227,7 +238,7 @@ V2 的 op 位段仅 6 位(64 个),FB 占 8 个不划算,且 machine.toml |---|---| | isa | Op.h 重排(位域)、Instr.h 变长 pack/拆、Encode disasm 表驱动、Types 宽度/符号表 + 饱和模板化 | | compiler | machine.toml V2(type 表 19 条 + fmt/type 位段互锁)、MachineConfig 校验、Codec 变长、Codegen(槽表+值区布局、初值写值段、E_* 变长发射、字节化回填)、Stb 新头/段 | -| vm | Image 新头/段校验、Machine 取指变长 + 两级访问(槽表→值区)+ 按 type 读写 | +| vm | Image 新头/段校验、Machine 取指变长 + 两级访问(槽表→值区)+ 按 func 读写 + **预分配栈区**(max_stack,替代动态 vector frames) | | executor | slot_bool 按 BOOL 读 1 字节(小改) | | tests | isa/vm/machine/codegen/compiler 全部重写;cases 20 个重新生成产物 | | docs | 指令与映像、指令配置、stb文件格式、寄存器码、指令执行(line1 推演重算)、扫描周期、初步计划、README | @@ -264,6 +275,7 @@ V2 的 op 位段仅 6 位(64 个),FB 占 8 个不划算,且 machine.toml - U7 定案:头 128B 修正版(offset_meta 占位、values_size 命名、n_i/n_q/n_m 保留恒 0、n_slots 关系、16 对齐) - U8 定案:槽表条目 {addr:u32, 预留:u32} 8B - U9 定案:值段 1/2/4/8B 对齐编译器保证 +- U10 定案:寄存器/调用约定维持现状、帧按 nregs 动态分配;栈方案 C(预分配栈区 + max_stack@116 编译期算 + 字节/深度双检查);递归 = 链接层环检测编译期报错 - A10 定案(B1/B2):1 CAL + fb_id 16 位(查 [[fb]] 表);V1 的 8 个 CAL_* opcode 作废 - B4 定案:领域指令(运动控制/通信)不进指令集,一律 FB 库;无 EXT 服务指令 - B3/B5 说明中待确认:单/双字计数编码(CAL type 位段)、op 位段预算 @@ -318,7 +330,7 @@ V2 的 op 位段仅 6 位(64 个),FB 占 8 个不划算,且 machine.toml | ~~U7~~ | ~~头 128 字节布局~~ | **已定案(修正版)**:17 字段表述、values_size 命名、offset_meta @112(v1=0)、n_i/n_q/n_m 保留恒 0、n_slots 关系定义、16 对齐(见 §2.5 注记) | | ~~U8~~ | ~~槽表条目格式~~ | **已定案**:{addr:u32, 预留:u32} 8B/条(引用表,地址指向值段) | | ~~U9~~ | ~~值段对齐~~ | **已定案**:1/2/4/8B 对齐由编译器布局保证(值段起点 16 对齐,见 U7) | -| U10 | **寄存器值 int64(8B)不变 + 调用约定 r0..r7 不变** | §2.2 已写 | 确认 / 改 | +| ~~U10~~ | ~~寄存器与调用栈~~ | **已定案**:寄存器 int64 不变;调用约定不变;CALL/RET 全宽复制;帧按 nregs 动态分配(§2.2 表述修正);栈方案 C(预分配 + max_stack@116 + 字节/深度双检查 + 递归编译器报错) | | ~~U11~~ | ~~CAL 编码布局~~ | **已定案**:010 101 分区,操作数区 fb_id16=31..16 + slot32=63..32 | | U12 | **C1 元数据段**:v1 定 0 长度占位、schema 延后 | §4 建议 | 确认 / 改 | | U13 | **DATE/TOD/DT 表示**(uint32 天 / uint32 当日ms / uint64) | §2.4 已写 | 确认 / 改 |