mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
better isolation of ZAM instruction elements
hooks for tracking extended ZAM profiling location
This commit is contained in:
parent
dc376953fa
commit
9f9f01580f
6 changed files with 134 additions and 90 deletions
|
@ -577,7 +577,7 @@ void ZAMCompiler::ReMapFrame() {
|
||||||
|
|
||||||
if ( new_slot < 0 ) {
|
if ( new_slot < 0 ) {
|
||||||
ODesc d;
|
ODesc d;
|
||||||
inst->stmt->GetLocationInfo()->Describe(&d);
|
inst->loc->Loc()->Describe(&d);
|
||||||
reporter->Error("%s: value used but not set: %s", d.Description(),
|
reporter->Error("%s: value used but not set: %s", d.Description(),
|
||||||
frame_denizens[slot]->Name());
|
frame_denizens[slot]->Name());
|
||||||
}
|
}
|
||||||
|
@ -748,7 +748,7 @@ void ZAMCompiler::CheckSlotUse(int slot, const ZInstI* inst) {
|
||||||
|
|
||||||
if ( denizen_beginning.count(slot) == 0 ) {
|
if ( denizen_beginning.count(slot) == 0 ) {
|
||||||
ODesc d;
|
ODesc d;
|
||||||
inst->stmt->GetLocationInfo()->Describe(&d);
|
inst->loc->Loc()->Describe(&d);
|
||||||
reporter->Error("%s: value used but not set: %s", d.Description(), frame_denizens[slot]->Name());
|
reporter->Error("%s: value used but not set: %s", d.Description(), frame_denizens[slot]->Name());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -228,6 +228,7 @@ private:
|
||||||
const ZAMStmt Call(const ExprStmt* e);
|
const ZAMStmt Call(const ExprStmt* e);
|
||||||
const ZAMStmt AssignToCall(const ExprStmt* e);
|
const ZAMStmt AssignToCall(const ExprStmt* e);
|
||||||
const ZAMStmt DoCall(const CallExpr* c, const NameExpr* n);
|
const ZAMStmt DoCall(const CallExpr* c, const NameExpr* n);
|
||||||
|
bool CheckForBuiltIn(const ExprPtr& e, CallExprPtr c);
|
||||||
|
|
||||||
const ZAMStmt AssignVecElems(const Expr* e);
|
const ZAMStmt AssignVecElems(const Expr* e);
|
||||||
const ZAMStmt AssignTableElem(const Expr* e);
|
const ZAMStmt AssignTableElem(const Expr* e);
|
||||||
|
|
|
@ -315,6 +315,7 @@ const ZAMStmt ZAMCompiler::CompileSchedule(const NameExpr* n, const ConstExpr* c
|
||||||
if ( len == 0 ) {
|
if ( len == 0 ) {
|
||||||
z = n ? ZInstI(OP_SCHEDULE0_ViH, FrameSlot(n), is_interval) : ZInstI(OP_SCHEDULE0_CiH, is_interval, c);
|
z = n ? ZInstI(OP_SCHEDULE0_ViH, FrameSlot(n), is_interval) : ZInstI(OP_SCHEDULE0_CiH, is_interval, c);
|
||||||
z.op_type = n ? OP_VV_I2 : OP_VC_I1;
|
z.op_type = n ? OP_VV_I2 : OP_VC_I1;
|
||||||
|
z.aux = new ZInstAux(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
|
@ -330,7 +331,7 @@ const ZAMStmt ZAMCompiler::CompileSchedule(const NameExpr* n, const ConstExpr* c
|
||||||
z.aux = InternalBuildVals(l);
|
z.aux = InternalBuildVals(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
z.event_handler = h;
|
z.aux->event_handler = h;
|
||||||
|
|
||||||
return AddInst(z);
|
return AddInst(z);
|
||||||
}
|
}
|
||||||
|
@ -349,12 +350,11 @@ const ZAMStmt ZAMCompiler::CompileEvent(EventHandler* h, const ListExpr* l) {
|
||||||
if ( n > 4 || ! all_vars ) { // do generic form
|
if ( n > 4 || ! all_vars ) { // do generic form
|
||||||
ZInstI z(OP_EVENT_HL);
|
ZInstI z(OP_EVENT_HL);
|
||||||
z.aux = InternalBuildVals(l);
|
z.aux = InternalBuildVals(l);
|
||||||
z.event_handler = h;
|
z.aux->event_handler = h;
|
||||||
return AddInst(z);
|
return AddInst(z);
|
||||||
}
|
}
|
||||||
|
|
||||||
ZInstI z;
|
ZInstI z;
|
||||||
z.event_handler = h;
|
|
||||||
|
|
||||||
if ( n == 0 ) {
|
if ( n == 0 ) {
|
||||||
z.op = OP_EVENT0_X;
|
z.op = OP_EVENT0_X;
|
||||||
|
@ -403,6 +403,11 @@ const ZAMStmt ZAMCompiler::CompileEvent(EventHandler* h, const ListExpr* l) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( ! z.aux )
|
||||||
|
z.aux = new ZInstAux(0);
|
||||||
|
|
||||||
|
z.aux->event_handler = h;
|
||||||
|
|
||||||
return AddInst(z);
|
return AddInst(z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -872,11 +877,8 @@ const ZAMStmt ZAMCompiler::AssignTableElem(const Expr* e) {
|
||||||
const ZAMStmt ZAMCompiler::Call(const ExprStmt* e) {
|
const ZAMStmt ZAMCompiler::Call(const ExprStmt* e) {
|
||||||
auto c = cast_intrusive<CallExpr>(e->StmtExprPtr());
|
auto c = cast_intrusive<CallExpr>(e->StmtExprPtr());
|
||||||
|
|
||||||
if ( IsZAM_BuiltIn(c.get()) ) {
|
if ( CheckForBuiltIn(c, c) )
|
||||||
auto ret = LastInst();
|
return LastInst();
|
||||||
insts1.back()->call_expr = std::move(c);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return DoCall(e->StmtExpr()->AsCallExpr(), nullptr);
|
return DoCall(e->StmtExpr()->AsCallExpr(), nullptr);
|
||||||
}
|
}
|
||||||
|
@ -885,26 +887,37 @@ const ZAMStmt ZAMCompiler::AssignToCall(const ExprStmt* e) {
|
||||||
auto assign = e->StmtExpr()->AsAssignExpr();
|
auto assign = e->StmtExpr()->AsAssignExpr();
|
||||||
auto call = cast_intrusive<CallExpr>(assign->GetOp2());
|
auto call = cast_intrusive<CallExpr>(assign->GetOp2());
|
||||||
|
|
||||||
if ( IsZAM_BuiltIn(e->StmtExpr()) ) {
|
if ( CheckForBuiltIn(e->StmtExprPtr(), call) )
|
||||||
auto ret = LastInst();
|
return LastInst();
|
||||||
insts1.back()->call_expr = call;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto n = assign->GetOp1()->AsRefExpr()->GetOp1()->AsNameExpr();
|
auto n = assign->GetOp1()->AsRefExpr()->GetOp1()->AsNameExpr();
|
||||||
|
|
||||||
return DoCall(call.get(), n);
|
return DoCall(call.get(), n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ZAMCompiler::CheckForBuiltIn(const ExprPtr& e, CallExprPtr c) {
|
||||||
|
if ( ! IsZAM_BuiltIn(e.get()) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto ret = LastInst();
|
||||||
|
auto& i = insts1.back();
|
||||||
|
if ( ! i->aux )
|
||||||
|
i->aux = new ZInstAux(0);
|
||||||
|
i->aux->call_expr = c;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
const ZAMStmt ZAMCompiler::DoCall(const CallExpr* c, const NameExpr* n) {
|
const ZAMStmt ZAMCompiler::DoCall(const CallExpr* c, const NameExpr* n) {
|
||||||
auto func = c->Func()->AsNameExpr();
|
auto func = c->Func()->AsNameExpr();
|
||||||
auto func_id = func->IdPtr();
|
auto func_id = func->IdPtr();
|
||||||
|
auto func_val = func_id->GetVal();
|
||||||
auto& args = c->Args()->Exprs();
|
auto& args = c->Args()->Exprs();
|
||||||
|
|
||||||
int nargs = args.length();
|
int nargs = args.length();
|
||||||
int call_case = nargs;
|
int call_case = nargs;
|
||||||
|
|
||||||
bool indirect = ! func_id->IsGlobal() || ! func_id->GetVal();
|
bool indirect = ! func_id->IsGlobal() || ! func_val;
|
||||||
bool in_when = c->IsInWhen();
|
bool in_when = c->IsInWhen();
|
||||||
|
|
||||||
if ( indirect || in_when )
|
if ( indirect || in_when )
|
||||||
|
@ -1041,7 +1054,7 @@ const ZAMStmt ZAMCompiler::DoCall(const CallExpr* c, const NameExpr* n) {
|
||||||
z.aux->can_change_non_locals = true;
|
z.aux->can_change_non_locals = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
z.call_expr = {NewRef{}, const_cast<CallExpr*>(c)};
|
z.aux->call_expr = {NewRef{}, const_cast<CallExpr*>(c)};
|
||||||
|
|
||||||
if ( in_when )
|
if ( in_when )
|
||||||
z.SetType(n->GetType());
|
z.SetType(n->GetType());
|
||||||
|
@ -1049,8 +1062,11 @@ const ZAMStmt ZAMCompiler::DoCall(const CallExpr* c, const NameExpr* n) {
|
||||||
if ( ! indirect || func_id->IsGlobal() ) {
|
if ( ! indirect || func_id->IsGlobal() ) {
|
||||||
z.aux->id_val = func_id;
|
z.aux->id_val = func_id;
|
||||||
|
|
||||||
if ( ! indirect )
|
if ( ! indirect ) {
|
||||||
z.func = func_id->GetVal()->AsFunc();
|
z.aux->func = func_id->GetVal()->AsFunc();
|
||||||
|
if ( z.aux->func->GetKind() == Func::BUILTIN_FUNC )
|
||||||
|
z.aux->is_BiF_call = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return AddInst(z);
|
return AddInst(z);
|
||||||
|
@ -1064,11 +1080,11 @@ const ZAMStmt ZAMCompiler::ConstructTable(const NameExpr* n, const Expr* e) {
|
||||||
auto z = GenInst(OP_CONSTRUCT_TABLE_VV, n, width);
|
auto z = GenInst(OP_CONSTRUCT_TABLE_VV, n, width);
|
||||||
z.aux = InternalBuildVals(con, width + 1);
|
z.aux = InternalBuildVals(con, width + 1);
|
||||||
z.t = tt;
|
z.t = tt;
|
||||||
z.attrs = e->AsTableConstructorExpr()->GetAttrs();
|
z.aux->attrs = e->AsTableConstructorExpr()->GetAttrs();
|
||||||
|
|
||||||
auto zstmt = AddInst(z);
|
auto zstmt = AddInst(z);
|
||||||
|
|
||||||
auto def_attr = z.attrs ? z.attrs->Find(ATTR_DEFAULT) : nullptr;
|
auto def_attr = z.aux->attrs ? z.aux->attrs->Find(ATTR_DEFAULT) : nullptr;
|
||||||
if ( ! def_attr || def_attr->GetExpr()->Tag() != EXPR_LAMBDA )
|
if ( ! def_attr || def_attr->GetExpr()->Tag() != EXPR_LAMBDA )
|
||||||
return zstmt;
|
return zstmt;
|
||||||
|
|
||||||
|
@ -1102,7 +1118,7 @@ const ZAMStmt ZAMCompiler::ConstructSet(const NameExpr* n, const Expr* e) {
|
||||||
auto z = GenInst(OP_CONSTRUCT_SET_VV, n, width);
|
auto z = GenInst(OP_CONSTRUCT_SET_VV, n, width);
|
||||||
z.aux = InternalBuildVals(con, width);
|
z.aux = InternalBuildVals(con, width);
|
||||||
z.t = e->GetType();
|
z.t = e->GetType();
|
||||||
z.attrs = e->AsSetConstructorExpr()->GetAttrs();
|
z.aux->attrs = e->AsSetConstructorExpr()->GetAttrs();
|
||||||
|
|
||||||
return AddInst(z);
|
return AddInst(z);
|
||||||
}
|
}
|
||||||
|
|
|
@ -273,7 +273,7 @@ macro AssignV1T(v, t) {
|
||||||
# the instruction.
|
# the instruction.
|
||||||
macro AssignV1(v) AssignV1T(v, z.t)
|
macro AssignV1(v) AssignV1T(v, z.t)
|
||||||
|
|
||||||
macro BRANCH(target_slot) { pc = z.target_slot; continue; }
|
macro BRANCH(target_slot) { DO_ZAM_PROFILE; pc = z.target_slot; continue; }
|
||||||
|
|
||||||
########## Unary Ops ##########
|
########## Unary Ops ##########
|
||||||
|
|
||||||
|
@ -1153,7 +1153,7 @@ direct-unary-op Table-Constructor ConstructTable
|
||||||
|
|
||||||
macro ConstructTableOrSetPre()
|
macro ConstructTableOrSetPre()
|
||||||
auto tt = cast_intrusive<TableType>(z.t);
|
auto tt = cast_intrusive<TableType>(z.t);
|
||||||
auto new_t = new TableVal(tt, z.attrs);
|
auto new_t = new TableVal(tt, z.aux->attrs);
|
||||||
auto aux = z.aux;
|
auto aux = z.aux;
|
||||||
auto n = aux->n;
|
auto n = aux->n;
|
||||||
auto ind_width = z.v2;
|
auto ind_width = z.v2;
|
||||||
|
@ -1654,7 +1654,7 @@ macro WhenCall(func)
|
||||||
throw ZAMDelayedCallException();
|
throw ZAMDelayedCallException();
|
||||||
auto& lhs = frame[z.v1];
|
auto& lhs = frame[z.v1];
|
||||||
auto trigger = f->GetTrigger();
|
auto trigger = f->GetTrigger();
|
||||||
Val* v = trigger ? trigger->Lookup(z.call_expr.get()) : nullptr;
|
Val* v = trigger ? trigger->Lookup(z.aux->call_expr.get()) : nullptr;
|
||||||
ValPtr vp;
|
ValPtr vp;
|
||||||
if ( v )
|
if ( v )
|
||||||
vp = {NewRef{}, v};
|
vp = {NewRef{}, v};
|
||||||
|
@ -1666,7 +1666,7 @@ macro WhenCall(func)
|
||||||
std::vector<ValPtr> args;
|
std::vector<ValPtr> args;
|
||||||
for ( auto i = 0; i < n; ++i )
|
for ( auto i = 0; i < n; ++i )
|
||||||
args.push_back(aux->ToVal(frame, i));
|
args.push_back(aux->ToVal(frame, i));
|
||||||
f->SetCall(z.call_expr.get());
|
f->SetCall(z.aux->call_expr.get());
|
||||||
/* It's possible that this function will call another that
|
/* It's possible that this function will call another that
|
||||||
* itself returns null because *it* is the actual blocker.
|
* itself returns null because *it* is the actual blocker.
|
||||||
* That will set ZAM_error, which we need to ignore.
|
* That will set ZAM_error, which we need to ignore.
|
||||||
|
@ -1685,7 +1685,7 @@ macro WhenCall(func)
|
||||||
internal-op WhenCallN
|
internal-op WhenCallN
|
||||||
type V
|
type V
|
||||||
side-effects
|
side-effects
|
||||||
eval WhenCall(z.func)
|
eval WhenCall(z.aux->func)
|
||||||
|
|
||||||
internal-op WhenIndCallN
|
internal-op WhenIndCallN
|
||||||
type VV
|
type VV
|
||||||
|
@ -1703,7 +1703,7 @@ macro EvalScheduleArgs(time, is_delta, build_args)
|
||||||
double dt = time.double_val;
|
double dt = time.double_val;
|
||||||
if ( is_delta )
|
if ( is_delta )
|
||||||
dt += run_state::network_time;
|
dt += run_state::network_time;
|
||||||
auto handler = EventHandlerPtr(z.event_handler);
|
auto handler = EventHandlerPtr(z.aux->event_handler);
|
||||||
ValVec args;
|
ValVec args;
|
||||||
build_args
|
build_args
|
||||||
auto timer = new ScheduleTimer(handler, std::move(args), dt);
|
auto timer = new ScheduleTimer(handler, std::move(args), dt);
|
||||||
|
@ -1744,19 +1744,19 @@ op1-read
|
||||||
custom-method return CompileEvent(h, l);
|
custom-method return CompileEvent(h, l);
|
||||||
eval ValVec args;
|
eval ValVec args;
|
||||||
z.aux->FillValVec(args, frame);
|
z.aux->FillValVec(args, frame);
|
||||||
QueueEvent(z.event_handler, args);
|
QueueEvent(z.aux->event_handler, args);
|
||||||
|
|
||||||
internal-op Event0
|
internal-op Event0
|
||||||
type X
|
type X
|
||||||
eval ValVec args(0);
|
eval ValVec args(0);
|
||||||
QueueEvent(z.event_handler, args);
|
QueueEvent(z.aux->event_handler, args);
|
||||||
|
|
||||||
internal-op Event1
|
internal-op Event1
|
||||||
type V
|
type V
|
||||||
op1-read
|
op1-read
|
||||||
eval ValVec args(1);
|
eval ValVec args(1);
|
||||||
args[0] = frame[z.v1].ToVal(z.t);
|
args[0] = frame[z.v1].ToVal(z.t);
|
||||||
QueueEvent(z.event_handler, args);
|
QueueEvent(z.aux->event_handler, args);
|
||||||
|
|
||||||
internal-op Event2
|
internal-op Event2
|
||||||
type VV
|
type VV
|
||||||
|
@ -1764,7 +1764,7 @@ op1-read
|
||||||
eval ValVec args(2);
|
eval ValVec args(2);
|
||||||
args[0] = frame[z.v1].ToVal(z.t);
|
args[0] = frame[z.v1].ToVal(z.t);
|
||||||
args[1] = frame[z.v2].ToVal(z.t2);
|
args[1] = frame[z.v2].ToVal(z.t2);
|
||||||
QueueEvent(z.event_handler, args);
|
QueueEvent(z.aux->event_handler, args);
|
||||||
|
|
||||||
internal-op Event3
|
internal-op Event3
|
||||||
type VVV
|
type VVV
|
||||||
|
@ -1774,7 +1774,7 @@ eval ValVec args(3);
|
||||||
args[0] = frame[z.v1].ToVal(z.t);
|
args[0] = frame[z.v1].ToVal(z.t);
|
||||||
args[1] = frame[z.v2].ToVal(z.t2);
|
args[1] = frame[z.v2].ToVal(z.t2);
|
||||||
args[2] = frame[z.v3].ToVal(aux->elems[2].GetType());
|
args[2] = frame[z.v3].ToVal(aux->elems[2].GetType());
|
||||||
QueueEvent(z.event_handler, args);
|
QueueEvent(z.aux->event_handler, args);
|
||||||
|
|
||||||
internal-op Event4
|
internal-op Event4
|
||||||
type VVVV
|
type VVVV
|
||||||
|
@ -1785,7 +1785,7 @@ eval ValVec args(4);
|
||||||
args[1] = frame[z.v2].ToVal(z.t2);
|
args[1] = frame[z.v2].ToVal(z.t2);
|
||||||
args[2] = frame[z.v3].ToVal(aux->elems[2].GetType());
|
args[2] = frame[z.v3].ToVal(aux->elems[2].GetType());
|
||||||
args[3] = frame[z.v4].ToVal(aux->elems[3].GetType());
|
args[3] = frame[z.v4].ToVal(aux->elems[3].GetType());
|
||||||
QueueEvent(z.event_handler, args);
|
QueueEvent(z.aux->event_handler, args);
|
||||||
|
|
||||||
|
|
||||||
op Return
|
op Return
|
||||||
|
@ -1795,6 +1795,7 @@ eval EvalReturn(nullptr,)
|
||||||
macro EvalReturn(val, type)
|
macro EvalReturn(val, type)
|
||||||
ret_u = val;
|
ret_u = val;
|
||||||
type
|
type
|
||||||
|
DO_ZAM_PROFILE
|
||||||
pc = end_pc;
|
pc = end_pc;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -1819,6 +1820,7 @@ macro EvalSwitchBody(cases, postscript)
|
||||||
else
|
else
|
||||||
pc = t[v];
|
pc = t[v];
|
||||||
postscript
|
postscript
|
||||||
|
DO_ZAM_PROFILE
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2130,7 +2132,7 @@ eval auto vt = cast_intrusive<VectorType>(z.t);
|
||||||
internal-op Init-Table
|
internal-op Init-Table
|
||||||
type V
|
type V
|
||||||
eval auto tt = cast_intrusive<TableType>(z.t);
|
eval auto tt = cast_intrusive<TableType>(z.t);
|
||||||
auto t = new TableVal(tt, z.attrs);
|
auto t = new TableVal(tt, z.aux->attrs);
|
||||||
Unref(frame[z.v1].table_val);
|
Unref(frame[z.v1].table_val);
|
||||||
frame[z.v1].table_val = t;
|
frame[z.v1].table_val = t;
|
||||||
|
|
||||||
|
@ -2162,7 +2164,7 @@ macro BuildWhen(timeout)
|
||||||
if ( v )
|
if ( v )
|
||||||
local_aggrs.push_back(v);
|
local_aggrs.push_back(v);
|
||||||
}
|
}
|
||||||
(void)make_intrusive<trigger::Trigger>(wi, wi->WhenExprGlobals(), local_aggrs, timeout, f, z.loc.get());
|
(void)make_intrusive<trigger::Trigger>(wi, wi->WhenExprGlobals(), local_aggrs, timeout, f, z.loc->Loc());
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
# Internal
|
# Internal
|
||||||
|
@ -2263,6 +2265,7 @@ internal-op Hook-Break
|
||||||
type X
|
type X
|
||||||
eval flow = FLOW_BREAK;
|
eval flow = FLOW_BREAK;
|
||||||
pc = end_pc;
|
pc = end_pc;
|
||||||
|
DO_ZAM_PROFILE
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
# Slot 2 gives frame size.
|
# Slot 2 gives frame size.
|
||||||
|
|
|
@ -10,75 +10,87 @@ using std::string;
|
||||||
|
|
||||||
namespace zeek::detail {
|
namespace zeek::detail {
|
||||||
|
|
||||||
void ZInst::Dump(zeek_uint_t inst_num, const FrameReMap* mappings) const {
|
void ZInst::Dump(FILE* f, zeek_uint_t inst_num, const FrameReMap* mappings, const string& prefix) const {
|
||||||
// printf("v%d ", n);
|
// fprintf(f, "v%d ", n);
|
||||||
|
|
||||||
auto id1 = VName(1, inst_num, mappings);
|
auto id1 = VName(1, inst_num, mappings);
|
||||||
auto id2 = VName(2, inst_num, mappings);
|
auto id2 = VName(2, inst_num, mappings);
|
||||||
auto id3 = VName(3, inst_num, mappings);
|
auto id3 = VName(3, inst_num, mappings);
|
||||||
auto id4 = VName(4, inst_num, mappings);
|
auto id4 = VName(4, inst_num, mappings);
|
||||||
|
|
||||||
Dump(id1, id2, id3, id4);
|
Dump(f, prefix, id1, id2, id3, id4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZInst::Dump(const string& id1, const string& id2, const string& id3, const string& id4) const {
|
void ZInst::Dump(FILE* f, const string& prefix, const string& id1, const string& id2, const string& id3,
|
||||||
printf("%s ", ZOP_name(op));
|
const string& id4) const {
|
||||||
// printf("(%s) ", op_type_name(op_type));
|
fprintf(f, "%s ", ZOP_name(op));
|
||||||
|
// fprintf(f, "(%s) ", op_type_name(op_type));
|
||||||
if ( t && 0 )
|
if ( t && 0 )
|
||||||
printf("(%s) ", type_name(t->Tag()));
|
fprintf(f, "(%s) ", type_name(t->Tag()));
|
||||||
|
|
||||||
switch ( op_type ) {
|
switch ( op_type ) {
|
||||||
case OP_X: break;
|
case OP_X: break;
|
||||||
|
|
||||||
case OP_V: printf("%s", id1.c_str()); break;
|
case OP_V: fprintf(f, "%s", id1.c_str()); break;
|
||||||
|
|
||||||
case OP_VV: printf("%s, %s", id1.c_str(), id2.c_str()); break;
|
case OP_VV: fprintf(f, "%s, %s", id1.c_str(), id2.c_str()); break;
|
||||||
|
|
||||||
case OP_VVV: printf("%s, %s, %s", id1.c_str(), id2.c_str(), id3.c_str()); break;
|
case OP_VVV: fprintf(f, "%s, %s, %s", id1.c_str(), id2.c_str(), id3.c_str()); break;
|
||||||
|
|
||||||
case OP_VVVV: printf("%s, %s, %s, %s", id1.c_str(), id2.c_str(), id3.c_str(), id4.c_str()); break;
|
case OP_VVVV: fprintf(f, "%s, %s, %s, %s", id1.c_str(), id2.c_str(), id3.c_str(), id4.c_str()); break;
|
||||||
|
|
||||||
case OP_VVVC: printf("%s, %s, %s, %s", id1.c_str(), id2.c_str(), id3.c_str(), ConstDump().c_str()); break;
|
case OP_VVVC: fprintf(f, "%s, %s, %s, %s", id1.c_str(), id2.c_str(), id3.c_str(), ConstDump().c_str()); break;
|
||||||
|
|
||||||
case OP_C: printf("%s", ConstDump().c_str()); break;
|
case OP_C: fprintf(f, "%s", ConstDump().c_str()); break;
|
||||||
|
|
||||||
case OP_VC: printf("%s, %s", id1.c_str(), ConstDump().c_str()); break;
|
case OP_VC: fprintf(f, "%s, %s", id1.c_str(), ConstDump().c_str()); break;
|
||||||
|
|
||||||
case OP_VVC: printf("%s, %s, %s", id1.c_str(), id2.c_str(), ConstDump().c_str()); break;
|
case OP_VVC: fprintf(f, "%s, %s, %s", id1.c_str(), id2.c_str(), ConstDump().c_str()); break;
|
||||||
|
|
||||||
case OP_V_I1: printf("%d", v1); break;
|
case OP_V_I1: fprintf(f, "%d", v1); break;
|
||||||
|
|
||||||
case OP_VC_I1: printf("%d %s", v1, ConstDump().c_str()); break;
|
case OP_VC_I1: fprintf(f, "%d %s", v1, ConstDump().c_str()); break;
|
||||||
|
|
||||||
case OP_VV_FRAME: printf("%s, interpreter frame[%d]", id1.c_str(), v2); break;
|
case OP_VV_FRAME: fprintf(f, "%s, interpreter frame[%d]", id1.c_str(), v2); break;
|
||||||
|
|
||||||
case OP_VV_I2: printf("%s, %d", id1.c_str(), v2); break;
|
case OP_VV_I2: fprintf(f, "%s, %d", id1.c_str(), v2); break;
|
||||||
|
|
||||||
case OP_VV_I1_I2: printf("%d, %d", v1, v2); break;
|
case OP_VV_I1_I2: fprintf(f, "%d, %d", v1, v2); break;
|
||||||
|
|
||||||
case OP_VVC_I2: printf("%s, %d, %s", id1.c_str(), v2, ConstDump().c_str()); break;
|
case OP_VVC_I2: fprintf(f, "%s, %d, %s", id1.c_str(), v2, ConstDump().c_str()); break;
|
||||||
|
|
||||||
case OP_VVV_I3: printf("%s, %s, %d", id1.c_str(), id2.c_str(), v3); break;
|
case OP_VVV_I3: fprintf(f, "%s, %s, %d", id1.c_str(), id2.c_str(), v3); break;
|
||||||
|
|
||||||
case OP_VVV_I2_I3: printf("%s, %d, %d", id1.c_str(), v2, v3); break;
|
case OP_VVV_I2_I3: fprintf(f, "%s, %d, %d", id1.c_str(), v2, v3); break;
|
||||||
|
|
||||||
case OP_VVVV_I4: printf("%s, %s, %s, %d", id1.c_str(), id2.c_str(), id3.c_str(), v4); break;
|
case OP_VVVV_I4: fprintf(f, "%s, %s, %s, %d", id1.c_str(), id2.c_str(), id3.c_str(), v4); break;
|
||||||
|
|
||||||
case OP_VVVV_I3_I4: printf("%s, %s, %d, %d", id1.c_str(), id2.c_str(), v3, v4); break;
|
case OP_VVVV_I3_I4: fprintf(f, "%s, %s, %d, %d", id1.c_str(), id2.c_str(), v3, v4); break;
|
||||||
|
|
||||||
case OP_VVVV_I2_I3_I4: printf("%s, %d, %d, %d", id1.c_str(), v2, v3, v4); break;
|
case OP_VVVV_I2_I3_I4: fprintf(f, "%s, %d, %d, %d", id1.c_str(), v2, v3, v4); break;
|
||||||
|
|
||||||
case OP_VVVC_I3: printf("%s, %s, %d, %s", id1.c_str(), id2.c_str(), v3, ConstDump().c_str()); break;
|
case OP_VVVC_I3: fprintf(f, "%s, %s, %d, %s", id1.c_str(), id2.c_str(), v3, ConstDump().c_str()); break;
|
||||||
|
|
||||||
case OP_VVVC_I2_I3: printf("%s, %d, %d, %s", id1.c_str(), v2, v3, ConstDump().c_str()); break;
|
case OP_VVVC_I2_I3: fprintf(f, "%s, %d, %d, %s", id1.c_str(), v2, v3, ConstDump().c_str()); break;
|
||||||
|
|
||||||
case OP_VVVC_I1_I2_I3: printf("%d, %d, %d, %s", v1, v2, v3, ConstDump().c_str()); break;
|
case OP_VVVC_I1_I2_I3: fprintf(f, "%d, %d, %d, %s", v1, v2, v3, ConstDump().c_str()); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( func )
|
auto func = aux ? aux->func : nullptr;
|
||||||
printf(" (func %s)", func->Name());
|
|
||||||
|
|
||||||
printf("\n");
|
if ( func )
|
||||||
|
fprintf(f, " (func %s)", func->Name());
|
||||||
|
|
||||||
|
if ( loc ) {
|
||||||
|
auto l = loc->Describe(true);
|
||||||
|
if ( func && (func->GetBodies().empty() || func->GetBodies()[0].stmts->Tag() != STMT_ZAM) )
|
||||||
|
l = l + ";" + func->Name();
|
||||||
|
if ( ! prefix.empty() )
|
||||||
|
l = prefix + l;
|
||||||
|
fprintf(f, " // %s", l.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(f, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int ZInst::NumFrameSlots() const {
|
int ZInst::NumFrameSlots() const {
|
||||||
|
@ -286,16 +298,16 @@ string ZInst::ConstDump() const {
|
||||||
return d.Description();
|
return d.Description();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZInstI::Dump(const FrameMap* frame_ids, const FrameReMap* remappings) const {
|
void ZInstI::Dump(FILE* f, const FrameMap* frame_ids, const FrameReMap* remappings) const {
|
||||||
int n = NumFrameSlots();
|
int n = NumFrameSlots();
|
||||||
// printf("v%d ", n);
|
// fprintf(f, "v%d ", n);
|
||||||
|
|
||||||
auto id1 = VName(1, frame_ids, remappings);
|
auto id1 = VName(1, frame_ids, remappings);
|
||||||
auto id2 = VName(2, frame_ids, remappings);
|
auto id2 = VName(2, frame_ids, remappings);
|
||||||
auto id3 = VName(3, frame_ids, remappings);
|
auto id3 = VName(3, frame_ids, remappings);
|
||||||
auto id4 = VName(4, frame_ids, remappings);
|
auto id4 = VName(4, frame_ids, remappings);
|
||||||
|
|
||||||
ZInst::Dump(id1, id2, id3, id4);
|
ZInst::Dump(f, "", id1, id2, id3, id4);
|
||||||
}
|
}
|
||||||
|
|
||||||
string ZInstI::VName(int n, const FrameMap* frame_ids, const FrameReMap* remappings) const {
|
string ZInstI::VName(int n, const FrameMap* frame_ids, const FrameReMap* remappings) const {
|
||||||
|
|
|
@ -60,16 +60,22 @@ public:
|
||||||
ZInst(ZOp _op, ZAMOpType _op_type) {
|
ZInst(ZOp _op, ZAMOpType _op_type) {
|
||||||
op = _op;
|
op = _op;
|
||||||
op_type = _op_type;
|
op_type = _op_type;
|
||||||
|
ASSERT(curr_loc);
|
||||||
|
loc = curr_loc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a stub instruction that will be populated later.
|
// Create a stub instruction that will be populated later.
|
||||||
ZInst() = default;
|
ZInst() {
|
||||||
|
ASSERT(curr_loc);
|
||||||
|
loc = curr_loc;
|
||||||
|
}
|
||||||
|
|
||||||
virtual ~ZInst() = default;
|
virtual ~ZInst() = default;
|
||||||
|
|
||||||
// Methods for printing out the instruction for debugging/maintenance.
|
// Methods for printing out the instruction for debugging/profiling.
|
||||||
void Dump(zeek_uint_t inst_num, const FrameReMap* mappings) const;
|
void Dump(FILE* f, zeek_uint_t inst_num, const FrameReMap* mappings, const std::string& prefix) const;
|
||||||
void Dump(const std::string& id1, const std::string& id2, const std::string& id3, const std::string& id4) const;
|
void Dump(FILE* f, const std::string& prefix, const std::string& id1, const std::string& id2,
|
||||||
|
const std::string& id3, const std::string& id4) const;
|
||||||
|
|
||||||
// Returns the name to use in identifying one of the slots/integer
|
// Returns the name to use in identifying one of the slots/integer
|
||||||
// values (designated by "n"). "inst_num" identifies the instruction
|
// values (designated by "n"). "inst_num" identifies the instruction
|
||||||
|
@ -121,10 +127,6 @@ public:
|
||||||
// Type, usually for interpreting the constant.
|
// Type, usually for interpreting the constant.
|
||||||
TypePtr t = nullptr;
|
TypePtr t = nullptr;
|
||||||
TypePtr t2 = nullptr; // just a few ops need two types
|
TypePtr t2 = nullptr; // just a few ops need two types
|
||||||
const Expr* e = nullptr; // only needed for "when" expressions
|
|
||||||
Func* func = nullptr; // used for calls
|
|
||||||
EventHandler* event_handler = nullptr; // used for referring to events
|
|
||||||
AttributesPtr attrs = nullptr; // used for things like constructors
|
|
||||||
|
|
||||||
// Auxiliary information. We could in principle use this to
|
// Auxiliary information. We could in principle use this to
|
||||||
// consolidate a bunch of the above, though at the cost of
|
// consolidate a bunch of the above, though at the cost of
|
||||||
|
@ -132,12 +134,9 @@ public:
|
||||||
// which is why we bundle these separately.
|
// which is why we bundle these separately.
|
||||||
ZInstAux* aux = nullptr;
|
ZInstAux* aux = nullptr;
|
||||||
|
|
||||||
// Location associated with this instruction, for error reporting.
|
// Location associated with this instruction, for error reporting
|
||||||
std::shared_ptr<Location> loc;
|
// and profiling.
|
||||||
|
std::shared_ptr<ZAMLocInfo> loc;
|
||||||
// Interpreter call expression associated with this instruction,
|
|
||||||
// for error reporting and stack backtraces.
|
|
||||||
CallExprPtr call_expr = nullptr;
|
|
||||||
|
|
||||||
// Whether v1 represents a frame slot type for which we
|
// Whether v1 represents a frame slot type for which we
|
||||||
// explicitly manage the memory.
|
// explicitly manage the memory.
|
||||||
|
@ -201,7 +200,7 @@ public:
|
||||||
ZInstI() {}
|
ZInstI() {}
|
||||||
|
|
||||||
// If "remappings" is non-nil, then it is used instead of frame_ids.
|
// If "remappings" is non-nil, then it is used instead of frame_ids.
|
||||||
void Dump(const FrameMap* frame_ids, const FrameReMap* remappings) const;
|
void Dump(FILE* f, const FrameMap* frame_ids, const FrameReMap* remappings) const;
|
||||||
|
|
||||||
// Note that this is *not* an override of the base class's VName
|
// Note that this is *not* an override of the base class's VName
|
||||||
// but instead a method with similar functionality but somewhat
|
// but instead a method with similar functionality but somewhat
|
||||||
|
@ -294,9 +293,6 @@ public:
|
||||||
// a branch target).
|
// a branch target).
|
||||||
int num_labels = 0;
|
int num_labels = 0;
|
||||||
|
|
||||||
// Used for debugging. Transformed into the ZInst "loc" field.
|
|
||||||
StmtPtr stmt = curr_stmt;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Initialize 'c' from the given ConstExpr.
|
// Initialize 'c' from the given ConstExpr.
|
||||||
void InitConst(const ConstExpr* ce);
|
void InitConst(const ConstExpr* ce);
|
||||||
|
@ -467,6 +463,22 @@ public:
|
||||||
// Used for accessing function names.
|
// Used for accessing function names.
|
||||||
IDPtr id_val = nullptr;
|
IDPtr id_val = nullptr;
|
||||||
|
|
||||||
|
// Interpreter call expression associated with this instruction,
|
||||||
|
// for error reporting and stack backtraces.
|
||||||
|
CallExprPtr call_expr = nullptr;
|
||||||
|
|
||||||
|
// Used for direct calls.
|
||||||
|
Func* func = nullptr;
|
||||||
|
|
||||||
|
// Whether we know that we're calling a BiF.
|
||||||
|
bool is_BiF_call = false;
|
||||||
|
|
||||||
|
// Used for referring to events.
|
||||||
|
EventHandler* event_handler = nullptr;
|
||||||
|
|
||||||
|
// Used for things like constructors.
|
||||||
|
AttributesPtr attrs = nullptr;
|
||||||
|
|
||||||
// Whether the instruction can lead to globals/captures changing.
|
// Whether the instruction can lead to globals/captures changing.
|
||||||
// Currently only needed by the optimizer, but convenient to
|
// Currently only needed by the optimizer, but convenient to
|
||||||
// store here.
|
// store here.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue