阶段4-2a:vm/Image V2(头 128B/6 段校验/槽表访问器)

- ImageHeader:V2 字段(offset_slots/offset_values + n_slots/values_size/
  offset_meta/max_stack);kModelVersion=2(STATOR2)
- 段校验:const/funcs/code/slots/values + meta=0 空段处理、尺寸一致性、对齐
- 常量表 8B 无 tag;FuncRow.code_len 字节;slot_addr/slots_bytes 访问器
- 验证:V2 产物解析 ok、model_matches(STATOR,2)/sha 校验通过
- 状态:Machine.cpp 仍破(4-2b)
This commit is contained in:
2026-08-26 09:59:18 +08:00
parent 4f3da55ed7
commit dbedc17032
2 changed files with 117 additions and 119 deletions
+42 -27
View File
@@ -1,11 +1,12 @@
/**
* @file Image.h
* @brief vm 自带的 .stb 只读视图(执行器侧;compiler 各有实现)
* @brief vm 自带的 .stb 只读视图(执行器侧;compiler 各有实现V2
* @author
* @date 2026-08-21
*
* @details 格式契约见 Doc/isa/指令与映像.md12.13 修订:头 104 = 72 + 型号标识[32]
* 文件尾 SHA-256[32]。解析头与段、补型号匹配与 SHA-256 校验都在本模块完成
* @details 格式契约见 Doc/isa/指令与映像.mdV2:头 128B、version=2、型号 STATOR2、
* 常量表 8B 无 tag、槽表段 8B/条 {addr,预留}、值段变宽紧凑、文件尾 SHA-256[32])。
* 解析头与段、补型号匹配与 SHA-256 校验都在本模块完成。
*/
#pragma once
@@ -19,11 +20,11 @@ namespace vm {
/// 执行器内建支持型号(与 machine.toml [meta] 对齐;.stb 型号不匹配直接拒绝)。
static const char* const kModelName = "STATOR";
/// 执行器内建支持型号版本(与 machine.toml [meta] 对齐)。
static const uint32_t kModelVersion = 1;
/// 执行器内建支持型号版本(V2;型号标识 = "STATOR2")。
static const uint32_t kModelVersion = 2;
/**
* @brief 映像头字段(104 字节;字段顺序与 Doc/isa/指令与映像.md 一致)。
* @brief 映像头字段(V2128 字节;字段顺序与 Doc/isa/指令与映像.md §8.1 一致)。
* @details 全部为小端值;型号标识 32 字节 @72 不在此结构内(见 model_id())。
*/
struct ImageHeader {
@@ -31,41 +32,45 @@ namespace vm {
uint32_t dt_ms = 0; ///< 周期时长(毫秒,定时器/计数器推进步长)
uint64_t project_hash = 0; ///< 工程哈希(FNV-1a 64,只读展示)
uint32_t entry_fn_id = 0; ///< 入口函数(PROGRAM MAIN)在函数表的下标
uint32_t n_globals = 0; ///< 全局变量槽数(数据段最前段)
uint32_t n_i = 0; ///< 输入变量(I槽数
uint32_t n_q = 0; ///< 输出变量(Q槽数
uint32_t n_m = 0; ///< 中间变量(M槽数
uint32_t n_globals = 0; ///< 全局变量槽数(槽表最前段)
uint32_t n_i = 0; ///< 输入槽数(保留恒 0
uint32_t n_q = 0; ///< 输出槽数(保留恒 0
uint32_t n_m = 0; ///< 中间槽数(保留恒 0
uint32_t n_consts = 0; ///< 常量表条目数
uint32_t n_funcs = 0; ///< 函数表行数
uint32_t offset_const = 0; ///< 常量表段起点(相对文件头)
uint32_t offset_funcs = 0; ///< 函数表段起点
uint32_t offset_code = 0; ///< 字节码段起点
uint32_t offset_fb = 0; ///< FB 表段起点
uint32_t offset_data = 0; ///< 数据段起点(之后为 SHA-256 文件尾
uint32_t offset_slots = 0; ///< 表段起点
uint32_t offset_values = 0; ///< 段起点(16 对齐
uint32_t n_slots = 0; ///< 槽表条目数(@104
uint32_t values_size = 0; ///< 值段字节数(@108
uint32_t offset_meta = 0; ///< 元数据段偏移(@1120 = 空段)
uint32_t max_stack = 0; ///< 栈区字节数(@116,编译期算)
};
/**
* @brief 函数表一行(12 字节)。
* @brief 函数表一行(12 字节code_len 为字节数,变长指令)。
*/
struct FuncRow {
uint32_t nregs = 0; ///< 本函数寄存器数(函数头 nregs)
uint32_t code_offset = 0; ///< 相对字节码段起点(字节)
uint32_t code_len = 0; ///< 指令条数
uint32_t code_len = 0; ///< 字节码长度(字节)
};
/**
* @brief 常量表一项(12 字节)。
* @brief 常量表一项(8 字节:原始位模式,无 tag——LOADK 按 func 位段解释)。
*/
struct ConstEntry {
uint32_t tag = 0; ///< 类型标记(isa::types::TypeTag0=BOOL、1=INT、2=TIME
uint64_t value = 0; ///< 值(LOADK 时按 tag 解释)
uint64_t value = 0; ///< 原始 64 位位模式
};
/**
* @brief 只读视图:指向外部缓冲的校验过的 .stb 映像。
* @details from() 完成魔数/版本/头/段/尺寸一致性校验;型号匹配与 SHA-256
* 由 model_matches() / sha_ok() 另行查询Machine::create 里一起做)。
* 所有方法在校验失败(ok() == false时返回安全默认值。
* @details from() 完成魔数/版本/头/段/尺寸一致性校验(元数据段 0 = 空段);
* 型号匹配与 SHA-256 由 model_matches() / sha_ok() 另行查询
* Machine::create 里一起做)。所有方法在校验失败(ok() == false
* 时返回安全默认值。
*/
class Image {
public:
@@ -74,9 +79,9 @@ namespace vm {
* @param buf 映像缓冲;可为 nullptr
* @param len 缓冲字节数
* @return 校验结果;ok() 判成功,error() 取失败原因
* @details 校验项:非空、长度 ≥ 头、魔数 STSC、版本 1、五个段偏移单调且在
* SHA-256 尾之前、常量表/函数表尺寸一致、代码段 4 字节对齐
* 入口 fn_id 在函数表内。
* @details 校验项:非空、长度 ≥ 头、魔数 STSC、版本 2、六段偏移单调且在
* SHA-256 尾之前、常量表/函数表/槽表尺寸一致、值段大小一致
* 代码段对齐、入口 fn_id 在函数表内。
*/
static Image from(const uint8_t* buf, size_t len);
@@ -104,19 +109,29 @@ namespace vm {
FuncRow func_row(size_t i) const;
/**
* @brief 读常量表一项。
* @brief 读常量表一项8B 原始值)
* @param i 常量下标
* @return 该条目;越界(或校验失败)时全 0
*/
ConstEntry const_entry(size_t i) const;
/**
* @brief 读槽表一项的地址(值段内偏移)。
* @param i 槽号
* @return addr;越界(或校验失败)时 0
*/
uint32_t slot_addr(size_t i) const;
/// @return 槽表段起点;校验失败返回 nullptr。
const uint8_t* slots_bytes() const;
/// @return 字节码段起点;校验失败返回 nullptr。
const uint8_t* code_bytes() const;
/// @return 数据段起点;校验失败返回 nullptr。
/// @return 段起点;校验失败返回 nullptr。
const uint8_t* data_bytes() const;
/// @return 数据段字节数(不含 SHA-256 尾);校验失败返回 0。
/// @return 段字节数(不含 SHA-256 尾);校验失败返回 0。
size_t data_len() const;
/// @return 型号标识字符串(头 @72 的 32 字节,去 '\0' 截断)。
@@ -125,7 +140,7 @@ namespace vm {
/**
* @brief 型号标识是否匹配。
* @param name 期望型号名(如 "STATOR"
* @param version 期望版本(如 1
* @param version 期望版本(如 2
* @return 头内 32 字节与 "name + version" 补零后逐字节相等
*/
bool model_matches(const std::string& name, uint32_t version) const;