simpler workflow for -O gen-C++ ; also some hooks for -O gen-standalone-C++

This commit is contained in:
Vern Paxson 2021-06-04 17:01:53 -07:00
parent 98f549d65d
commit e1dc3e7b08
4 changed files with 57 additions and 16 deletions

View file

@ -134,8 +134,8 @@ namespace zeek::detail {
class CPPCompile {
public:
CPPCompile(std::vector<FuncInfo>& _funcs, ProfileFuncs& pfs,
const char* gen_name, CPPHashManager& hm,
bool update, bool standalone);
const std::string& gen_name, const std::string& addl_name,
CPPHashManager& _hm, bool _update, bool _standalone);
~CPPCompile();
private:
@ -390,9 +390,14 @@ private:
// function.
std::string GenArgs(const RecordTypePtr& params, const Expr* e);
// Functions that we've declared/compiled.
// Functions that we've declared/compiled. Indexed by full C++ name.
std::unordered_set<std::string> compiled_funcs;
// "Simple" functions that we've compiled, i.e., those that have
// a single body and thus can be called dirctly. Indexed by
// function name, and maps to the C++ name.
std::unordered_map<std::string, std::string> compiled_simple_funcs;
// Maps those to their associated files - used to make add-C++ body
// hashes distinct.
std::unordered_map<std::string, std::string> cf_locs;
@ -858,6 +863,12 @@ private:
void AddInit(const IntrusivePtr<Obj>& o) { AddInit(o.get()); }
void AddInit(const Obj* o);
// This is akin to an initialization, but done separately
// (upon "activation") so it can include initializations that
// rely on parsing having finished (in particular, BiFs having
// been registered). Only used when generating standalone code.
void AddActivation(std::string a) { activations.emplace_back(a); }
// Records the fact that the initialization of object o1 depends
// on that of object o2.
void NoteInitDependency(const IntrusivePtr<Obj>& o1,
@ -922,6 +933,10 @@ private:
// other initializations, and that themselves have no dependencies).
std::vector<std::string> pre_inits;
// A list of "activations" (essentially, post-initializations).
// See AddActivation() above.
std::vector<std::string> activations;
// Expressions for which we need to generate initialization-time
// code. Currently, these are only expressions appearing in
// attributes.
@ -1010,6 +1025,9 @@ private:
// File to which we're generating code.
FILE* write_file;
// Name of file holding potential "additional" code.
std::string addl_name;
// Indentation level.
int block_level = 0;

View file

@ -24,6 +24,9 @@ void CPPCompile::DeclareFunc(const FuncInfo& func)
DeclareSubclass(f->GetType(), pf, fname, body, priority, nullptr,
f->Flavor());
if ( f->GetBodies().size() == 1 )
compiled_simple_funcs[f->Name()] = fname;
}
void CPPCompile::DeclareLambda(const LambdaExpr* l, const ProfileFunc* pf)

View file

@ -13,20 +13,24 @@ using namespace std;
CPPCompile::CPPCompile(vector<FuncInfo>& _funcs, ProfileFuncs& _pfs,
const char* gen_name, CPPHashManager& _hm,
bool _update, bool _standalone)
: funcs(_funcs), pfs(_pfs), hm(_hm), update(_update), standalone(_standalone)
const string& gen_name, const string& _addl_name,
CPPHashManager& _hm, bool _update, bool _standalone)
: funcs(_funcs), pfs(_pfs), hm(_hm),
update(_update), standalone(_standalone)
{
auto mode = hm.IsAppend() ? "a" : "w";
addl_name = _addl_name;
bool is_addl = hm.IsAppend();
auto target_name = is_addl ? addl_name.c_str() : gen_name.c_str();
auto mode = is_addl ? "a" : "w";
write_file = fopen(gen_name, mode);
write_file = fopen(target_name, mode);
if ( ! write_file )
{
reporter->Error("can't open C++ target file %s", gen_name);
reporter->Error("can't open C++ target file %s", target_name);
exit(1);
}
if ( hm.IsAppend() )
if ( is_addl )
{
// We need a unique number to associate with the name
// space for the code we're adding. A convenient way to
@ -39,7 +43,7 @@ CPPCompile::CPPCompile(vector<FuncInfo>& _funcs, ProfileFuncs& _pfs,
{
char buf[256];
util::zeek_strerror_r(errno, buf, sizeof(buf));
reporter->Error("fstat failed on %s: %s", gen_name, buf);
reporter->Error("fstat failed on %s: %s", target_name, buf);
exit(1);
}
@ -49,6 +53,20 @@ CPPCompile::CPPCompile(vector<FuncInfo>& _funcs, ProfileFuncs& _pfs,
addl_tag = st.st_size + 1;
}
else
{
// Create an empty "additional" file.
auto addl_f = fopen(addl_name.c_str(), "w");
if ( ! addl_f )
{
reporter->Error("can't open C++ additional file %s",
addl_name.c_str());
exit(1);
}
fclose(addl_f);
}
Compile();
}
@ -313,7 +331,7 @@ void CPPCompile::GenEpilog()
if ( addl_tag > 0 )
return;
Emit("#include \"CPP-gen-addl.h\"\n");
Emit("#include \"" + addl_name + "\"\n");
Emit("} // zeek::detail");
}

View file

@ -280,9 +280,6 @@ void analyze_scripts()
// Avoid profiling overhead.
return;
const auto hash_name = hash_dir + "CPP-hashes";
const auto gen_name = hash_dir + "CPP-gen-addl.h";
// Now that everything's parsed and BiF's have been initialized,
// profile the functions.
auto pfs = std::make_unique<ProfileFuncs>(funcs, is_CPP_compilable, false);
@ -376,6 +373,8 @@ void analyze_scripts()
if ( generating_CPP )
{
const auto hash_name = hash_dir + "CPP-hashes";
auto hm = std::make_unique<CPPHashManager>(hash_name.c_str(),
analysis_options.add_CPP);
@ -394,7 +393,10 @@ void analyze_scripts()
pfs = std::make_unique<ProfileFuncs>(funcs, is_CPP_compilable, false);
}
CPPCompile cpp(funcs, *pfs, gen_name.c_str(), *hm,
const auto gen_name = hash_dir + "CPP-gen.cc";
const auto addl_name = hash_dir + "CPP-gen-addl.h";
CPPCompile cpp(funcs, *pfs, gen_name, addl_name, *hm,
analysis_options.gen_CPP ||
analysis_options.update_CPP,
analysis_options.gen_standalone_CPP);