阶段2-4/2-5:Stb V2(头 128B/槽表段/值段/常量表 8B)+ Codegen V2 重写

Stb.h/.cpp V2:
- 头 128B:kOffSlots/kOffValues/kOffNSlots/kOffValuesSize/kOffMeta/kOffMaxStack
- 常量表 8B(无 tag)、槽表行 8B {addr,预留}、static_assert 更新
- StbView:新字段访问器 + slots_bytes + 段校验 6 段(含元数据空段)

Codegen V2:
- 变长指令发射(Codec 位号,emit/E_rr..E_cal/E_slot_off)
- 槽表→值段布局(1/2/4/8 对齐;实例=1 槽表条目指向字段块)
- 常量表位模式去重(LOADK 按 func 解释);字节化跳转回填
- max_stack(调用图 DAG 最长路径 + 环检测递归报错)
- 用户 FB 内联(LOAD_OFF/STORE_OFF 字段访问);内建 FB → CAL fb_id,slot
- 头 128B 拼装(version=2/STATOR2/段序)

配套:main.cpp 常量显示去 tag;codegen_test 临时剥离(阶段 3 重写);
machine_test 修正(72 op + 负例修复)。ctest:10/13 绿(vm/cases 预期内剥离)。
This commit is contained in:
2026-08-25 20:14:01 +08:00
parent 246fe09646
commit 924c0c1923
6 changed files with 551 additions and 487 deletions
+85 -63
View File
@@ -1,12 +1,13 @@
/** /**
* @file Stb.h * @file Stb.h
* @brief 编译器自带的 .stb 映像规范(写侧)+ 只读视图 + FNV-1a * @brief 编译器自带的 .stb 映像规范(写侧V2+ 只读视图 + FNV-1a
* @author * @author
* @date 2026-08-21 * @date 2026-08-21
* *
* @details 执行器(vm)各有自己的读写实现;格式契约见 Doc/isa/指令与映像.md。 * @details 执行器(vm)各有自己的读写实现;格式契约见 Doc/isa/指令与映像.mdV2
* 12.13 修订:头 104 = 原 72 + 型号标识[32] @72,文件尾 SHA-256[32]。 * V2:头 128Bversion=2、型号标识 STATOR2 @72、n_slots/values_size/offset_meta/max_stack),
* 常量表 tag 契约:0=BOOL、1=INT、2=TIME;工程哈希用 FNV-1a 64。 * 常量表 8B/条(无 tagLOADK 按 func 解释),槽表段 8B/条 {addr,预留}
* 值段变宽紧凑;文件尾 SHA-256[32];工程哈希 FNV-1a 64。
*/ */
#pragma once #pragma once
@@ -20,17 +21,19 @@
namespace compiler { namespace compiler {
// ---- .stb 格式常量(契约;12.13 修订:头 104 = 原 72 + 型号标识[32],文件尾 SHA-256[32]---- // ---- .stb 格式常量(V2 契约;头 128 = 原 72 字段 + 型号标识[32]@72 + 新增 24----
/// 映像魔数:"STSC" 小端。 /// 映像魔数:"STSC" 小端。
static const uint32_t kMagic = 0x43545353u; static const uint32_t kMagic = 0x43545353u;
/// 映像格式版本。 /// 映像格式版本V2
static const uint32_t kVersion = 1; static const uint32_t kVersion = 2;
/// 映像头字节数(原 72 字段 + 型号标识[32] @72)。 /// 映像头字节数(V2)。
static const size_t kHeaderSize = 104; static const size_t kHeaderSize = 128;
/// 常量表一行字节数(tag:4 + value:8)。 /// 常量表一行字节数(8B 原始值,无 tag)。
static const size_t kConstEntrySize = 12; static const size_t kConstEntrySize = 8;
/// 函数表一行字节数(nregs / code_offset / code_len 各 4)。 /// 函数表一行字节数(nregs / code_offset / code_len 各 4)。
static const size_t kFuncRowSize = 12; static const size_t kFuncRowSize = 12;
/// 槽表一行字节数(addr:4 + 预留:4)。
static const size_t kSlotRowSize = 8;
/// SHA-256 摘要长度(文件尾)。 /// SHA-256 摘要长度(文件尾)。
static const size_t kSha256Size = 32; static const size_t kSha256Size = 32;
/// 型号标识长度(头内 @72,不足补 '\0')。 /// 型号标识长度(头内 @72,不足补 '\0')。
@@ -40,49 +43,54 @@ namespace compiler {
/// FNV-1a 64 哈希素数。 /// FNV-1a 64 哈希素数。
static const uint64_t kFnvPrime = 0x100000001b3ull; static const uint64_t kFnvPrime = 0x100000001b3ull;
// ---- 头字段偏移(与 Doc/isa/指令与映像.md 字段表一致;vm 侧另有同值一份)---- // ---- 头字段偏移(与 Doc/isa/指令与映像.md §8.1 字段表一致;vm 侧另有同值一份)----
inline constexpr size_t kOffMagic = 0; ///< 魔数 "STSC" inline constexpr size_t kOffMagic = 0; ///< 魔数 "STSC"
inline constexpr size_t kOffVersion = 4; ///< 格式版本 inline constexpr size_t kOffVersion = 4; ///< 格式版本V2 = 2
inline constexpr size_t kOffCycleLimit = 8; ///< 每周期指令数上限 inline constexpr size_t kOffCycleLimit = 8; ///< 每周期指令数上限
inline constexpr size_t kOffDtMs = 12; ///< 周期时长(毫秒) inline constexpr size_t kOffDtMs = 12; ///< 周期时长(毫秒)
inline constexpr size_t kOffProjectHash = 16; ///< 工程哈希(8 字节) inline constexpr size_t kOffProjectHash = 16; ///< 工程哈希(8 字节)
inline constexpr size_t kOffEntryFnId = 24; ///< 入口函数 fn_id inline constexpr size_t kOffEntryFnId = 24; ///< 入口函数 fn_id
inline constexpr size_t kOffNGlobals = 28; ///< 全局槽数 inline constexpr size_t kOffNGlobals = 28; ///< 全局槽数
inline constexpr size_t kOffNI = 32; ///< 输入(I)槽数 inline constexpr size_t kOffNI = 32; ///< 输入(I)槽数(保留恒 0
inline constexpr size_t kOffNQ = 36; ///< 输出(Q)槽数 inline constexpr size_t kOffNQ = 36; ///< 输出(Q)槽数(保留恒 0
inline constexpr size_t kOffNM = 40; ///< 中间(M)槽数 inline constexpr size_t kOffNM = 40; ///< 中间(M)槽数(保留恒 0
inline constexpr size_t kOffNConsts = 44; ///< 常量表条目数 inline constexpr size_t kOffNConsts = 44; ///< 常量表条目数
inline constexpr size_t kOffNFuncs = 48; ///< 函数表行数 inline constexpr size_t kOffNFuncs = 48; ///< 函数表行数
inline constexpr size_t kOffConst = 52; ///< 常量表段偏移 inline constexpr size_t kOffConst = 52; ///< 常量表段偏移
inline constexpr size_t kOffFuncs = 56; ///< 函数表段偏移 inline constexpr size_t kOffFuncs = 56; ///< 函数表段偏移
inline constexpr size_t kOffCode = 60; ///< 字节码段偏移 inline constexpr size_t kOffCode = 60; ///< 字节码段偏移16 对齐)
inline constexpr size_t kOffFb = 64; ///< FB 表段偏移 inline constexpr size_t kOffSlots = 64; ///< 表段偏移
inline constexpr size_t kOffData = 68; ///< 数据段偏移 inline constexpr size_t kOffValues = 68; ///< 段偏移16 对齐)
inline constexpr size_t kOffModelId = 72; ///< 型号标识[32]12.13 修订 inline constexpr size_t kOffModelId = 72; ///< 型号标识[32]V2 = "STATOR2"
inline constexpr size_t kOffNSlots = 104; ///< 槽表条目数(= n_globals + 实例槽数)
inline constexpr size_t kOffValuesSize = 108; ///< 值段字节数
inline constexpr size_t kOffMeta = 112; ///< 元数据段偏移(v1 = 0 空段)
inline constexpr size_t kOffMaxStack = 116; ///< 栈区字节数(编译期算)
// ---- 段内行偏移 ---- // ---- 段内行偏移 ----
inline constexpr size_t kConstTagOff = 0; ///< 常量表行内:tag inline constexpr size_t kConstValueOff = 0; ///< 常量表行内:value8 字节,无 tag
inline constexpr size_t kConstValueOff = 4; ///< 常量表行内:value8 字节) inline constexpr size_t kFuncNregsOff = 0; ///< 函数表行内:nregs
inline constexpr size_t kFuncNregsOff = 0; ///< 函数表行内:nregs inline constexpr size_t kFuncCodeOff = 4; ///< 函数表行内:code_offset(字节)
inline constexpr size_t kFuncCodeOff = 4; ///< 函数表行内:code_offset(字节) inline constexpr size_t kFuncLenOff = 8; ///< 函数表行内:code_len(字节)
inline constexpr size_t kFuncLenOff = 8; ///< 函数表行内:code_len(指令条数 inline constexpr size_t kSlotAddrOff = 0; ///< 表行内:addr(值段内偏移
inline constexpr size_t kSlotPadOff = 4; ///< 槽表行内:预留
// 防漂移:头布局自洽性(与 Doc/isa/指令与映像.md 冻结表核对) // 防漂移:头布局自洽性(与 Doc/isa/指令与映像.md §8.1 冻结表核对)
static_assert(kHeaderSize == kOffModelId + kModelIdSize, "header size = 72 + model id[32]"); static_assert(kHeaderSize == kOffModelId + kModelIdSize + 24, "header = 72 + model id + 24");
static_assert(kOffData > kOffFb && kOffFb > kOffCode && kOffCode > kOffFuncs && static_assert(kOffValues > kOffSlots && kOffSlots > kOffCode && kOffCode > kOffFuncs &&
kOffFuncs > kOffConst, kOffFuncs > kOffConst,
"header field offsets monotonic"); "header field offsets monotonic");
static_assert(kOffModelId == kOffData + 4, "model id follows data offset field"); static_assert(kOffModelId == kOffValues + 4, "model id follows values offset field");
static_assert(kConstEntrySize == kConstValueOff + 8, "const row: tag + value:8"); static_assert(kOffMaxStack == kOffMeta + 4, "max_stack follows meta offset");
static_assert(kConstEntrySize == 8, "const row: value:8 (no tag)");
static_assert(kFuncRowSize == kFuncLenOff + 4, "func row: nregs/code_offset/code_len"); static_assert(kFuncRowSize == kFuncLenOff + 4, "func row: nregs/code_offset/code_len");
static_assert(kSlotRowSize == kSlotPadOff + 4, "slot row: addr + pad");
/** /**
* @brief 常量表一行。 * @brief 常量表一行8B 原始值,无 tag——LOADK 按 func 位段解释)
* @details tag 契约:0=BOOL、1=INT、2=TIME。
*/ */
struct ConstEntry { struct ConstEntry {
uint32_t tag = 0; ///< 类型 tag0=BOOL、1=INT、2=TIME uint64_t value = 0; ///< 原始位模式
uint64_t value = 0; ///< 常量值
}; };
/** /**
@@ -110,7 +118,7 @@ namespace compiler {
void sha256(const uint8_t* data, size_t len, uint8_t out[kSha256Size]); void sha256(const uint8_t* data, size_t len, uint8_t out[kSha256Size]);
/** /**
* @brief 型号标识:name + version 拼 32 字节 ASCII(如 "STATOR1")。 * @brief 型号标识:name + version 拼 32 字节 ASCII(如 "STATOR2")。
* @param name 型号名 * @param name 型号名
* @param version 版本号 * @param version 版本号
* @param out 32 字节输出缓冲 * @param out 32 字节输出缓冲
@@ -119,17 +127,17 @@ namespace compiler {
void fill_model_id(const std::string& name, uint32_t version, char out[kModelIdSize]); void fill_model_id(const std::string& name, uint32_t version, char out[kModelIdSize]);
/** /**
* @brief .stb 映像只读视图(--disasm 用)。 * @brief .stb 映像只读视图(--disasm 用V2)。
* @details from() 时校验魔数/版本/段边界,之后各访问器只读; * @details from() 时校验魔数/版本/段边界,之后各访问器只读;
* 失败时 ok() == falseerror() 取原因。 * 失败时 ok() == falseerror() 取原因。
*/ */
class StbView { class StbView {
public: public:
/// @brief 函数表一行(nregs / code_offset / code_len)。 /// @brief 函数表一行(nregs / code_offset / code_len,均字节)。
struct FuncRow { struct FuncRow {
uint32_t nregs = 0; ///< 帧寄存器数(含变量与临时) uint32_t nregs = 0; ///< 帧寄存器数(含变量与临时)
uint32_t code_offset = 0; ///< 字节码段内偏移(4 字节对齐 uint32_t code_offset = 0; ///< 字节码段内偏移(字节
uint32_t code_len = 0; ///< 指令条数 uint32_t code_len = 0; ///< 字节码长度(字节,变长指令)
}; };
/// 从原始字节构造(不拷贝,调用方保证生命周期)。 /// 从原始字节构造(不拷贝,调用方保证生命周期)。
@@ -158,12 +166,20 @@ namespace compiler {
uint32_t n_funcs() const { return n_funcs_; } uint32_t n_funcs() const { return n_funcs_; }
/// 字节码段偏移(头 @60)。 /// 字节码段偏移(头 @60)。
uint32_t offset_code() const { return offset_code_; } uint32_t offset_code() const { return offset_code_; }
/// 数据段(FB 区)偏移(头 @64;即字节码段终点)。 /// 槽表段偏移(头 @64)。
uint32_t offset_fb() const { return offset_fb_; } uint32_t offset_slots() const { return offset_slots_; }
/// 数据段偏移(头 @68)。 /// 段偏移(头 @68)。
uint32_t offset_data() const { return offset_data_; } uint32_t offset_values() const { return offset_values_; }
/// 槽表条目数(头 @104)。
uint32_t n_slots() const { return n_slots_; }
/// 值段字节数(头 @108)。
uint32_t values_size() const { return values_size_; }
/// 元数据段偏移(头 @112;0 = 空段)。
uint32_t offset_meta() const { return offset_meta_; }
/// 栈区字节数(头 @116)。
uint32_t max_stack() const { return max_stack_; }
/// 读常量表一行;越界时返回全 0。 /// 读常量表一行8B 原始值);越界时返回全 0。
ConstEntry const_entry(size_t i) const; ConstEntry const_entry(size_t i) const;
/// 读函数表一行;越界时返回全 0。 /// 读函数表一行;越界时返回全 0。
FuncRow func_row(size_t i) const; FuncRow func_row(size_t i) const;
@@ -171,39 +187,45 @@ namespace compiler {
const uint8_t* code_bytes() const; const uint8_t* code_bytes() const;
/// 字节码段字节数。 /// 字节码段字节数。
size_t code_len() const; size_t code_len() const;
/// 数据段起点。 /// 槽表段起点。
const uint8_t* slots_bytes() const;
/// 值段起点。
const uint8_t* data_bytes() const; const uint8_t* data_bytes() const;
/// 数据段字节数(不含文件尾 SHA-256)。 /// 段字节数(不含文件尾 SHA-256)。
size_t data_len() const; size_t data_len() const;
/// 型号标识字符串(头 72..103,截断到首个 '\0')。 /// 型号标识字符串(头 72..103,截断到首个 '\0')。
std::string model_id() const; // 头 72..103(补 '\0' 后字符串) std::string model_id() const;
/// 型号标识是否匹配 name + version。 /// 型号标识是否匹配 name + version。
bool model_matches(const std::string& name, uint32_t version) const; bool model_matches(const std::string& name, uint32_t version) const;
/// 文件尾 32 字节 SHA-256 校验(对文件尾之前全部内容重算)。 /// 文件尾 32 字节 SHA-256 校验(对文件尾之前全部内容重算)。
bool sha_ok() const; // 文件尾 32 字节 SHA-256 校验 bool sha_ok() const;
private: private:
/// 私有构造(只能经 from() 创建)。 /// 私有构造(只能经 from() 创建)。
StbView() : buf_(0), len_(0) {} StbView() : buf_(0), len_(0) {}
/// 常量表偏移(from 已校验的段起点)。 /// 常量表偏移(from 已校验的段起点)。
uint32_t offs_of_const() const; // offset_constfrom 已校验段起点) uint32_t offs_of_const() const;
const uint8_t* buf_; ///< 映像缓冲(不拥有) const uint8_t* buf_; ///< 映像缓冲(不拥有)
size_t len_; ///< 缓冲字节数 size_t len_; ///< 缓冲字节数
bool ok_ = false; ///< 解析成功标志 bool ok_ = false; ///< 解析成功标志
std::string err_; ///< 失败原因 std::string err_; ///< 失败原因
uint32_t cycle_limit_ = 0; ///< 周期上限 uint32_t cycle_limit_ = 0; ///< 周期上限
uint32_t dt_ms_ = 0; ///< 扫描周期 uint32_t dt_ms_ = 0; ///< 扫描周期
uint64_t project_hash_ = 0; ///< 工程哈希 uint64_t project_hash_ = 0; ///< 工程哈希
uint32_t entry_fn_id_ = 0; ///< 入口函数 fn_id uint32_t entry_fn_id_ = 0; ///< 入口函数 fn_id
uint32_t n_globals_ = 0; ///< 全局槽数 uint32_t n_globals_ = 0; ///< 全局槽数
uint32_t n_consts_ = 0; ///< 常量表行数 uint32_t n_consts_ = 0; ///< 常量表行数
uint32_t n_funcs_ = 0; ///< 函数表行数 uint32_t n_funcs_ = 0; ///< 函数表行数
uint32_t offset_code_ = 0; ///< 字节码段偏移 uint32_t offset_code_ = 0; ///< 字节码段偏移
uint32_t offset_fb_ = 0; ///< 数据段(FB 区)偏移 uint32_t offset_slots_ = 0; ///< 槽表段偏移
uint32_t offset_data_ = 0; ///< 数据段偏移 uint32_t offset_values_ = 0; ///< 段偏移
uint32_t n_slots_ = 0; ///< 槽表条目数
uint32_t values_size_ = 0; ///< 值段字节数
uint32_t offset_meta_ = 0; ///< 元数据段偏移(0 = 空段)
uint32_t max_stack_ = 0; ///< 栈区字节数
}; };
/** /**
+423 -397
View File
File diff suppressed because it is too large Load Diff
+29 -13
View File
@@ -259,17 +259,22 @@ StbView StbView::from(const uint8_t* buf, size_t len) {
v.n_consts_ = get_le32(buf + kOffNConsts); v.n_consts_ = get_le32(buf + kOffNConsts);
v.n_funcs_ = get_le32(buf + kOffNFuncs); v.n_funcs_ = get_le32(buf + kOffNFuncs);
v.offset_code_ = get_le32(buf + kOffCode); v.offset_code_ = get_le32(buf + kOffCode);
v.offset_fb_ = get_le32(buf + kOffFb); v.offset_slots_ = get_le32(buf + kOffSlots);
v.offset_data_ = get_le32(buf + kOffData); v.offset_values_ = get_le32(buf + kOffValues);
v.n_slots_ = get_le32(buf + kOffNSlots);
v.values_size_ = get_le32(buf + kOffValuesSize);
v.offset_meta_ = get_le32(buf + kOffMeta);
v.max_stack_ = get_le32(buf + kOffMaxStack);
// 段校验(12.13:文件尾 SHA-256[32] 在数据段之后 // 段校验(V2:值段之后是 SHA-256 文件尾;元数据段 v1 为 0 = 空段
if (len < static_cast<size_t>(v.offset_data_) + kSha256Size) { if (len < static_cast<size_t>(v.offset_values_) + kSha256Size) {
v.err_ = "missing sha256 tail"; v.err_ = "missing sha256 tail";
return v; return v;
} }
const uint64_t offs[5] = {get_le32(buf + kOffConst), get_le32(buf + kOffFuncs), v.offset_code_, const uint64_t offs[6] = {get_le32(buf + kOffConst), get_le32(buf + kOffFuncs), v.offset_code_,
v.offset_fb_, v.offset_data_}; v.offset_slots_, v.offset_values_,
for (int i = 0; i < 5; ++i) { (v.offset_meta_ != 0) ? v.offset_meta_ : v.offset_values_};
for (int i = 0; i < 6; ++i) {
if (offs[i] < kHeaderSize || offs[i] > len - kSha256Size) { if (offs[i] < kHeaderSize || offs[i] > len - kSha256Size) {
v.err_ = "segment offset out of range"; v.err_ = "segment offset out of range";
return v; return v;
@@ -287,8 +292,16 @@ StbView StbView::from(const uint8_t* buf, size_t len) {
v.err_ = "function table size mismatch"; v.err_ = "function table size mismatch";
return v; return v;
} }
if ((v.offset_fb_ - v.offset_code_) % 4 != 0) { if (offs[4] - offs[3] != static_cast<uint64_t>(v.n_slots_) * kSlotRowSize) {
v.err_ = "code segment not 4-byte aligned"; v.err_ = "slot table size mismatch";
return v;
}
if (offs[5] - offs[4] != v.values_size_) {
v.err_ = "values segment size mismatch";
return v;
}
if ((v.offset_slots_ - v.offset_code_) % 4 != 0) {
v.err_ = "code segment not aligned";
return v; return v;
} }
if (v.entry_fn_id_ >= v.n_funcs_ && v.n_funcs_ != 0) { if (v.entry_fn_id_ >= v.n_funcs_ && v.n_funcs_ != 0) {
@@ -310,7 +323,6 @@ ConstEntry StbView::const_entry(size_t i) const {
ConstEntry e; ConstEntry e;
if (ok_ && i < n_consts_) { if (ok_ && i < n_consts_) {
const uint8_t* p = buf_ + offs_of_const() + i * kConstEntrySize; const uint8_t* p = buf_ + offs_of_const() + i * kConstEntrySize;
e.tag = get_le32(p);
e.value = get_le64(p + kConstValueOff); e.value = get_le64(p + kConstValueOff);
} }
return e; return e;
@@ -341,20 +353,24 @@ const uint8_t* StbView::code_bytes() const {
/// 字节码段字节数(未 ok() 时返回 0)。 /// 字节码段字节数(未 ok() 时返回 0)。
size_t StbView::code_len() const { size_t StbView::code_len() const {
return ok_ ? offset_fb_ - offset_code_ : 0; return ok_ ? offset_slots_ - offset_code_ : 0;
} }
/// 数据段起点(未 ok() 时返回 nullptr)。 /// 数据段起点(未 ok() 时返回 nullptr)。
const uint8_t* StbView::data_bytes() const { const uint8_t* StbView::data_bytes() const {
return ok_ ? buf_ + offset_data_ : nullptr; return ok_ ? buf_ + offset_values_ : nullptr;
} }
/// 数据段字节数(不含文件尾 SHA-256;未 ok() 时返回 0)。 /// 数据段字节数(不含文件尾 SHA-256;未 ok() 时返回 0)。
size_t StbView::data_len() const { size_t StbView::data_len() const {
return ok_ ? (len_ - kSha256Size) - offset_data_ : 0; return ok_ ? (len_ - kSha256Size) - offset_values_ : 0;
} }
/// 型号标识字符串(头 72..103,截断到首个 '\0';未 ok() 时返回空串)。 /// 型号标识字符串(头 72..103,截断到首个 '\0';未 ok() 时返回空串)。
const uint8_t* StbView::slots_bytes() const {
return ok_ ? buf_ + offset_slots_ : nullptr;
}
std::string StbView::model_id() const { std::string StbView::model_id() const {
if (!ok_) { if (!ok_) {
return ""; return "";
+1 -2
View File
@@ -70,8 +70,7 @@ namespace {
std::printf("constants:\n"); std::printf("constants:\n");
for (uint32_t i = 0; i < v.n_consts(); ++i) { for (uint32_t i = 0; i < v.n_consts(); ++i) {
const compiler::ConstEntry c = v.const_entry(i); const compiler::ConstEntry c = v.const_entry(i);
const char* tag = c.tag == 0 ? "BOOL" : c.tag == 1 ? "INT" : "TIME"; std::printf(" [%u] %llu\n", i,
std::printf(" [%u] %s %llu\n", i, tag,
static_cast<unsigned long long>(c.value)); static_cast<unsigned long long>(c.value));
} }
} }
+10 -9
View File
@@ -78,16 +78,17 @@ target_compile_definitions(typecheck_test PRIVATE
add_test(NAME typecheck_types add_test(NAME typecheck_types
COMMAND typecheck_test) COMMAND typecheck_test)
# TODO(V2): 阶段 3 重写 codegen_test(用 compiler::Codec 断言 V2 产物,去 isa 依赖)
# 寄存器码测试(12.8 切片 1):用例 01/02 出映像(REPO_ROOT 注入源目录绝对路径) # 寄存器码测试(12.8 切片 1):用例 01/02 出映像(REPO_ROOT 注入源目录绝对路径)
add_executable(codegen_test # add_executable(codegen_test
./src/codegen_test.cpp) # ./src/codegen_test.cpp)
#
target_link_libraries(codegen_test PRIVATE compiler isa) # target_link_libraries(codegen_test PRIVATE compiler isa)
target_compile_definitions(codegen_test PRIVATE # target_compile_definitions(codegen_test PRIVATE
REPO_ROOT="${CMAKE_SOURCE_DIR}") # REPO_ROOT="${CMAKE_SOURCE_DIR}")
#
add_test(NAME codegen_slice1 # add_test(NAME codegen_slice1
COMMAND codegen_test) # COMMAND codegen_test)
# VM 测试:手工映像 + 编译器产物 + 定时器 + 确定性(REPO_ROOT 注入源目录绝对路径) # VM 测试:手工映像 + 编译器产物 + 定时器 + 确定性(REPO_ROOT 注入源目录绝对路径)
add_executable(vm_test add_executable(vm_test
+3 -3
View File
@@ -132,7 +132,7 @@ static bool test_positive() {
CHECK(cfg.find_type("DT") != nullptr && cfg.find_type("DT")->func == 6); CHECK(cfg.find_type("DT") != nullptr && cfg.find_type("DT")->func == 6);
CHECK(cfg.find_type("NOPE") == nullptr); CHECK(cfg.find_type("NOPE") == nullptr);
CHECK(cfg.ops().size() == 68); CHECK(cfg.ops().size() == 72);
const compiler::ConfigOp* move = cfg.find_op("MOVE"); const compiler::ConfigOp* move = cfg.find_op("MOVE");
CHECK(move != nullptr && move->prefix == "11" && move->op == 0 && move->fmt == "RR" && CHECK(move != nullptr && move->prefix == "11" && move->op == 0 && move->fmt == "RR" &&
move->func_mode == "width" && move->params.size() == 2); move->func_mode == "width" && move->params.size() == 2);
@@ -288,8 +288,8 @@ static bool test_negative() {
// fb 字段类型未知 // fb 字段类型未知
{ {
std::string fbs = kFbsAll; std::string fbs = kFbsAll;
const std::string old = "[[\"in\", \"BOOL\"]], [\"pt\", \"TIME\"]"; const std::string old = "[[\"in\", \"BOOL\"], [\"pt\", \"TIME\"]";
const std::string bad = "[[\"in\", \"REAL\"]], [\"pt\", \"TIME\"]"; const std::string bad = "[[\"in\", \"NOPE\"], [\"pt\", \"TIME\"]";
fbs.replace(fbs.find(old), old.size(), bad); fbs.replace(fbs.find(old), old.size(), bad);
if (!expect_load_err("mc_v2_bad12.toml", m + kTypesAll + kOpsBasic + fbs, if (!expect_load_err("mc_v2_bad12.toml", m + kTypesAll + kOpsBasic + fbs,
"unknown field type")) { "unknown field type")) {