From 815eb87a464a54745415864a6106980532a6a349 Mon Sep 17 00:00:00 2001 From: chentianya Date: Fri, 21 Aug 2026 20:12:43 +0800 Subject: [PATCH] =?UTF-8?q?12.9=20=E6=AD=A5=E9=AA=A4=201=EF=BC=9AVM=20?= =?UTF-8?q?=E5=A4=B4=E6=96=87=E4=BB=B6=EF=BC=88API=E3=80=81Fault=20?= =?UTF-8?q?=E6=9E=9A=E4=B8=BE=E3=80=81=E5=B8=A7=E7=BB=93=E6=9E=84=EF=BC=89?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Machine.h:create/run_cycle + 可观察性(step/pc/fn_id/cycle_count/call_depth/data/reg) - Fault:None/CycleLimit/StackOverflow/BadOp/BadSlot/BadConst - 帧 { fn_id, regs[nregs], ret_pc, ret_fn_id },调用栈深度 64,MAIN 帧跨周期保留 - ctu_prev_ 预留(步骤 4);exec_one/do_call/do_ret/do_cal 桩 --- vm/include/vm/Machine.h | 111 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 vm/include/vm/Machine.h diff --git a/vm/include/vm/Machine.h b/vm/include/vm/Machine.h new file mode 100644 index 0000000..ee3a238 --- /dev/null +++ b/vm/include/vm/Machine.h @@ -0,0 +1,111 @@ +/** + * @file Machine.h + * @brief 寄存器虚拟机(12.9) + * @author + * @date 2026-08-21 + * + * @details 设计说明(详见 Doc/vm/扫描周期.md 与 Doc/vm/指令执行.md): + * - 只认 isa 映像(ImageView);无 GC、无堆、无线程 + * - 扫描周期:MAIN pc=0 → RET;MAIN 帧跨周期保留,调用栈深度上限 64 + * - 帧:{ fn_id, regs[nregs], ret_pc, ret_fn_id };CALL 压帧复制 r0..r7, + * RET 复制回调用方(r0=结果) + * - 数据区:8 字节定宽槽(方案 a),指令 slot = 槽号,偏移 = slot × 8 + * - 可观察性(v1 预留):step / pc / fn_id / cycle_count / call_depth / reg + */ + +#pragma once + +#include +#include +#include + +#include "isa/Image.h" + +namespace vm { + + // 周期/指令故障 + enum class Fault { + None, // 正常 + CycleLimit, // 本周期指令数超过映像头 cycle_limit(用例 6) + StackOverflow, // 调用栈深度超过 64 + BadOp, // 非法操作码(op ≥ 29) + BadSlot, // slot × 8 + 8 越出数据区 + BadConst, // const_id 越出常量表 + }; + + class Machine { + public: + /** + * @brief 从映像字节构建机器(校验 + 拷贝数据段 + 建 MAIN 帧) + * @param image .stb 映像字节 + * @param out 输出 Machine(未初始化) + * @param err 错误输出;可为 nullptr(静默) + * @return true 成功;false(映像非法,err 已写) + */ + static bool create(const std::vector& image, Machine* out, + std::string* err); + + /** + * @brief 跑一个扫描周期:MAIN pc=0 执行到 RET + * @return 故障(None = 正常完成);调用栈清空但 MAIN 帧保留 + */ + Fault run_cycle(); + + // ---- 可观察性(v1 预留,12.11 供单步/回放/TUI)---- + + /** + * @brief 执行一条指令,停在指令边界 + * @return true 继续;false 周期结束(MAIN 的 RET)或发生故障 + */ + bool step(); + + /** @brief 最近一次故障(step 返回 false 后查询) */ + Fault fault() const; + + /** @brief 当前指令下标(相对当前函数字节码段) */ + uint32_t pc() const; + + /** @brief 当前函数 fn_id */ + uint32_t fn_id() const; + + /** @brief 本周期已执行指令数 */ + uint32_t cycle_count() const; + + /** @brief 调用栈深度(MAIN 帧 = 1) */ + uint32_t call_depth() const; + + /** @brief 数据区(I 采样写入 / Q 读回由外部做;8 字节定宽槽) */ + uint8_t* data(); + const uint8_t* data() const; + + /** @brief 数据区字节数 */ + size_t data_len() const; + + /** @brief 当前帧寄存器值(i < nregs) */ + int64_t reg(uint8_t i) const; + + private: + struct Frame { + uint32_t fn_id = 0; // 本帧函数 + std::vector regs; // 寄存器文件(大小 = 函数头 nregs) + uint32_t ret_pc = 0; // CALL 的下一条(非 MAIN 帧有意义) + uint32_t ret_fn_id = 0; // 返回目标函数 + }; + + isa::ImageView image_; // 映像只读视图 + std::vector data_; // 数据区工作副本(8 字节定宽槽) + std::vector frames_; // 调用栈([0] = MAIN,跨周期保留) + std::vector ctu_prev_; // CTU 上次 cu(按实例基槽索引,12.9 步骤 4) + uint32_t pc_ = 0; // 当前 pc(相对本帧函数字节码段) + uint32_t cycle_count_ = 0; // 本周期指令数 + Fault fault_ = Fault::None; // 最近一次故障 + bool ended_ = false; // step 后周期是否已结束 + + Frame& cur_frame(); + const Frame& cur_frame() const; + bool exec_one(); // 译码执行一条(12.9 步骤 2/3/4 填充) + Fault do_call(uint32_t fn_id); // 压帧;BadFn 用 BadOp 表示 + Fault do_ret(); // 弹帧 / 周期结束 + Fault do_cal(uint8_t op, uint16_t slot); // TON/TOF/CTU(12.9 步骤 4) + }; +}