Files
Interpreter/vm/include/vm/Image.h
T
Admin dbedc17032 阶段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)
2026-08-26 09:59:18 +08:00

163 lines
6.7 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* @file Image.h
* @brief vm 自带的 .stb 只读视图(执行器侧;compiler 各有实现,V2
* @author
* @date 2026-08-21
*
* @details 格式契约见 Doc/isa/指令与映像.mdV2:头 128B、version=2、型号 STATOR2、
* 常量表 8B 无 tag、槽表段 8B/条 {addr,预留}、值段变宽紧凑、文件尾 SHA-256[32])。
* 解析头与段、补型号匹配与 SHA-256 校验都在本模块完成。
*/
#pragma once
#include <cstddef>
#include <cstdint>
#include <string>
#include <vector>
namespace vm {
/// 执行器内建支持型号(与 machine.toml [meta] 对齐;.stb 型号不匹配直接拒绝)。
static const char* const kModelName = "STATOR";
/// 执行器内建支持型号版本(V2;型号标识 = "STATOR2")。
static const uint32_t kModelVersion = 2;
/**
* @brief 映像头字段(V2128 字节;字段顺序与 Doc/isa/指令与映像.md §8.1 一致)。
* @details 全部为小端值;型号标识 32 字节 @72 不在此结构内(见 model_id())。
*/
struct ImageHeader {
uint32_t cycle_limit = 0; ///< 每周期指令数上限(超出 → Fault::CycleLimit
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; ///< 输入槽数(保留恒 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_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 字节;code_len 为字节数,变长指令)。
*/
struct FuncRow {
uint32_t nregs = 0; ///< 本函数寄存器数(函数头 nregs)
uint32_t code_offset = 0; ///< 相对字节码段起点(字节)
uint32_t code_len = 0; ///< 字节码长度(字节)
};
/**
* @brief 常量表一项(8 字节:原始位模式,无 tag——LOADK 按 func 位段解释)。
*/
struct ConstEntry {
uint64_t value = 0; ///< 原始 64 位位模式
};
/**
* @brief 只读视图:指向外部缓冲的校验过的 .stb 映像。
* @details from() 完成魔数/版本/头/六段/尺寸一致性校验(元数据段 0 = 空段);
* 型号匹配与 SHA-256 由 model_matches() / sha_ok() 另行查询
* Machine::create 里一起做)。所有方法在校验失败(ok() == false
* 时返回安全默认值。
*/
class Image {
public:
/**
* @brief 从原始字节构造只读视图(不拷贝,调用方保证生命周期)。
* @param buf 映像缓冲;可为 nullptr
* @param len 缓冲字节数
* @return 校验结果;ok() 判成功,error() 取失败原因
* @details 校验项:非空、长度 ≥ 头、魔数 STSC、版本 2、六段偏移单调且在
* SHA-256 尾之前、常量表/函数表/槽表尺寸一致、值段大小一致、
* 代码段对齐、入口 fn_id 在函数表内。
*/
static Image from(const uint8_t* buf, size_t len);
/**
* @brief 从 vector 构造只读视图。
* @param buf 映像缓冲(引用 data(),调用方保证生命周期)
* @return 同 from(const uint8_t*, size_t)
*/
static Image from(const std::vector<uint8_t>& buf);
/// @return 校验是否通过。
bool ok() const { return ok_; }
/// @return 校验失败原因;成功时为空串。
const std::string& error() const { return err_; }
/// @return 映像头字段。
const ImageHeader& header() const { return hdr_; }
/**
* @brief 读函数表一行。
* @param i 函数下标
* @return 该行字段;越界(或校验失败)时全 0
*/
FuncRow func_row(size_t i) const;
/**
* @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。
const uint8_t* data_bytes() const;
/// @return 值段字节数(不含 SHA-256 尾);校验失败返回 0。
size_t data_len() const;
/// @return 型号标识字符串(头 @72 的 32 字节,去 '\0' 截断)。
std::string model_id() const;
/**
* @brief 型号标识是否匹配。
* @param name 期望型号名(如 "STATOR"
* @param version 期望版本(如 2
* @return 头内 32 字节与 "name + version" 补零后逐字节相等
*/
bool model_matches(const std::string& name, uint32_t version) const;
/// @return 文件尾 32 字节是否为内容(去尾后)的 SHA-256。
bool sha_ok() const;
public:
/// 默认构造为无效态(ok() == false)。
Image() : buf_(nullptr), len_(0) {}
private:
const uint8_t* buf_; ///< 外部缓冲指针(不持有)
size_t len_; ///< 缓冲长度
bool ok_ = false; ///< 校验是否通过
std::string err_; ///< 失败原因
ImageHeader hdr_; ///< 解析出的头字段
};
}