fix for redef'd globals in standalone scripts

This commit is contained in:
Vern Paxson 2024-12-28 18:32:18 -08:00
parent 68e1307ab3
commit 60656dafd8
7 changed files with 55 additions and 20 deletions

View file

@ -44,7 +44,16 @@ void CPPCompile::Compile(bool report_uncompilable) {
reporter->FatalError("aborting standalone compilation to C++ due to having to skip some functions"); reporter->FatalError("aborting standalone compilation to C++ due to having to skip some functions");
for ( auto& g : global_scope()->OrderedVars() ) { for ( auto& g : global_scope()->OrderedVars() ) {
if ( ! obj_matches_opt_files(g) ) bool compiled_global = obj_matches_opt_files(g);
if ( ! compiled_global )
for ( const auto& i_e : g->GetOptInfo()->GetInitExprs() )
if ( obj_matches_opt_files(i_e) ) {
compiled_global = true;
break;
}
if ( ! compiled_global )
continue; continue;
// We will need to generate this global's definition, including // We will need to generate this global's definition, including

View file

@ -355,14 +355,16 @@ AttrsInfo::AttrsInfo(CPPCompile* _c, const AttributesPtr& _attrs) : CompoundItem
} }
} }
GlobalLookupInitInfo::GlobalLookupInitInfo(CPPCompile* c, const ID* g, string _CPP_name) GlobalLookupInitInfo::GlobalLookupInitInfo(CPPCompile* c, const ID* g, string _CPP_name, bool do_init)
: CPP_InitInfo(g), CPP_name(std::move(_CPP_name)) { : CPP_InitInfo(g), CPP_name(std::move(_CPP_name)) {
Zeek_name = g->Name(); Zeek_name = g->Name();
val = ValElem(c, do_init ? g->GetVal() : nullptr);
} }
void GlobalLookupInitInfo::InitializerVals(std::vector<std::string>& ivs) const { void GlobalLookupInitInfo::InitializerVals(std::vector<std::string>& ivs) const {
ivs.push_back(CPP_name); ivs.push_back(CPP_name);
ivs.push_back(string("\"") + Zeek_name + "\""); ivs.push_back(string("\"") + Zeek_name + "\"");
ivs.push_back(val);
} }
GlobalInitInfo::GlobalInitInfo(CPPCompile* c, const ID* g, string _CPP_name) GlobalInitInfo::GlobalInitInfo(CPPCompile* c, const ID* g, string _CPP_name)

View file

@ -482,7 +482,7 @@ public:
// initialization time but not create it if missing. // initialization time but not create it if missing.
class GlobalLookupInitInfo : public CPP_InitInfo { class GlobalLookupInitInfo : public CPP_InitInfo {
public: public:
GlobalLookupInitInfo(CPPCompile* c, const ID* g, std::string CPP_name); GlobalLookupInitInfo(CPPCompile* c, const ID* g, std::string CPP_name, bool do_init = false);
std::string InitializerType() const override { return "CPP_GlobalLookupInit"; } std::string InitializerType() const override { return "CPP_GlobalLookupInit"; }
void InitializerVals(std::vector<std::string>& ivs) const override; void InitializerVals(std::vector<std::string>& ivs) const override;
@ -490,6 +490,7 @@ public:
protected: protected:
std::string Zeek_name; std::string Zeek_name;
std::string CPP_name; std::string CPP_name;
std::string val;
}; };
// Information for initializing a Zeek global. // Information for initializing a Zeek global.

View file

