U10 定案:寄存器/调用约定维持 + 栈方案 C(预分配栈区 + max_stack 编译期算 + 双检查 + 递归编译期报错)

- §2.2 修正:256 = 寻址上限(非每帧分配数);帧按 nregs 动态分配
- 新增调用栈设计:max_stack@116(调用图最坏路径)、预分配零分配、
  字节/深度双检查、MAIN 帧常驻
- 递归 = 链接层环检测编译期报错(link error: recursive call)
- 编译器优化.md:max_stack 计算职责 + Linker 环检测
- §9.2 U10 闭合;影响面/决策历史同步
This commit is contained in:
2026-08-24 16:00:45 +08:00
parent 44370c448e
commit 6869624f09
2 changed files with 26 additions and 8 deletions
+19 -7
View File
@@ -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 V2type 表 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 @112v1=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 | **寄存器 int648B)不变 + 调用约定 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 已写 | 确认 / 改 |