阶段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
+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_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 "";
+1 -2
View File
@@ -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));
}
}