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