mirror of
https://github.com/zeek/zeek.git
synced 2025-10-03 07:08:19 +00:00
extensive rewrite of generation & execution of run-time initialization
This commit is contained in:
parent
bc3bf4ea6c
commit
e1a760e674
26 changed files with 3459 additions and 1580 deletions
|
@ -4,55 +4,26 @@
|
|||
#include "zeek/RE.h"
|
||||
#include "zeek/script_opt/CPP/Compile.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace zeek::detail
|
||||
{
|
||||
|
||||
using namespace std;
|
||||
|
||||
string CPPCompile::BuildConstant(const Obj* parent, const ValPtr& vp)
|
||||
shared_ptr<CPP_InitInfo> CPPCompile::RegisterConstant(const ValPtr& vp, int& consts_offset)
|
||||
{
|
||||
if ( ! vp )
|
||||
return "nullptr";
|
||||
// Make sure the value pointer, which might be transient
|
||||
// in construction, sticks around so we can track its
|
||||
// value.
|
||||
cv_indices.push_back(vp);
|
||||
|
||||
if ( AddConstant(vp) )
|
||||
{
|
||||
auto v = vp.get();
|
||||
AddInit(parent);
|
||||
NoteInitDependency(parent, v);
|
||||
|
||||
// Make sure the value pointer, which might be transient
|
||||
// in construction, sticks around so we can track its
|
||||
// value.
|
||||
cv_indices.push_back(vp);
|
||||
|
||||
return const_vals[v];
|
||||
}
|
||||
else
|
||||
return NativeToGT(GenVal(vp), vp->GetType(), GEN_VAL_PTR);
|
||||
}
|
||||
|
||||
void CPPCompile::AddConstant(const ConstExpr* c)
|
||||
{
|
||||
auto v = c->ValuePtr();
|
||||
|
||||
if ( AddConstant(v) )
|
||||
{
|
||||
AddInit(c);
|
||||
NoteInitDependency(c, v.get());
|
||||
}
|
||||
}
|
||||
|
||||
bool CPPCompile::AddConstant(const ValPtr& vp)
|
||||
{
|
||||
auto v = vp.get();
|
||||
|
||||
if ( IsNativeType(v->GetType()) )
|
||||
// These we instantiate directly.
|
||||
return false;
|
||||
|
||||
if ( const_vals.count(v) > 0 )
|
||||
{
|
||||
// Already did this one.
|
||||
return true;
|
||||
consts_offset = const_offsets[v];
|
||||
return const_vals[v];
|
||||
}
|
||||
|
||||
// Formulate a key that's unique per distinct constant.
|
||||
|
||||
|
@ -82,213 +53,100 @@ bool CPPCompile::AddConstant(const ValPtr& vp)
|
|||
if ( constants.count(c_desc) > 0 )
|
||||
{
|
||||
const_vals[v] = constants[c_desc];
|
||||
|
||||
auto orig_v = constants_to_vals[c_desc];
|
||||
ASSERT(v != orig_v);
|
||||
AddInit(v);
|
||||
NoteInitDependency(v, orig_v);
|
||||
|
||||
return true;
|
||||
consts_offset = const_offsets[v] = constants_offsets[c_desc];
|
||||
return const_vals[v];
|
||||
}
|
||||
|
||||
// Need a C++ global for this constant.
|
||||
auto const_name = string("CPP__const__") + Fmt(int(constants.size()));
|
||||
|
||||
const_vals[v] = constants[c_desc] = const_name;
|
||||
constants_to_vals[c_desc] = v;
|
||||
|
||||
auto tag = t->Tag();
|
||||
auto const_name = const_info[tag]->NextName();
|
||||
shared_ptr<CPP_InitInfo> gi;
|
||||
|
||||
switch ( tag )
|
||||
{
|
||||
case TYPE_STRING:
|
||||
AddStringConstant(vp, const_name);
|
||||
case TYPE_BOOL:
|
||||
gi = make_shared<BasicConstInfo>(vp->AsBool() ? "true" : "false");
|
||||
break;
|
||||
|
||||
case TYPE_PATTERN:
|
||||
AddPatternConstant(vp, const_name);
|
||||
case TYPE_INT:
|
||||
gi = make_shared<BasicConstInfo>(to_string(vp->AsInt()));
|
||||
break;
|
||||
|
||||
case TYPE_LIST:
|
||||
AddListConstant(vp, const_name);
|
||||
case TYPE_COUNT:
|
||||
gi = make_shared<BasicConstInfo>(to_string(vp->AsCount()) + "ULL");
|
||||
break;
|
||||
|
||||
case TYPE_RECORD:
|
||||
AddRecordConstant(vp, const_name);
|
||||
case TYPE_DOUBLE:
|
||||
gi = make_shared<BasicConstInfo>(to_string(vp->AsDouble()));
|
||||
break;
|
||||
|
||||
case TYPE_TABLE:
|
||||
AddTableConstant(vp, const_name);
|
||||
case TYPE_TIME:
|
||||
gi = make_shared<BasicConstInfo>(to_string(vp->AsDouble()));
|
||||
break;
|
||||
|
||||
case TYPE_VECTOR:
|
||||
AddVectorConstant(vp, const_name);
|
||||
case TYPE_INTERVAL:
|
||||
gi = make_shared<BasicConstInfo>(to_string(vp->AsDouble()));
|
||||
break;
|
||||
|
||||
case TYPE_ADDR:
|
||||
case TYPE_SUBNET:
|
||||
{
|
||||
auto prefix = (tag == TYPE_ADDR) ? "Addr" : "SubNet";
|
||||
|
||||
Emit("%sValPtr %s;", prefix, const_name);
|
||||
|
||||
ODesc d;
|
||||
v->Describe(&d);
|
||||
|
||||
AddInit(v, const_name,
|
||||
string("make_intrusive<") + prefix + "Val>(\"" + d.Description() + "\")");
|
||||
}
|
||||
gi = make_shared<DescConstInfo>(this, vp);
|
||||
break;
|
||||
|
||||
case TYPE_FUNC:
|
||||
Emit("FuncValPtr %s;", const_name);
|
||||
case TYPE_SUBNET:
|
||||
gi = make_shared<DescConstInfo>(this, vp);
|
||||
break;
|
||||
|
||||
// We can't generate the initialization now because it
|
||||
// depends on first having compiled the associated body,
|
||||
// so we know its hash. So for now we just note it
|
||||
// to deal with later.
|
||||
func_vars[v->AsFuncVal()] = const_name;
|
||||
case TYPE_ENUM:
|
||||
gi = make_shared<EnumConstInfo>(this, vp);
|
||||
break;
|
||||
|
||||
case TYPE_STRING:
|
||||
gi = make_shared<StringConstInfo>(this, vp);
|
||||
break;
|
||||
|
||||
case TYPE_PATTERN:
|
||||
gi = make_shared<PatternConstInfo>(this, vp);
|
||||
break;
|
||||
|
||||
case TYPE_PORT:
|
||||
gi = make_shared<PortConstInfo>(vp);
|
||||
break;
|
||||
|
||||
case TYPE_LIST:
|
||||
gi = make_shared<ListConstInfo>(this, vp);
|
||||
break;
|
||||
|
||||
case TYPE_VECTOR:
|
||||
gi = make_shared<VectorConstInfo>(this, vp);
|
||||
break;
|
||||
|
||||
case TYPE_RECORD:
|
||||
gi = make_shared<RecordConstInfo>(this, vp);
|
||||
break;
|
||||
|
||||
case TYPE_TABLE:
|
||||
gi = make_shared<TableConstInfo>(this, vp);
|
||||
break;
|
||||
|
||||
case TYPE_FILE:
|
||||
{
|
||||
Emit("FileValPtr %s;", const_name);
|
||||
gi = make_shared<FileConstInfo>(this, vp);
|
||||
break;
|
||||
|
||||
auto f = cast_intrusive<FileVal>(vp)->Get();
|
||||
|
||||
AddInit(v, const_name,
|
||||
string("make_intrusive<FileVal>(") + "make_intrusive<File>(\"" + f->Name() +
|
||||
"\", \"w\"))");
|
||||
}
|
||||
case TYPE_FUNC:
|
||||
gi = make_shared<FuncConstInfo>(this, vp);
|
||||
break;
|
||||
|
||||
default:
|
||||
reporter->InternalError("bad constant type in CPPCompile::AddConstant");
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
const_info[tag]->AddInstance(gi);
|
||||
const_vals[v] = constants[c_desc] = gi;
|
||||
|
||||
void CPPCompile::AddStringConstant(const ValPtr& v, string& const_name)
|
||||
{
|
||||
Emit("StringValPtr %s;", const_name);
|
||||
consts_offset = const_offsets[v] = constants_offsets[c_desc] = consts.size();
|
||||
consts.emplace_back(pair(tag, gi->Offset()));
|
||||
|
||||
auto s = v->AsString();
|
||||
const char* b = (const char*)(s->Bytes());
|
||||
auto len = s->Len();
|
||||
|
||||
AddInit(v, const_name, GenString(b, len));
|
||||
}
|
||||
|
||||
void CPPCompile::AddPatternConstant(const ValPtr& v, string& const_name)
|
||||
{
|
||||
Emit("PatternValPtr %s;", const_name);
|
||||
|
||||
auto re = v->AsPatternVal()->Get();
|
||||
|
||||
AddInit(v, string("{ auto re = new RE_Matcher(") + CPPEscape(re->OrigText()) + ");");
|
||||
|
||||
if ( re->IsCaseInsensitive() )
|
||||
AddInit(v, "re->MakeCaseInsensitive();");
|
||||
|
||||
AddInit(v, "re->Compile();");
|
||||
AddInit(v, const_name, "make_intrusive<PatternVal>(re)");
|
||||
AddInit(v, "}");
|
||||
}
|
||||
|
||||
void CPPCompile::AddListConstant(const ValPtr& v, string& const_name)
|
||||
{
|
||||
Emit("ListValPtr %s;", const_name);
|
||||
|
||||
// No initialization dependency on the main type since we don't
|
||||
// use the underlying TypeList. However, we *do* use the types of
|
||||
// the elements.
|
||||
|
||||
AddInit(v, const_name, string("make_intrusive<ListVal>(TYPE_ANY)"));
|
||||
|
||||
auto lv = cast_intrusive<ListVal>(v);
|
||||
auto n = lv->Length();
|
||||
|
||||
for ( auto i = 0; i < n; ++i )
|
||||
{
|
||||
const auto& l_i = lv->Idx(i);
|
||||
auto l_i_c = BuildConstant(v, l_i);
|
||||
AddInit(v, const_name + "->Append(" + l_i_c + ");");
|
||||
NoteInitDependency(v, TypeRep(l_i->GetType()));
|
||||
}
|
||||
}
|
||||
|
||||
void CPPCompile::AddRecordConstant(const ValPtr& v, string& const_name)
|
||||
{
|
||||
const auto& t = v->GetType();
|
||||
|
||||
Emit("RecordValPtr %s;", const_name);
|
||||
|
||||
NoteInitDependency(v, TypeRep(t));
|
||||
|
||||
AddInit(v, const_name,
|
||||
string("make_intrusive<RecordVal>(") + "cast_intrusive<RecordType>(" + GenTypeName(t) +
|
||||
"))");
|
||||
|
||||
auto r = cast_intrusive<RecordVal>(v);
|
||||
auto n = r->NumFields();
|
||||
|
||||
for ( auto i = 0u; i < n; ++i )
|
||||
{
|
||||
const auto& r_i = r->GetField(i);
|
||||
|
||||
if ( r_i )
|
||||
{
|
||||
auto r_i_c = BuildConstant(v, r_i);
|
||||
AddInit(v, const_name + "->Assign(" + Fmt(static_cast<int>(i)) + ", " + r_i_c + ");");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CPPCompile::AddTableConstant(const ValPtr& v, string& const_name)
|
||||
{
|
||||
const auto& t = v->GetType();
|
||||
|
||||
Emit("TableValPtr %s;", const_name);
|
||||
|
||||
NoteInitDependency(v, TypeRep(t));
|
||||
|
||||
AddInit(v, const_name,
|
||||
string("make_intrusive<TableVal>(") + "cast_intrusive<TableType>(" + GenTypeName(t) +
|
||||
"))");
|
||||
|
||||
auto tv = cast_intrusive<TableVal>(v);
|
||||
auto tv_map = tv->ToMap();
|
||||
|
||||
for ( auto& tv_i : tv_map )
|
||||
{
|
||||
auto ind = BuildConstant(v, tv_i.first);
|
||||
auto val = BuildConstant(v, tv_i.second);
|
||||
AddInit(v, const_name + "->Assign(" + ind + ", " + val + ");");
|
||||
}
|
||||
}
|
||||
|
||||
void CPPCompile::AddVectorConstant(const ValPtr& v, string& const_name)
|
||||
{
|
||||
const auto& t = v->GetType();
|
||||
|
||||
Emit("VectorValPtr %s;", const_name);
|
||||
|
||||
NoteInitDependency(v, TypeRep(t));
|
||||
|
||||
AddInit(v, const_name,
|
||||
string("make_intrusive<VectorVal>(") + "cast_intrusive<VectorType>(" + GenTypeName(t) +
|
||||
"))");
|
||||
|
||||
auto vv = cast_intrusive<VectorVal>(v);
|
||||
auto n = vv->Size();
|
||||
|
||||
for ( auto i = 0u; i < n; ++i )
|
||||
{
|
||||
const auto& v_i = vv->ValAt(i);
|
||||
auto v_i_c = BuildConstant(v, v_i);
|
||||
AddInit(v, const_name + "->Append(" + v_i_c + ");");
|
||||
}
|
||||
return gi;
|
||||
}
|
||||
|
||||
} // zeek::detail
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue