diff --git a/src/script_opt/CPP/InitsInfo.cc b/src/script_opt/CPP/InitsInfo.cc index 24eb5986fd..682744510f 100644 --- a/src/script_opt/CPP/InitsInfo.cc +++ b/src/script_opt/CPP/InitsInfo.cc @@ -7,6 +7,7 @@ #include "zeek/ZeekString.h" #include "zeek/script_opt/CPP/Attrs.h" #include "zeek/script_opt/CPP/Compile.h" +#include "zeek/script_opt/CPP/RuntimeInits.h" using namespace std; @@ -85,25 +86,25 @@ void CPP_InitsInfo::BuildOffsetSet(CPPCompile* c) { offset_set = c->IndMgr().AddIndices(offsets_vec); } -void CPP_InitsInfo::BuildCohort(CPPCompile* c, std::vector>& cohort) { - int n = 0; +static std::string describe_initializer(const Obj* o) { + auto od = obj_desc(o); + // Escape any embedded comment characters. + od = regex_replace(od, std::regex("/\\*"), "<>"); + od = regex_replace(od, std::regex("\\*/"), "<>"); + + return od; +} + +void CPP_InitsInfo::BuildCohort(CPPCompile* c, std::vector>& cohort) { for ( auto& co : cohort ) { vector ivs; auto o = co->InitObj(); - if ( o ) { - auto od = obj_desc(o); - - // Escape any embedded comment characters. - od = regex_replace(od, std::regex("/\\*"), "<>"); - od = regex_replace(od, std::regex("\\*/"), "<>"); - - c->Emit("/* #%s: Initializing %s: */", Fmt(co->Offset()), od); - } + if ( o ) + c->Emit("/* #%s: Initializing %s: */", Fmt(co->Offset()), describe_initializer(o)); co->InitializerVals(ivs); BuildCohortElement(c, co->InitializerType(), ivs); - ++n; } } @@ -123,6 +124,7 @@ void CPP_InitsInfo::BuildCohortElement(CPPCompile* c, string init_type, vectorEmit(""); c->Emit("static int %s_init[] = {", tag); int n = 0; @@ -132,12 +134,25 @@ void CPP_CompoundInitsInfo::GenerateInitializers(CPPCompile* c) { if ( ++n > 1 ) c->Emit(""); - c->Emit(Fmt(int(cohort.size())) + ","); - BuildCohort(c, cohort); - c->Emit("-1,"); + // Figure out the size of the cohort. + for ( auto& co : cohort ) { + auto o = co->InitObj(); + if ( o ) + c->Emit("/* #%s: Initializing %s: */", Fmt(co->Offset()), describe_initializer(o)); + + vector ivs; + co->InitializerVals(ivs); + c->Emit(Fmt(int(ivs.size())) + ","); + BuildCohortElement(c, co->InitializerType(), ivs); + } + + static const auto end_of_vv = Fmt(END_OF_VEC_VEC) + ","; + c->Emit(end_of_vv); } - c->Emit("-2,"); + static const auto end_of_vvv = Fmt(END_OF_VEC_VEC_VEC) + ","; + c->Emit(end_of_vvv); + c->IndentDown(); c->Emit("};"); @@ -149,9 +164,9 @@ void CPP_CompoundInitsInfo::GenerateCohorts(CPPCompile* c) { c->Emit("%s_init", void CPP_CompoundInitsInfo::BuildCohortElement(CPPCompile* c, string init_type, vector& ivs) { string init_line; for ( auto& iv : ivs ) - init_line += iv; + init_line += iv + ","; - c->Emit("%s,", init_line); + c->Emit("%s", init_line); } void CPP_BasicConstInitsInfo::BuildCohortElement(CPPCompile* c, string init_type, vector& ivs) { @@ -581,7 +596,8 @@ void IndicesManager::Generate(CPPCompile* c) { c->Emit(line); } - c->Emit("-1"); + static const auto end_of_vv = Fmt(END_OF_VEC_VEC); + c->Emit(end_of_vv); c->EndBlock(true); } diff --git a/src/script_opt/CPP/RuntimeInits.cc b/src/script_opt/CPP/RuntimeInits.cc index 93105eccb7..99837d08e4 100644 --- a/src/script_opt/CPP/RuntimeInits.cc +++ b/src/script_opt/CPP/RuntimeInits.cc @@ -470,7 +470,7 @@ size_t generate_indices_set(int* inits, std::vector>& indices_s // can pre-allocate the outer vector. auto i_ptr = inits; int num_inits = 0; - while ( *i_ptr >= 0 ) { + while ( *i_ptr != END_OF_VEC_VEC && *i_ptr != END_OF_VEC_VEC_VEC ) { ++num_inits; int n = *i_ptr; i_ptr += n + 1; // skip over vector elements @@ -479,7 +479,7 @@ size_t generate_indices_set(int* inits, std::vector>& indices_s indices_set.reserve(num_inits); i_ptr = inits; - while ( *i_ptr >= 0 ) { + while ( *i_ptr != END_OF_VEC_VEC ) { int n = *i_ptr; ++i_ptr; std::vector indices; @@ -495,19 +495,13 @@ size_t generate_indices_set(int* inits, std::vector>& indices_s } std::vector>> generate_indices_set(int* inits) { - // Figure out how many vector-of-vectors there are. - int num_vv = 0; - for ( int i = 0; inits[i] >= -1; ++i ) - if ( inits[i] == -1 ) - ++num_vv; + std::vector>> indices_set; - std::vector>> indices_set(num_vv); - - auto i_ptr = inits; - for ( int i = 0; i < num_vv; ++i ) - i_ptr += generate_indices_set(i_ptr, indices_set[i]); - - ASSERT(*i_ptr == -2); + while ( *inits != END_OF_VEC_VEC_VEC ) { + std::vector> cohort_inits; + inits += generate_indices_set(inits, cohort_inits); + indices_set.push_back(std::move(cohort_inits)); + } return indices_set; } diff --git a/src/script_opt/CPP/RuntimeInits.h b/src/script_opt/CPP/RuntimeInits.h index 8e153e1472..6068ac7950 100644 --- a/src/script_opt/CPP/RuntimeInits.h +++ b/src/script_opt/CPP/RuntimeInits.h @@ -23,19 +23,24 @@ class InitsManager; // constructs the corresponding vector-of-vector-of-indices. Each // vector-of-indices is represented first by an int specifying its // size, and then that many int's for its values. We recognize the -// end of the array upon encountering a "size" entry of -1. +// end of the array upon encountering a "size" entry of END_OF_VEC_VEC. // // Returns how many elements were processed out of "inits", including its // terminator. extern size_t generate_indices_set(int* inits, std::vector>& indices_set); // The same but for one more level of vector construction. The source array -// has sub-arrays terminated with -1 per the above, and the whole shebang -// is terminated with -2. +// has sub-arrays terminated with END_OF_VEC_VEC per the above, and the whole +// shebang is terminated with END_OF_VEC_VEC_VEC. // // Returns the vector construction. extern std::vector>> generate_indices_set(int* inits); +// These need to be distinct from any values that can appear, which means +// they should be negative, and not -1, which is used as a "N/A" value. +#define END_OF_VEC_VEC -100 +#define END_OF_VEC_VEC_VEC -200 + // An abstract helper class used to access elements of an initialization vector. // We need the abstraction because InitsManager below needs to be able to refer // to any of a range of templated classes.