阶段2-6:V2 生成侧 bug 修复与验证收尾
- Codec:set_byte0 的 11/10 前缀位修正(0xC0/0x80);新增 JC 形态偏移 专用读写(off@55..24,字节 3..6)——修复 JF rd 被 off 覆盖 - Stb:offset_meta=0(空段)时值段大小校验按 SHA 尾计算(修复 values segment size mismatch) - Codegen:实例字段带 func(field_func),LOAD_OFF/STORE_OFF 按字段 类型设 func(pt=TIME → I64) - main.cpp:--disasm 按 instr_len 迭代变长字节码 - 验证:13 个正例全部编译出 V2 产物 + disasm 自读通过(RET/CAL.TON/ STORE_OFF.I64/JF 偏移等抽查正确);ctest 11/13(vm/cases 待阶段 4)
This commit is contained in:
+33
-16
@@ -175,11 +175,11 @@ namespace {
|
||||
set_off32(f.code.data() + s, off);
|
||||
return s;
|
||||
}
|
||||
/// 条件跳转(r 为真则跳;off 字节相对下一条)。
|
||||
/// 条件跳转(r 为真则跳;off 字节相对下一条,JC 形态 off@55..24)。
|
||||
size_t E_jc(FuncCtx& f, const char* name, uint8_t r, int32_t off) {
|
||||
const size_t s = emit(f, opc(name));
|
||||
set_rd(f.code.data() + s, r);
|
||||
set_off32(f.code.data() + s, off);
|
||||
set_off32_jc(f.code.data() + s, off);
|
||||
return s;
|
||||
}
|
||||
/// CALL 指令(fn_id32)。
|
||||
@@ -241,9 +241,10 @@ namespace {
|
||||
* @brief FB 实例布局(V2:槽表条目 + 值区偏移 + 字段偏移)。
|
||||
*/
|
||||
struct InstFields {
|
||||
std::map<std::string, int32_t> field_off; ///< 字段名 → 值区内偏移
|
||||
uint32_t slot = 0; ///< 实例槽号(槽表条目)
|
||||
std::string type_name; ///< 实例的 FB 类型名
|
||||
std::map<std::string, int32_t> field_off; ///< 字段名 → 值区内偏移
|
||||
std::map<std::string, uint8_t> field_func; ///< 字段名 → func(类型)
|
||||
uint32_t slot = 0; ///< 实例槽号(槽表条目)
|
||||
std::string type_name; ///< 实例的 FB 类型名
|
||||
};
|
||||
|
||||
void begin_stmt(FuncCtx& f) { f.temp_used = 0; }
|
||||
@@ -344,7 +345,12 @@ namespace {
|
||||
if (!compile_expr(f, *st.value, t)) {
|
||||
return false;
|
||||
}
|
||||
E_slot_off(f, "STORE_OFF", t, inline_fields_->slot, fit->second);
|
||||
const size_t so = E_slot_off(f, "STORE_OFF", t, inline_fields_->slot,
|
||||
fit->second);
|
||||
const auto ff = inline_fields_->field_func.find(st.target);
|
||||
if (ff != inline_fields_->field_func.end()) {
|
||||
set_func(f.code.data() + so, ff->second);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -372,7 +378,11 @@ namespace {
|
||||
if (!compile_expr(f, *a.value, t)) {
|
||||
return false;
|
||||
}
|
||||
E_slot_off(f, "STORE_OFF", t, inst->slot, it->second);
|
||||
const size_t so = E_slot_off(f, "STORE_OFF", t, inst->slot, it->second);
|
||||
const auto ff = inst->field_func.find(a.name);
|
||||
if (ff != inst->field_func.end()) {
|
||||
set_func(f.code.data() + so, ff->second);
|
||||
}
|
||||
}
|
||||
// 内建 FB:fb 表查 id
|
||||
const ConfigFb* fb = cfg_.find_fb(uppercase_of(inst->type_name));
|
||||
@@ -498,7 +508,12 @@ namespace {
|
||||
if (inline_fields_) {
|
||||
const auto fit = inline_fields_->field_off.find(e.name);
|
||||
if (fit != inline_fields_->field_off.end()) {
|
||||
E_slot_off(f, "LOAD_OFF", rd, inline_fields_->slot, fit->second);
|
||||
const size_t lo = E_slot_off(f, "LOAD_OFF", rd,
|
||||
inline_fields_->slot, fit->second);
|
||||
const auto ff = inline_fields_->field_func.find(e.name);
|
||||
if (ff != inline_fields_->field_func.end()) {
|
||||
set_func(f.code.data() + lo, ff->second);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -527,7 +542,11 @@ namespace {
|
||||
if (fit == inst->field_off.end()) {
|
||||
return fail("unknown field '" + e.field + "' for '" + e.name + "'");
|
||||
}
|
||||
E_slot_off(f, "LOAD_OFF", rd, inst->slot, fit->second);
|
||||
const size_t lo = E_slot_off(f, "LOAD_OFF", rd, inst->slot, fit->second);
|
||||
const auto ff = inst->field_func.find(e.field);
|
||||
if (ff != inst->field_func.end()) {
|
||||
set_func(f.code.data() + lo, ff->second);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (e.kind == ExprKind::Add || e.kind == ExprKind::Sub ||
|
||||
@@ -636,16 +655,13 @@ namespace {
|
||||
const int32_t off = static_cast<int32_t>(
|
||||
static_cast<int64_t>(target_off) -
|
||||
(static_cast<int64_t>(idx) + static_cast<int64_t>(instr_len(f.code.data() + idx))));
|
||||
const ConfigOp* j = nullptr;
|
||||
// 按字节 0 前缀推导跳转指令:JMP/JT/JF(010010/010011 区)
|
||||
// 按前缀选偏移字段:JMP(010010)off@47..16;JT/JF(010011)off@55..24
|
||||
const std::string prefix = prefix_of(f.code.data() + idx);
|
||||
if (prefix == "010010") {
|
||||
j = cfg_.find_op("JMP");
|
||||
} else if (prefix == "010011") {
|
||||
j = cfg_.find_op("JF"); // 占位:JF/JT 按 rd 区分不必要(偏移相同)
|
||||
set_off32(f.code.data() + idx, off);
|
||||
} else {
|
||||
set_off32_jc(f.code.data() + idx, off);
|
||||
}
|
||||
(void)j;
|
||||
set_off32(f.code.data() + idx, off);
|
||||
}
|
||||
|
||||
static const char* arith_name(ExprKind k) {
|
||||
@@ -717,6 +733,7 @@ namespace {
|
||||
}
|
||||
off = static_cast<int32_t>(align_up(off, tm.width()));
|
||||
inst.field_off[fd.name] = off;
|
||||
inst.field_func[fd.name] = static_cast<uint8_t>(tm.func());
|
||||
off += static_cast<int32_t>(tm.width());
|
||||
}
|
||||
// 实例块对齐到 max(字段对齐)
|
||||
|
||||
Reference in New Issue
Block a user