diff --git a/compiler/include/compiler/Codec.h b/compiler/include/compiler/Codec.h index a7d93c8..f09b296 100644 --- a/compiler/include/compiler/Codec.h +++ b/compiler/include/compiler/Codec.h @@ -60,8 +60,10 @@ namespace compiler { uint32_t imm32_of(const uint8_t* code); /// @brief 取 slot32(55..24,SLOT 形态)。 uint32_t slot32_of(const uint8_t* code); - /// @brief 取 off32(47..16,JMP/JC 形态,有符号字节偏移)。 + /// @brief 取 off32(47..16,JMP 形态,有符号字节偏移)。 int32_t off32_of(const uint8_t* code); + /// @brief 取 off32(55..24,JC 形态,有符号字节偏移)。 + int32_t off32_jc_of(const uint8_t* code); /// @brief 取 fn_id32(47..16,CALL 形态)。 uint32_t fn_id32_of(const uint8_t* code); /// @brief 取 fb_id16(31..16,CAL 形态)。 @@ -93,8 +95,10 @@ namespace compiler { void set_imm32(uint8_t* out, uint32_t v); /// @brief 写 slot32(55..24)。 void set_slot32(uint8_t* out, uint32_t v); - /// @brief 写 off32(47..16)。 + /// @brief 写 off32(47..16,JMP 形态)。 void set_off32(uint8_t* out, int32_t v); + /// @brief 写 off32(55..24,JC 形态)。 + void set_off32_jc(uint8_t* out, int32_t v); /// @brief 写 fn_id32(47..16)。 void set_fn_id32(uint8_t* out, uint32_t v); /// @brief 写 fb_id16(31..16)。 diff --git a/compiler/src/Codec.cpp b/compiler/src/Codec.cpp index f77de8c..342fa13 100644 --- a/compiler/src/Codec.cpp +++ b/compiler/src/Codec.cpp @@ -121,7 +121,7 @@ uint32_t imm32_of(const uint8_t* code) { uint32_t slot32_of(const uint8_t* code) { return imm32_of(code); } /** - * @brief 取 off32(47..16,小端 4 字节,有符号)。 + * @brief 取 off32(47..16,JMP 形态,小端 4 字节,有符号)。 * @param code 指令字节 * @return 字节偏移(相对下一条) */ @@ -132,6 +132,18 @@ int32_t off32_of(const uint8_t* code) { | (static_cast(code[5]) << 24)); } +/** + * @brief 取 off32(55..24,JC 形态,小端 4 字节,有符号)。 + * @param code 指令字节 + * @return 字节偏移(相对下一条) + */ +int32_t off32_jc_of(const uint8_t* code) { + return static_cast(static_cast(code[3]) + | (static_cast(code[4]) << 8) + | (static_cast(code[5]) << 16) + | (static_cast(code[6]) << 24)); +} + uint32_t fn_id32_of(const uint8_t* code) { return static_cast(code[2]) | (static_cast(code[3]) << 8) @@ -193,9 +205,9 @@ uint64_t imm64_of(const uint8_t* code) { */ void set_byte0(uint8_t* out, const std::string& prefix, uint32_t op) { if (prefix == "11") { - out[0] = static_cast(0x80 | (op & 0x3F)); + out[0] = static_cast(0xC0 | (op & 0x3F)); // bit7..6 = 11 } else if (prefix == "10") { - out[0] = static_cast(0x80 | 0x40 | (op & 0x3F)); + out[0] = static_cast(0x80 | (op & 0x3F)); // bit7..6 = 10 } else if (prefix == "011") { out[0] = static_cast(0x40 | (op & 0x1F)); } else if (prefix.size() == 6 && prefix.compare(0, 3, "010") == 0) { @@ -232,6 +244,14 @@ void set_off32(uint8_t* out, int32_t v) { out[4] = static_cast((u >> 16) & 0xFF); out[5] = static_cast((u >> 24) & 0xFF); } + +void set_off32_jc(uint8_t* out, int32_t v) { + const uint32_t u = static_cast(v); + out[3] = static_cast(u & 0xFF); + out[4] = static_cast((u >> 8) & 0xFF); + out[5] = static_cast((u >> 16) & 0xFF); + out[6] = static_cast((u >> 24) & 0xFF); +} void set_fn_id32(uint8_t* out, uint32_t v) { set_off32(out, static_cast(v)); } void set_fb_id16(uint8_t* out, uint16_t v) { out[2] = static_cast(v & 0xFF); @@ -302,7 +322,7 @@ void disasm(const MachineConfig& cfg, const uint8_t* code, size_t len, snprintf(out, cap, "%s %+d", op->name.c_str(), static_cast(off32_of(code))); } else if (f == "JC") { snprintf(out, cap, "%s r%u, %+d", op->name.c_str(), - static_cast(rd_of(code)), static_cast(off32_of(code))); + static_cast(rd_of(code)), static_cast(off32_jc_of(code))); } else if (f == "CALL") { snprintf(out, cap, "%s %u", op->name.c_str(), static_cast(fn_id32_of(code))); } else if (f == "CAL") { diff --git a/compiler/src/Codegen.cpp b/compiler/src/Codegen.cpp index 6d46add..36cd758 100644 --- a/compiler/src/Codegen.cpp +++ b/compiler/src/Codegen.cpp @@ -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 field_off; ///< 字段名 → 值区内偏移 - uint32_t slot = 0; ///< 实例槽号(槽表条目) - std::string type_name; ///< 实例的 FB 类型名 + std::map field_off; ///< 字段名 → 值区内偏移 + std::map 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( static_cast(target_off) - (static_cast(idx) + static_cast(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(align_up(off, tm.width())); inst.field_off[fd.name] = off; + inst.field_func[fd.name] = static_cast(tm.func()); off += static_cast(tm.width()); } // 实例块对齐到 max(字段对齐) diff --git a/compiler/src/Stb.cpp b/compiler/src/Stb.cpp index 4034747..917ea4a 100644 --- a/compiler/src/Stb.cpp +++ b/compiler/src/Stb.cpp @@ -271,10 +271,9 @@ StbView StbView::from(const uint8_t* buf, size_t len) { v.err_ = "missing sha256 tail"; return v; } - 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) { + const uint64_t offs[5] = {get_le32(buf + kOffConst), get_le32(buf + kOffFuncs), v.offset_code_, + v.offset_slots_, v.offset_values_}; + for (int i = 0; i < 5; ++i) { if (offs[i] < kHeaderSize || offs[i] > len - kSha256Size) { v.err_ = "segment offset out of range"; return v; @@ -296,7 +295,13 @@ StbView StbView::from(const uint8_t* buf, size_t len) { v.err_ = "slot table size mismatch"; return v; } - if (offs[5] - offs[4] != v.values_size_) { + // 值段大小:meta 段为 0(空段)时值段到 SHA 尾;否则到 meta 起点 + if (v.offset_meta_ != 0) { + if (static_cast(v.offset_meta_) - offs[4] != v.values_size_) { + v.err_ = "values segment size mismatch"; + return v; + } + } else if (static_cast(len - kSha256Size) - offs[4] != v.values_size_) { v.err_ = "values segment size mismatch"; return v; } diff --git a/compiler/src/main.cpp b/compiler/src/main.cpp index 21c5924..ec30553 100644 --- a/compiler/src/main.cpp +++ b/compiler/src/main.cpp @@ -81,12 +81,14 @@ namespace { std::printf(" fn %u: nregs=%u, offset=%u, len=%u\n", i, r.nregs, r.code_offset, r.code_len); const uint8_t* base = v.code_bytes() + r.code_offset; - for (uint32_t j = 0; j < r.code_len; ++j) { + uint32_t pc = 0; + while (pc < r.code_len) { char buf[64]; - // TODO(V2): Stb 重写(阶段2-4)后 code_len 为字节、instr_len 定长 - compiler::disasm(cfg, base + j * 4, 4, buf, sizeof buf); + const size_t ilen = compiler::instr_len(base + pc); + compiler::disasm(cfg, base + pc, ilen, buf, sizeof buf); std::printf(" 0x%04x %s\n", - v.offset_code() + r.code_offset + j * 4, buf); + v.offset_code() + r.code_offset + pc, buf); + pc += static_cast(ilen); } }