文档同步:machine.toml 配置驱动架构收尾。

- README.md:依赖方向(STCompiler→compiler 不链 isa)、模块表、isa 归执行器侧、
  数据流图(machine.toml + 型号/SHA)
- isa/README.md:重写——只管指令定义(Types/Op/Instr/Encode),删 Image 部分
- 指令与映像.md:依赖图与 CMake(compiler 不链 isa)
- 编译管线.md:管线首步加载 machine.toml、产物含型号/SHA
- 初步计划.md:12.10/12.13 修订(--machine、依赖方向)
- 扫描周期.md / 指令执行.md:12.9 步骤标注已落地、vm 读校验说明
- compiler/vm/executor README:依赖与边界同步
This commit is contained in:
2026-08-21 22:39:27 +08:00
parent 1168f5ae30
commit 6873b5ee0b
10 changed files with 76 additions and 158 deletions
+8 -7
View File
@@ -1,27 +1,28 @@
# 编译管线 # 编译管线
compiler 模块:ST / toml 编译器。CMake 目标:`compiler``STATIC`),依赖 [`指令与映像.md`](../isa/指令与映像.md)。可执行入口 `STCompiler`(本模块 `src/main.cpp`,链 `compiler` + `isa`)。 compiler 模块:ST / toml 编译器。CMake 目标:`compiler``STATIC`),**不依赖 isa**(指令 opcode / 类型元数据 / FB 布局来自 `compiler/machine.toml`,见 [`指令配置.md`](../isa/指令配置.md)。可执行入口 `STCompiler`(本模块 `src/main.cpp`,链 `compiler`)。
读齐工程后走直通 pass,产出单一映像文件,不上 LLVM。词法、语法、符号表、检查、codegen、链接都留在本库,不再拆 CMake 子库。 读齐工程后走直通 pass,产出单一映像文件,不上 LLVM。词法、语法、符号表、检查、codegen、链接都留在本库,不再拆 CMake 子库。
语言规则、toml 字段、链接与第 12 节阶段见 [`初步计划.md`](../初步计划.md)。指令和映像只认 [`指令与映像.md`](../isa/指令与映像.md)。 语言规则、toml 字段、链接与第 12 节阶段见 [`初步计划.md`](../初步计划.md)。`.stb` 格式契约见 [`指令与映像.md`](../isa/指令与映像.md)compiler 自带写实现 + 型号标识/SHA-256)
## 管线 ## 管线
```text ```text
读 toml、收齐 .st 加载 machine.toml--machine,强校验)
→ 读 toml、收齐 .st
→ 词法 / 递归下降语法 → 词法 / 递归下降语法
→ 收集导出符号 → 收集导出符号
→ 解析 VAR_EXTERNAL、链接、定地址 → 解析 VAR_EXTERNAL、链接、定地址
→ 类型检查 → 类型检查
→ 按 PROGRAM / FUNCTION / FB 编寄存器码 → 按 PROGRAM / FUNCTION / FB 编寄存器码opcode/类型/FB 布局查配置)
→ 回填跳转、写映像头与工程哈希 → 回填跳转、写映像头与工程哈希
→ 写 <name>.stb映像)与 <name>.runtime.tomlsidecario 绑定) → 写 <name>.stb头 104 含型号标识 + 段 + SHA-256 文件尾)与 <name>.runtime.tomlsidecario 绑定)
``` ```
## 边界 ## 边界
- toml **不声明变量**`VAR_GLOBAL` 第一版只允许出现在 `gvl.file` - toml **不声明变量**`VAR_GLOBAL` 第一版只允许出现在 `gvl.file`
- `[[io.*]]``var` 必须已在 GVL 中;同名全局链接失败 - `[[io.*]]``var` 必须已在 GVL 中;同名全局链接失败
- 第三方 toml 解析放 `third_party/`,本库私有链接 - 第三方 toml 解析toml++`third_party/`,本库私有链接
- 不写扫描周期,不链 `vm` - 不写扫描周期,不链 `vm`、不链 `isa`
+6 -6
View File
@@ -2,16 +2,16 @@
isa 模块规范:指令集 + 映像 + 定宽类型。不是编译器,不把 `.st` 编成映像。 isa 模块规范:指令集 + 映像 + 定宽类型。不是编译器,不把 `.st` 编成映像。
`compiler` 按本文件写出字节,`vm` 只认这些字节。两边不互链 `compiler` `.stb``vm``.stb`,两边**各自实现**读写;`isa` 归执行器侧只管指令定义。指令 opcode / 类型 / FB 布局的登记见 [`指令配置.md`](指令配置.md)`compiler/machine.toml`,与代码强校验)
全工程定案见 [`初步计划.md`](../初步计划.md)。**类型、指令编码、映像布局以本文为准**,不要另写一份互相打架的表。头文件实现本文,不另当规范。 全工程定案见 [`初步计划.md`](../初步计划.md)。**类型、指令编码、映像布局以本文为准**,不要另写一份互相打架的表。头文件实现本文,不另当规范。
```text ```text
STCompiler → compiler → isa STCompiler → compiler (编码查 machine.toml;自带 .stb 写)
BytecodeExecutor → vm → isa BytecodeExecutor → vm → isa isa 只管指令;vm 自带 .stb 读)
``` ```
CMake 目标:`isa``STATIC`),无依赖。公开头:`isa/include/isa/` CMake 目标:`isa``STATIC`),无依赖`vm` PUBLIC 链 `isa`。公开头:`isa/include/isa/`
--- ---
@@ -240,11 +240,11 @@ isa/
``` ```
```cmake ```cmake
add_library(isa STATIC src/Encode.cpp src/Image.cpp) add_library(isa STATIC src/Encode.cpp)
target_include_directories(isa PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) target_include_directories(isa PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
``` ```
`compiler` / `vm``target_link_libraries(... PUBLIC isa)` `vm``target_link_libraries(vm PUBLIC isa)``compiler` 不链 `isa`
--- ---
+10 -9
View File
@@ -15,7 +15,8 @@ vm 模块:寄存器虚拟机。CMake 目标:`vm``STATIC`),只依赖 [
## 边界 ## 边界
- 只认 `isa` 映像;类型与溢出按 [`指令与映像.md`](../isa/指令与映像.md)`INT` 饱和) - 只认 `.stb` 映像`vm` 自带读实现);读取时**型号标识匹配 + SHA-256 校验**,不符/篡改 → 拒绝
- 类型与溢出按 [`指令与映像.md`](../isa/指令与映像.md)`INT` 饱和);指令定义归 `isa`
- 局部 / `VAR` = 固定寄存器;`nregs` 在函数头 - 局部 / `VAR` = 固定寄存器;`nregs` 在函数头
- `CALL` 目标是立即数 `fn_id`,有界调用栈 - `CALL` 目标是立即数 `fn_id`,有界调用栈
- 无 GC、无堆、无线程;每周期受 `cycle_limit` 限制 - 无 GC、无堆、无线程;每周期受 `cycle_limit` 限制
@@ -63,7 +64,7 @@ VM 需要无歧义地访问数据区,当前变宽布局(BOOL 1B / INT 2B / T
- `Codegen.cpp` 简化:`width_of`/`align_up` 删除、`layout_data`/`layout_fb_instances` 按槽号布局、指令 slot = 符号表槽号 - `Codegen.cpp` 简化:`width_of`/`align_up` 删除、`layout_data`/`layout_fb_instances` 按槽号布局、指令 slot = 符号表槽号
- `codegen_test` 断言更新(slot 从字节偏移变槽号、数据区字节数变化) - `codegen_test` 断言更新(slot 从字节偏移变槽号、数据区字节数变化)
### 步骤 1`Machine.h`新建 `vm/include/vm/Machine.h` ### 步骤 1`Machine.h`已落地 `vm/include/vm/Machine.h`
```cpp ```cpp
namespace vm { namespace vm {
@@ -83,32 +84,32 @@ namespace vm {
``` ```
- `Fault` 枚举 + 帧结构 `{ fn_id, regs[nregs], ret_pc, ret_fn_id }`;调用栈深度上限 64 - `Fault` 枚举 + 帧结构 `{ fn_id, regs[nregs], ret_pc, ret_fn_id }`;调用栈深度上限 64
- 只依赖 `isa``ImageView` + 类型/饱和函数 - 只依赖 `isa`指令定义)+ 自带 `vm::Image`.stb 读
### 步骤 2`Machine.cpp` 译码 switch ### 步骤 2`Machine.cpp` 译码 switch(已落地)
- 取指:函数表 → `code_offset`(字节)→ 读 u32 → 拆 `op/rd/a/b` - 取指:函数表 → `code_offset`(字节)→ 读 u32 → 拆 `op/rd/a/b`
- 标量:`MOVE` / `LOADK`(常量表 tag 定值表示)/ `NOT` / `AND` / `OR`(布尔)/ `ADD/SUB/MUL/DIV``sat_*`/ `CMP_xx`(全宽比较) - 标量:`MOVE` / `LOADK`(常量表 tag 定值表示)/ `NOT` / `AND` / `OR`(布尔)/ `ADD/SUB/MUL/DIV``sat_*`/ `CMP_xx`(全宽比较)
- 跳转:`JMP` / `JT` / `JF``pc += off`,相对下一条语义) - 跳转:`JMP` / `JT` / `JF``pc += off`,相对下一条语义)
- 数据区:`LOAD_I/LOAD_M/LOAD_GLOBAL``STORE_Q/STORE_M/STORE_GLOBAL`(同一实现,slot × 8 - 数据区:`LOAD_I/LOAD_M/LOAD_GLOBAL``STORE_Q/STORE_M/STORE_GLOBAL`(同一实现,slot × 8
### 步骤 3CALL / RET 帧栈 + 故障 ### 步骤 3CALL / RET 帧栈 + 故障(已落地)
- `CALL fn_id`:压新帧(复制 r0..r7)→ pc=0`RET`:复制 r0..r7 回调用方 → 弹栈(MAIN 的 RET = 周期结束) - `CALL fn_id`:压新帧(复制 r0..r7)→ pc=0`RET`:复制 r0..r7 回调用方 → 弹栈(MAIN 的 RET = 周期结束)
- `cycle_limit` 超限(用例 6)、栈深 > 64、`BadOp` / `BadSlot` / `BadConst` → 周期中止返回故障 - `cycle_limit` 超限(用例 6)、栈深 > 64、`BadOp` / `BadSlot` / `BadConst` → 周期中止返回故障
### 步骤 4:定时器与边沿(8 个 CAL_* ### 步骤 4:定时器与边沿(已落地
- 执行时用映像 `dt_ms` 推进(每周期一次调用 = 推进一次),不读系统时钟 - 执行时用映像 `dt_ms` 推进(每周期一次调用 = 推进一次),不读系统时钟
- TONin 真 → et += dt(到 pt 停)、q = et ≥ ptin 假 → et = 0 - TONin 真 → et += dt(到 pt 停)、q = et ≥ ptin 假 → et = 0
- TOFin 真 → q=1、et=0;掉电 → et += dt、et ≥ pt → q=0 - TOFin 真 → q=1、et=0;掉电 → et += dt、et ≥ pt → q=0
- CTUcu 上升沿(**上次 cu 存 VM 侧 vector**,按实例基槽索引)→ cv+1r → 复位;q = cv ≥ pv - CTUcu 上升沿(**上次 cu 存 VM 侧 vector**,按实例基槽索引)→ cv+1r → 复位;q = cv ≥ pv
### 步骤 5:可观察性基础 ### 步骤 5:可观察性基础(已落地)
- `step()` / `pc` / `fn_id` / `cycle_count` / `call_depth` / `reg` 落基础实现;`snapshot()` 留 12.11 补全 - `step()` / `pc` / `fn_id` / `cycle_count` / `call_depth` / `reg` 落基础实现;`snapshot()` 留 12.11 补全
### 步骤 6`vm_test``tests/src/vm_test.cpp` + CMake,链 `vm` 库 ### 步骤 6`vm_test`已落地
- 手工拼小映像(`isa` 编码函数):赋值、跳转、CALL/RET 帧复制、cycle_limit - 手工拼小映像(`isa` 编码函数):赋值、跳转、CALL/RET 帧复制、cycle_limit
- 编译器产物全链路:用例 01/02/04/05/07/09/13/15/17/18/20 跑周期断言寄存器与数据区 - 编译器产物全链路:用例 01/02/04/05/07/09/13/15/17/18/20 跑周期断言寄存器与数据区
@@ -116,6 +117,6 @@ namespace vm {
- TONdt=10、pt=30 → 第 3 周期 q=1CTU:上升沿计数 - TONdt=10、pt=30 → 第 3 周期 q=1CTU:上升沿计数
- **确定性**:同一 I 序列跑两遍,数据区完全一致 - **确定性**:同一 I 序列跑两遍,数据区完全一致
### 步骤 7:验证 + 提交 ### 步骤 7:验证 + 提交(已落地,ctest 14/14
- `cmake --build` + `ctest`(新增 `vm_cycles` 后 10/10 全绿);20 用例扫描:14 正例执行通过 - `cmake --build` + `ctest`(新增 `vm_cycles` 后 10/10 全绿);20 用例扫描:14 正例执行通过
+3
View File
@@ -5,6 +5,9 @@
## 执行模型 ## 执行模型
```text ```text
加载(Machine::create):解析 .stb(vm 自读实现)→ 型号匹配(内建 STATOR1)→ SHA-256 校验
任一不符 → 直接拒绝(不创建机器)
每个扫描周期(run_cycle): 每个扫描周期(run_cycle):
1. pc = 0,从入口函数(MAIN)开始逐条执行 1. pc = 0,从入口函数(MAIN)开始逐条执行
2. 执行到 MAIN 的 RET → 周期结束 2. 执行到 MAIN 的 RET → 周期结束
+11 -7
View File
@@ -530,17 +530,21 @@ CMake 三个库能空编译:`isa`、`compiler`、`vm`;两个可执行 `STCom
编译与执行拆成两个可执行,映像 `.stb` 是中间产物: 编译与执行拆成两个可执行,映像 `.stb` 是中间产物:
```text ```text
STCompiler <project.toml> -o <name>.stb # 编译:读 toml + .st → 映像 + sidecar STCompiler <project.toml> -o <name>.stb --machine <machine.toml>
BytecodeExecutor <name>.stb [--cycles N] # 执行:加载 .stb + sidecar,跑 N 周期 BytecodeExecutor <name>.stb [--cycles N]
``` ```
- `STCompiler``compiler` + `isa``BytecodeExecutor``vm` + `isa`**不链 `compiler`**。 - `STCompiler``compiler`**不链 `isa`**,编码查 `machine.toml``BytecodeExecutor``vm` + `isa`**不链 `compiler`**。
- 产物两个文件:`<name>.stb`映像,魔数 `STSC`+ `<name>.runtime.toml`sidecarI/O 绑定 var → 槽号 → channel/bit)。`[[io.*]]` 不进映像,sidecar 由 STCompiler 生成,不创造变量。 - 产物两个文件:`<name>.stb`头 104 含型号标识 + 段 + SHA-256 文件尾+ `<name>.runtime.toml`sidecarI/O 绑定 var → 槽号 → channel/bit)。`[[io.*]]` 不进映像,sidecar 由 STCompiler 生成,不创造变量。
- `dt_ms` / `cycle_limit` 从映像头取,sidecar 不重复配置。 - `dt_ms` / `cycle_limit` 从映像头取,sidecar 不重复配置。
- 执行器读取时**型号匹配 + SHA-256 校验**,不匹配/篡改 → 拒绝。
- 最小可观测:BytecodeExecutor 打印本周期 I/Q,或把寄存器/映像 dump 出来。 - 最小可观测:BytecodeExecutor 打印本周期 I/Q,或把寄存器/映像 dump 出来。
- 回放:读预先录制的 I 序列(文本即可),不接真实硬件。 - 回放:读预先录制的 I 序列(文本即可),不接真实硬件。
完成:`STCompiler examples/line1/project.toml -o line1.stb` 产出两个文件;`BytecodeExecutor line1.stb` 能跑若干周期。 完成:`STCompiler examples/line1/project.toml -o line1.stb --machine compiler/machine.toml` 产出两个文件;`BytecodeExecutor line1.stb` 能跑若干周期。
> 12.13 修订:指令 opcode / 类型 / FB 布局的登记移入 `compiler/machine.toml`(见 [`指令配置.md`](isa/指令配置.md)),
> `STCompiler` 编译路径必填 `--machine`。
--- ---
@@ -575,8 +579,8 @@ BytecodeExecutor <name>.stb [--cycles N] # 执行:加载 .stb + sidecar
### 12.13 依赖方向(全程遵守) ### 12.13 依赖方向(全程遵守)
```text ```text
STCompiler → compiler → isa STCompiler → compiler (编码查 machine.toml;自带 .stb 写)
BytecodeExecutor → vm → isa BytecodeExecutor → vm → isa isa 只管指令;vm 自带 .stb 读)
``` ```
- 指令或映像布局有变:先改 `isa` 和编解码测试,再改两端。 - 指令或映像布局有变:先改 `isa` 和编解码测试,再改两端。
+14 -14
View File
@@ -5,14 +5,14 @@
方案见 [`Doc/初步计划.md`](Doc/初步计划.md),模块文档见 [`Doc/索引.md`](Doc/索引.md)。 方案见 [`Doc/初步计划.md`](Doc/初步计划.md),模块文档见 [`Doc/索引.md`](Doc/索引.md)。
```text ```text
多个 .st 多个 .st + machine.toml(指令/类型/FB 布局)
↑ project.toml 列出 ↑ project.toml 列出源文件;machine.toml 唯一事实来源
STCompilercompiler 库:词法 / 语法 → 符号表 → 类型检查 → 寄存器码 → 链接) STCompilercompiler 库:词法 / 语法 → 符号表 → 类型检查 → 寄存器码 → 链接;编码查 machine.toml
<name>.stb 映像 + <name>.runtime.toml sidecar <name>.stb 映像(头 104 含型号标识 + 段 + SHA-256 文件尾)+ <name>.runtime.toml sidecar
BytecodeExecutorvm 库按扫描周期执行;喂 I、收 Q、给 Δt、回放) BytecodeExecutorvm 库按扫描周期执行;型号/SHA 校验;喂 I、收 Q、给 Δt、回放)
``` ```
## 目录 ## 目录
@@ -40,33 +40,33 @@ BytecodeExecutorvm 库按扫描周期执行;喂 I、收 Q、给 Δt、回
## 模块与 CMake 目标 ## 模块与 CMake 目标
三个静态库与两个可执行,与目录一一对应。`compiler``vm` 不互相链接,合同放在 `isa`。依赖方向:`STCompiler → compiler → isa``BytecodeExecutor → vm → isa` 三个静态库与两个可执行,与目录一一对应。`compiler``vm` 不互相链接。指令/类型/FB 布局的**唯一事实来源是 `compiler/machine.toml`**(编译器运行时加载);`isa` 归执行器侧(`vm` 依赖),只管指令定义。依赖方向:`STCompiler → compiler``BytecodeExecutor → vm → isa`
| 目录 | 目标 | 类型 | 依赖 | 职责 | | 目录 | 目标 | 类型 | 依赖 | 职责 |
|---|---|---|---|---| |---|---|---|---|---|
| `isa/` | `isa` | `STATIC` | 无 | 约 20 条指令编码、映像头、工程哈希、`BOOL` / `INT` / `TIME` 宽度 | | `isa/` | `isa` | `STATIC` | 无 | 指令定义(Op/Instr/Encode/Types/饱和/disasm),**归执行器侧** |
| `compiler/` | `compiler` | `STATIC` | `isa` | 读 toml、收齐 `.st`、解析、链接、定址、类型检查、编寄存器码、写映像 | | `compiler/` | `compiler` | `STATIC` | toml++(私有) | 读 toml、收齐 `.st`、解析、链接、定址、类型检查、编寄存器码、写 `.stb`(指令 opcode/类型/FB 布局全部来自 `machine.toml` |
| `vm/` | `vm` | `STATIC` | `isa` | 一台 VM、一个入口、一份映像;扫描周期、寄存器、FB、有界 `CALL` / `RET` | | `vm/` | `vm` | `STATIC` | `isa` | 一台 VM、一个入口、一份映像;扫描周期、寄存器、FB、有界 `CALL` / `RET`;自带 `.stb` 读实现 + 型号/SHA-256 校验 |
| `compiler/` | `STCompiler` | `EXECUTABLE` | `compiler``isa` | `STCompiler <project.toml> -o <name>.stb`:编译并写映像 + sidecar`--disasm` 可反汇编 | | `compiler/` | `STCompiler` | `EXECUTABLE` | `compiler` | `STCompiler <project.toml> -o <name>.stb --machine <machine.toml>`:编译并写映像 + sidecar`--disasm` 可反汇编 |
| `executor/` | `BytecodeExecutor` | `EXECUTABLE` | `vm``isa` | `BytecodeExecutor <name>.stb`:加载映像 + sidecar,采样 I、执行 `PROGRAM MAIN`、写回 Q、用 Δt 推进定时器 / 计数器、回放 | | `executor/` | `BytecodeExecutor` | `EXECUTABLE` | `vm``isa` | `BytecodeExecutor <name>.stb`:加载映像 + sidecar,采样 I、执行 `PROGRAM MAIN`、写回 Q、用 Δt 推进定时器 / 计数器、回放 |
词法、语法、符号表、检查、codegen、链接都留在 `compiler` 一个库里,不再拆 CMake 子库。 词法、语法、符号表、检查、codegen、链接都留在 `compiler` 一个库里,不再拆 CMake 子库。
### `isa` ### `isa`
编译器写映像、虚拟机读映像,两边共用同一套编码。放这里避免循环依赖 归执行器侧(`vm` 依赖),**只管指令定义**:Op 枚举 / Instr 打包 / Encode(编解码·disasm/ Types(饱和)。执行器执行 switch 在 `vm`
### `compiler` ### `compiler`
toml **不声明变量**,只列出源文件、指定唯一 GVL、可选地把已有全局接到硬件。`VAR_GLOBAL` 第一版只允许出现在 `gvl.file`(如 `globals.st`)。 toml **不声明变量**,只列出源文件、指定唯一 GVL、可选地把已有全局接到硬件。`VAR_GLOBAL` 第一版只允许出现在 `gvl.file`(如 `globals.st`)。指令 opcode / 类型元数据 / FB 布局**全部来自 `compiler/machine.toml`**`STCompiler --machine` 加载,强校验后编译)。
### `vm` ### `vm`
每个扫描周期:采样 I → 从 `PROGRAM MAIN``pc=0` 执行到 `RET` → 写回 Q → 用本周期 Δt 推进 `TON` / `TOF` / `CTU`。无 GC、无堆、无线程;变量编译期分配 每个扫描周期:采样 I → 从 `PROGRAM MAIN``pc=0` 执行到 `RET` → 写回 Q → 用本周期 Δt 推进内置 FB。无 GC、无堆、无线程;变量编译期分配。读取 `.stb` 时**校验型号标识与 SHA-256**(不匹配/篡改 → 拒绝)
### `executor`BytecodeExecutor ### `executor`BytecodeExecutor
第一版两个可执行:`STCompiler` 编译出 `<name>.stb`映像+ `<name>.runtime.toml`sidecarI/O 绑定);`BytecodeExecutor` 加载后按扫描周期跑。不再有"一条命令编译 + 跑"。`dt_ms` / `cycle_limit` 从映像头取。 `STCompiler` 编译出 `<name>.stb`含型号标识 + SHA-256+ `<name>.runtime.toml`sidecarI/O 绑定);`BytecodeExecutor` 加载后按扫描周期跑。`dt_ms` / `cycle_limit` 从映像头取。
### `examples/` 与 `tests/` ### `examples/` 与 `tests/`
+1 -1
View File
@@ -1,6 +1,6 @@
# compiler # compiler
ST / toml 编译器。CMake 目标:`compiler``STATIC`),依赖 `isa`可执行 `STCompiler` ST / toml 编译器。CMake 目标:`compiler``STATIC`),**不依赖 `isa`**——指令 opcode / 类型元数据 / FB 布局来自 `compiler/machine.toml`(见 [`指令配置.md`](../doc/isa/指令配置.md));自带 `.stb` 写实现。可执行入口 `STCompiler`
- **使用说明**(构建 / 用法 / 工程文件 / ST 子集 / 错误类别):[`doc/compiler/STCompiler使用说明.md`](../doc/compiler/STCompiler使用说明.md) - **使用说明**(构建 / 用法 / 工程文件 / ST 子集 / 错误类别):[`doc/compiler/STCompiler使用说明.md`](../doc/compiler/STCompiler使用说明.md)
- 边界与管线:[`doc/compiler/编译管线.md`](../doc/compiler/编译管线.md) - 边界与管线:[`doc/compiler/编译管线.md`](../doc/compiler/编译管线.md)
+1 -1
View File
@@ -1,5 +1,5 @@
# executor # executor
BytecodeExecutor 模块:可执行入口。CMake 目标:`BytecodeExecutor``EXECUTABLE`),链接 `vm``isa`**不链 `compiler`**。 BytecodeExecutor 模块:可执行入口。CMake 目标:`BytecodeExecutor``EXECUTABLE`),链接 `vm``isa`**不链 `compiler`**。读取 `.stb` 时校验型号标识与 SHA-256。
职责与边界见 [`doc/executor/执行器入口.md`](../doc/executor/执行器入口.md)。 职责与边界见 [`doc/executor/执行器入口.md`](../doc/executor/执行器入口.md)。
+21 -112
View File
@@ -1,15 +1,15 @@
# isa # isa
指令集 + 映像 + 定宽类型。CMake 目标:`isa``STATIC`),无依赖。 **归执行器侧**,只管指令定义。CMake 目标:`isa``STATIC`),无依赖;被 `vm` 依赖。
`compiler` 写映像、`vm` 读映像,两边只依赖本目录,不互链 `compiler` **不依赖 isa**——指令 opcode / 类型元数据 / FB 布局全部来自 `compiler/machine.toml`(见 [`指令配置.md`](../doc/isa/指令配置.md))。`.stb` 映像读写由 `compiler`(写侧)与 `vm`(读侧)**各自实现**
```text ```text
STCompiler → compiler → isa STCompiler → compiler (编码查 machine.toml,自带 .stb 写)
BytecodeExecutor → vm → isa BytecodeExecutor → vm → isa isa 只管指令;vm 自带 .stb 读)
``` ```
**类型、操作码、指令字、映像布局** [`doc/isa/指令与映像.md`](../doc/isa/指令与映像.md) **为准。** 头文件实现该文,本 README 不另当规范。`.stb` 结构面向使用者的拆解见 [`doc/isa/stb文件格式.md`](../doc/isa/stb文件格式.md)。全工程阶段见 [`doc/初步计划.md`](../doc/初步计划.md) 12.012.1 **操作码、指令字以** [`doc/isa/指令与映像.md`](../doc/isa/指令与映像.md) **为准。** 头文件实现该文,本 README 不另当规范。`.stb` 结构拆解见 [`doc/isa/stb文件格式.md`](../doc/isa/stb文件格式.md)。指令/类型/FB 登记见 [`doc/isa/指令配置.md`](../doc/isa/指令配置.md)
公开头:`isa/include/isa/` 公开头:`isa/include/isa/`
@@ -17,139 +17,48 @@ BytecodeExecutor → vm → isa
## 做 / 不做 ## 做 / 不做
**做:** 操作码与 32-bit 指令、映像头与段`BOOL`/`INT`/`TIME`与饱和、编解码、工程哈希、一条指令的文本转储。 **做:** 操作码与 32-bit 指令`BOOL`/`INT`/`TIME` 宽与饱和、编解码、一条指令的文本转储。
**不做:** toml、关键字符号表AST、VM `switch`、扫描周期、I/O 采样。`AND`/`OR` 只组合已算好的值;短路由 `compiler` 编成跳转。 **不做:** 映像读写(compiler/vm 各自实现)、toml/关键字/符号表/AST、VM 执行 switch(在 `vm`、扫描周期、I/O 采样。
--- ---
## 实现步骤 ## 目录与 CMake
原则:先冻合同,再头文件,再 `.cpp`,再最小测试。每步能编过再进下一步。改编码或映像字段时,先改规范文和本模块,再动 `compiler` / `vm`
目标目录(与规范一致):
```text ```text
isa/ isa/
CMakeLists.txt CMakeLists.txt
README.md README.md
include/isa/ include/isa/
Types.h # 宽度、饱和、槽值 Types.h # 宽度、饱和
Op.h # 操作码枚举 + 助记符 Op.h # 操作码枚举 + OpFormat/OpClass + kOpDefs 表 + 助记符
Instr.h # 32-bit 打包/拆字段(inline Instr.h # 32-bit 打包/拆字段(inline
Encode.h # encode / decode / disasm Encode.h # encode / decode / disasm
Image.h # 头、段、FNV、读写缓冲
src/ src/
Encode.cpp Encode.cpp
Image.cpp
``` ```
```cmake ```cmake
add_library(isa STATIC src/Encode.cpp src/Image.cpp) add_library(isa STATIC src/Encode.cpp)
target_include_directories(isa PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) target_include_directories(isa PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
``` ```
`compiler` / `vm``target_link_libraries(... PUBLIC isa)` `vm``target_link_libraries(vm PUBLIC isa)``compiler` 不链 `isa`
--- ---
### 0. CMake 骨架 ## 实现说明
`CMakeLists.txt` `add_subdirectory` `compiler` / `vm` / `executor`。这三个目录若没有 `CMakeLists.txt`,顶层 configure 失败,`isa` 也编不过。 - **`Types.h`**`Bool` = `uint8_t``Int` = `int16_t``Time` = `int64_t`(毫秒,理由见规范文);`sat_add/sub/mul/div`(饱和规则见规范文);`TypeTag`0/1/2`.stb` 常量表契约)
- **`Op.h`**`enum Op : uint8_t`(数值即编码,与 `machine.toml` 强校验一致);`OpFormat`RR/RRR/IMM/SLOT/JMP/JC/CALL/CAL/NONE)与 `OpClass`Plain/Instance);34 条 `kOpDefs{ name, format, cls }``mnemonic/format/op_class` 查表
- **`Encode.cpp`**`encode/decode` 往返 + `disasm`(按 format 表驱动,文本与规范文一致)
本步只让工程能配置、能链,不写业务。 ## 测试
- 写本目录 `CMakeLists.txt`(上面那段即可) `tests/isa_test`(链 `isa`):饱和、操作码冻结值、指令打包、encode/decode 往返、disasm 文本、OpClass 分类。
- `compiler` / `vm`:空 `.cpp` + `PUBLIC``isa`
- `executor``BytecodeExecutor``main` 打印版本,链 `vm``isa``STCompiler` 入口在 `compiler/src/main.cpp`,链 `compiler``isa`
- 根 CMake`enable_testing()`(测试文件下一步再加)
完成:`cmake --build` 过。
---
### 1. 冻合同(先改规范文)
[`指令与映像.md`](../doc/isa/指令与映像.md) 已有助记符和 `[ op:8 | rd:8 | a:8 | b:8 ]`,还缺**数值和映像字节**。头文件不得自己发明一份表。
把下面这些写进规范文,再写代码(细则以该文最终落笔为准):
- 指令字:小端 `uint32_t``op`/`rd`/`a`/`b` 各 8 bit`imm16 = a | (b << 8)``off16` 为有符号、单位是指令条数
- 操作码 0..28 连续赋值,以后只追加不插队
- 各指令操作数字面(`LOADK`/`JMP`/`CALL`/`LOAD_*`/`STORE_*`/`CAL_*`/`RET`
- `INT` 饱和、`INT_MIN / -1`、除零、`BOOL` 只允许 0/1
- FNV-1a 64 的 basis/prime;路径只当排序键,对文件内容 update;空集合 = basis
- 映像魔数 `STSC`、版本 1、头字段偏移与长度、常量表/函数表/FB 表一行的字节
- 第一版可写映像:空槽、空常量表/FB、`MAIN``fn_id=0`)、一条 `RET`
完成:规范文能当唯一合同;本 README 仍只指向它。
---
### 2. `Types.h`
`include/isa/Types.h`inline,无对应 `.cpp`。命名空间 `isa`。C++20;本模块保持简单结构体,不依赖花哨特性。
- `Bool` = `uint8_t``Int` = `int16_t``Time` = `int64_t`(毫秒;理由见规范文)
- `TypeTag``Bool` / `Int` / `Time`
- `sat_add` / `sat_sub` / `sat_mul` / `sat_div`(规则见规范文)
- `pack_bool` / `pack_int` / `pack_time` → 4 字节 cell;对应 unpack
完成:单独包含该头能编译。
---
### 3. `Op.h` + `Instr.h`
- `Op.h``enum Op : uint8_t`,取值与规范文一致;`mnemonic(Op)` 助记符(已在头内落地)
- `Instr.h``typedef uint32_t Instr``pack`、取 `op`/`rd`/`a`/`b``imm16`/`off16`;按形态 `enc_rr` / `enc_rrr` / `enc_imm` / `enc_jmp` / `enc_jc`
完成:能打包/拆开一条 32-bit 指令,不依赖 `.cpp`
---
### 4. `Encode.h` + `Encode.cpp`
`STCompiler --disasm` 和测试往返打印:
- `Decoded { Op op; uint8_t rd, a, b; }`
- `Instr encode(Decoded)` / `Decoded decode(Instr)`
- `disasm(Instr, char* out, size_t cap)`
`disasm` 格式冻在规范文,例如:`RET``MOVE r1, r2``LOADK r0, 3``ADD r1, r2, r3``JMP +4``JT r0, -1``CALL 1``LOAD_I r0, 2``CAL_TON 0`
完成:一条指令能编、能解、能打出一行文本。
---
### 5. `Image.h` + `Image.cpp`
- `fnv1a64` / `fnv1a64_update`
- `ImageView`:只读视图,指向外部缓冲
- `read_image`:校验魔数、版本、头大小、各段不越界、`entry_fn_id` 落在函数表内
- `write_ret_main(cycle_limit, dt_ms, hash)``std::vector<uint8_t>`:空槽 + `MAIN` + 一条 `RET`
- `.stb` 文件读写与 `<name>.runtime.toml` sidecarI/O 绑定 var → 槽号 → channel/bit
小端 `put_*` / `get_*` 只放 `.cpp`,不把 packed struct 当 ABI。本阶段不写完整 `ImageBuilder`(等 codegen)。
完成:能写出并读回「空映像 + 一条 `RET`」。
---
### 6. 最小测试
`tests/` 加一个只链 `isa` 的 CTest 可执行文件(不是第 12.2 节那 20 个用例):
- `RET` / `ADD` / `LOADK` / `JMP -1`encode 后再 decode,字段一致;`disasm` 非空
- `write_ret_main``read_image`:魔数、version=1、`n_funcs=1`、入口是 `RET`
- `fnv1a64` 空输入等于 basis
完成:`ctest` 过上述用例。
---
## 验收 ## 验收
- `cmake --build` 过;`ctest` isa 往返 - `cmake --build` 过;`ctest``isa_roundtrip` 等 14 个用例全绿)
- `compiler` / `vm``#include <isa/...>`,不互相包含 - `vm``#include <isa/...>``compiler` 不引用 `isa`
- 操作码或映像有变:先改 [`指令与映像.md`](../doc/isa/指令与映像.md) + 本目录 + 测试,再改两端 - 操作码有变:先改 `compiler/machine.toml` + 本目录 + 测试,再改两端
+1 -1
View File
@@ -1,5 +1,5 @@
# vm # vm
寄存器虚拟机。CMake 目标:`vm``STATIC`),只依赖 `isa` 寄存器虚拟机。CMake 目标:`vm``STATIC`),只依赖 `isa`(只管指令定义);自带 `.stb` 读实现 + 型号/SHA-256 校验
扫描周期与边界见 [`doc/vm/扫描周期.md`](../doc/vm/扫描周期.md)。 扫描周期与边界见 [`doc/vm/扫描周期.md`](../doc/vm/扫描周期.md)。