阶段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:
+42
-27
@@ -1,11 +1,12 @@
|
||||
/**
|
||||
* @file Image.h
|
||||
* @brief vm 自带的 .stb 只读视图(执行器侧;compiler 各有实现)
|
||||
* @brief vm 自带的 .stb 只读视图(执行器侧;compiler 各有实现,V2)
|
||||
* @author
|
||||
* @date 2026-08-21
|
||||
*
|
||||
* @details 格式契约见 Doc/isa/指令与映像.md(12.13 修订:头 104 = 72 + 型号标识[32],
|
||||
* 文件尾 SHA-256[32])。解析头与段、补型号匹配与 SHA-256 校验都在本模块完成。
|
||||
* @details 格式契约见 Doc/isa/指令与映像.md(V2:头 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 映像头字段(V2:128 字节;字段顺序与 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; ///< 元数据段偏移(@112;0 = 空段)
|
||||
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::TypeTag:0=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;
|
||||
|
||||
Reference in New Issue
Block a user