步骤3:Codegen VAR_TEMP——初值装载(emit_temp_init)+ FB 内联 Temp 固定寄存器(nlocals 隔离临时区)+ VarRef/赋值 fallback

This commit is contained in:
2026-08-26 17:58:32 +08:00
parent 94634dc0b0
commit 536ad1a96b
+75
View File
@@ -120,6 +120,8 @@ namespace {
std::vector<uint8_t> code; ///< 字节码(变长指令,字节流)
std::map<std::string, uint8_t> regs; ///< 变量名 → 帧寄存器
std::map<std::string, uint8_t> reg_func; ///< 变量名 → func(类型)
std::map<std::string, uint8_t> fb_temp; ///< FB 内联 VAR_TEMP → 帧寄存器(当前内联层)
std::map<std::string, uint8_t> fb_temp_func; ///< FB 内联 VAR_TEMP → func
uint8_t nlocals = 0; ///< 变量区终点 = 临时寄存器起始
uint8_t nregs = 0; ///< 寄存器峰值
uint8_t temp_used = 0; ///< 本语句已用临时数
@@ -266,6 +268,33 @@ namespace {
return "int";
}
/// VAR_TEMP 初值装载:对 temp_map 中每个变量 emit LOADK(声明初值或 0)。
/// temp_map 键为变量名、值为 (寄存器, func);调用点开头执行 → 每次调用重新初始化。
void emit_temp_init(FuncCtx& f, const POU& pou,
const std::map<std::string, uint8_t>& map,
const std::map<std::string, uint8_t>& func_map) {
for (const VarBlock& b : pou.blocks) {
if (b.section != VarSection::Temp) {
continue;
}
for (const VarDecl& d : b.vars) {
const auto it = map.find(d.name);
if (it == map.end()) {
continue;
}
const uint8_t func = func_map.count(d.name)
? func_map.at(d.name)
: func_of_name("INT");
int64_t v = d.has_init ? d.init_value : 0;
if (d.has_init && d.type.name == "bool") {
v = d.init_value ? 1 : 0;
}
const size_t s = E_imm(f, "LOADK", it->second, const_id(v));
set_func(f.code.data() + s, func);
}
}
}
bool build_function(const POU& pou, FuncCtx* f) {
if (pou.kind == PouKind::FunctionBlock) {
f->nlocals = 8;
@@ -320,6 +349,7 @@ namespace {
}
map_->funcs.emplace_back(f->name, vars);
}
emit_temp_init(*f, pou, f->regs, f->reg_func);
for (const Stmt& st : pou.body) {
begin_stmt(*f);
if (!compile_stmt(*f, st)) {
@@ -363,6 +393,18 @@ namespace {
return true;
}
}
const auto tit = f.fb_temp.find(st.target);
if (tit != f.fb_temp.end()) {
const uint8_t t = alloc_temp(f);
const uint8_t tf_ = f.fb_temp_func.count(st.target)
? f.fb_temp_func.at(st.target)
: func_of_name("INT");
if (!compile_expr(f, *st.value, t, tf_)) {
return false;
}
E_rr(f, "MOVE", tit->second, t);
return true;
}
const auto it = f.regs.find(st.target);
if (it == f.regs.end()) {
return store_target(f, st.target, *st.value);
@@ -421,12 +463,36 @@ namespace {
bool compile_fb_inline(FuncCtx& f, const POU& fb, const InstFields& inst) {
const InstFields* saved = inline_fields_;
inline_fields_ = &inst;
// VAR_TEMP:本调用点分配独立固定寄存器(MAIN 帧,nregs 之后),
// 内联体开头装载初值 → 每次调用重新初始化;嵌套内联 save/restore
const std::map<std::string, uint8_t> saved_temp = f.fb_temp;
const std::map<std::string, uint8_t> saved_temp_func = f.fb_temp_func;
f.fb_temp.clear();
f.fb_temp_func.clear();
for (const VarBlock& b : fb.blocks) {
if (b.section != VarSection::Temp) {
continue;
}
for (const VarDecl& d : b.vars) {
if (d.type.kind != TypeKind::Scalar) {
continue;
}
const uint8_t r = f.nregs++;
f.fb_temp[d.name] = r;
f.fb_temp_func[d.name] = func_of_name(type_name_of_var(fb, d.name));
}
}
// 临时寄存器起点提到 Temp 区之上,避免语句内 alloc_temp 撞上 Temp 寄存器
f.nlocals = f.nregs;
emit_temp_init(f, fb, f.fb_temp, f.fb_temp_func);
for (const Stmt& s : fb.body) {
begin_stmt(f);
if (!compile_stmt(f, s)) {
return false;
}
}
f.fb_temp = saved_temp;
f.fb_temp_func = saved_temp_func;
inline_fields_ = saved;
return true;
}
@@ -554,6 +620,15 @@ namespace {
return true;
}
}
const auto tit = f.fb_temp.find(e.name);
if (tit != f.fb_temp.end()) {
const size_t s = E_rr(f, "MOVE", rd, tit->second);
const auto tf = f.fb_temp_func.find(e.name);
set_func(f.code.data() + s,
tf != f.fb_temp_func.end() ? tf->second
: func_of_name("INT"));
return true;
}
const auto sit = f.regs.find(e.name);
if (sit != f.regs.end()) {
const size_t s = E_rr(f, "MOVE", rd, sit->second);