ZAM bug fix for incorrect management of global variables

This commit is contained in:
Vern Paxson 2023-06-14 17:44:48 -07:00
parent 5722596970
commit 40054e5f77
3 changed files with 29 additions and 32 deletions

View file

@ -333,7 +333,10 @@ private:
// Returns how many values were added. // Returns how many values were added.
int InternalAddVal(ZInstAux* zi, int i, Expr* e); int InternalAddVal(ZInstAux* zi, int i, Expr* e);
const ZAMStmt AddInst(const ZInstI& inst); // Adds the given instruction to the ZAM program. The second
// argument, if true, suppresses generation of any pending
// global/capture store for this instruction.
const ZAMStmt AddInst(const ZInstI& inst, bool suppress_non_local = false);
// Returns the statement just before the given one. // Returns the statement just before the given one.
ZAMStmt PrevStmt(const ZAMStmt s); ZAMStmt PrevStmt(const ZAMStmt s);

View file

@ -128,7 +128,7 @@ int ZAMCompiler::InternalAddVal(ZInstAux* zi, int i, Expr* e)
return 1; return 1;
} }
const ZAMStmt ZAMCompiler::AddInst(const ZInstI& inst) const ZAMStmt ZAMCompiler::AddInst(const ZInstI& inst, bool suppress_non_local)
{ {
ZInstI* i; ZInstI* i;
@ -146,19 +146,24 @@ const ZAMStmt ZAMCompiler::AddInst(const ZInstI& inst)
top_main_inst = insts1.size() - 1; top_main_inst = insts1.size() - 1;
if ( pending_global_store < 0 ) if ( suppress_non_local )
return ZAMStmt(top_main_inst); return ZAMStmt(top_main_inst);
auto global_slot = pending_global_store; if ( pending_global_store >= 0 )
{
auto gs = pending_global_store;
pending_global_store = -1; pending_global_store = -1;
auto store_inst = ZInstI(OP_STORE_GLOBAL_V, global_slot); auto store_inst = ZInstI(OP_STORE_GLOBAL_V, gs);
store_inst.op_type = OP_V_I1; store_inst.op_type = OP_V_I1;
store_inst.t = globalsI[global_slot].id->GetType(); store_inst.t = globalsI[gs].id->GetType();
return AddInst(store_inst); return AddInst(store_inst);
} }
return ZAMStmt(top_main_inst);
}
const Stmt* ZAMCompiler::LastStmt(const Stmt* s) const const Stmt* ZAMCompiler::LastStmt(const Stmt* s) const
{ {
if ( s->Tag() == STMT_LIST ) if ( s->Tag() == STMT_LIST )

View file

@ -66,7 +66,7 @@ const ZAMStmt ZAMCompiler::LoadGlobal(const ID* id)
z.aux = new ZInstAux(0); z.aux = new ZInstAux(0);
z.aux->id_val = id; z.aux->id_val = id;
return AddInst(z); return AddInst(z, true);
} }
int ZAMCompiler::AddToFrame(const ID* id) int ZAMCompiler::AddToFrame(const ID* id)
@ -81,38 +81,27 @@ int ZAMCompiler::FrameSlot(const ID* id)
auto slot = RawSlot(id); auto slot = RawSlot(id);
if ( id->IsGlobal() ) if ( id->IsGlobal() )
(void)LoadGlobal(frame_denizens[slot]); (void)LoadGlobal(id);
return slot; return slot;
} }
int ZAMCompiler::Frame1Slot(const ID* id, ZAMOp1Flavor fl) int ZAMCompiler::Frame1Slot(const ID* id, ZAMOp1Flavor fl)
{ {
auto slot = RawSlot(id); if ( fl == OP1_READ )
return FrameSlot(id);
switch ( fl ) if ( fl == OP1_INTERNAL )
{ return RawSlot(id);
case OP1_READ:
if ( id->IsGlobal() ) ASSERT(fl == OP1_WRITE || fl == OP1_READ_WRITE);
(void)LoadGlobal(frame_denizens[slot]);
break; // Important: get the slot *before* tracking non-locals, so we don't
// prematurely generate a Store for the read/write case.
auto slot = fl == OP1_READ_WRITE ? FrameSlot(id) : RawSlot(id);
case OP1_WRITE:
if ( id->IsGlobal() ) if ( id->IsGlobal() )
pending_global_store = global_id_to_info[id]; pending_global_store = global_id_to_info[id];
break;
case OP1_READ_WRITE:
if ( id->IsGlobal() )
{
(void)LoadGlobal(frame_denizens[slot]);
pending_global_store = global_id_to_info[id];
}
break;
case OP1_INTERNAL:
break;
}
return slot; return slot;
} }