@ -457,6 +457,9 @@ int CPP_EnumMapping::ComputeOffset(InitsManager* im) const {
void CPP_GlobalLookupInit::Generate(InitsManager* im, std::vector<void*>& /* inits_vec */, int /* offset */) const { void CPP_GlobalLookupInit::Generate(InitsManager* im, std::vector<void*>& /* inits_vec */, int /* offset */) const {
global = find_global__CPP(name); global = find_global__CPP(name);
if ( val >= 0 )
// Have explicit initialization value.
global->SetVal(im->ConstVals(val));
} }
void CPP_GlobalInit::Generate(InitsManager* im, std::vector<void*>& /* inits_vec */, int /* offset */) const { void CPP_GlobalInit::Generate(InitsManager* im, std::vector<void*>& /* inits_vec */, int /* offset */) const {

View file

@ -383,13 +383,15 @@ public:
// vector, so we use void* as the underlying type. // vector, so we use void* as the underlying type.
class CPP_GlobalLookupInit : public CPP_Init<void*> { class CPP_GlobalLookupInit : public CPP_Init<void*> {
public: public:
CPP_GlobalLookupInit(IDPtr& _global, const char* _name) : CPP_Init<void*>(), global(_global), name(_name) {} CPP_GlobalLookupInit(IDPtr& _global, const char* _name, int _val)
: CPP_Init<void*>(), global(_global), name(_name), val(_val) {}
void Generate(InitsManager* im, std::vector<void*>& /* inits_vec */, int /* offset */) const override; void Generate(InitsManager* im, std::vector<void*>& /* inits_vec */, int /* offset */) const override;
protected: protected:
IDPtr& global; IDPtr& global;
const char* name; const char* name;
int val;
}; };
class CPP_GlobalInit : public CPP_Init<void*> { class CPP_GlobalInit : public CPP_Init<void*> {

View file

@ -1,6 +1,7 @@
// See the file "COPYING" in the main distribution directory for copyright. // See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/script_opt/CPP/Compile.h" #include "zeek/script_opt/CPP/Compile.h"
#include "zeek/script_opt/IDOptInfo.h"
#include "zeek/script_opt/ProfileFunc.h" #include "zeek/script_opt/ProfileFunc.h"
namespace zeek::detail { namespace zeek::detail {
@ -32,12 +33,7 @@ void CPPCompile::CreateGlobal(const ID* g) {
// This is an event that's also used as a variable. // This is an event that's also used as a variable.
Emit("EventHandlerPtr %s_ev;", globals[gn]); Emit("EventHandlerPtr %s_ev;", globals[gn]);
shared_ptr<CPP_InitInfo> gi; auto gi = GenerateGlobalInit(g);
if ( standalone )
gi = make_shared<GlobalInitInfo>(this, g, globals[gn]);
else
gi = make_shared<GlobalLookupInitInfo>(this, g, globals[gn]);
global_id_info->AddInstance(gi); global_id_info->AddInstance(gi);
global_gis[g] = gi; global_gis[g] = gi;
} }
@ -69,18 +65,36 @@ std::shared_ptr<CPP_InitInfo> CPPCompile::RegisterGlobal(const ID* g) {
return gg->second; return gg->second;
} }
shared_ptr<CPP_InitInfo> gi; auto gi = GenerateGlobalInit(g);
if ( standalone )
gi = make_shared<GlobalInitInfo>(this, g, globals[gn]);
else
gi = make_shared<GlobalLookupInitInfo>(this, g, globals[gn]);
global_id_info->AddInstance(gi); global_id_info->AddInstance(gi);
global_gis[g] = gi; global_gis[g] = gi;
return gi; return gi;
} }
std::shared_ptr<CPP_InitInfo> CPPCompile::GenerateGlobalInit(const ID* g) {
auto gn = string(g->Name());
if ( ! standalone )
return make_shared<GlobalLookupInitInfo>(this, g, globals[gn]);
if ( obj_matches_opt_files(g) )
return make_shared<GlobalInitInfo>(this, g, globals[gn]);
// It's not a global that's created by the scripts we're compiling,
// but it might have a redef in those scripts, in which case we need
// to generate an initializer that will both look it up and then assign
// it to that value.
bool needs_redef = false;
for ( const auto& i_e : g->GetOptInfo()->GetInitExprs() )
if ( obj_matches_opt_files(i_e) ) {
needs_redef = true;
break;
}
return make_shared<GlobalLookupInitInfo>(this, g, globals[gn], needs_redef);
}
void CPPCompile::AddBiF(const ID* b, bool is_var) { void CPPCompile::AddBiF(const ID* b, bool is_var) {
auto bn = b->Name(); auto bn = b->Name();
auto n = string(bn); auto n = string(bn);

View file

@ -14,6 +14,10 @@ private:
// as a variable (not just as a function being called), track it as such. // as a variable (not just as a function being called), track it as such.
void CreateGlobal(const ID* g); void CreateGlobal(const ID* g);
// Low-level function for generating an initializer for a global. Takes
// into account differences for standalone-compilation.
std::shared_ptr<CPP_InitInfo> GenerateGlobalInit(const ID* g);
// Register the given identifier as a BiF. If is_var is true then the BiF // Register the given identifier as a BiF. If is_var is true then the BiF
// is also used in a non-call context. // is also used in a non-call context.
void AddBiF(const ID* b, bool is_var); void AddBiF(const ID* b, bool is_var);