mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
restructured tracking of initializations of globals for script compilation
This commit is contained in:
parent
0d5c669c1c
commit
1af905a14f
5 changed files with 80 additions and 32 deletions
|
@ -680,11 +680,6 @@ std::vector<Func*> ID::GetOptionHandlers() const
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IDOptInfo::AddInitExpr(ExprPtr init_expr)
|
|
||||||
{
|
|
||||||
init_exprs.emplace_back(std::move(init_expr));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
} // namespace zeek
|
} // namespace zeek
|
||||||
|
|
48
src/Var.cc
48
src/Var.cc
|
@ -17,6 +17,7 @@
|
||||||
#include "zeek/Traverse.h"
|
#include "zeek/Traverse.h"
|
||||||
#include "zeek/Val.h"
|
#include "zeek/Val.h"
|
||||||
#include "zeek/module_util.h"
|
#include "zeek/module_util.h"
|
||||||
|
#include "zeek/script_opt/IDOptInfo.h"
|
||||||
#include "zeek/script_opt/StmtOptInfo.h"
|
#include "zeek/script_opt/StmtOptInfo.h"
|
||||||
#include "zeek/script_opt/UsageAnalyzer.h"
|
#include "zeek/script_opt/UsageAnalyzer.h"
|
||||||
|
|
||||||
|
@ -117,12 +118,12 @@ static bool add_prototype(const IDPtr& id, Type* t, std::vector<AttrPtr>* attrs,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void initialize_var(const IDPtr& id, InitClass c, ExprPtr init)
|
static ExprPtr initialize_var(const IDPtr& id, InitClass c, ExprPtr init)
|
||||||
{
|
{
|
||||||
if ( ! id->HasVal() )
|
if ( ! id->HasVal() )
|
||||||
{
|
{
|
||||||
if ( c == INIT_REMOVE )
|
if ( c == INIT_REMOVE )
|
||||||
return;
|
return nullptr;
|
||||||
|
|
||||||
bool no_init = ! init;
|
bool no_init = ! init;
|
||||||
|
|
||||||
|
@ -134,7 +135,7 @@ static void initialize_var(const IDPtr& id, InitClass c, ExprPtr init)
|
||||||
auto& t = id->GetType();
|
auto& t = id->GetType();
|
||||||
|
|
||||||
if ( ! IsAggr(t) )
|
if ( ! IsAggr(t) )
|
||||||
return;
|
return nullptr;
|
||||||
|
|
||||||
ValPtr init_val;
|
ValPtr init_val;
|
||||||
|
|
||||||
|
@ -147,7 +148,7 @@ static void initialize_var(const IDPtr& id, InitClass c, ExprPtr init)
|
||||||
catch ( InterpreterException& )
|
catch ( InterpreterException& )
|
||||||
{
|
{
|
||||||
id->Error("initialization failed");
|
id->Error("initialization failed");
|
||||||
return;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,11 +158,11 @@ static void initialize_var(const IDPtr& id, InitClass c, ExprPtr init)
|
||||||
else if ( t->Tag() == TYPE_VECTOR )
|
else if ( t->Tag() == TYPE_VECTOR )
|
||||||
init_val = make_intrusive<VectorVal>(cast_intrusive<VectorType>(t));
|
init_val = make_intrusive<VectorVal>(cast_intrusive<VectorType>(t));
|
||||||
|
|
||||||
id->SetVal(init_val);
|
init = make_intrusive<ConstExpr>(init_val);
|
||||||
return;
|
c = INIT_FULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( c == INIT_EXTRA )
|
else if ( c == INIT_EXTRA )
|
||||||
c = INIT_FULL;
|
c = INIT_FULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,19 +178,12 @@ static void initialize_var(const IDPtr& id, InitClass c, ExprPtr init)
|
||||||
assignment = make_intrusive<RemoveFromExpr>(lhs, init);
|
assignment = make_intrusive<RemoveFromExpr>(lhs, init);
|
||||||
else
|
else
|
||||||
// This can happen due to error propagation.
|
// This can happen due to error propagation.
|
||||||
return;
|
return nullptr;
|
||||||
|
|
||||||
if ( assignment->IsError() )
|
if ( assignment->IsError() )
|
||||||
return;
|
return nullptr;
|
||||||
|
|
||||||
try
|
return assignment;
|
||||||
{
|
|
||||||
(void)assignment->Eval(nullptr);
|
|
||||||
}
|
|
||||||
catch ( InterpreterException& )
|
|
||||||
{
|
|
||||||
id->Error("initialization failed");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void make_var(const IDPtr& id, TypePtr t, InitClass c, ExprPtr init,
|
static void make_var(const IDPtr& id, TypePtr t, InitClass c, ExprPtr init,
|
||||||
|
@ -347,11 +341,29 @@ static void make_var(const IDPtr& id, TypePtr t, InitClass c, ExprPtr init,
|
||||||
|
|
||||||
if ( init && ((c == INIT_EXTRA && id->GetAttr(ATTR_ADD_FUNC)) ||
|
if ( init && ((c == INIT_EXTRA && id->GetAttr(ATTR_ADD_FUNC)) ||
|
||||||
(c == INIT_REMOVE && id->GetAttr(ATTR_DEL_FUNC))) )
|
(c == INIT_REMOVE && id->GetAttr(ATTR_DEL_FUNC))) )
|
||||||
|
{
|
||||||
// Just apply the function.
|
// Just apply the function.
|
||||||
id->SetVal(init, c);
|
id->SetVal(init, c);
|
||||||
|
id->GetOptInfo()->AddInitExpr(init, c);
|
||||||
|
}
|
||||||
|
|
||||||
else if ( dt != VAR_REDEF || init || ! attr )
|
else if ( dt != VAR_REDEF || init || ! attr )
|
||||||
initialize_var(id, c, init);
|
{
|
||||||
|
auto init_expr = initialize_var(id, c, init);
|
||||||
|
if ( init_expr )
|
||||||
|
{
|
||||||
|
id->GetOptInfo()->AddInitExpr(init_expr);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
(void)init_expr->Eval(nullptr);
|
||||||
|
}
|
||||||
|
catch ( InterpreterException& )
|
||||||
|
{
|
||||||
|
id->Error("initialization failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( dt == VAR_CONST )
|
if ( dt == VAR_CONST )
|
||||||
|
|
|
@ -102,7 +102,6 @@
|
||||||
#include "zeek/zeekygen/Manager.h"
|
#include "zeek/zeekygen/Manager.h"
|
||||||
#include "zeek/module_util.h"
|
#include "zeek/module_util.h"
|
||||||
#include "zeek/IntrusivePtr.h"
|
#include "zeek/IntrusivePtr.h"
|
||||||
#include "zeek/script_opt/IDOptInfo.h"
|
|
||||||
|
|
||||||
extern const char* filename; // Absolute path of file currently being parsed.
|
extern const char* filename; // Absolute path of file currently being parsed.
|
||||||
extern const char* last_filename; // Absolute path of last file parsed.
|
extern const char* last_filename; // Absolute path of last file parsed.
|
||||||
|
@ -321,8 +320,6 @@ static void build_global(ID* id, Type* t, InitClass ic, Expr* e,
|
||||||
|
|
||||||
add_global(id_ptr, std::move(t_ptr), ic, e_ptr, std::move(attrs_ptr), dt);
|
add_global(id_ptr, std::move(t_ptr), ic, e_ptr, std::move(attrs_ptr), dt);
|
||||||
|
|
||||||
id->GetOptInfo()->AddInitExpr(e_ptr);
|
|
||||||
|
|
||||||
if ( dt == VAR_REDEF )
|
if ( dt == VAR_REDEF )
|
||||||
zeekygen_mgr->Redef(id, ::filename, ic, std::move(e_ptr));
|
zeekygen_mgr->Redef(id, ::filename, ic, std::move(e_ptr));
|
||||||
else
|
else
|
||||||
|
@ -342,8 +339,6 @@ static StmtPtr build_local(ID* id, Type* t, InitClass ic, Expr* e,
|
||||||
auto init = add_local(std::move(id_ptr), std::move(t_ptr), ic,
|
auto init = add_local(std::move(id_ptr), std::move(t_ptr), ic,
|
||||||
e_ptr, std::move(attrs_ptr), dt);
|
e_ptr, std::move(attrs_ptr), dt);
|
||||||
|
|
||||||
id->GetOptInfo()->AddInitExpr(std::move(e_ptr));
|
|
||||||
|
|
||||||
if ( do_coverage )
|
if ( do_coverage )
|
||||||
script_coverage_mgr.AddStmt(init.get());
|
script_coverage_mgr.AddStmt(init.get());
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,8 @@ void IDDefRegion::Dump() const
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<IDInitInfo> IDOptInfo::global_init_exprs;
|
||||||
|
|
||||||
void IDOptInfo::Clear()
|
void IDOptInfo::Clear()
|
||||||
{
|
{
|
||||||
static bool did_init = false;
|
static bool did_init = false;
|
||||||
|
@ -69,6 +71,17 @@ void IDOptInfo::Clear()
|
||||||
tracing = trace_ID && util::streq(trace_ID, my_id->Name());
|
tracing = trace_ID && util::streq(trace_ID, my_id->Name());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IDOptInfo::AddInitExpr(ExprPtr init_expr, InitClass ic)
|
||||||
|
{
|
||||||
|
if ( ! init_expr )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( my_id->IsGlobal() )
|
||||||
|
global_init_exprs.emplace_back(IDInitInfo(my_id, init_expr, ic));
|
||||||
|
|
||||||
|
init_exprs.emplace_back(std::move(init_expr));
|
||||||
|
}
|
||||||
|
|
||||||
void IDOptInfo::DefinedAfter(const Stmt* s, const ExprPtr& e,
|
void IDOptInfo::DefinedAfter(const Stmt* s, const ExprPtr& e,
|
||||||
const std::vector<const Stmt*>& conf_blocks, zeek_uint_t conf_start)
|
const std::vector<const Stmt*>& conf_blocks, zeek_uint_t conf_start)
|
||||||
{
|
{
|
||||||
|
|
|
@ -105,6 +105,24 @@ protected:
|
||||||
ExprPtr def_expr;
|
ExprPtr def_expr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Class tracking information associated with a (global) identifier's
|
||||||
|
// (re-)initialization.
|
||||||
|
|
||||||
|
class IDInitInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IDInitInfo(const ID* _id, ExprPtr _init, InitClass _ic) : id(_id), init(_init), ic(_ic) { }
|
||||||
|
|
||||||
|
const ID* Id() const { return id; }
|
||||||
|
const ExprPtr& Init() const { return init; }
|
||||||
|
InitClass IC() const { return ic; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
const ID* id;
|
||||||
|
ExprPtr init;
|
||||||
|
InitClass ic;
|
||||||
|
};
|
||||||
|
|
||||||
// Class tracking optimization information associated with identifiers.
|
// Class tracking optimization information associated with identifiers.
|
||||||
|
|
||||||
class IDOptInfo
|
class IDOptInfo
|
||||||
|
@ -118,11 +136,19 @@ public:
|
||||||
void Clear();
|
void Clear();
|
||||||
|
|
||||||
// Used to track expressions employed when explicitly initializing
|
// Used to track expressions employed when explicitly initializing
|
||||||
// the identifier. These are needed by compile-to-C++ script
|
// the (global) identifier. These are needed by compile-to-C++ script
|
||||||
// optimization. They're not used by ZAM optimization.
|
// optimization, and for tracking variable usage. An initialization
|
||||||
void AddInitExpr(ExprPtr init_expr);
|
// class other than INIT_NONE indicates that initialization should
|
||||||
|
// be done with the ExprPtr form of ID::SetVal.
|
||||||
|
void AddInitExpr(ExprPtr init_expr, InitClass ic = INIT_NONE);
|
||||||
|
|
||||||
|
// Returns the initialization expressions for this identifier.
|
||||||
const std::vector<ExprPtr>& GetInitExprs() const { return init_exprs; }
|
const std::vector<ExprPtr>& GetInitExprs() const { return init_exprs; }
|
||||||
|
|
||||||
|
// Returns a list of the initialization expressions seen for all
|
||||||
|
// globals, ordered by when they were processed.
|
||||||
|
static auto& GetGlobalInitExprs() { return global_init_exprs; }
|
||||||
|
|
||||||
// Associated constant expression, if any. This is only set
|
// Associated constant expression, if any. This is only set
|
||||||
// for identifiers that are aliases for a constant (i.e., there
|
// for identifiers that are aliases for a constant (i.e., there
|
||||||
// are no other assignments to them).
|
// are no other assignments to them).
|
||||||
|
@ -224,6 +250,9 @@ private:
|
||||||
// one of the earlier instances rather than the last one.
|
// one of the earlier instances rather than the last one.
|
||||||
std::vector<ExprPtr> init_exprs;
|
std::vector<ExprPtr> init_exprs;
|
||||||
|
|
||||||
|
// Tracks initializations of globals in the order they're seen.
|
||||||
|
static std::vector<IDInitInfo> global_init_exprs;
|
||||||
|
|
||||||
// If non-nil, a constant that this identifier always holds
|
// If non-nil, a constant that this identifier always holds
|
||||||
// once initially defined.
|
// once initially defined.
|
||||||
const ConstExpr* const_expr = nullptr;
|
const ConstExpr* const_expr = nullptr;
|
||||||
|
@ -256,8 +285,12 @@ private:
|
||||||
// Whether the identifier is a temporary variable.
|
// Whether the identifier is a temporary variable.
|
||||||
bool is_temp = false;
|
bool is_temp = false;
|
||||||
|
|
||||||
// Only needed for debugging purposes.
|
// Associated identifier, to enable tracking of initialization
|
||||||
|
// expressions for globals (for C++ compilation), and for debugging
|
||||||
|
// output.
|
||||||
const ID* my_id;
|
const ID* my_id;
|
||||||
|
|
||||||
|
// Only needed for debugging purposes.
|
||||||
bool tracing = false;
|
bool tracing = false;
|
||||||
|
|
||||||
// Track whether we've already generated usage errors.
|
// Track whether we've already generated usage errors.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue