captures for "when" statements

update Triggers to IntrusivePtr's and simpler AST traversal
introduce IDSet type, migrate associated "ID*" types to "const ID*"
This commit is contained in:
Vern Paxson 2022-01-07 14:50:35 -08:00
parent fa142438fe
commit f895008c34
24 changed files with 648 additions and 202 deletions

View file

@ -656,7 +656,7 @@ void ZAMCompiler::ReMapInterpreterFrame()
remapped_intrp_frame_sizes[func] = next_interp_slot;
}
void ZAMCompiler::ReMapVar(ID* id, int slot, bro_uint_t inst)
void ZAMCompiler::ReMapVar(const ID* id, int slot, bro_uint_t inst)
{
// A greedy algorithm for this is to simply find the first suitable
// frame slot. We do that with one twist: we also look for a
@ -832,7 +832,7 @@ void ZAMCompiler::ExtendLifetime(int slot, const ZInstI* inst)
if ( inst_endings.count(inst) == 0 )
{
std::unordered_set<ID*> denizens;
IDSet denizens;
inst_endings[inst] = denizens;
}

View file

@ -349,10 +349,10 @@ private:
bool IsUnused(const IDPtr& id, const Stmt* where) const;
void LoadParam(ID* id);
const ZAMStmt LoadGlobal(ID* id);
void LoadParam(const ID* id);
const ZAMStmt LoadGlobal(const ID* id);
int AddToFrame(ID*);
int AddToFrame(const ID*);
int FrameSlot(const IDPtr& id) { return FrameSlot(id.get()); }
int FrameSlot(const ID* id);
@ -420,7 +420,7 @@ private:
// Computes the remapping for a variable currently in the given slot,
// whose scope begins at the given instruction.
void ReMapVar(ID* id, int slot, bro_uint_t inst);
void ReMapVar(const ID* id, int slot, bro_uint_t inst);
// Look to initialize the beginning of local lifetime based on slot
// assignment at instruction inst.
@ -541,7 +541,7 @@ private:
// A type for mapping an instruction to a set of locals associated
// with it.
using AssociatedLocals = std::unordered_map<const ZInstI*, std::unordered_set<ID*>>;
using AssociatedLocals = std::unordered_map<const ZInstI*, IDSet>;
// Maps (live) instructions to which frame denizens begin their
// lifetime via an initialization at that instruction, if any ...

View file

@ -1740,20 +1740,23 @@ eval (*tiv_ptr)[z.v1].Clear();
op When
op1-read
type VVVV
eval auto when_body = new ZAMResumption(this, z.v2);
auto timeout_body = new ZAMResumption(this, z.v3);
new trigger::Trigger(z.e, when_body, timeout_body, frame[z.v1].double_val, f, z.v4, z.loc);
eval auto when_body = make_intrusive<ZAMResumption>(this, z.v2);
auto timeout_body = make_intrusive<ZAMResumption>(this, z.v3);
ExprPtr when_cond = {NewRef{}, const_cast<Expr*>(z.e)};
new trigger::Trigger(when_cond, when_body, timeout_body, frame[z.v1].double_val, f, z.v4, z.loc);
op When
type VVVC
eval auto when_body = new ZAMResumption(this, z.v1);
auto timeout_body = new ZAMResumption(this, z.v2);
new trigger::Trigger(z.e, when_body, timeout_body, z.c.double_val, f, z.v3, z.loc);
eval auto when_body = make_intrusive<ZAMResumption>(this, z.v1);
auto timeout_body = make_intrusive<ZAMResumption>(this, z.v2);
ExprPtr when_cond = {NewRef{}, const_cast<Expr*>(z.e)};
new trigger::Trigger(when_cond, when_body, timeout_body, z.c.double_val, f, z.v3, z.loc);
op When
type VV
eval auto when_body = new ZAMResumption(this, z.v2);
new trigger::Trigger(z.e, when_body, nullptr, -1.0, f, z.v1, z.loc);
eval auto when_body = make_intrusive<ZAMResumption>(this, z.v2);
ExprPtr when_cond = {NewRef{}, const_cast<Expr*>(z.e)};
new trigger::Trigger(when_cond, when_body, nullptr, -1.0, f, z.v1, z.loc);
op CheckAnyLen
op1-read

View file

@ -1115,7 +1115,7 @@ const ZAMStmt ZAMCompiler::CompileWhen(const WhenStmt* ws)
z.v1 = is_return;
}
z.e = cond;
z.e = cond.get();
auto when_eval = AddInst(z);

View file

@ -24,7 +24,7 @@ bool ZAMCompiler::IsUnused(const IDPtr& id, const Stmt* where) const
return ! usage || ! usage->HasID(id.get());
}
void ZAMCompiler::LoadParam(ID* id)
void ZAMCompiler::LoadParam(const ID* id)
{
if ( id->IsType() )
reporter->InternalError(
@ -45,7 +45,7 @@ void ZAMCompiler::LoadParam(ID* id)
(void)AddInst(z);
}
const ZAMStmt ZAMCompiler::LoadGlobal(ID* id)
const ZAMStmt ZAMCompiler::LoadGlobal(const ID* id)
{
ZOp op;
@ -69,7 +69,7 @@ const ZAMStmt ZAMCompiler::LoadGlobal(ID* id)
return AddInst(z);
}
int ZAMCompiler::AddToFrame(ID* id)
int ZAMCompiler::AddToFrame(const ID* id)
{
frame_layout1[id] = frame_sizeI;
frame_denizens.push_back(id);

View file

@ -18,7 +18,7 @@ class Stmt;
using AttributesPtr = IntrusivePtr<Attributes>;
// Maps ZAM frame slots to associated identifiers.
using FrameMap = std::vector<ID*>;
using FrameMap = std::vector<const ID*>;
// Maps ZAM frame slots to information for sharing the slot across
// multiple script variables.
@ -28,7 +28,7 @@ public:
// The variables sharing the slot. ID's need to be non-const so we
// can manipulate them, for example by changing their interpreter
// frame offset.
std::vector<ID*> ids;
std::vector<const ID*> ids;
// A parallel vector, only used for fully compiled code, which
// gives the names of the identifiers. When in use, the above
@ -402,7 +402,7 @@ public:
TypePtr* types = nullptr;
// Used for accessing function names.
ID* id_val = nullptr;
const ID* id_val = nullptr;
// Whether the instruction can lead to globals changing.
// Currently only needed by the optimizer, but convenient