mirror of
https://github.com/zeek/zeek.git
synced 2025-10-03 23:28:20 +00:00
the bulk of the compiler
This commit is contained in:
parent
158e82a2c1
commit
863be9436b
40 changed files with 7730 additions and 0 deletions
292
src/script_opt/CPP/Consts.cc
Normal file
292
src/script_opt/CPP/Consts.cc
Normal file
|
@ -0,0 +1,292 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "zeek/File.h"
|
||||
#include "zeek/RE.h"
|
||||
#include "zeek/script_opt/CPP/Compile.h"
|
||||
|
||||
|
||||
namespace zeek::detail {
|
||||
|
||||
std::string CPPCompile::BuildConstant(const Obj* parent, const ValPtr& vp)
|
||||
{
|
||||
if ( ! vp )
|
||||
return "nullptr";
|
||||
|
||||
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;
|
||||
|
||||
// Formulate a key that's unique per distinct constant.
|
||||
|
||||
const auto& t = v->GetType();
|
||||
std::string c_desc;
|
||||
|
||||
if ( t->Tag() == TYPE_STRING )
|
||||
{
|
||||
// We can't rely on these to render with consistent
|
||||
// escaping, sigh. Just use the raw string.
|
||||
auto s = v->AsString();
|
||||
auto b = (const char*)(s->Bytes());
|
||||
c_desc = std::string(b, s->Len()) + "string";
|
||||
}
|
||||
else
|
||||
{
|
||||
ODesc d;
|
||||
v->Describe(&d);
|
||||
|
||||
// Don't confuse constants of different types that happen to
|
||||
// render the same.
|
||||
t->Describe(&d);
|
||||
|
||||
c_desc = d.Description();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// Need a C++ global for this constant.
|
||||
auto const_name = std::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();
|
||||
|
||||
switch ( tag ) {
|
||||
case TYPE_STRING:
|
||||
AddStringConstant(vp, const_name);
|
||||
break;
|
||||
|
||||
case TYPE_PATTERN:
|
||||
AddPatternConstant(vp, const_name);
|
||||
break;
|
||||
|
||||
case TYPE_LIST:
|
||||
AddListConstant(vp, const_name);
|
||||
break;
|
||||
|
||||
case TYPE_RECORD:
|
||||
AddRecordConstant(vp, const_name);
|
||||
break;
|
||||
|
||||
case TYPE_TABLE:
|
||||
AddTableConstant(vp, const_name);
|
||||
break;
|
||||
|
||||
case TYPE_VECTOR:
|
||||
AddVectorConstant(vp, const_name);
|
||||
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,
|
||||
std::string("make_intrusive<") + prefix +
|
||||
"Val>(\"" + d.Description() + "\")");
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_FUNC:
|
||||
Emit("FuncValPtr %s;", const_name);
|
||||
|
||||
// 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;
|
||||
break;
|
||||
|
||||
case TYPE_FILE:
|
||||
{
|
||||
Emit("FileValPtr %s;", const_name);
|
||||
|
||||
auto f = cast_intrusive<FileVal>(vp)->Get();
|
||||
|
||||
AddInit(v, const_name,
|
||||
std::string("make_intrusive<FileVal>(") +
|
||||
"make_intrusive<File>(\"" + f->Name() + "\", \"w\"))");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
reporter->InternalError("bad constant type in CPPCompile::AddConstant");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CPPCompile::AddStringConstant(const ValPtr& v, std::string& const_name)
|
||||
{
|
||||
Emit("StringValPtr %s;", const_name);
|
||||
|
||||
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, std::string& const_name)
|
||||
{
|
||||
Emit("PatternValPtr %s;", const_name);
|
||||
|
||||
auto re = v->AsPatternVal()->Get();
|
||||
|
||||
AddInit(v, std::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, std::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, std::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, std::string& const_name)
|
||||
{
|
||||
const auto& t = v->GetType();
|
||||
|
||||
Emit("RecordValPtr %s;", const_name);
|
||||
|
||||
NoteInitDependency(v, TypeRep(t));
|
||||
|
||||
AddInit(v, const_name, std::string("make_intrusive<RecordVal>(") +
|
||||
"cast_intrusive<RecordType>(" + GenTypeName(t) + "))");
|
||||
|
||||
auto r = cast_intrusive<RecordVal>(v);
|
||||
auto n = r->NumFields();
|
||||
|
||||
for ( auto i = 0; 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(i) +
|
||||
", " + r_i_c + ");");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CPPCompile::AddTableConstant(const ValPtr& v, std::string& const_name)
|
||||
{
|
||||
const auto& t = v->GetType();
|
||||
|
||||
Emit("TableValPtr %s;", const_name);
|
||||
|
||||
NoteInitDependency(v, TypeRep(t));
|
||||
|
||||
AddInit(v, const_name, std::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, std::string& const_name)
|
||||
{
|
||||
const auto& t = v->GetType();
|
||||
|
||||
Emit("VectorValPtr %s;", const_name);
|
||||
|
||||
NoteInitDependency(v, TypeRep(t));
|
||||
|
||||
AddInit(v, const_name, std::string("make_intrusive<VectorVal>(") +
|
||||
"cast_intrusive<VectorType>(" + GenTypeName(t) + "))");
|
||||
|
||||
auto vv = cast_intrusive<VectorVal>(v);
|
||||
auto n = vv->Size();
|
||||
|
||||
for ( auto i = 0; 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 + ");");
|
||||
}
|
||||
}
|
||||
|
||||
} // zeek::detail
|
Loading…
Add table
Add a link
Reference in a new issue