support for standalone compiled scripts to export globals with module qualifiers

This commit is contained in:
Vern Paxson 2021-06-11 08:49:52 -07:00
parent 4ecf70f515
commit b4f025dda9
5 changed files with 59 additions and 19 deletions

View file

@ -187,6 +187,11 @@ private:
// Maps functions (not hooks or events) to upstream compiled names. // Maps functions (not hooks or events) to upstream compiled names.
std::unordered_map<std::string, std::string> hashed_funcs; std::unordered_map<std::string, std::string> hashed_funcs;
// Tracks all of the module names used in activate_bodies__CPP()
// calls, to ensure all of the global names of compiled-to-standalone
// functions are available to subsequent scripts.
std::unordered_set<std::string> module_names;
// If non-zero, provides a tag used for auxiliary/additional // If non-zero, provides a tag used for auxiliary/additional
// compilation units. // compilation units.
int addl_tag = 0; int addl_tag = 0;
@ -1007,6 +1012,16 @@ private:
NL(); NL();
} }
void Emit(const std::string& fmt, const std::string& arg1,
const std::string& arg2, const std::string& arg3,
const std::string& arg4, const std::string& arg5) const
{
Indent();
fprintf(write_file, fmt.c_str(), arg1.c_str(), arg2.c_str(),
arg3.c_str(), arg4.c_str(), arg5.c_str());
NL();
}
// Returns an expression for constructing a Zeek String object // Returns an expression for constructing a Zeek String object
// corresponding to the given byte array. // corresponding to the given byte array.
std::string GenString(const char* b, int len) const; std::string GenString(const char* b, int len) const;

View file

@ -4,6 +4,7 @@
#include <unistd.h> #include <unistd.h>
#include <sys/stat.h> #include <sys/stat.h>
#include "zeek/module_util.h"
#include "zeek/script_opt/ProfileFunc.h" #include "zeek/script_opt/ProfileFunc.h"
#include "zeek/script_opt/CPP/Compile.h" #include "zeek/script_opt/CPP/Compile.h"
@ -516,10 +517,6 @@ void CPPCompile::GenStandaloneActivation()
for ( auto& fb : func_bodies ) for ( auto& fb : func_bodies )
{ {
auto f = fb.first;
const auto fn = f->Name();
const auto& ft = f->GetType();
string hashes; string hashes;
for ( auto h : fb.second ) for ( auto h : fb.second )
{ {
@ -531,8 +528,23 @@ void CPPCompile::GenStandaloneActivation()
hashes = "{" + hashes + "}"; hashes = "{" + hashes + "}";
Emit("activate_bodies__CPP(\"%s\", %s, %s);", auto f = fb.first;
fn, GenTypeName(ft), hashes); auto fn = f->Name();
const auto& ft = f->GetType();
auto var = extract_var_name(fn);
auto mod = extract_module_name(fn);
module_names.insert(mod);
auto fid = lookup_ID(var.c_str(), mod.c_str(),
false, true, false);
if ( ! fid )
reporter->InternalError("can't find identifier %s", fn);
auto exported = fid->IsExport() ? "true" : "false";
Emit("activate_bodies__CPP(\"%s\", \"%s\", %s, %s, %s);",
var, mod, exported, GenTypeName(ft), hashes);
} }
NL(); NL();
@ -552,7 +564,15 @@ void CPPCompile::GenLoad()
Emit("register_scripts__CPP(%s, standalone_init__CPP);", Fmt(total_hash)); Emit("register_scripts__CPP(%s, standalone_init__CPP);", Fmt(total_hash));
// Spit out the placeholder script. // Spit out the placeholder script, and any associated module
// definitions.
for ( auto& m : module_names )
if ( m != "GLOBAL" )
printf("module %s;\n", m.c_str());
if ( module_names.size() > 0 )
printf("module GLOBAL;\n\n");
printf("global init_CPP_%llu = load_CPP(%llu);\n", printf("global init_CPP_%llu = load_CPP(%llu);\n",
total_hash, total_hash); total_hash, total_hash);
} }

