extensive rewrite of generation & execution of run-time initialization

This commit is contained in:
Vern Paxson 2021-11-07 17:00:19 -08:00
parent bc3bf4ea6c
commit e1a760e674
26 changed files with 3459 additions and 1580 deletions

View file

@ -7,42 +7,53 @@ namespace zeek::detail
using namespace std;
void CPPCompile::RegisterAttributes(const AttributesPtr& attrs)
shared_ptr<CPP_InitInfo> CPPCompile::RegisterAttributes(const AttributesPtr& attrs)
{
if ( ! attrs || attributes.HasKey(attrs) )
return;
if ( ! attrs )
return nullptr;
auto a = attrs.get();
if ( processed_attrs.count(a) > 0 )
return processed_attrs[a];
attributes.AddKey(attrs);
AddInit(attrs);
auto a_rep = attributes.GetRep(attrs);
if ( a_rep != attrs.get() )
// The cast is just so we can make an IntrusivePtr.
auto a_rep = const_cast<Attributes*>(attributes.GetRep(attrs));
if ( a_rep != a )
{
NoteInitDependency(attrs.get(), a_rep);
return;
AttributesPtr a_rep_ptr = {NewRef{}, a_rep};
processed_attrs[a] = RegisterAttributes(a_rep_ptr);
return processed_attrs[a];
}
for ( const auto& a : attrs->GetAttrs() )
{
const auto& e = a->GetExpr();
if ( e )
{
if ( IsSimpleInitExpr(e) )
{
// Make sure any dependencies it has get noted.
(void)GenExpr(e, GEN_VAL_PTR);
continue;
}
(void)RegisterAttr(a);
init_exprs.AddKey(e);
AddInit(e);
NoteInitDependency(attrs, e);
shared_ptr<CPP_InitInfo> gi = make_shared<AttrsInfo>(this, attrs);
attrs_info->AddInstance(gi);
processed_attrs[a] = gi;
auto e_rep = init_exprs.GetRep(e);
if ( e_rep != e.get() )
NoteInitDependency(e.get(), e_rep);
}
}
return gi;
}
shared_ptr<CPP_InitInfo> CPPCompile::RegisterAttr(const AttrPtr& attr)
{
auto a = attr.get();
if ( processed_attr.count(a) > 0 )
return processed_attr[a];
const auto& e = a->GetExpr();
if ( e && ! IsSimpleInitExpr(e) )
init_exprs.AddKey(e);
auto gi = make_shared<AttrInfo>(this, attr);
attr_info->AddInstance(gi);
processed_attr[a] = gi;
return gi;
}
void CPPCompile::BuildAttrs(const AttributesPtr& attrs, string& attr_tags, string& attr_vals)
@ -72,78 +83,9 @@ void CPPCompile::BuildAttrs(const AttributesPtr& attrs, string& attr_tags, strin
attr_vals = string("{") + attr_vals + "}";
}
void CPPCompile::GenAttrs(const AttributesPtr& attrs)
const char* CPPCompile::AttrName(AttrTag t)
{
NL();
Emit("AttributesPtr %s", AttrsName(attrs));
StartBlock();
const auto& avec = attrs->GetAttrs();
Emit("auto attrs = std::vector<AttrPtr>();");
AddInit(attrs);
for ( const auto& attr : avec )
{
const auto& e = attr->GetExpr();
if ( ! e )
{
Emit("attrs.emplace_back(make_intrusive<Attr>(%s));", AttrName(attr));
continue;
}
NoteInitDependency(attrs, e);
AddInit(e);
string e_arg;
if ( IsSimpleInitExpr(e) )
e_arg = GenAttrExpr(e);
else
e_arg = InitExprName(e);
Emit("attrs.emplace_back(make_intrusive<Attr>(%s, %s));", AttrName(attr), e_arg);
}
Emit("return make_intrusive<Attributes>(attrs, nullptr, true, false);");
EndBlock();
}
string CPPCompile::GenAttrExpr(const ExprPtr& e)
{
switch ( e->Tag() )
{
case EXPR_CONST:
return string("make_intrusive<ConstExpr>(") + GenExpr(e, GEN_VAL_PTR) + ")";
case EXPR_NAME:
NoteInitDependency(e, e->AsNameExpr()->IdPtr());
return string("make_intrusive<NameExpr>(") + globals[e->AsNameExpr()->Id()->Name()] +
")";
case EXPR_RECORD_COERCE:
NoteInitDependency(e, TypeRep(e->GetType()));
return string("make_intrusive<RecordCoerceExpr>(make_intrusive<RecordConstructorExpr>("
"make_intrusive<ListExpr>()), cast_intrusive<RecordType>(") +
GenTypeName(e->GetType()) + "))";
default:
reporter->InternalError("bad expr tag in CPPCompile::GenAttrs");
return "###";
}
}
string CPPCompile::AttrsName(const AttributesPtr& a)
{
return attributes.KeyName(a) + "()";
}
const char* CPPCompile::AttrName(const AttrPtr& attr)
{
switch ( attr->Tag() )
switch ( t )
{
case ATTR_OPTIONAL:
return "ATTR_OPTIONAL";