use richer block-aware location information for ZAM instructions

This commit is contained in:
Vern Paxson 2024-03-10 17:10:28 -04:00 committed by Tim Wojtulewicz
parent 9f9f01580f
commit c8d15f1eaa
5 changed files with 65 additions and 27 deletions

View file

@ -24,12 +24,17 @@ ZAMCompiler::ZAMCompiler(ScriptFuncPtr f, std::shared_ptr<ProfileFuncs> _pfs, st
reducer = std::move(_rd);
frame_sizeI = 0;
auto loc = body->GetLocationInfo();
ASSERT(loc->first_line != 0 || body->Tag() == STMT_NULL);
auto loc_copy =
std::make_shared<Location>(loc->filename, loc->first_line, loc->last_line, loc->first_column, loc->last_column);
curr_func = func->Name();
curr_loc = std::make_shared<ZAMLocInfo>(curr_func, std::move(loc_copy), nullptr);
Init();
}
ZAMCompiler::~ZAMCompiler() {
curr_stmt = nullptr;
for ( auto i : insts1 )
delete i;
}
@ -117,8 +122,6 @@ void ZAMCompiler::TrackMemoryManagement() {
}
StmtPtr ZAMCompiler::CompileBody() {
curr_stmt = nullptr;
if ( func->Flavor() == FUNC_FLAVOR_HOOK )
PushBreaks();
@ -193,12 +196,17 @@ StmtPtr ZAMCompiler::CompileBody() {
ConcretizeSwitches();
std::string fname = func->Name();
if ( func->Flavor() == FUNC_FLAVOR_FUNCTION )
fname = func_name_at_loc(fname, body->GetLocationInfo());
auto zb = make_intrusive<ZBody>(fname, this);
zb->SetInsts(insts2);
// Could erase insts1 here to recover memory, but it's handy
// for debugging.
auto zb = make_intrusive<ZBody>(func->Name(), this);
zb->SetInsts(insts2);
return zb;
}
@ -388,7 +396,7 @@ void ZAMCompiler::Dump() {
printf("%d %s%s: ", i, liveness.c_str(), depth.c_str());
inst->Dump(&frame_denizens, remappings);
inst->Dump(stdout, &frame_denizens, remappings);
}
if ( ! insts2.empty() )
@ -396,8 +404,9 @@ void ZAMCompiler::Dump() {
for ( auto i = 0U; i < insts2.size(); ++i ) {
auto& inst = insts2[i];
// printf("%s:%d\n", inst->loc->filename, inst->loc->first_line);
printf("%d: ", i);
inst->Dump(&frame_denizens, remappings);
inst->Dump(stdout, &frame_denizens, remappings);
}
DumpCases(int_cases, "int");
@ -445,7 +454,7 @@ void ZAMCompiler::DumpInsts1(const FrameReMap* remappings) {
printf("%d %s%s: ", i, liveness.c_str(), depth.c_str());
inst->Dump(&frame_denizens, remappings);
inst->Dump(stdout, &frame_denizens, remappings);
}
}

View file

@ -18,7 +18,7 @@ public:
// No constructor needed, as all of our member variables are
// instead instantiated via BeginLoop(). This allows us to
// reuse TableIterInfo objects to lower the overhead associated
// with executing ZBody::DoExec for non-recursive functions.
// with executing ZBody::Exec for non-recursive functions.
// We do, however, want to make sure that when we go out of scope,
// if we have any pending iterators we clear them.

View file

@ -10,8 +10,13 @@
namespace zeek::detail {
const ZAMStmt ZAMCompiler::CompileStmt(const Stmt* s) {
curr_stmt = const_cast<Stmt*>(s)->ThisPtr();
ASSERT(curr_stmt->Tag() == STMT_NULL || curr_stmt->GetLocationInfo()->first_line != 0);
auto loc = s->GetLocationInfo();
ASSERT(loc->first_line != 0 || s->Tag() == STMT_NULL);
auto loc_copy =
std::make_shared<Location>(loc->filename, loc->first_line, loc->last_line, loc->first_column, loc->last_column);
ASSERT(! blocks || s->Tag() == STMT_NULL || blocks->HaveExpDesc(loc_copy.get()));
auto loc_parent = curr_loc->Parent();
curr_loc = std::make_shared<ZAMLocInfo>(curr_func, std::move(loc_copy), curr_loc->Parent());
switch ( s->Tag() ) {
case STMT_PRINT: return CompilePrint(static_cast<const PrintStmt*>(s));
@ -902,6 +907,16 @@ const ZAMStmt ZAMCompiler::CompileReturn(const ReturnStmt* r) {
const ZAMStmt ZAMCompiler::CompileCatchReturn(const CatchReturnStmt* cr) {
retvars.push_back(cr->RetVar());
auto hold_func = curr_func;
auto hold_loc = curr_loc;
curr_func = cr->Func()->Name();
bool is_event_inline = (hold_func == curr_func);
if ( ! is_event_inline )
curr_loc = std::make_shared<ZAMLocInfo>(curr_func, curr_loc->LocPtr(), hold_loc);
PushCatchReturns();
auto block = cr->Block();
@ -910,6 +925,14 @@ const ZAMStmt ZAMCompiler::CompileCatchReturn(const CatchReturnStmt* cr) {
ResolveCatchReturns(GoToTargetBeyond(block_end));
if ( ! is_event_inline ) {
// Strictly speaking, we could do this even if is_event_inline
// is true, because the values won't have changed. However, that
// just looks weird, so we condition this to match the above.
curr_func = hold_func;
curr_loc = hold_loc;
}
return block_end;
}
@ -1008,7 +1031,8 @@ const ZAMStmt ZAMCompiler::InitVector(IDPtr id, VectorType* vt) {
const ZAMStmt ZAMCompiler::InitTable(IDPtr id, TableType* tt, Attributes* attrs) {
auto z = ZInstI(OP_INIT_TABLE_V, FrameSlot(id));
z.SetType({NewRef{}, tt});
z.attrs = {NewRef{}, attrs};
z.aux = new ZInstAux(0);
z.aux->attrs = {NewRef{}, attrs};
return AddInst(z);
}

View file

@ -12,7 +12,8 @@
namespace zeek::detail {
StmtPtr curr_stmt;
std::string curr_func;
std::shared_ptr<ZAMLocInfo> curr_loc;
TypePtr log_ID_enum_type;
TypePtr any_base_type;
bool ZAM_error = false;
@ -77,8 +78,8 @@ void ZAM_run_time_error(const char* msg) {
ZAM_error = true;
}
void ZAM_run_time_error(std::shared_ptr<Location> loc, const char* msg) {
reporter->RuntimeError(loc.get(), "%s", msg);
void ZAM_run_time_error(std::shared_ptr<ZAMLocInfo> loc, const char* msg) {
reporter->RuntimeError(loc->Loc(), "%s", msg);
ZAM_error = true;
}
@ -87,14 +88,14 @@ void ZAM_run_time_error(const char* msg, const Obj* o) {
ZAM_error = true;
}
void ZAM_run_time_error(std::shared_ptr<Location> loc, const char* msg, const Obj* o) {
reporter->RuntimeError(loc.get(), "%s (%s)", msg, obj_desc(o).c_str());
void ZAM_run_time_error(std::shared_ptr<ZAMLocInfo> loc, const char* msg, const Obj* o) {
reporter->RuntimeError(loc->Loc(), "%s (%s)", msg, obj_desc(o).c_str());
ZAM_error = true;
}
void ZAM_run_time_warning(std::shared_ptr<Location> loc, const char* msg) {
void ZAM_run_time_warning(std::shared_ptr<ZAMLocInfo> loc, const char* msg) {
ODesc d;
loc->Describe(&d);
loc->Loc()->Describe(&d);
reporter->Warning("%s: %s", d.Description(), msg);
}

View file

@ -6,14 +6,18 @@
#include "zeek/Expr.h"
#include "zeek/Stmt.h"
#include "zeek/script_opt/ZAM/Profile.h"
namespace zeek::detail {
using ValVec = std::vector<ValPtr>;
// The (reduced) statement currently being compiled. Used for both
// tracking "use" and "reaching" definitions, and for error messages.
extern StmtPtr curr_stmt;
// The name of the current function being compiled. For inlined functions,
// this is the name of the inlinee, not the inliner.
extern std::string curr_func;
// The location corresponding to the current statement being compiled.
extern std::shared_ptr<ZAMLocInfo> curr_loc;
// True if a function with the given profile can be compiled to ZAM.
// If not, returns the reason in *reason, if non-nil.
@ -35,14 +39,14 @@ extern TypePtr log_ID_enum_type;
extern TypePtr any_base_type;
extern void ZAM_run_time_error(const char* msg);
extern void ZAM_run_time_error(std::shared_ptr<Location> loc, const char* msg);
extern void ZAM_run_time_error(std::shared_ptr<Location> loc, const char* msg, const Obj* o);
extern void ZAM_run_time_error(std::shared_ptr<ZAMLocInfo> loc, const char* msg);
extern void ZAM_run_time_error(std::shared_ptr<ZAMLocInfo> loc, const char* msg, const Obj* o);
extern void ZAM_run_time_error(const Stmt* stmt, const char* msg);
extern void ZAM_run_time_error(const char* msg, const Obj* o);
extern bool ZAM_error;
extern void ZAM_run_time_warning(std::shared_ptr<Location> loc, const char* msg);
extern void ZAM_run_time_warning(std::shared_ptr<ZAMLocInfo> loc, const char* msg);
extern StringVal* ZAM_to_lower(const StringVal* sv);
extern StringVal* ZAM_sub_bytes(const StringVal* s, zeek_uint_t start, zeek_int_t n);