View file

@ -98,14 +98,15 @@ void register_scripts__CPP(p_hash_type h, void (*callback)())
standalone_callbacks[h] = callback; standalone_callbacks[h] = callback;
} }
void activate_bodies__CPP(const char* fn, TypePtr t, vector<p_hash_type> hashes) void activate_bodies__CPP(const char* fn, const char* module, bool exported,
TypePtr t, vector<p_hash_type> hashes)
{ {
auto ft = cast_intrusive<FuncType>(t); auto ft = cast_intrusive<FuncType>(t);
auto fg = lookup_ID(fn, GLOBAL_MODULE_NAME, false, false, false); auto fg = lookup_ID(fn, module, false, false, false);
if ( ! fg ) if ( ! fg )
{ {
fg = install_ID(fn, GLOBAL_MODULE_NAME, true, false); fg = install_ID(fn, module, true, exported);
fg->SetType(ft); fg->SetType(ft);
} }
@ -170,13 +171,13 @@ void activate_bodies__CPP(const char* fn, TypePtr t, vector<p_hash_type> hashes)
} }
} }
IDPtr lookup_global__CPP(const char* g, const TypePtr& t) IDPtr lookup_global__CPP(const char* g, const TypePtr& t, bool exported)
{ {
auto gl = lookup_ID(g, GLOBAL_MODULE_NAME, false, false, false); auto gl = lookup_ID(g, GLOBAL_MODULE_NAME, false, false, false);
if ( ! gl ) if ( ! gl )
{ {
gl = install_ID(g, GLOBAL_MODULE_NAME, true, false); gl = install_ID(g, GLOBAL_MODULE_NAME, true, exported);
gl->SetType(t); gl->SetType(t);
} }

View file

@ -47,15 +47,17 @@ extern void register_lambda__CPP(CPPStmtPtr body, p_hash_type hash,
// the given hash. // the given hash.
extern void register_scripts__CPP(p_hash_type h, void (*callback)()); extern void register_scripts__CPP(p_hash_type h, void (*callback)());
// Activates the event handler/hook with the given name (which is created // Activates the function/event handler/hook with the given name and in
// if it doesn't exist) and type, using (at least) the bodies associated // the given module, using (at least) the bodies associated with the
// with the given hashes. // given hashes. Creates the identifier using the given module and
extern void activate_bodies__CPP(const char* fn, TypePtr t, // export setting if it doesn't already exist.
extern void activate_bodies__CPP(const char* fn, const char* module,
bool exported, TypePtr t,
std::vector<p_hash_type> hashes); std::vector<p_hash_type> hashes);
// Looks for a global with the given name. If not present, creates it // Looks for a global with the given name. If not present, creates it
// with the given type. // with the given type and export setting.
extern IDPtr lookup_global__CPP(const char* g, const TypePtr& t); extern IDPtr lookup_global__CPP(const char* g, const TypePtr& t, bool exported);
// Looks for a BiF with the given name. Returns nil if not present. // Looks for a BiF with the given name. Returns nil if not present.
extern Func* lookup_bif__CPP(const char* bif); extern Func* lookup_bif__CPP(const char* bif);

View file

@ -109,9 +109,11 @@ void CPPCompile::CreateGlobal(const ID* g)
const auto& t = g->GetType(); const auto& t = g->GetType();
NoteInitDependency(g, TypeRep(t)); NoteInitDependency(g, TypeRep(t));
auto exported = g->IsExport() ? "true" : "false";
AddInit(g, globals[gn], AddInit(g, globals[gn],
string("lookup_global__CPP(\"") + gn + "\", " + string("lookup_global__CPP(\"") + gn + "\", " +
GenTypeName(t) + ")"); GenTypeName(t) + ", " + exported + ")");
} }
if ( is_bif ) if ( is_bif )