Reformat the world

This commit is contained in:
Tim Wojtulewicz 2021-09-16 15:35:39 -07:00
parent 194cb24547
commit b2f171ec69
714 changed files with 35149 additions and 35203 deletions

View file

@ -2,8 +2,8 @@
#include "zeek/script_opt/CPP/Compile.h"
namespace zeek::detail {
namespace zeek::detail
{
using namespace std;
@ -30,7 +30,7 @@ void CPPCompile::RegisterAttributes(const AttributesPtr& attrs)
if ( IsSimpleInitExpr(e) )
{
// Make sure any dependencies it has get noted.
(void) GenExpr(e, GEN_VAL_PTR);
(void)GenExpr(e, GEN_VAL_PTR);
continue;
}
@ -45,8 +45,7 @@ void CPPCompile::RegisterAttributes(const AttributesPtr& attrs)
}
}
void CPPCompile::BuildAttrs(const AttributesPtr& attrs, string& attr_tags,
string& attr_vals)
void CPPCompile::BuildAttrs(const AttributesPtr& attrs, string& attr_tags, string& attr_vals)
{
if ( attrs )
{
@ -92,8 +91,7 @@ void CPPCompile::GenAttrs(const AttributesPtr& attrs)
if ( ! e )
{
Emit("attrs.emplace_back(make_intrusive<Attr>(%s));",
AttrName(attr));
Emit("attrs.emplace_back(make_intrusive<Attr>(%s));", AttrName(attr));
continue;
}
@ -106,8 +104,7 @@ void CPPCompile::GenAttrs(const AttributesPtr& attrs)
else
e_arg = InitExprName(e);
Emit("attrs.emplace_back(make_intrusive<Attr>(%s, %s));",
AttrName(attr), e_arg);
Emit("attrs.emplace_back(make_intrusive<Attr>(%s, %s));", AttrName(attr), e_arg);
}
Emit("return make_intrusive<Attributes>(attrs, nullptr, true, false);");
@ -117,25 +114,26 @@ void CPPCompile::GenAttrs(const AttributesPtr& attrs)
string CPPCompile::GenAttrExpr(const ExprPtr& e)
{
switch ( e->Tag() ) {
case EXPR_CONST:
return string("make_intrusive<ConstExpr>(") +
GenExpr(e, GEN_VAL_PTR) + ")";
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_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()) + "))";
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 "###";
}
default:
reporter->InternalError("bad expr tag in CPPCompile::GenAttrs");
return "###";
}
}
string CPPCompile::AttrsName(const AttributesPtr& a)
@ -145,33 +143,58 @@ string CPPCompile::AttrsName(const AttributesPtr& a)
const char* CPPCompile::AttrName(const AttrPtr& attr)
{
switch ( attr->Tag() ) {
case ATTR_OPTIONAL: return "ATTR_OPTIONAL";
case ATTR_DEFAULT: return "ATTR_DEFAULT";
case ATTR_REDEF: return "ATTR_REDEF";
case ATTR_ADD_FUNC: return "ATTR_ADD_FUNC";
case ATTR_DEL_FUNC: return "ATTR_DEL_FUNC";
case ATTR_EXPIRE_FUNC: return "ATTR_EXPIRE_FUNC";
case ATTR_EXPIRE_READ: return "ATTR_EXPIRE_READ";
case ATTR_EXPIRE_WRITE: return "ATTR_EXPIRE_WRITE";
case ATTR_EXPIRE_CREATE: return "ATTR_EXPIRE_CREATE";
case ATTR_RAW_OUTPUT: return "ATTR_RAW_OUTPUT";
case ATTR_PRIORITY: return "ATTR_PRIORITY";
case ATTR_GROUP: return "ATTR_GROUP";
case ATTR_LOG: return "ATTR_LOG";
case ATTR_ERROR_HANDLER: return "ATTR_ERROR_HANDLER";
case ATTR_TYPE_COLUMN: return "ATTR_TYPE_COLUMN";
case ATTR_TRACKED: return "ATTR_TRACKED";
case ATTR_ON_CHANGE: return "ATTR_ON_CHANGE";
case ATTR_BROKER_STORE: return "ATTR_BROKER_STORE";
case ATTR_BROKER_STORE_ALLOW_COMPLEX: return "ATTR_BROKER_STORE_ALLOW_COMPLEX";
case ATTR_BACKEND: return "ATTR_BACKEND";
case ATTR_DEPRECATED: return "ATTR_DEPRECATED";
case ATTR_IS_ASSIGNED: return "ATTR_IS_ASSIGNED";
case ATTR_IS_USED: return "ATTR_IS_USED";
switch ( attr->Tag() )
{
case ATTR_OPTIONAL:
return "ATTR_OPTIONAL";
case ATTR_DEFAULT:
return "ATTR_DEFAULT";
case ATTR_REDEF:
return "ATTR_REDEF";
case ATTR_ADD_FUNC:
return "ATTR_ADD_FUNC";
case ATTR_DEL_FUNC:
return "ATTR_DEL_FUNC";
case ATTR_EXPIRE_FUNC:
return "ATTR_EXPIRE_FUNC";
case ATTR_EXPIRE_READ:
return "ATTR_EXPIRE_READ";
case ATTR_EXPIRE_WRITE:
return "ATTR_EXPIRE_WRITE";
case ATTR_EXPIRE_CREATE:
return "ATTR_EXPIRE_CREATE";
case ATTR_RAW_OUTPUT:
return "ATTR_RAW_OUTPUT";
case ATTR_PRIORITY:
return "ATTR_PRIORITY";
case ATTR_GROUP:
return "ATTR_GROUP";
case ATTR_LOG:
return "ATTR_LOG";
case ATTR_ERROR_HANDLER:
return "ATTR_ERROR_HANDLER";
case ATTR_TYPE_COLUMN:
return "ATTR_TYPE_COLUMN";
case ATTR_TRACKED:
return "ATTR_TRACKED";
case ATTR_ON_CHANGE:
return "ATTR_ON_CHANGE";
case ATTR_BROKER_STORE:
return "ATTR_BROKER_STORE";
case ATTR_BROKER_STORE_ALLOW_COMPLEX:
return "ATTR_BROKER_STORE_ALLOW_COMPLEX";
case ATTR_BACKEND:
return "ATTR_BACKEND";
case ATTR_DEPRECATED:
return "ATTR_DEPRECATED";
case ATTR_IS_ASSIGNED:
return "ATTR_IS_ASSIGNED";
case ATTR_IS_USED:
return "ATTR_IS_USED";
default: return "<busted>";
}
default:
return "<busted>";
}
}
} // zeek::detail
} // zeek::detail

View file

@ -3,11 +3,11 @@
#pragma once
#include "zeek/Desc.h"
#include "zeek/script_opt/ScriptOpt.h"
#include "zeek/script_opt/CPP/Func.h"
#include "zeek/script_opt/CPP/Util.h"
#include "zeek/script_opt/CPP/Tracker.h"
#include "zeek/script_opt/CPP/HashMgr.h"
#include "zeek/script_opt/CPP/Tracker.h"
#include "zeek/script_opt/CPP/Util.h"
#include "zeek/script_opt/ScriptOpt.h"
// We structure the compiler for generating C++ versions of Zeek script
// bodies as a single large class. While we divide the compiler's
@ -128,14 +128,14 @@
// variables are used by multiple groups, which is why we haven't created
// distinct per-group classes.
namespace zeek::detail
{
namespace zeek::detail {
class CPPCompile {
class CPPCompile
{
public:
CPPCompile(std::vector<FuncInfo>& _funcs, ProfileFuncs& pfs,
const std::string& gen_name, const std::string& addl_name,
CPPHashManager& _hm, bool _update, bool _standalone,
CPPCompile(std::vector<FuncInfo>& _funcs, ProfileFuncs& pfs, const std::string& gen_name,
const std::string& addl_name, CPPHashManager& _hm, bool _update, bool _standalone,
bool report_uncompilable);
~CPPCompile();
@ -161,7 +161,7 @@ private:
// run-time initialization of various dynamic values.
void GenEpilog();
// True if the given function (plus body and profile) is one
// True if the given function (plus body and profile) is one
// that should be compiled. If non-nil, sets reason to the
// the reason why, if there's a fundamental problem. If however
// the function should be skipped for other reasons, then sets
@ -221,7 +221,6 @@ private:
//
// End of methods related to script/C++ variables.
// Start of methods related to script variables and their C++
// counterparts.
// See Vars.cc for definitions.
@ -246,7 +245,7 @@ private:
// then the BiF is also used in a non-call context.
void AddBiF(const ID* b, bool is_var);
// Register the given global name. "suffix" distinguishs particular
// Register the given global name. "suffix" distinguishs particular
// types of globals, such as the names of bifs, global (non-function)
// variables, or compiled Zeek functions. If "track" is true then
// if we're compiling incrementally, and this is a new global not
@ -259,9 +258,9 @@ private:
// The following match various forms of identifiers to the
// name used for their C++ equivalent.
const char* IDName(const ID& id) { return IDName(&id); }
const char* IDName(const IDPtr& id) { return IDName(id.get()); }
const char* IDName(const ID* id) { return IDNameStr(id).c_str(); }
const char* IDName(const ID& id) { return IDName(&id); }
const char* IDName(const IDPtr& id) { return IDName(id.get()); }
const char* IDName(const ID* id) { return IDNameStr(id).c_str(); }
const std::string& IDNameStr(const ID* id) const;
// Returns a canonicalized version of a variant of a global made
@ -274,8 +273,7 @@ private:
// Returns a canonicalized form of a local identifier's name,
// expanding its module prefix if needed.
std::string LocalName(const ID* l) const;
std::string LocalName(const IDPtr& l) const
{ return LocalName(l.get()); }
std::string LocalName(const IDPtr& l) const { return LocalName(l.get()); }
// Returns a canonicalized name, with various non-alphanumeric
// characters stripped or transformed, and guananteed not to
@ -297,7 +295,6 @@ private:
//
// End of methods related to script/C++ variables.
// Start of methods related to declaring compiled script functions,
// including related classes.
// See DeclFunc.cc for definitions.
@ -315,16 +312,14 @@ private:
// "fname" its C++ name, "body" its AST, "l" if non-nil its
// corresponding lambda expression, and "flavor" whether it's
// a hook/event/function.
void DeclareSubclass(const FuncTypePtr& ft, const ProfileFunc* pf,
const std::string& fname,
const StmtPtr& body, int priority,
const LambdaExpr* l, FunctionFlavor flavor);
void DeclareSubclass(const FuncTypePtr& ft, const ProfileFunc* pf, const std::string& fname,
const StmtPtr& body, int priority, const LambdaExpr* l,
FunctionFlavor flavor);
// Generates the declarations (and in-line definitions) associated
// with compiling a lambda.
void BuildLambda(const FuncTypePtr& ft, const ProfileFunc* pf,
const std::string& fname, const StmtPtr& body,
const LambdaExpr* l, const IDPList* lambda_ids);
void BuildLambda(const FuncTypePtr& ft, const ProfileFunc* pf, const std::string& fname,
const StmtPtr& body, const LambdaExpr* l, const IDPList* lambda_ids);
// For a call to the C++ version of a function of type "ft" and
// with lambda captures lambda_ids (nil if not applicable), generates
@ -334,8 +329,7 @@ private:
// Generates the declaration for the parameters for a function with
// the given type, lambda captures (if non-nil), and profile.
std::string ParamDecl(const FuncTypePtr& ft, const IDPList* lambda_ids,
const ProfileFunc* pf);
std::string ParamDecl(const FuncTypePtr& ft, const IDPList* lambda_ids, const ProfileFunc* pf);
// Inspects the given profile to find the i'th parameter (starting
// at 0). Returns nil if the profile indicates that that parameter
@ -356,7 +350,6 @@ private:
//
// End of methods related to declaring compiled script functions.
// Start of methods related to generating the bodies of compiled
// script functions. Note that some of this sort of functionality is
// instead in CPPDeclFunc.cc, due to the presence of inlined methods.
@ -370,15 +363,13 @@ private:
// Generates the body of the Invoke() method (which supplies the
// "glue" between for calling the C++-generated code).
void GenInvokeBody(const std::string& fname, const TypePtr& t,
const std::string& args);
void GenInvokeBody(const std::string& fname, const TypePtr& t, const std::string& args);
// Generates the code for the body of a script function with
// the given type, profile, C++ name, AST, lambda captures
// (if non-nil), and hook/event/function "flavor".
void DefineBody(const FuncTypePtr& ft, const ProfileFunc* pf,
const std::string& fname, const StmtPtr& body,
const IDPList* lambda_ids, FunctionFlavor flavor);
void DefineBody(const FuncTypePtr& ft, const ProfileFunc* pf, const std::string& fname,
const StmtPtr& body, const IDPList* lambda_ids, FunctionFlavor flavor);
// Declare parameters that originate from a type signature of
// "any" but were concretized in this declaration.
@ -435,7 +426,6 @@ private:
//
// End of methods related to generating compiled script bodies.
// Start of methods related to generating code for representing
// script constants as run-time values.
// See Consts.cc for definitions.
@ -447,7 +437,9 @@ private:
// by the given "parent" object (which acquires an initialization
// dependency, if a C++ variable is needed).
std::string BuildConstant(IntrusivePtr<Obj> parent, const ValPtr& vp)
{ return BuildConstant(parent.get(), vp); }
{
return BuildConstant(parent.get(), vp);
}
std::string BuildConstant(const Obj* parent, const ValPtr& vp);
// Called to create a constant appropriate for the given expression
@ -494,7 +486,6 @@ private:
//
// End of methods related to generating code for script constants.
// Start of methods related to generating code for AST Stmt's.
// For the most part, code generation is straightforward as
// it matches the Exec/DoExec methods of the corresponding
@ -502,7 +493,7 @@ private:
// See Stmts.cc for definitions.
//
void GenStmt(const StmtPtr& s) { GenStmt(s.get()); }
void GenStmt(const StmtPtr& s) { GenStmt(s.get()); }
void GenStmt(const Stmt* s);
void GenInitStmt(const InitStmt* init);
void GenIfStmt(const IfStmt* i);
@ -514,8 +505,7 @@ private:
void GenSwitchStmt(const SwitchStmt* sw);
void GenForStmt(const ForStmt* f);
void GenForOverTable(const ExprPtr& tbl, const IDPtr& value_var,
const IDPList* loop_vars);
void GenForOverTable(const ExprPtr& tbl, const IDPtr& value_var, const IDPList* loop_vars);
void GenForOverVector(const ExprPtr& tbl, const IDPList* loop_vars);
void GenForOverString(const ExprPtr& str, const IDPList* loop_vars);
@ -526,7 +516,6 @@ private:
//
// End of methods related to generating code for AST Stmt's.
// Start of methods related to generating code for AST Expr's.
// See Exprs.cc for definitions.
//
@ -545,11 +534,12 @@ private:
// form, (2) instead in ValPtr form, or (3) whichever is more
// convenient to generate (sometimes used when the caller knows
// that the value is non-native).
enum GenType {
enum GenType
{
GEN_NATIVE,
GEN_VAL_PTR,
GEN_DONT_CARE,
};
};
// Generate an expression for which we want the result embedded
// in {} initializers (generally to be used in calling a function
@ -566,7 +556,9 @@ private:
// Per-Expr-subclass code generation. The resulting code generally
// reflects the corresponding Eval() or Fold() methods.
std::string GenExpr(const ExprPtr& e, GenType gt, bool top_level = false)
{ return GenExpr(e.get(), gt, top_level); }
{
return GenExpr(e.get(), gt, top_level);
}
std::string GenExpr(const Expr* e, GenType gt, bool top_level = false);
std::string GenNameExpr(const NameExpr* ne, GenType gt);
@ -600,39 +592,28 @@ private:
std::string GenVal(const ValPtr& v);
// Helper functions for particular Expr subclasses / flavors.
std::string GenUnary(const Expr* e, GenType gt,
const char* op, const char* vec_op = nullptr);
std::string GenBinary(const Expr* e, GenType gt,
const char* op, const char* vec_op = nullptr);
std::string GenUnary(const Expr* e, GenType gt, const char* op, const char* vec_op = nullptr);
std::string GenBinary(const Expr* e, GenType gt, const char* op, const char* vec_op = nullptr);
std::string GenBinarySet(const Expr* e, GenType gt, const char* op);
std::string GenBinaryString(const Expr* e, GenType gt, const char* op);
std::string GenBinaryPattern(const Expr* e, GenType gt, const char* op);
std::string GenBinaryAddr(const Expr* e, GenType gt, const char* op);
std::string GenBinarySubNet(const Expr* e, GenType gt, const char* op);
std::string GenEQ(const Expr* e, GenType gt,
const char* op, const char* vec_op);
std::string GenEQ(const Expr* e, GenType gt, const char* op, const char* vec_op);
std::string GenAssign(const ExprPtr& lhs, const ExprPtr& rhs,
const std::string& rhs_native,
const std::string& rhs_val_ptr,
GenType gt, bool top_level);
std::string GenDirectAssign(const ExprPtr& lhs,
const std::string& rhs_native,
const std::string& rhs_val_ptr,
GenType gt, bool top_level);
std::string GenAssign(const ExprPtr& lhs, const ExprPtr& rhs, const std::string& rhs_native,
const std::string& rhs_val_ptr, GenType gt, bool top_level);
std::string GenDirectAssign(const ExprPtr& lhs, const std::string& rhs_native,
const std::string& rhs_val_ptr, GenType gt, bool top_level);
std::string GenIndexAssign(const ExprPtr& lhs, const ExprPtr& rhs,
const std::string& rhs_val_ptr,
GenType gt, bool top_level);
const std::string& rhs_val_ptr, GenType gt, bool top_level);
std::string GenFieldAssign(const ExprPtr& lhs, const ExprPtr& rhs,
const std::string& rhs_val_ptr,
GenType gt, bool top_level);
const std::string& rhs_val_ptr, GenType gt, bool top_level);
std::string GenListAssign(const ExprPtr& lhs, const ExprPtr& rhs);
// Support for element-by-element vector operations.
std::string GenVectorOp(const Expr* e, std::string op,
const char* vec_op);
std::string GenVectorOp(const Expr* e, std::string op1,
std::string op2, const char* vec_op);
std::string GenVectorOp(const Expr* e, std::string op, const char* vec_op);
std::string GenVectorOp(const Expr* e, std::string op1, std::string op2, const char* vec_op);
// If "all_deep" is true, it means make all of the captures
// deep copies, not just the ones that were explicitly marked
@ -662,8 +643,7 @@ private:
//
// So for each such record, there's a second map of
// field-in-the-record to offset-in-field_mapping.
std::unordered_map<const RecordType*, std::unordered_map<int, int>>
record_field_mappings;
std::unordered_map<const RecordType*, std::unordered_map<int, int>> record_field_mappings;
// Total number of such mappings (i.e., entries in the inner maps,
// not the outer map).
@ -679,8 +659,7 @@ private:
//
// So for each such enum, there's a second map of
// value-during-compilation to offset-in-enum_mapping.
std::unordered_map<const EnumType*, std::unordered_map<int, int>>
enum_val_mappings;
std::unordered_map<const EnumType*, std::unordered_map<int, int>> enum_val_mappings;
// Total number of such mappings (i.e., entries in the inner maps,
// not the outer map).
@ -693,7 +672,6 @@ private:
//
// End of methods related to generating code for AST Expr's.
// Start of methods related to managing script types.
// See Types.cc for definitions.
//
@ -706,13 +684,11 @@ private:
// Given an expression corresponding to a native type (and with
// the given script type 't'), converts it to the given GenType.
std::string NativeToGT(const std::string& expr, const TypePtr& t,
GenType gt);
std::string NativeToGT(const std::string& expr, const TypePtr& t, GenType gt);
// Given an expression with a C++ type of generic "ValPtr", of the
// given script type 't', converts it as needed to the given GenType.
std::string GenericValPtrToGT(const std::string& expr, const TypePtr& t,
GenType gt);
std::string GenericValPtrToGT(const std::string& expr, const TypePtr& t, GenType gt);
// For a given type, generates the code necessary to initialize
// it at run time. The term "expand" in the method's name refers
@ -736,14 +712,13 @@ private:
// of the appropriate flavor. 't' does not need to be a type
// representative.
std::string GenTypeName(const Type* t);
std::string GenTypeName(const TypePtr& t)
{ return GenTypeName(t.get()); }
std::string GenTypeName(const TypePtr& t) { return GenTypeName(t.get()); }
// Returns the "representative" for a given type, used to ensure
// that we re-use the C++ variable corresponding to a type and
// don't instantiate redundant instances.
const Type* TypeRep(const Type* t) { return pfs.TypeRep(t); }
const Type* TypeRep(const TypePtr& t) { return TypeRep(t.get()); }
const Type* TypeRep(const Type* t) { return pfs.TypeRep(t); }
const Type* TypeRep(const TypePtr& t) { return TypeRep(t.get()); }
// Low-level C++ representations for types, of various flavors.
const char* TypeTagName(TypeTag tag) const;
@ -778,7 +753,6 @@ private:
//
// End of methods related to managing script types.
// Start of methods related to managing script type attributes.
// Attributes arise mainly in the context of constructing types.
// See Attrs.cc for definitions.
@ -792,8 +766,7 @@ private:
// Populates the 2nd and 3rd arguments with C++ representations
// of the tags and (optional) values/expressions associated with
// the set of attributes.
void BuildAttrs(const AttributesPtr& attrs, std::string& attr_tags,
std::string& attr_vals);
void BuildAttrs(const AttributesPtr& attrs, std::string& attr_tags, std::string& attr_vals);
// Generates code to create the given attributes at run-time.
void GenAttrs(const AttributesPtr& attrs);
@ -813,7 +786,6 @@ private:
//
// End of methods related to managing script type attributes.
// Start of methods related to run-time initialization.
// See Inits.cc for definitions.
//
@ -854,14 +826,15 @@ private:
//
// Versions with "lhs" and "rhs" arguments provide an initialization
// of the form "lhs = rhs;", as a convenience.
void AddInit(const IntrusivePtr<Obj>& o,
const std::string& lhs, const std::string& rhs)
{ AddInit(o.get(), lhs + " = " + rhs + ";"); }
void AddInit(const Obj* o,
const std::string& lhs, const std::string& rhs)
{ AddInit(o, lhs + " = " + rhs + ";"); }
void AddInit(const IntrusivePtr<Obj>& o, const std::string& init)
{ AddInit(o.get(), init); }
void AddInit(const IntrusivePtr<Obj>& o, const std::string& lhs, const std::string& rhs)
{
AddInit(o.get(), lhs + " = " + rhs + ";");
}
void AddInit(const Obj* o, const std::string& lhs, const std::string& rhs)
{
AddInit(o, lhs + " = " + rhs + ";");
}
void AddInit(const IntrusivePtr<Obj>& o, const std::string& init) { AddInit(o.get(), init); }
void AddInit(const Obj* o, const std::string& init);
// We do consistency checking of initialization dependencies by
@ -869,24 +842,29 @@ private:
// it's unclear whether the object will actually require
// initialization, in which case we add an empty initialization
// for it so that the consistency-checking is happy.
void AddInit(const IntrusivePtr<Obj>& o) { AddInit(o.get()); }
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); }
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,
const IntrusivePtr<Obj>& o2)
{ NoteInitDependency(o1.get(), o2.get()); }
void NoteInitDependency(const IntrusivePtr<Obj>& o1, const IntrusivePtr<Obj>& o2)
{
NoteInitDependency(o1.get(), o2.get());
}
void NoteInitDependency(const IntrusivePtr<Obj>& o1, const Obj* o2)
{ NoteInitDependency(o1.get(), o2); }
{
NoteInitDependency(o1.get(), o2);
}
void NoteInitDependency(const Obj* o1, const IntrusivePtr<Obj>& o2)
{ NoteInitDependency(o1, o2.get()); }
{
NoteInitDependency(o1, o2.get());
}
void NoteInitDependency(const Obj* o1, const Obj* o2);
// Records an initialization dependency of the given object
@ -899,7 +877,9 @@ private:
NoteInitDependency(o, TypeRep(t));
}
void NoteNonRecordInitDependency(const IntrusivePtr<Obj> o, const TypePtr& t)
{ NoteNonRecordInitDependency(o.get(), t); }
{
NoteNonRecordInitDependency(o.get(), t);
}
// Analyzes the initialization dependencies to ensure that they're
// consistent, i.e., every object that either depends on another,
@ -924,8 +904,7 @@ private:
// Same, but for enum types. The second form does a single
// initialization corresponding to the given index in the mapping.
void InitializeEnumMappings();
void InitializeEnumMappings(const EnumType* et,
const std::string& e_name, int index);
void InitializeEnumMappings(const EnumType* et, const std::string& e_name, int index);
// Generate the initialization hook for this set of compiled code.
void GenInitHook();
@ -961,7 +940,6 @@ private:
//
// End of methods related to run-time initialization.
// Start of methods related to low-level code generation.
// See Emit.cc for definitions.
//
@ -989,40 +967,35 @@ private:
NL();
}
void Emit(const std::string& fmt, const std::string& arg1,
const std::string& arg2) const
void Emit(const std::string& fmt, const std::string& arg1, const std::string& arg2) const
{
Indent();
fprintf(write_file, fmt.c_str(), arg1.c_str(), arg2.c_str());
NL();
}
void Emit(const std::string& fmt, const std::string& arg1,
const std::string& arg2, const std::string& arg3) const
void Emit(const std::string& fmt, const std::string& arg1, const std::string& arg2,
const std::string& arg3) const
{
Indent();
fprintf(write_file, fmt.c_str(), arg1.c_str(), arg2.c_str(),
arg3.c_str());
fprintf(write_file, fmt.c_str(), arg1.c_str(), arg2.c_str(), arg3.c_str());
NL();
}
void Emit(const std::string& fmt, const std::string& arg1,
const std::string& arg2, const std::string& arg3,
const std::string& arg4) const
void Emit(const std::string& fmt, const std::string& arg1, const std::string& arg2,
const std::string& arg3, const std::string& arg4) const
{
Indent();
fprintf(write_file, fmt.c_str(), arg1.c_str(), arg2.c_str(),
arg3.c_str(), arg4.c_str());
fprintf(write_file, fmt.c_str(), arg1.c_str(), arg2.c_str(), arg3.c_str(), arg4.c_str());
NL();
}
void Emit(const std::string& fmt, const std::string& arg1,
const std::string& arg2, const std::string& arg3,
const std::string& arg4, const std::string& arg5) const
void Emit(const std::string& fmt, const std::string& arg1, const std::string& arg2,
const std::string& arg3, const std::string& arg4, const std::string& arg5) const
{
Indent();
fprintf(write_file, fmt.c_str(), arg1.c_str(), arg2.c_str(),
arg3.c_str(), arg4.c_str(), arg5.c_str());
fprintf(write_file, fmt.c_str(), arg1.c_str(), arg2.c_str(), arg3.c_str(), arg4.c_str(),
arg5.c_str());
NL();
}
@ -1033,10 +1006,9 @@ private:
// For the given byte array / string, returns a version expanded
// with escape sequences in order to represent it as a C++ string.
std::string CPPEscape(const char* b, int len) const;
std::string CPPEscape(const char* s) const
{ return CPPEscape(s, strlen(s)); }
std::string CPPEscape(const char* s) const { return CPPEscape(s, strlen(s)); }
void NL() const { fputc('\n', write_file); }
void NL() const { fputc('\n', write_file); }
// Indents to the current indentation level.
void Indent() const;
@ -1052,6 +1024,6 @@ private:
//
// End of methods related to run-time initialization.
};
};
} // zeek::detail
} // zeek::detail

View file

@ -4,8 +4,8 @@
#include "zeek/RE.h"
#include "zeek/script_opt/CPP/Compile.h"
namespace zeek::detail {
namespace zeek::detail
{
using namespace std;
@ -99,72 +99,72 @@ bool CPPCompile::AddConstant(const ValPtr& vp)
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:
switch ( tag )
{
auto prefix = (tag == TYPE_ADDR) ? "Addr" : "SubNet";
case TYPE_STRING:
AddStringConstant(vp, const_name);
break;
Emit("%sValPtr %s;", prefix, const_name);
case TYPE_PATTERN:
AddPatternConstant(vp, const_name);
break;
ODesc d;
v->Describe(&d);
case TYPE_LIST:
AddListConstant(vp, const_name);
break;
AddInit(v, const_name,
string("make_intrusive<") + prefix +
"Val>(\"" + d.Description() + "\")");
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,
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,
string("make_intrusive<FileVal>(") + "make_intrusive<File>(\"" + f->Name() +
"\", \"w\"))");
}
break;
default:
reporter->InternalError("bad constant type in CPPCompile::AddConstant");
}
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,
string("make_intrusive<FileVal>(") +
"make_intrusive<File>(\"" + f->Name() + "\", \"w\"))");
}
break;
default:
reporter->InternalError("bad constant type in CPPCompile::AddConstant");
}
return true;
}
@ -186,8 +186,7 @@ void CPPCompile::AddPatternConstant(const ValPtr& v, string& const_name)
auto re = v->AsPatternVal()->Get();
AddInit(v, string("{ auto re = new RE_Matcher(") +
CPPEscape(re->OrigText()) + ");");
AddInit(v, string("{ auto re = new RE_Matcher(") + CPPEscape(re->OrigText()) + ");");
if ( re->IsCaseInsensitive() )
AddInit(v, "re->MakeCaseInsensitive();");
@ -227,8 +226,9 @@ void CPPCompile::AddRecordConstant(const ValPtr& v, string& const_name)
NoteInitDependency(v, TypeRep(t));
AddInit(v, const_name, string("make_intrusive<RecordVal>(") +
"cast_intrusive<RecordType>(" + GenTypeName(t) + "))");
AddInit(v, const_name,
string("make_intrusive<RecordVal>(") + "cast_intrusive<RecordType>(" + GenTypeName(t) +
"))");
auto r = cast_intrusive<RecordVal>(v);
auto n = r->NumFields();
@ -240,8 +240,7 @@ void CPPCompile::AddRecordConstant(const ValPtr& v, string& const_name)
if ( r_i )
{
auto r_i_c = BuildConstant(v, r_i);
AddInit(v, const_name + "->Assign(" + Fmt(static_cast<int>(i)) +
", " + r_i_c + ");");
AddInit(v, const_name + "->Assign(" + Fmt(static_cast<int>(i)) + ", " + r_i_c + ");");
}
}
}
@ -254,8 +253,9 @@ void CPPCompile::AddTableConstant(const ValPtr& v, string& const_name)
NoteInitDependency(v, TypeRep(t));
AddInit(v, const_name, string("make_intrusive<TableVal>(") +
"cast_intrusive<TableType>(" + GenTypeName(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();
@ -276,8 +276,9 @@ void CPPCompile::AddVectorConstant(const ValPtr& v, string& const_name)
NoteInitDependency(v, TypeRep(t));
AddInit(v, const_name, string("make_intrusive<VectorVal>(") +
"cast_intrusive<VectorType>(" + GenTypeName(t) + "))");
AddInit(v, const_name,
string("make_intrusive<VectorVal>(") + "cast_intrusive<VectorType>(" + GenTypeName(t) +
"))");
auto vv = cast_intrusive<VectorVal>(v);
auto n = vv->Size();
@ -290,4 +291,4 @@ void CPPCompile::AddVectorConstant(const ValPtr& v, string& const_name)
}
}
} // zeek::detail
} // zeek::detail

View file

@ -1,13 +1,13 @@
// See the file "COPYING" in the main distribution directory for copyright.
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <unistd.h>
#include "zeek/script_opt/CPP/Compile.h"
namespace zeek::detail {
namespace zeek::detail
{
using namespace std;
@ -22,8 +22,7 @@ void CPPCompile::DeclareFunc(const FuncInfo& func)
const auto& body = func.Body();
auto priority = func.Priority();
DeclareSubclass(f->GetType(), pf, fname, body, priority, nullptr,
f->Flavor());
DeclareSubclass(f->GetType(), pf, fname, body, priority, nullptr, f->Flavor());
if ( f->GetBodies().size() == 1 )
compiled_simple_funcs[f->Name()] = fname;
@ -41,14 +40,12 @@ void CPPCompile::DeclareLambda(const LambdaExpr* l, const ProfileFunc* pf)
for ( auto id : ids )
lambda_names[id] = LocalName(id);
DeclareSubclass(l_id->GetType<FuncType>(), pf, lname, body, 0, l,
FUNC_FLAVOR_FUNCTION);
DeclareSubclass(l_id->GetType<FuncType>(), pf, lname, body, 0, l, FUNC_FLAVOR_FUNCTION);
}
void CPPCompile::DeclareSubclass(const FuncTypePtr& ft, const ProfileFunc* pf,
const string& fname,
const StmtPtr& body, int priority,
const LambdaExpr* l, FunctionFlavor flavor)
void CPPCompile::DeclareSubclass(const FuncTypePtr& ft, const ProfileFunc* pf, const string& fname,
const StmtPtr& body, int priority, const LambdaExpr* l,
FunctionFlavor flavor)
{
const auto& yt = ft->Yield();
in_hook = flavor == FUNC_FLAVOR_HOOK;
@ -64,8 +61,8 @@ void CPPCompile::DeclareSubclass(const FuncTypePtr& ft, const ProfileFunc* pf,
Emit("public:");
string addl_args; // captures passed in on construction
string inits; // initializers for corresponding member vars
string addl_args; // captures passed in on construction
string inits; // initializers for corresponding member vars
if ( lambda_ids )
{
@ -79,8 +76,8 @@ void CPPCompile::DeclareSubclass(const FuncTypePtr& ft, const ProfileFunc* pf,
}
}
Emit("%s_cl(const char* name%s) : CPPStmt(name)%s { }",
fname, addl_args.c_str(), inits.c_str());
Emit("%s_cl(const char* name%s) : CPPStmt(name)%s { }", fname, addl_args.c_str(),
inits.c_str());
// An additional constructor just used to generate place-holder
// instances, due to the mis-design that lambdas are identified
@ -141,9 +138,8 @@ void CPPCompile::DeclareSubclass(const FuncTypePtr& ft, const ProfileFunc* pf,
total_hash = merge_p_hashes(total_hash, h);
}
void CPPCompile::BuildLambda(const FuncTypePtr& ft, const ProfileFunc* pf,
const string& fname, const StmtPtr& body,
const LambdaExpr* l, const IDPList* lambda_ids)
void CPPCompile::BuildLambda(const FuncTypePtr& ft, const ProfileFunc* pf, const string& fname,
const StmtPtr& body, const LambdaExpr* l, const IDPList* lambda_ids)
{
// Declare the member variables for holding the captures.
for ( auto& id : *lambda_ids )
@ -155,15 +151,13 @@ void CPPCompile::BuildLambda(const FuncTypePtr& ft, const ProfileFunc* pf,
// Generate initialization to create and register the lambda.
auto literal_name = string("\"") + l->Name() + "\"";
auto instantiate = string("make_intrusive<") + fname + "_cl>(" +
literal_name + ")";
auto instantiate = string("make_intrusive<") + fname + "_cl>(" + literal_name + ")";
int nl = lambda_ids->length();
auto h = Fmt(pf->HashVal());
auto has_captures = nl > 0 ? "true" : "false";
auto l_init = string("register_lambda__CPP(") + instantiate +
", " + h + ", \"" + l->Name() + "\", " +
GenTypeName(ft) + ", " + has_captures + ");";
auto l_init = string("register_lambda__CPP(") + instantiate + ", " + h + ", \"" + l->Name() +
"\", " + GenTypeName(ft) + ", " + has_captures + ");";
AddInit(l, l_init);
NoteInitDependency(l, TypeRep(ft));
@ -184,8 +178,7 @@ void CPPCompile::BuildLambda(const FuncTypePtr& ft, const ProfileFunc* pf,
auto l_i = (*lambda_ids)[i];
const auto& t_i = l_i->GetType();
auto cap_i = string("f->GetElement(") + Fmt(i) + ")";
Emit("%s = %s;", lambda_names[l_i],
GenericValPtrToGT(cap_i, t_i, GEN_NATIVE));
Emit("%s = %s;", lambda_names[l_i], GenericValPtrToGT(cap_i, t_i, GEN_NATIVE));
}
EndBlock();
@ -197,8 +190,7 @@ void CPPCompile::BuildLambda(const FuncTypePtr& ft, const ProfileFunc* pf,
{
auto l_i = (*lambda_ids)[i];
const auto& t_i = l_i->GetType();
Emit("vals.emplace_back(%s);",
NativeToGT(lambda_names[l_i], t_i, GEN_VAL_PTR));
Emit("vals.emplace_back(%s);", NativeToGT(lambda_names[l_i], t_i, GEN_VAL_PTR));
}
Emit("return vals;");
EndBlock();
@ -259,8 +251,7 @@ string CPPCompile::ParamDecl(const FuncTypePtr& ft, const IDPList* lambda_ids,
if ( param_id )
{
if ( t->Tag() == TYPE_ANY &&
param_id->GetType()->Tag() != TYPE_ANY )
if ( t->Tag() == TYPE_ANY && param_id->GetType()->Tag() != TYPE_ANY )
// We'll need to translate the parameter
// from its current representation to
// type "any".
@ -321,4 +312,4 @@ const ID* CPPCompile::FindParam(int i, const ProfileFunc* pf)
return nullptr;
}
} // zeek::detail
} // zeek::detail

View file

@ -1,23 +1,20 @@
// See the file "COPYING" in the main distribution directory for copyright.
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <unistd.h>
#include "zeek/script_opt/CPP/Compile.h"
namespace zeek::detail {
namespace zeek::detail
{
using namespace std;
CPPCompile::CPPCompile(vector<FuncInfo>& _funcs, ProfileFuncs& _pfs,
const string& gen_name, const string& _addl_name,
CPPHashManager& _hm, bool _update, bool _standalone,
bool report_uncompilable)
: funcs(_funcs), pfs(_pfs), hm(_hm),
update(_update), standalone(_standalone)
CPPCompile::CPPCompile(vector<FuncInfo>& _funcs, ProfileFuncs& _pfs, const string& gen_name,
const string& _addl_name, CPPHashManager& _hm, bool _update,
bool _standalone, bool report_uncompilable)
: funcs(_funcs), pfs(_pfs), hm(_hm), update(_update), standalone(_standalone)
{
addl_name = _addl_name;
bool is_addl = hm.IsAppend();
@ -60,8 +57,7 @@ CPPCompile::CPPCompile(vector<FuncInfo>& _funcs, ProfileFuncs& _pfs,
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());
reporter->Error("can't open C++ additional file %s", addl_name.c_str());
exit(1);
}
@ -105,9 +101,8 @@ void CPPCompile::Compile(bool report_uncompilable)
if ( IsCompilable(func, &reason) )
compilable_funcs.insert(BodyName(func));
else if ( reason && report_uncompilable )
fprintf(stderr,
"%s cannot be compiled to C++ due to %s\n",
func.Func()->Name(), reason);
fprintf(stderr, "%s cannot be compiled to C++ due to %s\n", func.Func()->Name(),
reason);
auto h = func.Profile()->HashVal();
if ( hm.HasHash(h) )
@ -257,16 +252,14 @@ void CPPCompile::RegisterCompiledBody(const string& f)
// same binary).
h = merge_p_hashes(h, p_hash(cf_locs[f]));
auto init = string("register_body__CPP(make_intrusive<") +
f + "_cl>(\"" + f + "\"), " + Fmt(p) + ", " +
Fmt(h) + ", " + events + ");";
auto init = string("register_body__CPP(make_intrusive<") + f + "_cl>(\"" + f + "\"), " +
Fmt(p) + ", " + Fmt(h) + ", " + events + ");";
AddInit(names_to_bodies[f], init);
if ( update )
{
fprintf(hm.HashFile(), "func\n%s%s\n",
scope_prefix(addl_tag).c_str(), f.c_str());
fprintf(hm.HashFile(), "func\n%s%s\n", scope_prefix(addl_tag).c_str(), f.c_str());
fprintf(hm.HashFile(), "%llu\n", h);
}
}
@ -367,4 +360,4 @@ bool CPPCompile::IsCompilable(const FuncInfo& func, const char** reason)
return true;
}
} // zeek::detail
} // zeek::detail

View file

@ -1,13 +1,13 @@
// See the file "COPYING" in the main distribution directory for copyright.
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <unistd.h>
#include "zeek/script_opt/CPP/Compile.h"
namespace zeek::detail {
namespace zeek::detail
{
using namespace std;
@ -25,8 +25,7 @@ void CPPCompile::EndBlock(bool needs_semi)
string CPPCompile::GenString(const char* b, int len) const
{
return string("make_intrusive<StringVal>(") + Fmt(len) + ", " +
CPPEscape(b, len) + ")";
return string("make_intrusive<StringVal>(") + Fmt(len) + ", " + CPPEscape(b, len) + ")";
}
string CPPCompile::CPPEscape(const char* b, int len) const
@ -37,30 +36,49 @@ string CPPCompile::CPPEscape(const char* b, int len) const
{
unsigned char c = b[i];
switch ( c ) {
case '\a': res += "\\a"; break;
case '\b': res += "\\b"; break;
case '\f': res += "\\f"; break;
case '\n': res += "\\n"; break;
case '\r': res += "\\r"; break;
case '\t': res += "\\t"; break;
case '\v': res += "\\v"; break;
switch ( c )
{
case '\a':
res += "\\a";
break;
case '\b':
res += "\\b";
break;
case '\f':
res += "\\f";
break;
case '\n':
res += "\\n";
break;
case '\r':
res += "\\r";
break;
case '\t':
res += "\\t";
break;
case '\v':
res += "\\v";
break;
case '\\': res += "\\\\"; break;
case '"': res += "\\\""; break;
case '\\':
res += "\\\\";
break;
case '"':
res += "\\\"";
break;
default:
if ( isprint(c) )
res += c;
else
{
char buf[8192];
snprintf(buf, sizeof buf, "%03o", c);
res += "\\";
res += buf;
}
break;
}
default:
if ( isprint(c) )
res += c;
else
{
char buf[8192];
snprintf(buf, sizeof buf, "%03o", c);
res += "\\";
res += buf;
}
break;
}
}
return res + "\"";
@ -72,4 +90,4 @@ void CPPCompile::Indent() const
fprintf(write_file, "%s", "\t");
}
} // zeek::detail
} // zeek::detail

View file

@ -1,15 +1,15 @@
// See the file "COPYING" in the main distribution directory for copyright.
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <unistd.h>
#include "zeek/RE.h"
#include "zeek/script_opt/ProfileFunc.h"
#include "zeek/script_opt/CPP/Compile.h"
#include "zeek/script_opt/ProfileFunc.h"
namespace zeek::detail {
namespace zeek::detail
{
using namespace std;
@ -53,107 +53,149 @@ string CPPCompile::GenExpr(const Expr* e, GenType gt, bool top_level)
{
string gen;
switch ( e->Tag() ) {
case EXPR_NAME: return GenNameExpr(e->AsNameExpr(), gt);
case EXPR_CONST: return GenConstExpr(e->AsConstExpr(), gt);
switch ( e->Tag() )
{
case EXPR_NAME:
return GenNameExpr(e->AsNameExpr(), gt);
case EXPR_CONST:
return GenConstExpr(e->AsConstExpr(), gt);
case EXPR_CLONE:
gen = GenExpr(e->GetOp1(), GEN_VAL_PTR) + "->Clone()";
return GenericValPtrToGT(gen, e->GetType(), gt);
case EXPR_CLONE:
gen = GenExpr(e->GetOp1(), GEN_VAL_PTR) + "->Clone()";
return GenericValPtrToGT(gen, e->GetType(), gt);
case EXPR_INCR:
case EXPR_DECR:
return GenIncrExpr(e, gt, e->Tag() == EXPR_INCR, top_level);
case EXPR_INCR:
case EXPR_DECR:
return GenIncrExpr(e, gt, e->Tag() == EXPR_INCR, top_level);
case EXPR_NOT: return GenUnary(e, gt, "!", "not");
case EXPR_COMPLEMENT: return GenUnary(e, gt, "~", "comp");
case EXPR_POSITIVE: return GenUnary(e, gt, "+", "pos");
case EXPR_NEGATE: return GenUnary(e, gt, "-", "neg");
case EXPR_NOT:
return GenUnary(e, gt, "!", "not");
case EXPR_COMPLEMENT:
return GenUnary(e, gt, "~", "comp");
case EXPR_POSITIVE:
return GenUnary(e, gt, "+", "pos");
case EXPR_NEGATE:
return GenUnary(e, gt, "-", "neg");
case EXPR_ADD: return GenBinary(e, gt, "+", "add");
case EXPR_SUB: return GenBinary(e, gt, "-", "sub");
case EXPR_REMOVE_FROM: return GenBinary(e, gt, "-=");
case EXPR_TIMES: return GenBinary(e, gt, "*", "mul");
case EXPR_DIVIDE: return GenBinary(e, gt, "/", "div");
case EXPR_MOD: return GenBinary(e, gt, "%", "mod");
case EXPR_AND: return GenBinary(e, gt, "&", "and");
case EXPR_OR: return GenBinary(e, gt, "|", "or");
case EXPR_XOR: return GenBinary(e, gt, "^", "xor");
case EXPR_AND_AND: return GenBinary(e, gt, "&&", "andand");
case EXPR_OR_OR: return GenBinary(e, gt, "||", "oror");
case EXPR_LT: return GenBinary(e, gt, "<", "lt");
case EXPR_LE: return GenBinary(e, gt, "<=", "le");
case EXPR_GE: return GenBinary(e, gt, ">=","ge");
case EXPR_GT: return GenBinary(e, gt, ">", "gt");
case EXPR_ADD:
return GenBinary(e, gt, "+", "add");
case EXPR_SUB:
return GenBinary(e, gt, "-", "sub");
case EXPR_REMOVE_FROM:
return GenBinary(e, gt, "-=");
case EXPR_TIMES:
return GenBinary(e, gt, "*", "mul");
case EXPR_DIVIDE:
return GenBinary(e, gt, "/", "div");
case EXPR_MOD:
return GenBinary(e, gt, "%", "mod");
case EXPR_AND:
return GenBinary(e, gt, "&", "and");
case EXPR_OR:
return GenBinary(e, gt, "|", "or");
case EXPR_XOR:
return GenBinary(e, gt, "^", "xor");
case EXPR_AND_AND:
return GenBinary(e, gt, "&&", "andand");
case EXPR_OR_OR:
return GenBinary(e, gt, "||", "oror");
case EXPR_LT:
return GenBinary(e, gt, "<", "lt");
case EXPR_LE:
return GenBinary(e, gt, "<=", "le");
case EXPR_GE:
return GenBinary(e, gt, ">=", "ge");
case EXPR_GT:
return GenBinary(e, gt, ">", "gt");
case EXPR_EQ: return GenEQ(e, gt, "==", "eq");
case EXPR_NE: return GenEQ(e, gt, "!=", "ne");
case EXPR_EQ:
return GenEQ(e, gt, "==", "eq");
case EXPR_NE:
return GenEQ(e, gt, "!=", "ne");
case EXPR_COND: return GenCondExpr(e, gt);
case EXPR_CALL: return GenCallExpr(e->AsCallExpr(), gt);
case EXPR_LIST: return GenListExpr(e, gt, false);
case EXPR_IN: return GenInExpr(e, gt);
case EXPR_FIELD: return GenFieldExpr(e->AsFieldExpr(), gt);
case EXPR_HAS_FIELD: return GenHasFieldExpr(e->AsHasFieldExpr(), gt);
case EXPR_INDEX: return GenIndexExpr(e, gt);
case EXPR_ASSIGN: return GenAssignExpr(e, gt, top_level);
case EXPR_ADD_TO: return GenAddToExpr(e, gt, top_level);
case EXPR_REF: return GenExpr(e->GetOp1(), gt);
case EXPR_SIZE: return GenSizeExpr(e, gt);
case EXPR_SCHEDULE: return GenScheduleExpr(e);
case EXPR_LAMBDA: return GenLambdaExpr(e);
case EXPR_IS: return GenIsExpr(e, gt);
case EXPR_COND:
return GenCondExpr(e, gt);
case EXPR_CALL:
return GenCallExpr(e->AsCallExpr(), gt);
case EXPR_LIST:
return GenListExpr(e, gt, false);
case EXPR_IN:
return GenInExpr(e, gt);
case EXPR_FIELD:
return GenFieldExpr(e->AsFieldExpr(), gt);
case EXPR_HAS_FIELD:
return GenHasFieldExpr(e->AsHasFieldExpr(), gt);
case EXPR_INDEX:
return GenIndexExpr(e, gt);
case EXPR_ASSIGN:
return GenAssignExpr(e, gt, top_level);
case EXPR_ADD_TO:
return GenAddToExpr(e, gt, top_level);
case EXPR_REF:
return GenExpr(e->GetOp1(), gt);
case EXPR_SIZE:
return GenSizeExpr(e, gt);
case EXPR_SCHEDULE:
return GenScheduleExpr(e);
case EXPR_LAMBDA:
return GenLambdaExpr(e);
case EXPR_IS:
return GenIsExpr(e, gt);
case EXPR_ARITH_COERCE: return GenArithCoerceExpr(e, gt);
case EXPR_RECORD_COERCE: return GenRecordCoerceExpr(e);
case EXPR_TABLE_COERCE: return GenTableCoerceExpr(e);
case EXPR_VECTOR_COERCE: return GenVectorCoerceExpr(e);
case EXPR_ARITH_COERCE:
return GenArithCoerceExpr(e, gt);
case EXPR_RECORD_COERCE:
return GenRecordCoerceExpr(e);
case EXPR_TABLE_COERCE:
return GenTableCoerceExpr(e);
case EXPR_VECTOR_COERCE:
return GenVectorCoerceExpr(e);
case EXPR_RECORD_CONSTRUCTOR: return GenRecordConstructorExpr(e);
case EXPR_SET_CONSTRUCTOR: return GenSetConstructorExpr(e);
case EXPR_TABLE_CONSTRUCTOR: return GenTableConstructorExpr(e);
case EXPR_VECTOR_CONSTRUCTOR: return GenVectorConstructorExpr(e);
case EXPR_RECORD_CONSTRUCTOR:
return GenRecordConstructorExpr(e);
case EXPR_SET_CONSTRUCTOR:
return GenSetConstructorExpr(e);
case EXPR_TABLE_CONSTRUCTOR:
return GenTableConstructorExpr(e);
case EXPR_VECTOR_CONSTRUCTOR:
return GenVectorConstructorExpr(e);
case EXPR_EVENT:
// These should not wind up being directly generated,
// but instead deconstructed in the context of either
// a "schedule" expression or an "event" statement.
ASSERT(0);
case EXPR_EVENT:
// These should not wind up being directly generated,
// but instead deconstructed in the context of either
// a "schedule" expression or an "event" statement.
ASSERT(0);
case EXPR_CAST:
gen = string("cast_value_to_type__CPP(") +
GenExpr(e->GetOp1(), GEN_VAL_PTR) + ", " +
GenTypeName(e->GetType()) + ")";
return GenericValPtrToGT(gen, e->GetType(), gt);
case EXPR_CAST:
gen = string("cast_value_to_type__CPP(") + GenExpr(e->GetOp1(), GEN_VAL_PTR) + ", " +
GenTypeName(e->GetType()) + ")";
return GenericValPtrToGT(gen, e->GetType(), gt);
case EXPR_TO_ANY_COERCE:
return GenExpr(e->GetOp1(), GEN_VAL_PTR);
case EXPR_TO_ANY_COERCE:
return GenExpr(e->GetOp1(), GEN_VAL_PTR);
case EXPR_FROM_ANY_COERCE:
gen = string("from_any__CPP(") +
GenExpr(e->GetOp1(), GEN_VAL_PTR) + ", " +
GenTypeName(e->GetType()) + ")";
return GenericValPtrToGT(gen, e->GetType(), gt);
case EXPR_FROM_ANY_COERCE:
gen = string("from_any__CPP(") + GenExpr(e->GetOp1(), GEN_VAL_PTR) + ", " +
GenTypeName(e->GetType()) + ")";
return GenericValPtrToGT(gen, e->GetType(), gt);
case EXPR_FROM_ANY_VEC_COERCE:
gen = string("from_any_vec__CPP(") +
GenExpr(e->GetOp1(), GEN_VAL_PTR) + ", " +
GenTypeName(e->GetType()->Yield()) + ")";
return GenericValPtrToGT(gen, e->GetType(), gt);
case EXPR_FROM_ANY_VEC_COERCE:
gen = string("from_any_vec__CPP(") + GenExpr(e->GetOp1(), GEN_VAL_PTR) + ", " +
GenTypeName(e->GetType()->Yield()) + ")";
return GenericValPtrToGT(gen, e->GetType(), gt);
case EXPR_FIELD_ASSIGN:
case EXPR_INDEX_SLICE_ASSIGN:
case EXPR_INLINE:
// These are only generated for reduced ASTs, which
// we shouldn't be compiling.
ASSERT(0);
case EXPR_FIELD_ASSIGN:
case EXPR_INDEX_SLICE_ASSIGN:
case EXPR_INLINE:
// These are only generated for reduced ASTs, which
// we shouldn't be compiling.
ASSERT(0);
default:
// Intended to catch errors in overlooking the possible
// expressions that might appear.
return string("EXPR");
}
default:
// Intended to catch errors in overlooking the possible
// expressions that might appear.
return string("EXPR");
}
}
string CPPCompile::GenNameExpr(const NameExpr* ne, GenType gt)
@ -165,8 +207,7 @@ string CPPCompile::GenNameExpr(const NameExpr* ne, GenType gt)
if ( t->Tag() == TYPE_FUNC && ! is_global_var )
{
auto func = n->Name();
if ( globals.count(func) > 0 &&
pfs.BiFGlobals().count(n) == 0 )
if ( globals.count(func) > 0 && pfs.BiFGlobals().count(n) == 0 )
return GenericValPtrToGT(IDNameStr(n), t, gt);
}
@ -175,9 +216,7 @@ string CPPCompile::GenNameExpr(const NameExpr* ne, GenType gt)
string gen;
if ( n->IsType() )
gen = string("make_intrusive<TypeVal>(") +
globals[n->Name()] +
"->GetType(), true)";
gen = string("make_intrusive<TypeVal>(") + globals[n->Name()] + "->GetType(), true)";
else
gen = globals[n->Name()] + "->GetVal()";
@ -205,8 +244,8 @@ string CPPCompile::GenIncrExpr(const Expr* e, GenType gt, bool is_incr, bool top
// twice, so easiest is to just transform this node
// into the expanded equivalent.
auto op = e->GetOp1();
auto one = e->GetType()->InternalType() == TYPE_INTERNAL_INT ?
val_mgr->Int(1) : val_mgr->Count(1);
auto one =
e->GetType()->InternalType() == TYPE_INTERNAL_INT ? val_mgr->Int(1) : val_mgr->Count(1);
auto one_e = make_intrusive<ConstExpr>(one);
ExprPtr rhs;
@ -215,14 +254,13 @@ string CPPCompile::GenIncrExpr(const Expr* e, GenType gt, bool is_incr, bool top
else
rhs = make_intrusive<SubExpr>(op, one_e);
auto assign = make_intrusive<AssignExpr>(op, rhs, false,
nullptr, nullptr, false);
auto assign = make_intrusive<AssignExpr>(op, rhs, false, nullptr, nullptr, false);
// Make sure any newly created types are known to
// the profiler.
(void) pfs.HashType(one_e->GetType());
(void) pfs.HashType(rhs->GetType());
(void) pfs.HashType(assign->GetType());
(void)pfs.HashType(one_e->GetType());
(void)pfs.HashType(rhs->GetType());
(void)pfs.HashType(assign->GetType());
auto gen = GenExpr(assign, GEN_DONT_CARE, top_level);
@ -243,8 +281,7 @@ string CPPCompile::GenCondExpr(const Expr* e, GenType gt)
auto gen3 = GenExpr(op3, gt);
if ( op1->GetType()->Tag() == TYPE_VECTOR )
return string("vector_select__CPP(") +
gen1 + ", " + gen2 + ", " + gen3 + ")";
return string("vector_select__CPP(") + gen1 + ", " + gen2 + ", " + gen3 + ")";
return string("(") + gen1 + ") ? (" + gen2 + ") : (" + gen3 + ")";
}
@ -276,8 +313,7 @@ string CPPCompile::GenCallExpr(const CallExpr* c, GenType gt)
fname = compiled_simple_funcs[id_name];
if ( args_l->Exprs().length() > 0 )
gen = fname + "(" + GenArgs(params, args_l) +
", f__CPP)";
gen = fname + "(" + GenArgs(params, args_l) + ", f__CPP)";
else
gen = fname + "(f__CPP)";
@ -291,7 +327,7 @@ string CPPCompile::GenCallExpr(const CallExpr* c, GenType gt)
// If it is a BiF *that's also a global variable*, then
// we need to look up the BiF version of the global.
if ( pfs.BiFGlobals().count(f_id) == 0 )
gen += + "->AsFunc()";
gen += +"->AsFunc()";
else if ( pfs.Globals().count(f_id) > 0 )
// The BiF version has an extra "_", per
@ -323,27 +359,23 @@ string CPPCompile::GenInExpr(const Expr* e, GenType gt)
string gen;
if ( t1->Tag() == TYPE_PATTERN )
gen = string("(") + GenExpr(op1, GEN_DONT_CARE) +
")->MatchAnywhere(" +
GenExpr(op2, GEN_DONT_CARE) + "->AsString())";
gen = string("(") + GenExpr(op1, GEN_DONT_CARE) + ")->MatchAnywhere(" +
GenExpr(op2, GEN_DONT_CARE) + "->AsString())";
else if ( t2->Tag() == TYPE_STRING )
gen = string("str_in__CPP(") +
GenExpr(op1, GEN_DONT_CARE) + "->AsString(), " +
GenExpr(op2, GEN_DONT_CARE) + "->AsString())";
gen = string("str_in__CPP(") + GenExpr(op1, GEN_DONT_CARE) + "->AsString(), " +
GenExpr(op2, GEN_DONT_CARE) + "->AsString())";
else if ( t1->Tag() == TYPE_ADDR && t2->Tag() == TYPE_SUBNET )
gen = string("(") + GenExpr(op2, GEN_DONT_CARE) +
")->Contains(" + GenExpr(op1, GEN_VAL_PTR) + "->Get())";
gen = string("(") + GenExpr(op2, GEN_DONT_CARE) + ")->Contains(" +
GenExpr(op1, GEN_VAL_PTR) + "->Get())";
else if ( t2->Tag() == TYPE_VECTOR )
gen = GenExpr(op2, GEN_DONT_CARE) + "->Has(" +
GenExpr(op1, GEN_NATIVE) + ")";
gen = GenExpr(op2, GEN_DONT_CARE) + "->Has(" + GenExpr(op1, GEN_NATIVE) + ")";
else
gen = string("(") + GenExpr(op2, GEN_DONT_CARE) +
"->Find(index_val__CPP({" + GenExpr(op1, GEN_VAL_PTR) +
"})) ? true : false)";
gen = string("(") + GenExpr(op2, GEN_DONT_CARE) + "->Find(index_val__CPP({" +
GenExpr(op1, GEN_VAL_PTR) + "})) ? true : false)";
return NativeToGT(gen, e->GetType(), gt);
}
@ -354,8 +386,7 @@ string CPPCompile::GenFieldExpr(const FieldExpr* fe, GenType gt)
auto f = fe->Field();
auto f_s = GenField(r, f);
auto gen = string("field_access__CPP(") + GenExpr(r, GEN_VAL_PTR) +
", " + f_s + ")";
auto gen = string("field_access__CPP(") + GenExpr(r, GEN_VAL_PTR) + ", " + f_s + ")";
return GenericValPtrToGT(gen, fe->GetType(), gt);
}
@ -367,8 +398,7 @@ string CPPCompile::GenHasFieldExpr(const HasFieldExpr* hfe, GenType gt)
auto f_s = GenField(r, f);
// Need to use accessors for native types.
auto gen = string("(") + GenExpr(r, GEN_DONT_CARE) +
"->GetField(" + f_s + ") != nullptr)";
auto gen = string("(") + GenExpr(r, GEN_DONT_CARE) + "->GetField(" + f_s + ") != nullptr)";
return NativeToGT(gen, hfe->GetType(), gt);
}
@ -381,9 +411,8 @@ string CPPCompile::GenIndexExpr(const Expr* e, GenType gt)
string gen;
if ( aggr_t->Tag() == TYPE_TABLE )
gen = string("index_table__CPP(") +
GenExpr(aggr, GEN_NATIVE) + ", {" +
GenExpr(e->GetOp2(), GEN_VAL_PTR) + "})";
gen = string("index_table__CPP(") + GenExpr(aggr, GEN_NATIVE) + ", {" +
GenExpr(e->GetOp2(), GEN_VAL_PTR) + "})";
else if ( aggr_t->Tag() == TYPE_VECTOR )
{
@ -391,27 +420,22 @@ string CPPCompile::GenIndexExpr(const Expr* e, GenType gt)
const auto& t2 = op2->GetType();
ASSERT(t2->Tag() == TYPE_LIST);
if ( t2->Tag() == TYPE_LIST &&
t2->AsTypeList()->GetTypes().size() == 2 )
if ( t2->Tag() == TYPE_LIST && t2->AsTypeList()->GetTypes().size() == 2 )
{
auto& inds = op2->AsListExpr()->Exprs();
auto first = inds[0];
auto last = inds[1];
gen = string("index_slice(") +
GenExpr(aggr, GEN_VAL_PTR) + ".get(), " +
GenExpr(first, GEN_NATIVE) + ", " +
GenExpr(last, GEN_NATIVE) + ")";
gen = string("index_slice(") + GenExpr(aggr, GEN_VAL_PTR) + ".get(), " +
GenExpr(first, GEN_NATIVE) + ", " + GenExpr(last, GEN_NATIVE) + ")";
}
else
gen = string("index_vec__CPP(") +
GenExpr(aggr, GEN_NATIVE) + ", " +
GenExpr(e->GetOp2(), GEN_NATIVE) + ")";
gen = string("index_vec__CPP(") + GenExpr(aggr, GEN_NATIVE) + ", " +
GenExpr(e->GetOp2(), GEN_NATIVE) + ")";
}
else if ( aggr_t->Tag() == TYPE_STRING )
gen = string("index_string__CPP(") +
GenExpr(aggr, GEN_NATIVE) + ", {" +
GenExpr(e->GetOp2(), GEN_VAL_PTR) + "})";
gen = string("index_string__CPP(") + GenExpr(aggr, GEN_NATIVE) + ", {" +
GenExpr(e->GetOp2(), GEN_VAL_PTR) + "})";
return GenericValPtrToGT(gen, e->GetType(), gt);
}
@ -434,8 +458,7 @@ string CPPCompile::GenAssignExpr(const Expr* e, GenType gt, bool top_level)
rhs_native = rhs_val_ptr;
if ( rhs_is_any && ! lhs_is_any && t1->Tag() != TYPE_LIST )
rhs_native = rhs_val_ptr =
GenericValPtrToGT(rhs_val_ptr, t1, GEN_NATIVE);
rhs_native = rhs_val_ptr = GenericValPtrToGT(rhs_val_ptr, t1, GEN_NATIVE);
return GenAssign(op1, op2, rhs_native, rhs_val_ptr, gt, top_level);
}
@ -446,9 +469,8 @@ string CPPCompile::GenAddToExpr(const Expr* e, GenType gt, bool top_level)
if ( t->Tag() == TYPE_VECTOR )
{
auto gen = string("vector_append__CPP(") +
GenExpr(e->GetOp1(), GEN_VAL_PTR) +
", " + GenExpr(e->GetOp2(), GEN_VAL_PTR) + ")";
auto gen = string("vector_append__CPP(") + GenExpr(e->GetOp1(), GEN_VAL_PTR) + ", " +
GenExpr(e->GetOp2(), GEN_VAL_PTR) + ")";
return GenericValPtrToGT(gen, t, gt);
}
@ -472,8 +494,8 @@ string CPPCompile::GenAddToExpr(const Expr* e, GenType gt, bool top_level)
// Make sure any newly created types are known to
// the profiler.
(void) pfs.HashType(rhs->GetType());
(void) pfs.HashType(assign->GetType());
(void)pfs.HashType(rhs->GetType());
(void)pfs.HashType(assign->GetType());
return GenExpr(assign, gt, top_level);
}
@ -521,9 +543,8 @@ string CPPCompile::GenScheduleExpr(const Expr* e)
if ( when->GetType()->Tag() == TYPE_INTERVAL )
when_s += " + run_state::network_time";
return string("schedule__CPP(") + when_s +
", " + globals[event_name] + "_ev, { " +
GenExpr(event->Args(), GEN_VAL_PTR) + " })";
return string("schedule__CPP(") + when_s + ", " + globals[event_name] + "_ev, { " +
GenExpr(event->Args(), GEN_VAL_PTR) + " })";
}
string CPPCompile::GenLambdaExpr(const Expr* e)
@ -536,17 +557,15 @@ string CPPCompile::GenLambdaExpr(const Expr* e)
cl_args = cl_args + GenLambdaClone(l, false);
auto body = string("make_intrusive<") + name + ">(" + cl_args + ")";
auto func = string("make_intrusive<CPPLambdaFunc>(\"") +
l->Name() + "\", cast_intrusive<FuncType>(" +
GenTypeName(l->GetType()) + "), " + body + ")";
auto func = string("make_intrusive<CPPLambdaFunc>(\"") + l->Name() +
"\", cast_intrusive<FuncType>(" + GenTypeName(l->GetType()) + "), " + body + ")";
return string("make_intrusive<FuncVal>(") + func + ")";
}
string CPPCompile::GenIsExpr(const Expr* e, GenType gt)
{
auto ie = static_cast<const IsExpr*>(e);
auto gen = string("can_cast_value_to_type(") +
GenExpr(ie->GetOp1(), GEN_VAL_PTR) + ".get(), " +
auto gen = string("can_cast_value_to_type(") + GenExpr(ie->GetOp1(), GEN_VAL_PTR) + ".get(), " +
GenTypeName(ie->TestType()) + ".get())";
return NativeToGT(gen, ie->GetType(), gt);
@ -566,19 +585,25 @@ string CPPCompile::GenArithCoerceExpr(const Expr* e, GenType gt)
string cast_name;
switch ( coerce_t->InternalType() ) {
case TYPE_INTERNAL_INT: cast_name = "bro_int_t"; break;
case TYPE_INTERNAL_UNSIGNED: cast_name = "bro_uint_t"; break;
case TYPE_INTERNAL_DOUBLE: cast_name = "double"; break;
switch ( coerce_t->InternalType() )
{
case TYPE_INTERNAL_INT:
cast_name = "bro_int_t";
break;
case TYPE_INTERNAL_UNSIGNED:
cast_name = "bro_uint_t";
break;
case TYPE_INTERNAL_DOUBLE:
cast_name = "double";
break;
default:
reporter->InternalError("bad type in arithmetic coercion");
}
default:
reporter->InternalError("bad type in arithmetic coercion");
}
if ( is_vec )
return string("vec_coerce_") + cast_name +
"__CPP(" + GenExpr(op, GEN_NATIVE) +
", " + GenTypeName(t) + ")";
return string("vec_coerce_") + cast_name + "__CPP(" + GenExpr(op, GEN_NATIVE) + ", " +
GenTypeName(t) + ")";
return NativeToGT(cast_name + "(" + GenExpr(op, GEN_NATIVE) + ")", t, gt);
}
@ -597,9 +622,8 @@ string CPPCompile::GenRecordCoerceExpr(const Expr* e)
const auto& map = rc->Map();
auto type_var = GenTypeName(to_type);
return string("coerce_to_record(cast_intrusive<RecordType>(") +
type_var + "), " + GenExpr(op1, GEN_VAL_PTR) + ".get(), " +
GenIntVector(map) + ")";
return string("coerce_to_record(cast_intrusive<RecordType>(") + type_var + "), " +
GenExpr(op1, GEN_VAL_PTR) + ".get(), " + GenIntVector(map) + ")";
}
string CPPCompile::GenTableCoerceExpr(const Expr* e)
@ -608,8 +632,7 @@ string CPPCompile::GenTableCoerceExpr(const Expr* e)
const auto& t = tc->GetType();
auto op1 = tc->GetOp1();
return string("table_coerce__CPP(") + GenExpr(op1, GEN_VAL_PTR) +
", " + GenTypeName(t) + ")";
return string("table_coerce__CPP(") + GenExpr(op1, GEN_VAL_PTR) + ", " + GenTypeName(t) + ")";
}
string CPPCompile::GenVectorCoerceExpr(const Expr* e)
@ -618,8 +641,7 @@ string CPPCompile::GenVectorCoerceExpr(const Expr* e)
const auto& op = vc->GetOp1();
const auto& t = vc->GetType<VectorType>();
return string("vector_coerce__CPP(" + GenExpr(op, GEN_VAL_PTR) +
", " + GenTypeName(t) + ")");
return string("vector_coerce__CPP(" + GenExpr(op, GEN_VAL_PTR) + ", " + GenTypeName(t) + ")");
}
string CPPCompile::GenRecordConstructorExpr(const Expr* e)
@ -643,8 +665,8 @@ string CPPCompile::GenRecordConstructorExpr(const Expr* e)
vals += ", ";
}
return string("record_constructor__CPP({") + vals + "}, " +
"cast_intrusive<RecordType>(" + GenTypeName(t) + "))";
return string("record_constructor__CPP({") + vals + "}, " + "cast_intrusive<RecordType>(" +
GenTypeName(t) + "))";
}
string CPPCompile::GenSetConstructorExpr(const Expr* e)
@ -657,10 +679,9 @@ string CPPCompile::GenSetConstructorExpr(const Expr* e)
string attr_vals;
BuildAttrs(attrs, attr_tags, attr_vals);
return string("set_constructor__CPP(") +
GenExprs(sc->GetOp1().get()) + ", " +
"cast_intrusive<TableType>(" + GenTypeName(t) + "), " +
attr_tags + ", " + attr_vals + ")";
return string("set_constructor__CPP(") + GenExprs(sc->GetOp1().get()) + ", " +
"cast_intrusive<TableType>(" + GenTypeName(t) + "), " + attr_tags + ", " + attr_vals +
")";
}
string CPPCompile::GenTableConstructorExpr(const Expr* e)
@ -690,8 +711,7 @@ string CPPCompile::GenTableConstructorExpr(const Expr* e)
if ( index->Tag() == EXPR_LIST )
// Multiple indices.
indices += "index_val__CPP({" +
GenExpr(index, GEN_VAL_PTR) + "})";
indices += "index_val__CPP({" + GenExpr(index, GEN_VAL_PTR) + "})";
else
indices += GenExpr(index, GEN_VAL_PTR);
@ -704,10 +724,9 @@ string CPPCompile::GenTableConstructorExpr(const Expr* e)
}
}
return string("table_constructor__CPP({") +
indices + "}, {" + vals + "}, " +
"cast_intrusive<TableType>(" + GenTypeName(t) + "), " +
attr_tags + ", " + attr_vals + ")";
return string("table_constructor__CPP({") + indices + "}, {" + vals + "}, " +
"cast_intrusive<TableType>(" + GenTypeName(t) + "), " + attr_tags + ", " + attr_vals +
")";
}
string CPPCompile::GenVectorConstructorExpr(const Expr* e)
@ -715,9 +734,8 @@ string CPPCompile::GenVectorConstructorExpr(const Expr* e)
auto vc = static_cast<const VectorConstructorExpr*>(e);
const auto& t = vc->GetType();
return string("vector_constructor__CPP({") +
GenExpr(vc->GetOp1(), GEN_VAL_PTR) + "}, " +
"cast_intrusive<VectorType>(" + GenTypeName(t) + "))";
return string("vector_constructor__CPP({") + GenExpr(vc->GetOp1(), GEN_VAL_PTR) + "}, " +
"cast_intrusive<VectorType>(" + GenTypeName(t) + "))";
}
string CPPCompile::GenVal(const ValPtr& v)
@ -744,19 +762,15 @@ string CPPCompile::GenVal(const ValPtr& v)
return d.Description();
}
string CPPCompile::GenUnary(const Expr* e, GenType gt,
const char* op, const char* vec_op)
string CPPCompile::GenUnary(const Expr* e, GenType gt, const char* op, const char* vec_op)
{
if ( e->GetType()->Tag() == TYPE_VECTOR )
return GenVectorOp(e, GenExpr(e->GetOp1(), GEN_NATIVE), vec_op);
return NativeToGT(string(op) + "(" +
GenExpr(e->GetOp1(), GEN_NATIVE) + ")",
e->GetType(), gt);
return NativeToGT(string(op) + "(" + GenExpr(e->GetOp1(), GEN_NATIVE) + ")", e->GetType(), gt);
}
string CPPCompile::GenBinary(const Expr* e, GenType gt,
const char* op, const char* vec_op)
string CPPCompile::GenBinary(const Expr* e, GenType gt, const char* op, const char* vec_op)
{
const auto& op1 = e->GetOp1();
const auto& op2 = e->GetOp2();
@ -767,11 +781,9 @@ string CPPCompile::GenBinary(const Expr* e, GenType gt,
auto gen1 = GenExpr(op1, GEN_NATIVE);
auto gen2 = GenExpr(op2, GEN_NATIVE);
if ( t->Tag() == TYPE_VECTOR &&
t->Yield()->Tag() == TYPE_STRING &&
if ( t->Tag() == TYPE_VECTOR && t->Yield()->Tag() == TYPE_STRING &&
op2->GetType()->Tag() == TYPE_VECTOR )
return string("vec_str_op_") + vec_op + "__CPP(" +
gen1 + ", " + gen2 + ")";
return string("vec_str_op_") + vec_op + "__CPP(" + gen1 + ", " + gen2 + ")";
return GenVectorOp(e, gen1, gen2, vec_op);
}
@ -785,20 +797,30 @@ string CPPCompile::GenBinary(const Expr* e, GenType gt,
// employed to support an operation.
string flavor;
switch ( t->InternalType() ) {
case TYPE_INTERNAL_INT: flavor = "i"; break;
case TYPE_INTERNAL_UNSIGNED: flavor = "u"; break;
case TYPE_INTERNAL_DOUBLE: flavor = "f"; break;
switch ( t->InternalType() )
{
case TYPE_INTERNAL_INT:
flavor = "i";
break;
case TYPE_INTERNAL_UNSIGNED:
flavor = "u";
break;
case TYPE_INTERNAL_DOUBLE:
flavor = "f";
break;
case TYPE_INTERNAL_STRING: return GenBinaryString(e, gt, op);
case TYPE_INTERNAL_ADDR: return GenBinaryAddr(e, gt, op);
case TYPE_INTERNAL_SUBNET: return GenBinarySubNet(e, gt, op);
case TYPE_INTERNAL_STRING:
return GenBinaryString(e, gt, op);
case TYPE_INTERNAL_ADDR:
return GenBinaryAddr(e, gt, op);
case TYPE_INTERNAL_SUBNET:
return GenBinarySubNet(e, gt, op);
default:
if ( t->Tag() == TYPE_PATTERN )
return GenBinaryPattern(e, gt, op);
break;
}
default:
if ( t->Tag() == TYPE_PATTERN )
return GenBinaryPattern(e, gt, op);
break;
}
auto g1 = GenExpr(e->GetOp1(), GEN_NATIVE);
auto g2 = GenExpr(e->GetOp2(), GEN_NATIVE);
@ -824,45 +846,45 @@ string CPPCompile::GenBinarySet(const Expr* e, GenType gt, const char* op)
string res;
switch ( e->Tag() ) {
case EXPR_AND:
res = v1 + "->Intersection(*" + v2 + ")";
break;
switch ( e->Tag() )
{
case EXPR_AND:
res = v1 + "->Intersection(*" + v2 + ")";
break;
case EXPR_OR:
res = v1 + "->Union(" + v2 + ")";
break;
case EXPR_OR:
res = v1 + "->Union(" + v2 + ")";
break;
case EXPR_SUB:
res = v1 + "->TakeOut(" + v2 + ")";
break;
case EXPR_SUB:
res = v1 + "->TakeOut(" + v2 + ")";
break;
case EXPR_EQ:
res = v1 + "->EqualTo(*" + v2 + ")";
break;
case EXPR_EQ:
res = v1 + "->EqualTo(*" + v2 + ")";
break;
case EXPR_NE:
res = string("! ") + v1 + "->EqualTo(*" + v2 + ")";
break;
case EXPR_NE:
res = string("! ") + v1 + "->EqualTo(*" + v2 + ")";
break;
case EXPR_LE:
res = v1 + "->IsSubsetOf(*" + v2 + ")";
break;
case EXPR_LE:
res = v1 + "->IsSubsetOf(*" + v2 + ")";
break;
case EXPR_LT:
res = string("(") + v1 + "->IsSubsetOf(*" + v2 + ") &&" +
v1 + "->Size() < " + v2 + "->Size())";
break;
case EXPR_LT:
res = string("(") + v1 + "->IsSubsetOf(*" + v2 + ") &&" + v1 + "->Size() < " + v2 +
"->Size())";
break;
default:
reporter->InternalError("bad type in CPPCompile::GenBinarySet");
}
default:
reporter->InternalError("bad type in CPPCompile::GenBinarySet");
}
return NativeToGT(res, e->GetType(), gt);
}
string CPPCompile::GenBinaryString(const Expr* e, GenType gt,
const char* op)
string CPPCompile::GenBinaryString(const Expr* e, GenType gt, const char* op)
{
auto v1 = GenExpr(e->GetOp1(), GEN_DONT_CARE) + "->AsString()";
auto v2 = GenExpr(e->GetOp2(), GEN_DONT_CARE) + "->AsString()";
@ -877,17 +899,15 @@ string CPPCompile::GenBinaryString(const Expr* e, GenType gt,
return NativeToGT(res, e->GetType(), gt);
}
string CPPCompile::GenBinaryPattern(const Expr* e, GenType gt,
const char* op)
string CPPCompile::GenBinaryPattern(const Expr* e, GenType gt, const char* op)
{
auto v1 = GenExpr(e->GetOp1(), GEN_DONT_CARE) + "->AsPattern()";
auto v2 = GenExpr(e->GetOp2(), GEN_DONT_CARE) + "->AsPattern()";
auto func = e->Tag() == EXPR_AND ?
"RE_Matcher_conjunction" : "RE_Matcher_disjunction";
auto func = e->Tag() == EXPR_AND ? "RE_Matcher_conjunction" : "RE_Matcher_disjunction";
return NativeToGT(string("make_intrusive<PatternVal>(") +
func + "(" + v1 + ", " + v2 + "))", e->GetType(), gt);
return NativeToGT(string("make_intrusive<PatternVal>(") + func + "(" + v1 + ", " + v2 + "))",
e->GetType(), gt);
}
string CPPCompile::GenBinaryAddr(const Expr* e, GenType gt, const char* op)
@ -896,8 +916,7 @@ string CPPCompile::GenBinaryAddr(const Expr* e, GenType gt, const char* op)
if ( e->Tag() == EXPR_DIVIDE )
{
auto gen = string("addr_mask__CPP(") + v1 + ", " +
GenExpr(e->GetOp2(), GEN_NATIVE) + ")";
auto gen = string("addr_mask__CPP(") + v1 + ", " + GenExpr(e->GetOp2(), GEN_NATIVE) + ")";
return NativeToGT(gen, e->GetType(), gt);
}
@ -915,8 +934,7 @@ string CPPCompile::GenBinarySubNet(const Expr* e, GenType gt, const char* op)
return NativeToGT(v1 + op + v2, e->GetType(), gt);
}
string CPPCompile::GenEQ(const Expr* e, GenType gt,
const char* op, const char* vec_op)
string CPPCompile::GenEQ(const Expr* e, GenType gt, const char* op, const char* vec_op)
{
auto op1 = e->GetOp1();
auto op2 = e->GetOp2();
@ -932,9 +950,8 @@ string CPPCompile::GenEQ(const Expr* e, GenType gt,
string negated(e->Tag() == EXPR_EQ ? "" : "! ");
if ( tag == TYPE_PATTERN )
return NativeToGT(negated + GenExpr(op1, GEN_DONT_CARE) +
"->MatchExactly(" +
GenExpr(op2, GEN_DONT_CARE) + "->AsString())",
return NativeToGT(negated + GenExpr(op1, GEN_DONT_CARE) + "->MatchExactly(" +
GenExpr(op2, GEN_DONT_CARE) + "->AsString())",
e->GetType(), gt);
if ( tag == TYPE_FUNC )
@ -953,33 +970,31 @@ string CPPCompile::GenEQ(const Expr* e, GenType gt,
return GenBinary(e, gt, op, vec_op);
}
string CPPCompile::GenAssign(const ExprPtr& lhs, const ExprPtr& rhs,
const string& rhs_native,
const string& rhs_val_ptr,
GenType gt, bool top_level)
string CPPCompile::GenAssign(const ExprPtr& lhs, const ExprPtr& rhs, const string& rhs_native,
const string& rhs_val_ptr, GenType gt, bool top_level)
{
switch ( lhs->Tag() ) {
case EXPR_NAME:
return GenDirectAssign(lhs, rhs_native, rhs_val_ptr, gt, top_level);
switch ( lhs->Tag() )
{
case EXPR_NAME:
return GenDirectAssign(lhs, rhs_native, rhs_val_ptr, gt, top_level);
case EXPR_INDEX:
return GenIndexAssign(lhs, rhs, rhs_val_ptr, gt, top_level);
case EXPR_INDEX:
return GenIndexAssign(lhs, rhs, rhs_val_ptr, gt, top_level);
case EXPR_FIELD:
return GenFieldAssign(lhs, rhs, rhs_val_ptr, gt, top_level);
case EXPR_FIELD:
return GenFieldAssign(lhs, rhs, rhs_val_ptr, gt, top_level);
case EXPR_LIST:
return GenListAssign(lhs, rhs);
case EXPR_LIST:
return GenListAssign(lhs, rhs);
default:
reporter->InternalError("bad assigment node in CPPCompile::GenExpr");
return "XXX";
}
default:
reporter->InternalError("bad assigment node in CPPCompile::GenExpr");
return "XXX";
}
}
string CPPCompile::GenDirectAssign(const ExprPtr& lhs, const string& rhs_native,
const string& rhs_val_ptr, GenType gt,
bool top_level)
const string& rhs_val_ptr, GenType gt, bool top_level)
{
auto n = lhs->AsNameExpr()->Id();
auto name = IDNameStr(n);
@ -991,11 +1006,9 @@ string CPPCompile::GenDirectAssign(const ExprPtr& lhs, const string& rhs_native,
const auto& t = n->GetType();
auto gn = globals[n->Name()];
if ( t->Tag() == TYPE_FUNC &&
t->AsFuncType()->Flavor() == FUNC_FLAVOR_EVENT )
if ( t->Tag() == TYPE_FUNC && t->AsFuncType()->Flavor() == FUNC_FLAVOR_EVENT )
{
gen = string("set_event__CPP(") + gn + ", " +
rhs_val_ptr + ", " + gn + "_ev)";
gen = string("set_event__CPP(") + gn + ", " + rhs_val_ptr + ", " + gn + "_ev)";
if ( ! top_level )
gen = GenericValPtrToGT(gen, n->GetType(), gt);
@ -1006,8 +1019,7 @@ string CPPCompile::GenDirectAssign(const ExprPtr& lhs, const string& rhs_native,
else
{
gen = string("set_global__CPP(") +
gn + ", " + rhs_val_ptr + ")";
gen = string("set_global__CPP(") + gn + ", " + rhs_val_ptr + ")";
gen = GenericValPtrToGT(gen, n->GetType(), gt);
}
}
@ -1017,8 +1029,7 @@ string CPPCompile::GenDirectAssign(const ExprPtr& lhs, const string& rhs_native,
return gen;
}
string CPPCompile::GenIndexAssign(const ExprPtr& lhs, const ExprPtr& rhs,
const string& rhs_val_ptr,
string CPPCompile::GenIndexAssign(const ExprPtr& lhs, const ExprPtr& rhs, const string& rhs_val_ptr,
GenType gt, bool top_level)
{
auto gen = string("assign_to_index__CPP(");
@ -1032,9 +1043,8 @@ string CPPCompile::GenIndexAssign(const ExprPtr& lhs, const ExprPtr& rhs,
return gen;
}
string CPPCompile::GenFieldAssign(const ExprPtr& lhs, const ExprPtr& rhs,
const string& rhs_val_ptr, GenType gt,
bool top_level)
string CPPCompile::GenFieldAssign(const ExprPtr& lhs, const ExprPtr& rhs, const string& rhs_val_ptr,
GenType gt, bool top_level)
{
auto rec = lhs->GetOp1();
auto rec_gen = GenExpr(rec, GEN_VAL_PTR);
@ -1044,8 +1054,7 @@ string CPPCompile::GenFieldAssign(const ExprPtr& lhs, const ExprPtr& rhs,
return rec_gen + "->Assign(" + field + ", " + rhs_val_ptr + ")";
else
{
auto gen = string("assign_field__CPP(") + rec_gen +
", " + field + ", " + rhs_val_ptr + ")";
auto gen = string("assign_field__CPP(") + rec_gen + ", " + field + ", " + rhs_val_ptr + ")";
return GenericValPtrToGT(gen, rhs->GetType(), gt);
}
}
@ -1086,14 +1095,12 @@ string CPPCompile::GenVectorOp(const Expr* e, string op, const char* vec_op)
auto gen = string("vec_op_") + vec_op + "__CPP(" + op + ")";
if ( ! IsArithmetic(e->GetType()->Yield()->Tag()) )
gen = string("vector_coerce_to__CPP(") + gen + ", " +
GenTypeName(e->GetType()) + ")";
gen = string("vector_coerce_to__CPP(") + gen + ", " + GenTypeName(e->GetType()) + ")";
return gen;
}
string CPPCompile::GenVectorOp(const Expr* e, string op1, string op2,
const char* vec_op)
string CPPCompile::GenVectorOp(const Expr* e, string op1, string op2, const char* vec_op)
{
auto invoke = string(vec_op) + "__CPP(" + op1 + ", " + op2 + ")";
@ -1104,8 +1111,7 @@ string CPPCompile::GenVectorOp(const Expr* e, string op1, string op2,
auto yt = e->GetType()->Yield()->Tag();
if ( ! IsArithmetic(yt) && yt != TYPE_STRING )
gen = string("vector_coerce_to__CPP(") + gen + ", " +
GenTypeName(e->GetType()) + ")";
gen = string("vector_coerce_to__CPP(") + gen + ", " + GenTypeName(e->GetType()) + ")";
return gen;
}
@ -1162,8 +1168,7 @@ string CPPCompile::GenField(const ExprPtr& rec, int field)
// Need to dynamically map the field.
int mapping_slot;
if ( record_field_mappings.count(rt) > 0 &&
record_field_mappings[rt].count(field) > 0 )
if ( record_field_mappings.count(rt) > 0 && record_field_mappings[rt].count(field) > 0 )
// We're already tracking this field.
mapping_slot = record_field_mappings[rt][field];
@ -1202,8 +1207,7 @@ string CPPCompile::GenEnum(const TypePtr& t, const ValPtr& ev)
// Need to dynamically map the access.
int mapping_slot;
if ( enum_val_mappings.count(et) > 0 &&
enum_val_mappings[et].count(v) > 0 )
if ( enum_val_mappings.count(et) > 0 && enum_val_mappings[et].count(v) > 0 )
// We're already tracking this value.
mapping_slot = enum_val_mappings[et][v];
@ -1232,4 +1236,4 @@ string CPPCompile::GenEnum(const TypePtr& t, const ValPtr& ev)
return string("enum_mapping[") + Fmt(mapping_slot) + "]";
}
} // zeek::detail
} // zeek::detail

View file

@ -1,13 +1,14 @@
// See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/script_opt/CPP/Func.h"
#include <broker/error.hh>
#include "zeek/Desc.h"
#include "zeek/broker/Data.h"
#include "zeek/script_opt/CPP/Func.h"
namespace zeek::detail {
namespace zeek::detail
{
using namespace std;
@ -23,7 +24,7 @@ void CPPFunc::Describe(ODesc* d) const
}
CPPLambdaFunc::CPPLambdaFunc(string _name, FuncTypePtr ft, CPPStmtPtr _l_body)
: ScriptFunc(move(_name), move(ft), {_l_body}, {0})
: ScriptFunc(move(_name), move(ft), {_l_body}, {0})
{
l_body = move(_l_body);
}
@ -44,8 +45,7 @@ broker::expected<broker::data> CPPLambdaFunc::SerializeClosure() const
return broker::ec::invalid_data;
TypeTag tag = val->GetType()->Tag();
broker::vector val_tuple {move(*expected),
static_cast<broker::integer>(tag)};
broker::vector val_tuple{move(*expected), static_cast<broker::integer>(tag)};
body.emplace_back(move(val_tuple));
}
@ -64,4 +64,4 @@ FuncPtr CPPLambdaFunc::DoClone()
return make_intrusive<CPPLambdaFunc>(name, type, l_body->Clone());
}
} // zeek::detail
} // zeek::detail

View file

@ -8,18 +8,21 @@
#include "zeek/Func.h"
#include "zeek/script_opt/ProfileFunc.h"
namespace zeek {
namespace zeek
{
namespace detail {
namespace detail
{
// A subclass of Func used for lambdas that the compiler creates for
// complex initializations (expressions used in type attributes).
// The usage is via derivation from this class, rather than direct
// use of it.
class CPPFunc : public Func {
class CPPFunc : public Func
{
public:
bool IsPure() const override { return is_pure; }
bool IsPure() const override { return is_pure; }
void Describe(ODesc* d) const override;
@ -33,57 +36,56 @@ protected:
std::string name;
bool is_pure;
};
};
// A subclass of Stmt used to replace a function/event handler/hook body.
class CPPStmt : public Stmt {
class CPPStmt : public Stmt
{
public:
CPPStmt(const char* _name) : Stmt(STMT_CPP), name(_name) { }
CPPStmt(const char* _name) : Stmt(STMT_CPP), name(_name) { }
const std::string& Name() { return name; }
const std::string& Name() { return name; }
// Sets/returns a hash associated with this statement. A value
// of 0 means "not set".
p_hash_type GetHash() const { return hash; }
void SetHash(p_hash_type h) { hash = h; }
p_hash_type GetHash() const { return hash; }
void SetHash(p_hash_type h) { hash = h; }
// The following only get defined by lambda bodies.
virtual void SetLambdaCaptures(Frame* f) { }
virtual std::vector<ValPtr> SerializeLambdaCaptures() const
{ return std::vector<ValPtr>{}; }
virtual void SetLambdaCaptures(Frame* f) { }
virtual std::vector<ValPtr> SerializeLambdaCaptures() const { return std::vector<ValPtr>{}; }
virtual IntrusivePtr<CPPStmt> Clone()
{
return {NewRef{}, this};
}
virtual IntrusivePtr<CPPStmt> Clone() { return {NewRef{}, this}; }
protected:
// This method being called means that the inliner is running
// on compiled code, which shouldn't happen.
StmtPtr Duplicate() override { ASSERT(0); return ThisPtr(); }
StmtPtr Duplicate() override
{
ASSERT(0);
return ThisPtr();
}
TraversalCode Traverse(TraversalCallback* cb) const override
{ return TC_CONTINUE; }
TraversalCode Traverse(TraversalCallback* cb) const override { return TC_CONTINUE; }
std::string name;
p_hash_type hash = 0ULL;
};
};
using CPPStmtPtr = IntrusivePtr<CPPStmt>;
// For script-level lambdas, a ScriptFunc subclass that knows how to
// deal with its captures for serialization. Different from CPPFunc in
// that CPPFunc is for lambdas generated directly by the compiler,
// rather than those explicitly present in scripts.
class CPPLambdaFunc : public ScriptFunc {
class CPPLambdaFunc : public ScriptFunc
{
public:
CPPLambdaFunc(std::string name, FuncTypePtr ft, CPPStmtPtr l_body);
bool HasCopySemantics() const override { return true; }
bool HasCopySemantics() const override { return true; }
protected:
// Methods related to sending lambdas via Broker.
@ -93,17 +95,17 @@ protected:
FuncPtr DoClone() override;
CPPStmtPtr l_body;
};
};
// Information associated with a given compiled script body: its
// Stmt subclass, priority, and any events that should be registered
// upon instantiating the body.
struct CompiledScript {
CPPStmtPtr body;
struct CompiledScript
{
CPPStmtPtr body;
int priority;
std::vector<std::string> events;
};
};
// Maps hashes to compiled information.
extern std::unordered_map<p_hash_type, CompiledScript> compiled_scripts;
@ -113,8 +115,7 @@ extern std::unordered_map<p_hash_type, CompiledScript> compiled_scripts;
// the body twice, leading to two copies. Indexed first by the name
// of the function, and then via the hash of the body that has been
// added to it.
extern std::unordered_map<std::string, std::unordered_set<p_hash_type>>
added_bodies;
extern std::unordered_map<std::string, std::unordered_set<p_hash_type>> added_bodies;
// Maps hashes to standalone script initialization callbacks.
extern std::unordered_map<p_hash_type, void (*)()> standalone_callbacks;
@ -123,6 +124,6 @@ extern std::unordered_map<p_hash_type, void (*)()> standalone_callbacks;
// load_CPP() BiF.
extern std::vector<void (*)()> standalone_activations;
} // namespace detail
} // namespace detail
} // namespace zeek
} // namespace zeek

View file

@ -1,13 +1,13 @@
// See the file "COPYING" in the main distribution directory for copyright.
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <unistd.h>
#include "zeek/script_opt/CPP/Compile.h"
namespace zeek::detail {
namespace zeek::detail
{
using namespace std;
@ -31,12 +31,10 @@ void CPPCompile::CompileLambda(const LambdaExpr* l, const ProfileFunc* pf)
auto l_id = l->Ingredients().id;
auto& ids = l->OuterIDs();
DefineBody(l_id->GetType<FuncType>(), pf, lname, body, &ids,
FUNC_FLAVOR_FUNCTION);
DefineBody(l_id->GetType<FuncType>(), pf, lname, body, &ids, FUNC_FLAVOR_FUNCTION);
}
void CPPCompile::GenInvokeBody(const string& fname, const TypePtr& t,
const string& args)
void CPPCompile::GenInvokeBody(const string& fname, const TypePtr& t, const string& args)
{
auto call = fname + "(" + args + ")";
@ -49,9 +47,8 @@ void CPPCompile::GenInvokeBody(const string& fname, const TypePtr& t,
Emit("return %s;", NativeToGT(call, t, GEN_VAL_PTR));
}
void CPPCompile::DefineBody(const FuncTypePtr& ft, const ProfileFunc* pf,
const string& fname, const StmtPtr& body,
const IDPList* lambda_ids, FunctionFlavor flavor)
void CPPCompile::DefineBody(const FuncTypePtr& ft, const ProfileFunc* pf, const string& fname,
const StmtPtr& body, const IDPList* lambda_ids, FunctionFlavor flavor)
{
locals.clear();
params.clear();
@ -207,8 +204,10 @@ string CPPCompile::BodyName(const FuncInfo& func)
while ( *fn == '.' || *fn == '/' )
++fn;
auto canonicalize =
[](char c) -> char { return isalnum(c) ? c : '_'; };
auto canonicalize = [](char c) -> char
{
return isalnum(c) ? c : '_';
};
string fns = fn;
transform(fns.begin(), fns.end(), fns.begin(), canonicalize);
@ -266,4 +265,4 @@ string CPPCompile::GenArgs(const RecordTypePtr& params, const Expr* e)
return gen;
}
} // zeek::detail
} // zeek::detail

View file

@ -1,10 +1,12 @@
// See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/script_opt/CPP/HashMgr.h"
#include "zeek/script_opt/CPP/Func.h"
#include "zeek/script_opt/CPP/Util.h"
namespace zeek::detail {
namespace zeek::detail
{
using namespace std;
@ -21,8 +23,7 @@ CPPHashManager::CPPHashManager(const char* hash_name_base, bool _append)
hf_r = fopen(hash_name.c_str(), "r");
if ( ! hf_r )
{
reporter->Error("can't open auxiliary C++ hash file %s for reading",
hash_name.c_str());
reporter->Error("can't open auxiliary C++ hash file %s for reading", hash_name.c_str());
exit(1);
}
@ -35,8 +36,7 @@ CPPHashManager::CPPHashManager(const char* hash_name_base, bool _append)
hf_w = fopen(hash_name.c_str(), mode);
if ( ! hf_w )
{
reporter->Error("can't open auxiliary C++ hash file %s for writing",
hash_name.c_str());
reporter->Error("can't open auxiliary C++ hash file %s for writing", hash_name.c_str());
exit(1);
}
}
@ -87,8 +87,7 @@ void CPPHashManager::LoadHashes(FILE* f)
RequireLine(f, line);
p_hash_type gl_t_h, gl_v_h;
if ( sscanf(line.c_str(), "%llu %llu",
&gl_t_h, &gl_v_h) != 2 )
if ( sscanf(line.c_str(), "%llu %llu", &gl_t_h, &gl_v_h) != 2 )
BadLine(line);
gl_type_hashes[gl] = gl_t_h;
@ -97,7 +96,7 @@ void CPPHashManager::LoadHashes(FILE* f)
// Eat the location info. It's there just for
// maintainers to be able to track down peculiarities
// in the hash file.
(void) RequireLine(f, line);
(void)RequireLine(f, line);
}
else if ( key == "global-var" )
@ -118,8 +117,7 @@ void CPPHashManager::LoadHashes(FILE* f)
int index;
int scope;
if ( sscanf(line.c_str(), "%llu %d %d", &hash, &index,
&scope) != 3 || hash == 0 )
if ( sscanf(line.c_str(), "%llu %d %d", &hash, &index, &scope) != 3 || hash == 0 )
BadLine(line);
compiled_items[hash] = CompiledItemPair{index, scope};
@ -151,8 +149,8 @@ bool CPPHashManager::GetLine(FILE* f, string& line)
return false;
int n = strlen(buf);
if ( n > 0 && buf[n-1] == '\n' )
buf[n-1] = '\0';
if ( n > 0 && buf[n - 1] == '\n' )
buf[n - 1] = '\0';
line = buf;
return true;
@ -160,9 +158,8 @@ bool CPPHashManager::GetLine(FILE* f, string& line)
void CPPHashManager::BadLine(string& line)
{
reporter->Error("bad %s hash file entry: %s",
hash_name.c_str(), line.c_str());
reporter->Error("bad %s hash file entry: %s", hash_name.c_str(), line.c_str());
exit(1);
}
} // zeek::detail
} // zeek::detail

View file

@ -9,11 +9,14 @@
#pragma once
#include <stdio.h>
#include "zeek/script_opt/ProfileFunc.h"
namespace zeek::detail {
namespace zeek::detail
{
class CPPHashManager {
class CPPHashManager
{
public:
// Create a hash manager that uses the given name for
// referring to hash file(s). It's a "base" rather than
@ -27,46 +30,40 @@ public:
CPPHashManager(const char* hash_name_base, bool append);
~CPPHashManager();
bool IsAppend() const { return append; }
bool IsAppend() const { return append; }
// True if the given hash has already been generated.
bool HasHash(p_hash_type h) const
{ return previously_compiled.count(h) > 0; }
bool HasHash(p_hash_type h) const { return previously_compiled.count(h) > 0; }
// The internal (C++) name of a previously compiled function,
// as identified by its hash.
const std::string& FuncBodyName(p_hash_type h)
{ return previously_compiled[h]; }
const std::string& FuncBodyName(p_hash_type h) { return previously_compiled[h]; }
// Whether the given global has already been generated;
// and, if so, the hashes of its type and initialization
// value (used for consistency checking). Here the name
// is that used at the script level.
bool HasGlobal(const std::string& gl) const
{ return gl_type_hashes.count(gl) > 0; }
p_hash_type GlobalTypeHash(const std::string& gl)
{ return gl_type_hashes[gl]; }
p_hash_type GlobalValHash(const std::string& gl)
{ return gl_val_hashes[gl]; }
bool HasGlobal(const std::string& gl) const { return gl_type_hashes.count(gl) > 0; }
p_hash_type GlobalTypeHash(const std::string& gl) { return gl_type_hashes[gl]; }
p_hash_type GlobalValHash(const std::string& gl) { return gl_val_hashes[gl]; }
// Whether the given C++ global already exists, and, if so,
// in what scope.
bool HasGlobalVar(const std::string& gv) const
{ return gv_scopes.count(gv) > 0; }
int GlobalVarScope(const std::string& gv)
{ return gv_scopes[gv]; }
bool HasGlobalVar(const std::string& gv) const { return gv_scopes.count(gv) > 0; }
int GlobalVarScope(const std::string& gv) { return gv_scopes[gv]; }
// True if the given global corresponds to a record type
// or an enum type. Used to suppress complaints about
// definitional inconsistencies for extensible types.
bool HasRecordTypeGlobal(const std::string& rt) const
{ return record_type_globals.count(rt) > 0; }
bool HasEnumTypeGlobal(const std::string& et) const
{ return enum_type_globals.count(et) > 0; }
{
return record_type_globals.count(rt) > 0;
}
bool HasEnumTypeGlobal(const std::string& et) const { return enum_type_globals.count(et) > 0; }
// Access to the file we're writing hashes to, so that the
// compiler can add new entries to it.
FILE* HashFile() const { return hf_w; }
FILE* HashFile() const { return hf_w; }
protected:
// Parses an existing file with hash information.
@ -110,13 +107,17 @@ protected:
// We lock on the first
FILE* hf_r = nullptr;
FILE* hf_w = nullptr;
};
};
// Maps hashes to indices into C++ globals (like "types_N__CPP"), and
// namespace scopes.
struct CompiledItemPair { int index; int scope; };
struct CompiledItemPair
{
int index;
int scope;
};
using VarMapper = std::unordered_map<p_hash_type, CompiledItemPair>;
extern VarMapper compiled_items;
} // zeek::detail
} // zeek::detail

View file

@ -1,16 +1,16 @@
// See the file "COPYING" in the main distribution directory for copyright.
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <unistd.h>
#include "zeek/module_util.h"
#include "zeek/script_opt/ProfileFunc.h"
#include "zeek/script_opt/IDOptInfo.h"
#include "zeek/script_opt/CPP/Compile.h"
#include "zeek/script_opt/IDOptInfo.h"
#include "zeek/script_opt/ProfileFunc.h"
namespace zeek::detail {
namespace zeek::detail
{
using namespace std;
@ -36,7 +36,9 @@ void CPPCompile::GenInitExpr(const ExprPtr& e)
Emit("%s_cl() : CPPFunc(\"%s\", %s)", name, name, e->IsPure() ? "true" : "false");
StartBlock();
Emit("type = make_intrusive<FuncType>(make_intrusive<RecordType>(new type_decl_list()), %s, FUNC_FLAVOR_FUNCTION);", GenTypeName(t));
Emit("type = make_intrusive<FuncType>(make_intrusive<RecordType>(new type_decl_list()), %s, "
"FUNC_FLAVOR_FUNCTION);",
GenTypeName(t));
NoteInitDependency(e, TypeRep(t));
EndBlock();
@ -62,33 +64,36 @@ void CPPCompile::GenInitExpr(const ExprPtr& e)
Emit("CallExprPtr %s;", ename);
NoteInitDependency(e, TypeRep(t));
AddInit(e, ename, string("make_intrusive<CallExpr>(make_intrusive<ConstExpr>(make_intrusive<FuncVal>(make_intrusive<") +
name + "_cl>())), make_intrusive<ListExpr>(), false)");
AddInit(e, ename,
string("make_intrusive<CallExpr>(make_intrusive<ConstExpr>(make_intrusive<FuncVal>("
"make_intrusive<") +
name + "_cl>())), make_intrusive<ListExpr>(), false)");
}
bool CPPCompile::IsSimpleInitExpr(const ExprPtr& e) const
{
switch ( e->Tag() ) {
case EXPR_CONST:
case EXPR_NAME:
return true;
switch ( e->Tag() )
{
case EXPR_CONST:
case EXPR_NAME:
return true;
case EXPR_RECORD_COERCE:
{ // look for coercion of empty record
auto op = e->GetOp1();
case EXPR_RECORD_COERCE:
{ // look for coercion of empty record
auto op = e->GetOp1();
if ( op->Tag() != EXPR_RECORD_CONSTRUCTOR )
if ( op->Tag() != EXPR_RECORD_CONSTRUCTOR )
return false;
auto rc = static_cast<const RecordConstructorExpr*>(op.get());
const auto& exprs = rc->Op()->AsListExpr()->Exprs();
return exprs.length() == 0;
}
default:
return false;
auto rc = static_cast<const RecordConstructorExpr*>(op.get());
const auto& exprs = rc->Op()->AsListExpr()->Exprs();
return exprs.length() == 0;
}
default:
return false;
}
}
string CPPCompile::InitExprName(const ExprPtr& e)
@ -182,8 +187,8 @@ void CPPCompile::GenFuncVarInits()
hashes += "}";
auto init = string("lookup_func__CPP(\"") + fn +
"\", " + hashes + ", " + GenTypeName(ft) + ")";
auto init =
string("lookup_func__CPP(\"") + fn + "\", " + hashes + ", " + GenTypeName(ft) + ")";
AddInit(fv, const_name, init);
}
@ -193,70 +198,69 @@ void CPPCompile::GenPreInit(const Type* t)
{
string pre_init;
switch ( t->Tag() ) {
case TYPE_ADDR:
case TYPE_ANY:
case TYPE_BOOL:
case TYPE_COUNT:
case TYPE_DOUBLE:
case TYPE_ERROR:
case TYPE_INT:
case TYPE_INTERVAL:
case TYPE_PATTERN:
case TYPE_PORT:
case TYPE_STRING:
case TYPE_TIME:
case TYPE_TIMER:
case TYPE_VOID:
pre_init = string("base_type(") + TypeTagName(t->Tag()) + ")";
break;
case TYPE_ENUM:
pre_init = string("get_enum_type__CPP(\"") +
t->GetName() + "\")";
break;
case TYPE_SUBNET:
pre_init = string("make_intrusive<SubNetType>()");
break;
case TYPE_FILE:
pre_init = string("make_intrusive<FileType>(") +
GenTypeName(t->AsFileType()->Yield()) + ")";
break;
case TYPE_OPAQUE:
pre_init = string("make_intrusive<OpaqueType>(\"") +
t->AsOpaqueType()->Name() + "\")";
break;
case TYPE_RECORD:
switch ( t->Tag() )
{
string name;
case TYPE_ADDR:
case TYPE_ANY:
case TYPE_BOOL:
case TYPE_COUNT:
case TYPE_DOUBLE:
case TYPE_ERROR:
case TYPE_INT:
case TYPE_INTERVAL:
case TYPE_PATTERN:
case TYPE_PORT:
case TYPE_STRING:
case TYPE_TIME:
case TYPE_TIMER:
case TYPE_VOID:
pre_init = string("base_type(") + TypeTagName(t->Tag()) + ")";
break;
if ( t->GetName() != "" )
name = string("\"") + t->GetName() + string("\"");
else
name = "nullptr";
case TYPE_ENUM:
pre_init = string("get_enum_type__CPP(\"") + t->GetName() + "\")";
break;
pre_init = string("get_record_type__CPP(") + name + ")";
case TYPE_SUBNET:
pre_init = string("make_intrusive<SubNetType>()");
break;
case TYPE_FILE:
pre_init =
string("make_intrusive<FileType>(") + GenTypeName(t->AsFileType()->Yield()) + ")";
break;
case TYPE_OPAQUE:
pre_init = string("make_intrusive<OpaqueType>(\"") + t->AsOpaqueType()->Name() + "\")";
break;
case TYPE_RECORD:
{
string name;
if ( t->GetName() != "" )
name = string("\"") + t->GetName() + string("\"");
else
name = "nullptr";
pre_init = string("get_record_type__CPP(") + name + ")";
}
break;
case TYPE_LIST:
pre_init = string("make_intrusive<TypeList>()");
break;
case TYPE_TYPE:
case TYPE_VECTOR:
case TYPE_TABLE:
case TYPE_FUNC:
// Nothing to do for these, pre-initialization-wise.
return;
default:
reporter->InternalError("bad type in CPPCompile::GenType");
}
break;
case TYPE_LIST:
pre_init = string("make_intrusive<TypeList>()");
break;
case TYPE_TYPE:
case TYPE_VECTOR:
case TYPE_TABLE:
case TYPE_FUNC:
// Nothing to do for these, pre-initialization-wise.
return;
default:
reporter->InternalError("bad type in CPPCompile::GenType");
}
pre_inits.emplace_back(GenTypeName(t) + " = " + pre_init + ";");
}
@ -296,8 +300,7 @@ void CPPCompile::CheckInitConsistency(unordered_set<const Obj*>& to_do)
if ( to_do.count(o) == 0 )
{
fprintf(stderr, "object not in to_do: %s\n",
obj_desc(o).c_str());
fprintf(stderr, "object not in to_do: %s\n", obj_desc(o).c_str());
exit(1);
}
@ -305,8 +308,8 @@ void CPPCompile::CheckInitConsistency(unordered_set<const Obj*>& to_do)
{
if ( to_do.count(d) == 0 )
{
fprintf(stderr, "dep object for %s not in to_do: %s\n",
obj_desc(o).c_str(), obj_desc(d).c_str());
fprintf(stderr, "dep object for %s not in to_do: %s\n", obj_desc(o).c_str(),
obj_desc(d).c_str());
exit(1);
}
}
@ -430,14 +433,12 @@ void CPPCompile::InitializeEnumMappings()
InitializeEnumMappings(mapping.first, mapping.second, n++);
}
void CPPCompile::InitializeEnumMappings(const EnumType* et,
const string& e_name, int index)
void CPPCompile::InitializeEnumMappings(const EnumType* et, const string& e_name, int index)
{
AddInit(et, "{");
auto et_name = GenTypeName(et) + "->AsEnumType()";
AddInit(et, "int em_offset = " + et_name +
"->Lookup(\"" + e_name + "\");");
AddInit(et, "int em_offset = " + et_name + "->Lookup(\"" + e_name + "\");");
AddInit(et, "if ( em_offset < 0 )");
AddInit(et, "\t{");
@ -445,9 +446,10 @@ void CPPCompile::InitializeEnumMappings(const EnumType* et,
// The following is to catch the case where the offset is already
// in use due to it being specified explicitly for an existing enum.
AddInit(et, "\tif ( " + et_name + "->Lookup(em_offset) )");
AddInit(et, "\t\treporter->InternalError(\"enum inconsistency while initializing compiled scripts\");");
AddInit(et, "\t" + et_name +
"->AddNameInternal(\"" + e_name + "\", em_offset);");
AddInit(
et,
"\t\treporter->InternalError(\"enum inconsistency while initializing compiled scripts\");");
AddInit(et, "\t" + et_name + "->AddNameInternal(\"" + e_name + "\", em_offset);");
AddInit(et, "\t}");
AddInit(et, "enum_mapping[" + Fmt(index) + "] = em_offset;");
@ -468,7 +470,7 @@ void CPPCompile::GenInitHook()
if ( standalone )
GenLoad();
Emit("return 0;");
Emit("return 0;");
EndBlock();
// Trigger the activation of the hook at run-time.
@ -534,15 +536,14 @@ void CPPCompile::GenStandaloneActivation()
auto mod = extract_module_name(fn);
module_names.insert(mod);
auto fid = lookup_ID(var.c_str(), mod.c_str(),
false, true, false);
auto fid = lookup_ID(var.c_str(), mod.c_str(), false, true, false);
if ( ! fid )
reporter->InternalError("can't find identifier %s", fn);
auto exported = fid->IsExport() ? "true" : "false";
Emit("activate_bodies__CPP(\"%s\", \"%s\", %s, %s, %s);",
var, mod, exported, GenTypeName(ft), hashes);
Emit("activate_bodies__CPP(\"%s\", \"%s\", %s, %s, %s);", var, mod, exported,
GenTypeName(ft), hashes);
}
NL();
@ -571,8 +572,7 @@ void CPPCompile::GenLoad()
if ( module_names.size() > 0 )
printf("module GLOBAL;\n\n");
printf("global init_CPP_%llu = load_CPP(%llu);\n",
total_hash, total_hash);
printf("global init_CPP_%llu = load_CPP(%llu);\n", total_hash, total_hash);
}
} // zeek::detail
} // zeek::detail

View file

@ -2,27 +2,28 @@
#pragma once
#include "zeek/module_util.h"
#include "zeek/ZeekString.h"
#include "zeek/Func.h"
#include "zeek/File.h"
#include "zeek/Frame.h"
#include "zeek/Scope.h"
#include "zeek/RE.h"
#include "zeek/IPAddr.h"
#include "zeek/Val.h"
#include "zeek/OpaqueVal.h"
#include "zeek/Expr.h"
#include "zeek/Event.h"
#include "zeek/EventRegistry.h"
#include "zeek/Expr.h"
#include "zeek/File.h"
#include "zeek/Frame.h"
#include "zeek/Func.h"
#include "zeek/IPAddr.h"
#include "zeek/OpaqueVal.h"
#include "zeek/RE.h"
#include "zeek/RunState.h"
#include "zeek/script_opt/ScriptOpt.h"
#include "zeek/Scope.h"
#include "zeek/Val.h"
#include "zeek/ZeekString.h"
#include "zeek/module_util.h"
#include "zeek/script_opt/CPP/Func.h"
#include "zeek/script_opt/CPP/RuntimeInit.h"
#include "zeek/script_opt/CPP/RuntimeOps.h"
#include "zeek/script_opt/CPP/RuntimeVec.h"
#include "zeek/script_opt/ScriptOpt.h"
namespace zeek {
namespace zeek
{
using BoolValPtr = IntrusivePtr<zeek::BoolVal>;
using CountValPtr = IntrusivePtr<zeek::CountVal>;
@ -34,4 +35,4 @@ using FuncValPtr = IntrusivePtr<zeek::FuncVal>;
using FileValPtr = IntrusivePtr<zeek::FileVal>;
using SubNetValPtr = IntrusivePtr<zeek::SubNetVal>;
}
}

View file

@ -1,10 +1,12 @@
// See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/module_util.h"
#include "zeek/EventRegistry.h"
#include "zeek/script_opt/CPP/RuntimeInit.h"
namespace zeek::detail {
#include "zeek/EventRegistry.h"
#include "zeek/module_util.h"
namespace zeek::detail
{
using namespace std;
@ -47,7 +49,6 @@ static int flag_init_CPP()
static int dummy = flag_init_CPP();
void register_type__CPP(TypePtr t, const std::string& name)
{
if ( t->GetName().size() > 0 )
@ -61,14 +62,13 @@ void register_type__CPP(TypePtr t, const std::string& name)
id->MakeType();
}
void register_body__CPP(CPPStmtPtr body, int priority, p_hash_type hash,
vector<string> events)
void register_body__CPP(CPPStmtPtr body, int priority, p_hash_type hash, vector<string> events)
{
compiled_scripts[hash] = { move(body), priority, move(events) };
compiled_scripts[hash] = {move(body), priority, move(events)};
}
void register_lambda__CPP(CPPStmtPtr body, p_hash_type hash, const char* name,
TypePtr t, bool has_captures)
void register_lambda__CPP(CPPStmtPtr body, p_hash_type hash, const char* name, TypePtr t,
bool has_captures)
{
auto ft = cast_intrusive<FuncType>(t);
@ -98,8 +98,8 @@ void register_scripts__CPP(p_hash_type h, void (*callback)())
standalone_callbacks[h] = callback;
}
void activate_bodies__CPP(const char* fn, const char* module, bool exported,
TypePtr t, vector<p_hash_type> hashes)
void activate_bodies__CPP(const char* fn, const char* module, bool exported, TypePtr t,
vector<p_hash_type> hashes)
{
auto ft = cast_intrusive<FuncType>(t);
auto fg = lookup_ID(fn, module, false, false, false);
@ -115,8 +115,7 @@ void activate_bodies__CPP(const char* fn, const char* module, bool exported,
{ // Create it.
std::vector<StmtPtr> no_bodies;
std::vector<int> no_priorities;
auto sf = make_intrusive<ScriptFunc>(fn, ft, no_bodies,
no_priorities);
auto sf = make_intrusive<ScriptFunc>(fn, ft, no_bodies, no_priorities);
v = make_intrusive<FuncVal>(move(sf));
fg->SetVal(v);
@ -143,7 +142,7 @@ void activate_bodies__CPP(const char* fn, const char* module, bool exported,
if ( ft->Flavor() == FUNC_FLAVOR_EVENT )
events.insert(fn);
vector<detail::IDPtr> no_inits; // empty initialization vector
vector<detail::IDPtr> no_inits; // empty initialization vector
int num_params = ft->Params()->NumFields();
for ( auto h : hashes )
@ -190,8 +189,7 @@ Func* lookup_bif__CPP(const char* bif)
return b ? b->GetVal()->AsFunc() : nullptr;
}
FuncValPtr lookup_func__CPP(string name, vector<p_hash_type> hashes,
const TypePtr& t)
FuncValPtr lookup_func__CPP(string name, vector<p_hash_type> hashes, const TypePtr& t)
{
auto ft = cast_intrusive<FuncType>(t);
@ -216,20 +214,17 @@ FuncValPtr lookup_func__CPP(string name, vector<p_hash_type> hashes,
}
}
auto sf = make_intrusive<ScriptFunc>(move(name), move(ft), move(bodies),
move(priorities));
auto sf = make_intrusive<ScriptFunc>(move(name), move(ft), move(bodies), move(priorities));
return make_intrusive<FuncVal>(move(sf));
}
RecordTypePtr get_record_type__CPP(const char* record_type_name)
{
IDPtr existing_type;
if ( record_type_name &&
(existing_type = global_scope()->Find(record_type_name)) &&
existing_type->GetType()->Tag() == TYPE_RECORD )
if ( record_type_name && (existing_type = global_scope()->Find(record_type_name)) &&
existing_type->GetType()->Tag() == TYPE_RECORD )
return cast_intrusive<RecordType>(existing_type->GetType());
return make_intrusive<RecordType>(new type_decl_list());
@ -251,4 +246,4 @@ EnumValPtr make_enum__CPP(TypePtr t, int i)
return make_intrusive<EnumVal>(et, i);
}
} // namespace zeek::detail
} // namespace zeek::detail

View file

@ -7,11 +7,13 @@
#include "zeek/Val.h"
#include "zeek/script_opt/CPP/Func.h"
namespace zeek {
namespace zeek
{
using FuncValPtr = IntrusivePtr<zeek::FuncVal>;
namespace detail {
namespace detail
{
// An initialization hook for a collection of compiled-to-C++ functions
// (the result of a single invocation of the compiler on a set of scripts).
@ -39,8 +41,7 @@ extern void register_body__CPP(CPPStmtPtr body, int priority, p_hash_type hash,
// Registers a lambda body as associated with the given hash. Includes
// the name of the lambda (so it can be made available as a quasi-global
// identifier), its type, and whether it needs captures.
extern void register_lambda__CPP(CPPStmtPtr body, p_hash_type hash,
const char* name, TypePtr t,
extern void register_lambda__CPP(CPPStmtPtr body, p_hash_type hash, const char* name, TypePtr t,
bool has_captures);
// Registers a callback for activating a set of scripts associated with
@ -51,8 +52,7 @@ extern void register_scripts__CPP(p_hash_type h, void (*callback)());
// the given module, using (at least) the bodies associated with the
// given hashes. Creates the identifier using the given module and
// export setting if it doesn't already exist.
extern void activate_bodies__CPP(const char* fn, const char* module,
bool exported, TypePtr t,
extern void activate_bodies__CPP(const char* fn, const char* module, bool exported, TypePtr t,
std::vector<p_hash_type> hashes);
// Looks for a global with the given name. If not present, creates it
@ -66,8 +66,7 @@ extern Func* lookup_bif__CPP(const char* bif);
// returns an associated FuncVal. It's a fatal error for the hash
// not to exist, because this function should only be called by compiled
// code that has ensured its existence.
extern FuncValPtr lookup_func__CPP(std::string name, std::vector<p_hash_type> h,
const TypePtr& t);
extern FuncValPtr lookup_func__CPP(std::string name, std::vector<p_hash_type> h, const TypePtr& t);
// Returns the record corresponding to the given name, as long as the
// name is indeed a record type. Otherwise (or if the name is nil)
@ -83,5 +82,5 @@ extern EnumTypePtr get_enum_type__CPP(const std::string& enum_type_name);
// in the context of the given enum type 't'.
extern EnumValPtr make_enum__CPP(TypePtr t, int i);
} // namespace zeek::detail
} // namespace zeek
} // namespace zeek::detail
} // namespace zeek

View file

@ -1,12 +1,14 @@
// See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/ZeekString.h"
#include "zeek/RunState.h"
#include "zeek/EventRegistry.h"
#include "zeek/IPAddr.h"
#include "zeek/script_opt/CPP/RuntimeOps.h"
namespace zeek::detail {
#include "zeek/EventRegistry.h"
#include "zeek/IPAddr.h"
#include "zeek/RunState.h"
#include "zeek/ZeekString.h"
namespace zeek::detail
{
using namespace std;
@ -55,8 +57,7 @@ ValPtr index_vec__CPP(const VectorValPtr& vec, int index)
ValPtr index_string__CPP(const StringValPtr& svp, vector<ValPtr> indices)
{
return index_string(svp->AsString(),
index_val__CPP(move(indices)).get());
return index_string(svp->AsString(), index_val__CPP(move(indices)).get());
}
ValPtr set_event__CPP(IDPtr g, ValPtr v, EventHandlerPtr& gh)
@ -71,7 +72,7 @@ ValPtr cast_value_to_type__CPP(const ValPtr& v, const TypePtr& t)
auto result = cast_value_to_type(v.get(), t.get());
if ( ! result )
reporter->CPPRuntimeError("invalid cast of value with type '%s' to type '%s'",
type_name(v->GetType()->Tag()), type_name(t->Tag()));
type_name(v->GetType()->Tag()), type_name(t->Tag()));
return result;
}
@ -80,8 +81,8 @@ ValPtr from_any__CPP(const ValPtr& v, const TypePtr& t)
auto vt = v->GetType()->Tag();
if ( vt != t->Tag() && vt != TYPE_ERROR )
reporter->CPPRuntimeError("incompatible \"any\" type (%s vs. %s)",
type_name(vt), type_name(t->Tag()));
reporter->CPPRuntimeError("incompatible \"any\" type (%s vs. %s)", type_name(vt),
type_name(t->Tag()));
return v;
}
@ -96,21 +97,20 @@ ValPtr from_any_vec__CPP(const ValPtr& v, const TypePtr& t)
SubNetValPtr addr_mask__CPP(const IPAddr& a, uint32_t mask)
{
if ( a.GetFamily() == IPv4 )
{
if ( mask > 32 )
reporter->CPPRuntimeError("bad IPv4 subnet prefix length: %d", int(mask));
}
else
{
if ( mask > 128 )
reporter->CPPRuntimeError("bad IPv6 subnet prefix length: %d", int(mask));
}
if ( a.GetFamily() == IPv4 )
{
if ( mask > 32 )
reporter->CPPRuntimeError("bad IPv4 subnet prefix length: %d", int(mask));
}
else
{
if ( mask > 128 )
reporter->CPPRuntimeError("bad IPv6 subnet prefix length: %d", int(mask));
}
return make_intrusive<SubNetVal>(a, mask);
return make_intrusive<SubNetVal>(a, mask);
}
// Helper function for reporting invalidation of interators.
static void check_iterators__CPP(bool invalid)
{
@ -119,8 +119,7 @@ static void check_iterators__CPP(bool invalid)
}
// Template for aggregate assignments of the form "v1[v2] = v3".
template <typename T>
ValPtr assign_to_index__CPP(T v1, ValPtr v2, ValPtr v3)
template <typename T> ValPtr assign_to_index__CPP(T v1, ValPtr v2, ValPtr v3)
{
bool iterators_invalidated = false;
auto err_msg = assign_to_index(move(v1), move(v2), v3, iterators_invalidated);
@ -164,8 +163,7 @@ void remove_element__CPP(TableValPtr aggr, ListValPtr indices)
// and values and returns a collective AttributesPtr corresponding to
// those instantiated attributes. For attributes that don't have
// associated expressions, the correspoinding value should be nil.
static AttributesPtr build_attrs__CPP(vector<int> attr_tags,
vector<ValPtr> attr_vals)
static AttributesPtr build_attrs__CPP(vector<int> attr_tags, vector<ValPtr> attr_vals)
{
vector<AttrPtr> attrs;
int nattrs = attr_tags.size();
@ -184,8 +182,7 @@ static AttributesPtr build_attrs__CPP(vector<int> attr_tags,
return make_intrusive<Attributes>(move(attrs), nullptr, false, false);
}
TableValPtr set_constructor__CPP(vector<ValPtr> elements, TableTypePtr t,
vector<int> attr_tags,
TableValPtr set_constructor__CPP(vector<ValPtr> elements, TableTypePtr t, vector<int> attr_tags,
vector<ValPtr> attr_vals)
{
auto attrs = build_attrs__CPP(move(attr_tags), move(attr_vals));
@ -197,9 +194,8 @@ TableValPtr set_constructor__CPP(vector<ValPtr> elements, TableTypePtr t,
return aggr;
}
TableValPtr table_constructor__CPP(vector<ValPtr> indices, vector<ValPtr> vals,
TableTypePtr t, vector<int> attr_tags,
vector<ValPtr> attr_vals)
TableValPtr table_constructor__CPP(vector<ValPtr> indices, vector<ValPtr> vals, TableTypePtr t,
vector<int> attr_tags, vector<ValPtr> attr_vals)
{
const auto& yt = t->Yield().get();
auto n = indices.size();
@ -247,4 +243,4 @@ ValPtr schedule__CPP(double dt, EventHandlerPtr event, vector<ValPtr> args)
return nullptr;
}
} // namespace zeek::detail
} // namespace zeek::detail

View file

@ -7,11 +7,13 @@
#include "zeek/Val.h"
#include "zeek/script_opt/CPP/Func.h"
namespace zeek {
namespace zeek
{
using SubNetValPtr = IntrusivePtr<zeek::SubNetVal>;
namespace detail {
namespace detail
{
// Returns the concatenation of the given strings.
extern StringValPtr str_concat__CPP(const String* s1, const String* s2);
@ -108,8 +110,7 @@ inline TableValPtr table_coerce__CPP(const ValPtr& v, const TypePtr& t)
if ( tv->Size() > 0 )
reporter->CPPRuntimeError("coercion of non-empty table/set");
return make_intrusive<TableVal>(cast_intrusive<TableType>(t),
tv->GetAttrs());
return make_intrusive<TableVal>(cast_intrusive<TableType>(t), tv->GetAttrs());
}
// The same, for an empty record.
@ -125,34 +126,27 @@ inline VectorValPtr vector_coerce__CPP(const ValPtr& v, const TypePtr& t)
// Constructs a set of the given type, containing the given elements, and
// with the associated attributes.
extern TableValPtr set_constructor__CPP(std::vector<ValPtr> elements,
TableTypePtr t,
std::vector<int> attr_tags,
std::vector<ValPtr> attr_vals);
extern TableValPtr set_constructor__CPP(std::vector<ValPtr> elements, TableTypePtr t,
std::vector<int> attr_tags, std::vector<ValPtr> attr_vals);
// Constructs a table of the given type, containing the given elements
// (specified as parallel index/value vectors), and with the associated
// attributes.
extern TableValPtr table_constructor__CPP(std::vector<ValPtr> indices,
std::vector<ValPtr> vals,
TableTypePtr t,
std::vector<int> attr_tags,
extern TableValPtr table_constructor__CPP(std::vector<ValPtr> indices, std::vector<ValPtr> vals,
TableTypePtr t, std::vector<int> attr_tags,
std::vector<ValPtr> attr_vals);
// Constructs a record of the given type, whose (ordered) fields are
// assigned to the corresponding elements of the given vector of values.
extern RecordValPtr record_constructor__CPP(std::vector<ValPtr> vals,
RecordTypePtr t);
extern RecordValPtr record_constructor__CPP(std::vector<ValPtr> vals, RecordTypePtr t);
// Constructs a vector of the given type, populated with the given values.
extern VectorValPtr vector_constructor__CPP(std::vector<ValPtr> vals,
VectorTypePtr t);
extern VectorValPtr vector_constructor__CPP(std::vector<ValPtr> vals, VectorTypePtr t);
// Schedules an event to occur at the given absolute time, parameterized
// with the given set of values. A separate function to facilitate avoiding
// the scheduling if Zeek is terminating.
extern ValPtr schedule__CPP(double dt, EventHandlerPtr event,
std::vector<ValPtr> args);
extern ValPtr schedule__CPP(double dt, EventHandlerPtr event, std::vector<ValPtr> args);
// Simple helper functions for supporting absolute value.
inline bro_uint_t iabs__CPP(bro_int_t v)
@ -202,5 +196,5 @@ inline double fdiv__CPP(double v1, double v2)
return v1 / v2;
}
} // namespace zeek::detail
} // namespace zeek
} // namespace zeek::detail
} // namespace zeek

View file

@ -1,9 +1,11 @@
// See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/ZeekString.h"
#include "zeek/script_opt/CPP/RuntimeVec.h"
namespace zeek::detail {
#include "zeek/ZeekString.h"
namespace zeek::detail
{
using namespace std;
@ -25,27 +27,28 @@ static bool check_vec_sizes__CPP(const VectorValPtr& v1, const VectorValPtr& v2)
// convert the vector to the high-level representation if needed.
static VectorTypePtr base_vector_type__CPP(const VectorTypePtr& vt)
{
switch ( vt->Yield()->InternalType() ) {
case TYPE_INTERNAL_INT:
return make_intrusive<VectorType>(base_type(TYPE_INT));
switch ( vt->Yield()->InternalType() )
{
case TYPE_INTERNAL_INT:
return make_intrusive<VectorType>(base_type(TYPE_INT));
case TYPE_INTERNAL_UNSIGNED:
return make_intrusive<VectorType>(base_type(TYPE_COUNT));
case TYPE_INTERNAL_UNSIGNED:
return make_intrusive<VectorType>(base_type(TYPE_COUNT));
case TYPE_INTERNAL_DOUBLE:
return make_intrusive<VectorType>(base_type(TYPE_DOUBLE));
case TYPE_INTERNAL_DOUBLE:
return make_intrusive<VectorType>(base_type(TYPE_DOUBLE));
default:
return nullptr;
}
default:
return nullptr;
}
}
// The kernel used for unary vector operations.
#define VEC_OP1_KERNEL(accessor, type, op) \
for ( unsigned int i = 0; i < v->Size(); ++i ) \
{ \
auto v_i = v->ValAt(i)->accessor(); \
v_result->Assign(i, make_intrusive<type>(op v_i)); \
#define VEC_OP1_KERNEL(accessor, type, op) \
for ( unsigned int i = 0; i < v->Size(); ++i ) \
{ \
auto v_i = v->ValAt(i)->accessor(); \
v_result->Assign(i, make_intrusive<type>(op v_i)); \
}
// A macro (since it's beyond my templating skillz to deal with the
@ -54,145 +57,156 @@ static VectorTypePtr base_vector_type__CPP(const VectorTypePtr& vt)
// is an optional kernel to use for vectors whose underlying type
// is "double". It needs to be optional because C++ will (rightfully)
// complain about applying certain C++ unary operations to doubles.
#define VEC_OP1(name, op, double_kernel) \
VectorValPtr vec_op_ ## name ## __CPP(const VectorValPtr& v) \
{ \
auto vt = base_vector_type__CPP(v->GetType<VectorType>()); \
auto v_result = make_intrusive<VectorVal>(vt); \
\
switch ( vt->Yield()->InternalType() ) { \
case TYPE_INTERNAL_INT: \
{ \
VEC_OP1_KERNEL(AsInt, IntVal, op) \
break; \
} \
\
case TYPE_INTERNAL_UNSIGNED: \
{ \
VEC_OP1_KERNEL(AsCount, CountVal, op) \
break; \
} \
\
double_kernel \
\
default: \
break; \
} \
\
return v_result; \
}
#define VEC_OP1(name, op, double_kernel) \
VectorValPtr vec_op_##name##__CPP(const VectorValPtr& v) \
{ \
auto vt = base_vector_type__CPP(v->GetType<VectorType>()); \
auto v_result = make_intrusive<VectorVal>(vt); \
\
switch ( vt->Yield()->InternalType() ) \
{ \
case TYPE_INTERNAL_INT: \
{ \
VEC_OP1_KERNEL(AsInt, IntVal, op) \
break; \
} \
\
case TYPE_INTERNAL_UNSIGNED: \
{ \
VEC_OP1_KERNEL(AsCount, CountVal, op) \
break; \
} \
\
double_kernel \
\
default : break; \
} \
\
return v_result; \
}
// Instantiates a double_kernel for a given operation.
#define VEC_OP1_WITH_DOUBLE(name, op) \
VEC_OP1(name, op, case TYPE_INTERNAL_DOUBLE: { VEC_OP1_KERNEL(AsDouble, DoubleVal, op) break; })
#define VEC_OP1_WITH_DOUBLE(name, op) \
VEC_OP1( \
name, op, case TYPE_INTERNAL_DOUBLE \
: \
{ \
VEC_OP1_KERNEL(AsDouble, DoubleVal, op) break; \
})
// The unary operations supported for vectors.
VEC_OP1_WITH_DOUBLE(pos, +)
VEC_OP1_WITH_DOUBLE(neg, -)
VEC_OP1(not, !,)
VEC_OP1(comp, ~,)
VEC_OP1(not, !, )
VEC_OP1(comp, ~, )
// A kernel for applying a binary operation element-by-element to two
// vectors of a given low-level type.
#define VEC_OP2_KERNEL(accessor, type, op) \
for ( unsigned int i = 0; i < v1->Size(); ++i ) \
{ \
auto v1_i = v1->ValAt(i)->accessor(); \
auto v2_i = v2->ValAt(i)->accessor(); \
v_result->Assign(i, make_intrusive<type>(v1_i op v2_i)); \
#define VEC_OP2_KERNEL(accessor, type, op) \
for ( unsigned int i = 0; i < v1->Size(); ++i ) \
{ \
auto v1_i = v1->ValAt(i)->accessor(); \
auto v2_i = v2->ValAt(i)->accessor(); \
v_result->Assign(i, make_intrusive<type>(v1_i op v2_i)); \
}
// Analogous to VEC_OP1, instantiates a function for a given binary operation,
// which might-or-might-not be supported for low-level "double" types.
// This version is for operations whose result type is the same as the
// operand type.
#define VEC_OP2(name, op, double_kernel) \
VectorValPtr vec_op_ ## name ## __CPP(const VectorValPtr& v1, const VectorValPtr& v2) \
{ \
if ( ! check_vec_sizes__CPP(v1, v2) ) \
return nullptr; \
\
auto vt = base_vector_type__CPP(v1->GetType<VectorType>()); \
auto v_result = make_intrusive<VectorVal>(vt); \
\
switch ( vt->Yield()->InternalType() ) { \
case TYPE_INTERNAL_INT: \
{ \
if ( vt->Yield()->Tag() == TYPE_BOOL ) \
VEC_OP2_KERNEL(AsBool, BoolVal, op) \
else \
VEC_OP2_KERNEL(AsInt, IntVal, op) \
break; \
} \
\
case TYPE_INTERNAL_UNSIGNED: \
{ \
VEC_OP2_KERNEL(AsCount, CountVal, op) \
break; \
} \
\
double_kernel \
\
default: \
break; \
} \
\
return v_result; \
}
#define VEC_OP2(name, op, double_kernel) \
VectorValPtr vec_op_##name##__CPP(const VectorValPtr& v1, const VectorValPtr& v2) \
{ \
if ( ! check_vec_sizes__CPP(v1, v2) ) \
return nullptr; \
\
auto vt = base_vector_type__CPP(v1->GetType<VectorType>()); \
auto v_result = make_intrusive<VectorVal>(vt); \
\
switch ( vt->Yield()->InternalType() ) \
{ \
case TYPE_INTERNAL_INT: \
{ \
if ( vt->Yield()->Tag() == TYPE_BOOL ) \
VEC_OP2_KERNEL(AsBool, BoolVal, op) \
else \
VEC_OP2_KERNEL(AsInt, IntVal, op) \
break; \
} \
\
case TYPE_INTERNAL_UNSIGNED: \
{ \
VEC_OP2_KERNEL(AsCount, CountVal, op) \
break; \
} \
\
double_kernel \
\
default : break; \
} \
\
return v_result; \
}
// Instantiates a double_kernel for a binary operation.
#define VEC_OP2_WITH_DOUBLE(name, op) \
VEC_OP2(name, op, case TYPE_INTERNAL_DOUBLE: { VEC_OP2_KERNEL(AsDouble, DoubleVal, op) break; })
#define VEC_OP2_WITH_DOUBLE(name, op) \
VEC_OP2( \
name, op, case TYPE_INTERNAL_DOUBLE \
: \
{ \
VEC_OP2_KERNEL(AsDouble, DoubleVal, op) break; \
})
// The binary operations supported for vectors.
VEC_OP2_WITH_DOUBLE(add, +)
VEC_OP2_WITH_DOUBLE(sub, -)
VEC_OP2_WITH_DOUBLE(mul, *)
VEC_OP2_WITH_DOUBLE(div, /)
VEC_OP2(mod, %,)
VEC_OP2(and, &,)
VEC_OP2(or, |,)
VEC_OP2(xor, ^,)
VEC_OP2(andand, &&,)
VEC_OP2(oror, ||,)
VEC_OP2(mod, %, )
VEC_OP2(and, &, )
VEC_OP2(or, |, )
VEC_OP2(xor, ^, )
VEC_OP2(andand, &&, )
VEC_OP2(oror, ||, )
// A version of VEC_OP2 that instead supports relational operations, so
// the result type is always vector-of-bool.
#define VEC_REL_OP(name, op) \
VectorValPtr vec_op_ ## name ## __CPP(const VectorValPtr& v1, const VectorValPtr& v2) \
{ \
if ( ! check_vec_sizes__CPP(v1, v2) ) \
return nullptr; \
\
auto vt = v1->GetType<VectorType>(); \
auto res_type = make_intrusive<VectorType>(base_type(TYPE_BOOL)); \
auto v_result = make_intrusive<VectorVal>(res_type); \
\
switch ( vt->Yield()->InternalType() ) { \
case TYPE_INTERNAL_INT: \
{ \
VEC_OP2_KERNEL(AsInt, BoolVal, op) \
break; \
} \
\
case TYPE_INTERNAL_UNSIGNED: \
{ \
VEC_OP2_KERNEL(AsCount, BoolVal, op) \
break; \
} \
\
case TYPE_INTERNAL_DOUBLE: \
{ \
VEC_OP2_KERNEL(AsDouble, BoolVal, op) \
break; \
} \
\
default: \
break; \
} \
\
return v_result; \
}
#define VEC_REL_OP(name, op) \
VectorValPtr vec_op_##name##__CPP(const VectorValPtr& v1, const VectorValPtr& v2) \
{ \
if ( ! check_vec_sizes__CPP(v1, v2) ) \
return nullptr; \
\
auto vt = v1->GetType<VectorType>(); \
auto res_type = make_intrusive<VectorType>(base_type(TYPE_BOOL)); \
auto v_result = make_intrusive<VectorVal>(res_type); \
\
switch ( vt->Yield()->InternalType() ) \
{ \
case TYPE_INTERNAL_INT: \
{ \
VEC_OP2_KERNEL(AsInt, BoolVal, op) \
break; \
} \
\
case TYPE_INTERNAL_UNSIGNED: \
{ \
VEC_OP2_KERNEL(AsCount, BoolVal, op) \
break; \
} \
\
case TYPE_INTERNAL_DOUBLE: \
{ \
VEC_OP2_KERNEL(AsDouble, BoolVal, op) \
break; \
} \
\
default: \
break; \
} \
\
return v_result; \
}
// The relational operations supported for vectors.
VEC_REL_OP(lt, <)
@ -233,9 +247,8 @@ VectorValPtr vec_op_sub__CPP(VectorValPtr v, int i)
// are applied as though they appeared left-to-right in a statement
// "s1 + v2 + v3 + s4". For any invocation, v2 will always be
// non-nil, and one-and-only-one of s1, v3, or s4 will be non-nil.
static VectorValPtr str_vec_op_str_vec_add__CPP(const StringValPtr& s1,
const VectorValPtr& v2, const VectorValPtr& v3,
const StringValPtr& s4)
static VectorValPtr str_vec_op_str_vec_add__CPP(const StringValPtr& s1, const VectorValPtr& v2,
const VectorValPtr& v3, const StringValPtr& s4)
{
auto vt = v2->GetType<VectorType>();
auto v_result = make_intrusive<VectorVal>(vt);
@ -260,10 +273,13 @@ static VectorValPtr str_vec_op_str_vec_add__CPP(const StringValPtr& s1,
s3 = v3_i->AsString();
}
if ( s1 ) strings.push_back(s1->AsString());
if ( s1 )
strings.push_back(s1->AsString());
strings.push_back(s2);
if ( s3 ) strings.push_back(s3);
if ( s4 ) strings.push_back(s4->AsString());
if ( s3 )
strings.push_back(s3);
if ( s4 )
strings.push_back(s4->AsString());
auto res = make_intrusive<StringVal>(concatenate(strings));
v_result->Assign(i, res);
@ -290,9 +306,8 @@ VectorValPtr str_vec_op_add__CPP(const StringValPtr& s1, const VectorValPtr& v2)
// Kernel for element-by-element string relationals. "rel1" and "rel2"
// codify which relational (</<=/==/!=/>=/>) we're aiming to support,
// in terms of how a Bstr_cmp() comparison should be assessed.
static VectorValPtr str_vec_op_kernel__CPP(const VectorValPtr& v1,
const VectorValPtr& v2,
int rel1, int rel2)
static VectorValPtr str_vec_op_kernel__CPP(const VectorValPtr& v1, const VectorValPtr& v2, int rel1,
int rel2)
{
auto res_type = make_intrusive<VectorType>(base_type(TYPE_BOOL));
auto v_result = make_intrusive<VectorVal>(res_type);
@ -342,8 +357,7 @@ VectorValPtr str_vec_op_ge__CPP(const VectorValPtr& v1, const VectorValPtr& v2)
return str_vec_op_kernel__CPP(v1, v2, 0, 1);
}
VectorValPtr vector_select__CPP(const VectorValPtr& v1, VectorValPtr v2,
VectorValPtr v3)
VectorValPtr vector_select__CPP(const VectorValPtr& v1, VectorValPtr v2, VectorValPtr v3)
{
auto vt = v2->GetType<VectorType>();
auto v_result = make_intrusive<VectorVal>(vt);
@ -374,30 +388,31 @@ VectorValPtr vector_coerce_to__CPP(const VectorValPtr& v, const TypePtr& targ)
{
ValPtr v_i = v->ValAt(i);
ValPtr r_i;
switch ( ytag ) {
case TYPE_BOOL:
r_i = val_mgr->Bool(v_i->AsBool());
break;
switch ( ytag )
{
case TYPE_BOOL:
r_i = val_mgr->Bool(v_i->AsBool());
break;
case TYPE_ENUM:
r_i = yt->AsEnumType()->GetEnumVal(v_i->AsInt());
break;
case TYPE_ENUM:
r_i = yt->AsEnumType()->GetEnumVal(v_i->AsInt());
break;
case TYPE_PORT:
r_i = make_intrusive<PortVal>(v_i->AsCount());
break;
case TYPE_PORT:
r_i = make_intrusive<PortVal>(v_i->AsCount());
break;
case TYPE_INTERVAL:
r_i = make_intrusive<IntervalVal>(v_i->AsDouble());
break;
case TYPE_INTERVAL:
r_i = make_intrusive<IntervalVal>(v_i->AsDouble());
break;
case TYPE_TIME:
r_i = make_intrusive<TimeVal>(v_i->AsDouble());
break;
case TYPE_TIME:
r_i = make_intrusive<TimeVal>(v_i->AsDouble());
break;
default:
reporter->InternalError("bad vector type in vector_coerce_to__CPP");
}
default:
reporter->InternalError("bad vector type in vector_coerce_to__CPP");
}
v_result->Assign(i, move(r_i));
}
@ -441,4 +456,4 @@ VectorValPtr vec_coerce_to_double__CPP(const VectorValPtr& v, TypePtr targ)
return v_result;
}
} // namespace zeek::detail
} // namespace zeek::detail

View file

@ -10,7 +10,8 @@
#include "zeek/Val.h"
namespace zeek::detail {
namespace zeek::detail
{
// Appends v2 to the vector v1. A separate function because of the
// need to support assignment cascades.
@ -52,45 +53,31 @@ extern VectorValPtr vec_op_sub__CPP(VectorValPtr v, int i);
// ... and these for vector-plus-scalar and vector-plus-vector string
// operations.
extern VectorValPtr str_vec_op_add__CPP(const VectorValPtr& v1,
const VectorValPtr& v2);
extern VectorValPtr str_vec_op_add__CPP(const VectorValPtr& v1,
const StringValPtr& v2);
extern VectorValPtr str_vec_op_add__CPP(const StringValPtr& v1,
const VectorValPtr& v2);
extern VectorValPtr str_vec_op_add__CPP(const VectorValPtr& v1, const VectorValPtr& v2);
extern VectorValPtr str_vec_op_add__CPP(const VectorValPtr& v1, const StringValPtr& v2);
extern VectorValPtr str_vec_op_add__CPP(const StringValPtr& v1, const VectorValPtr& v2);
// String vector relationals.
extern VectorValPtr str_vec_op_lt__CPP(const VectorValPtr& v1,
const VectorValPtr& v2);
extern VectorValPtr str_vec_op_le__CPP(const VectorValPtr& v1,
const VectorValPtr& v2);
extern VectorValPtr str_vec_op_eq__CPP(const VectorValPtr& v1,
const VectorValPtr& v2);
extern VectorValPtr str_vec_op_ne__CPP(const VectorValPtr& v1,
const VectorValPtr& v2);
extern VectorValPtr str_vec_op_gt__CPP(const VectorValPtr& v1,
const VectorValPtr& v2);
extern VectorValPtr str_vec_op_ge__CPP(const VectorValPtr& v1,
const VectorValPtr& v2);
extern VectorValPtr str_vec_op_lt__CPP(const VectorValPtr& v1, const VectorValPtr& v2);
extern VectorValPtr str_vec_op_le__CPP(const VectorValPtr& v1, const VectorValPtr& v2);
extern VectorValPtr str_vec_op_eq__CPP(const VectorValPtr& v1, const VectorValPtr& v2);
extern VectorValPtr str_vec_op_ne__CPP(const VectorValPtr& v1, const VectorValPtr& v2);
extern VectorValPtr str_vec_op_gt__CPP(const VectorValPtr& v1, const VectorValPtr& v2);
extern VectorValPtr str_vec_op_ge__CPP(const VectorValPtr& v1, const VectorValPtr& v2);
// Support for vector conditional ('?:') expressions. Using the boolean
// vector v1 as a selector, returns a new vector populated with the
// elements selected out of v2 and v3.
extern VectorValPtr vector_select__CPP(const VectorValPtr& v1, VectorValPtr v2,
VectorValPtr v3);
extern VectorValPtr vector_select__CPP(const VectorValPtr& v1, VectorValPtr v2, VectorValPtr v3);
// Returns a new vector reflecting the given vector coerced to the given
// type. Assumes v already has the correct internal type. This can go
// away after we finish migrating to ZVal's.
extern VectorValPtr vector_coerce_to__CPP(const VectorValPtr& v,
const TypePtr& targ);
extern VectorValPtr vector_coerce_to__CPP(const VectorValPtr& v, const TypePtr& targ);
// Similar coercion, but works for v having perhaps not the correct type.
extern VectorValPtr vec_coerce_to_bro_int_t__CPP(const VectorValPtr& v,
TypePtr targ);
extern VectorValPtr vec_coerce_to_bro_uint_t__CPP(const VectorValPtr& v,
TypePtr targ);
extern VectorValPtr vec_coerce_to_double__CPP(const VectorValPtr& v,
TypePtr targ);
extern VectorValPtr vec_coerce_to_bro_int_t__CPP(const VectorValPtr& v, TypePtr targ);
extern VectorValPtr vec_coerce_to_bro_uint_t__CPP(const VectorValPtr& v, TypePtr targ);
extern VectorValPtr vec_coerce_to_double__CPP(const VectorValPtr& v, TypePtr targ);
} // namespace zeek::detail
} // namespace zeek::detail

View file

@ -4,98 +4,100 @@
#include "zeek/script_opt/CPP/Compile.h"
namespace zeek::detail {
namespace zeek::detail
{
using namespace std;
void CPPCompile::GenStmt(const Stmt* s)
{
switch ( s->Tag() ) {
case STMT_INIT:
GenInitStmt(s->AsInitStmt());
break;
case STMT_LIST:
switch ( s->Tag() )
{
// These always occur in contexts surrounded by {}'s,
// so no need to add them explicitly.
auto sl = s->AsStmtList();
const auto& stmts = sl->Stmts();
case STMT_INIT:
GenInitStmt(s->AsInitStmt());
break;
for ( const auto& stmt : stmts )
GenStmt(stmt);
case STMT_LIST:
{
// These always occur in contexts surrounded by {}'s,
// so no need to add them explicitly.
auto sl = s->AsStmtList();
const auto& stmts = sl->Stmts();
for ( const auto& stmt : stmts )
GenStmt(stmt);
}
break;
case STMT_EXPR:
if ( auto e = s->AsExprStmt()->StmtExpr() )
Emit("%s;", GenExpr(e, GEN_DONT_CARE, true));
break;
case STMT_IF:
GenIfStmt(s->AsIfStmt());
break;
case STMT_WHILE:
GenWhileStmt(s->AsWhileStmt());
break;
case STMT_NULL:
Emit(";");
break;
case STMT_RETURN:
GenReturnStmt(s->AsReturnStmt());
break;
case STMT_ADD:
GenAddStmt(static_cast<const ExprStmt*>(s));
break;
case STMT_DELETE:
GenDeleteStmt(static_cast<const ExprStmt*>(s));
break;
case STMT_EVENT:
GenEventStmt(static_cast<const EventStmt*>(s));
break;
case STMT_SWITCH:
GenSwitchStmt(static_cast<const SwitchStmt*>(s));
break;
case STMT_FOR:
GenForStmt(s->AsForStmt());
break;
case STMT_NEXT:
Emit("continue;");
break;
case STMT_BREAK:
if ( break_level > 0 )
Emit("break;");
else
Emit("return false;");
break;
case STMT_PRINT:
{
auto el = static_cast<const ExprListStmt*>(s)->ExprList();
Emit("do_print_stmt({%s});", GenExpr(el, GEN_VAL_PTR));
}
break;
case STMT_FALLTHROUGH:
break;
case STMT_WHEN:
ASSERT(0);
break;
default:
reporter->InternalError("bad statement type in CPPCompile::GenStmt");
}
break;
case STMT_EXPR:
if ( auto e = s->AsExprStmt()->StmtExpr() )
Emit("%s;", GenExpr(e, GEN_DONT_CARE, true));
break;
case STMT_IF:
GenIfStmt(s->AsIfStmt());
break;
case STMT_WHILE:
GenWhileStmt(s->AsWhileStmt());
break;
case STMT_NULL:
Emit(";");
break;
case STMT_RETURN:
GenReturnStmt(s->AsReturnStmt());
break;
case STMT_ADD:
GenAddStmt(static_cast<const ExprStmt*>(s));
break;
case STMT_DELETE:
GenDeleteStmt(static_cast<const ExprStmt*>(s));
break;
case STMT_EVENT:
GenEventStmt(static_cast<const EventStmt*>(s));
break;
case STMT_SWITCH:
GenSwitchStmt(static_cast<const SwitchStmt*>(s));
break;
case STMT_FOR:
GenForStmt(s->AsForStmt());
break;
case STMT_NEXT:
Emit("continue;");
break;
case STMT_BREAK:
if ( break_level > 0 )
Emit("break;");
else
Emit("return false;");
break;
case STMT_PRINT:
{
auto el = static_cast<const ExprListStmt*>(s)->ExprList();
Emit("do_print_stmt({%s});", GenExpr(el, GEN_VAL_PTR));
}
break;
case STMT_FALLTHROUGH:
break;
case STMT_WHEN:
ASSERT(0);
break;
default:
reporter->InternalError("bad statement type in CPPCompile::GenStmt");
}
}
void CPPCompile::GenInitStmt(const InitStmt* init)
@ -119,9 +121,8 @@ void CPPCompile::GenInitStmt(const InitStmt* init)
continue;
}
Emit("%s = make_intrusive<%s>(cast_intrusive<%s>(%s));",
IDName(aggr), type_name,
type_type, type_ind);
Emit("%s = make_intrusive<%s>(cast_intrusive<%s>(%s));", IDName(aggr), type_name, type_type,
type_ind);
}
}
@ -147,8 +148,7 @@ void CPPCompile::GenIfStmt(const IfStmt* i)
void CPPCompile::GenWhileStmt(const WhileStmt* w)
{
Emit("while ( %s )",
GenExpr(w->Condition(), GEN_NATIVE));
Emit("while ( %s )", GenExpr(w->Condition(), GEN_NATIVE));
StartBlock();
@ -188,8 +188,7 @@ void CPPCompile::GenAddStmt(const ExprStmt* es)
auto aggr = GenExpr(op->GetOp1(), GEN_DONT_CARE);
auto indices = op->GetOp2();
Emit("add_element__CPP(%s, index_val__CPP({%s}));",
aggr, GenExpr(indices, GEN_VAL_PTR));
Emit("add_element__CPP(%s, index_val__CPP({%s}));", aggr, GenExpr(indices, GEN_VAL_PTR));
}
void CPPCompile::GenDeleteStmt(const ExprStmt* es)
@ -202,8 +201,8 @@ void CPPCompile::GenDeleteStmt(const ExprStmt* es)
{
auto indices = op->GetOp2();
Emit("remove_element__CPP(%s, index_val__CPP({%s}));",
aggr_gen, GenExpr(indices, GEN_VAL_PTR));
Emit("remove_element__CPP(%s, index_val__CPP({%s}));", aggr_gen,
GenExpr(indices, GEN_VAL_PTR));
}
else
@ -223,12 +222,10 @@ void CPPCompile::GenEventStmt(const EventStmt* ev)
RegisterEvent(ev_n);
if ( ev_e->Args()->Exprs().length() > 0 )
Emit("event_mgr.Enqueue(%s_ev, %s);",
globals[string(ev_n)],
GenExpr(ev_e->Args(), GEN_VAL_PTR));
Emit("event_mgr.Enqueue(%s_ev, %s);", globals[string(ev_n)],
GenExpr(ev_e->Args(), GEN_VAL_PTR));
else
Emit("event_mgr.Enqueue(%s_ev, Args{});",
globals[string(ev_n)]);
Emit("event_mgr.Enqueue(%s_ev, Args{});", globals[string(ev_n)]);
}
void CPPCompile::GenSwitchStmt(const SwitchStmt* sw)
@ -256,8 +253,7 @@ void CPPCompile::GenSwitchStmt(const SwitchStmt* sw)
{
if ( c->ExprCases() )
{
const auto& c_e_s =
c->ExprCases()->AsListExpr()->Exprs();
const auto& c_e_s = c->ExprCases()->AsListExpr()->Exprs();
for ( const auto& c_e : c_e_s )
{
@ -340,11 +336,8 @@ void CPPCompile::GenForOverTable(const ExprPtr& tbl, const IDPtr& value_var,
Emit("auto ind_lv__CPP = tv__CPP->RecreateIndex(*k__CPP);");
if ( value_var )
Emit("%s = %s;",
IDName(value_var),
GenericValPtrToGT("current_tev__CPP->GetVal()",
value_var->GetType(),
GEN_NATIVE));
Emit("%s = %s;", IDName(value_var),
GenericValPtrToGT("current_tev__CPP->GetVal()", value_var->GetType(), GEN_NATIVE));
for ( int i = 0; i < loop_vars->length(); ++i )
{
@ -353,11 +346,9 @@ void CPPCompile::GenForOverTable(const ExprPtr& tbl, const IDPtr& value_var,
auto acc = NativeAccessor(v_t);
if ( IsNativeType(v_t) )
Emit("%s = ind_lv__CPP->Idx(%s)%s;",
IDName(var), Fmt(i), acc);
Emit("%s = ind_lv__CPP->Idx(%s)%s;", IDName(var), Fmt(i), acc);
else
Emit("%s = {NewRef{}, ind_lv__CPP->Idx(%s)%s};",
IDName(var), Fmt(i), acc);
Emit("%s = {NewRef{}, ind_lv__CPP->Idx(%s)%s};", IDName(var), Fmt(i), acc);
}
}
@ -383,4 +374,4 @@ void CPPCompile::GenForOverString(const ExprPtr& str, const IDPList* loop_vars)
Emit("%s = std::move(sv__CPP);", IDName((*loop_vars)[0]));
}
} // zeek::detail
} // zeek::detail

View file

@ -1,17 +1,17 @@
// See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/Desc.h"
#include "zeek/script_opt/CPP/Tracker.h"
#include "zeek/Desc.h"
#include "zeek/script_opt/CPP/Util.h"
#include "zeek/script_opt/ProfileFunc.h"
namespace zeek::detail {
namespace zeek::detail
{
using namespace std;
template<class T>
void CPPTracker<T>::AddKey(IntrusivePtr<T> key, p_hash_type h)
template <class T> void CPPTracker<T>::AddKey(IntrusivePtr<T> key, p_hash_type h)
{
if ( HasKey(key) )
return;
@ -39,13 +39,12 @@ void CPPTracker<T>::AddKey(IntrusivePtr<T> key, p_hash_type h)
reps[h] = key.get();
}
ASSERT(h != 0); // check for hash botches
ASSERT(h != 0); // check for hash botches
map[key.get()] = h;
}
template<class T>
string CPPTracker<T>::KeyName(const T* key)
template <class T> string CPPTracker<T>::KeyName(const T* key)
{
ASSERT(HasKey(key));
@ -61,8 +60,7 @@ string CPPTracker<T>::KeyName(const T* key)
return scope + string(base_name) + "_" + Fmt(index) + "__CPP";
}
template<class T>
void CPPTracker<T>::LogIfNew(IntrusivePtr<T> key, int scope, FILE* log_file)
template <class T> void CPPTracker<T>::LogIfNew(IntrusivePtr<T> key, int scope, FILE* log_file)
{
if ( IsInherited(key) )
return;
@ -73,8 +71,7 @@ void CPPTracker<T>::LogIfNew(IntrusivePtr<T> key, int scope, FILE* log_file)
fprintf(log_file, "hash\n%llu %d %d\n", hash, index, scope);
}
template<class T>
p_hash_type CPPTracker<T>::Hash(IntrusivePtr<T> key) const
template <class T> p_hash_type CPPTracker<T>::Hash(IntrusivePtr<T> key) const
{
ODesc d;
d.SetDeterminism(true);
@ -84,10 +81,9 @@ p_hash_type CPPTracker<T>::Hash(IntrusivePtr<T> key) const
return p_hash_type(h);
}
// Instantiate the templates we'll need.
template class CPPTracker<Type>;
template class CPPTracker<Attributes>;
template class CPPTracker<Expr>;
} // zeek::detail
} // zeek::detail

View file

@ -16,24 +16,25 @@
#include "zeek/script_opt/CPP/HashMgr.h"
namespace zeek::detail {
namespace zeek::detail
{
// T is a type that has an IntrusivePtr instantiation.
template <class T>
class CPPTracker {
template <class T> class CPPTracker
{
public:
// The base name is used to construct key names. The mapper,
// if present, maps hash values to information about the previously
// generated scope in which the value appears.
CPPTracker(const char* _base_name, VarMapper* _mapper = nullptr)
: base_name(_base_name), mapper(_mapper)
: base_name(_base_name), mapper(_mapper)
{
}
// True if the given key has already been entered.
bool HasKey(const T* key) const { return map.count(key) > 0; }
bool HasKey(IntrusivePtr<T> key) const { return HasKey(key.get()); }
bool HasKey(const T* key) const { return map.count(key) > 0; }
bool HasKey(IntrusivePtr<T> key) const { return HasKey(key.get()); }
// Only adds the key if it's not already present. If a hash
// is provided, then refrains from computing it.
@ -41,26 +42,33 @@ public:
// Returns the (C++ variable) name associated with the given key.
std::string KeyName(const T* key);
std::string KeyName(IntrusivePtr<T> key)
{ return KeyName(key.get()); }
std::string KeyName(IntrusivePtr<T> key) { return KeyName(key.get()); }
// Returns all of the distinct keys entered into the tracker.
// A key is "distinct" if it's both (1) a representative and
// (2) not inherited.
const std::vector<IntrusivePtr<T>>& DistinctKeys() const
{ return keys; }
const std::vector<IntrusivePtr<T>>& DistinctKeys() const { return keys; }
// For a given key, get its representative.
const T* GetRep(const T* key)
{ ASSERT(HasKey(key)); return reps[map[key]]; }
const T* GetRep(IntrusivePtr<T> key) { return GetRep(key.get()); }
{
ASSERT(HasKey(key));
return reps[map[key]];
}
const T* GetRep(IntrusivePtr<T> key) { return GetRep(key.get()); }
// True if the given key is represented by an inherited value.
bool IsInherited(const T* key)
{ ASSERT(HasKey(key)); return IsInherited(map[key]); }
{
ASSERT(HasKey(key));
return IsInherited(map[key]);
}
bool IsInherited(const IntrusivePtr<T>& key)
{ ASSERT(HasKey(key)); return IsInherited(map[key.get()]); }
bool IsInherited(p_hash_type h) { return inherited.count(h) > 0; }
{
ASSERT(HasKey(key));
return IsInherited(map[key.get()]);
}
bool IsInherited(p_hash_type h) { return inherited.count(h) > 0; }
// If the given key is not inherited, logs it and its associated
// scope to the given file.
@ -76,9 +84,9 @@ private:
// Maps internal representations to distinct values. These
// may-or-may-not be indices into an "inherited" namespace scope.
std::unordered_map<p_hash_type, int> map2;
std::unordered_map<p_hash_type, std::string> scope2; // only if inherited
std::unordered_set<p_hash_type> inherited; // which are inherited
int num_non_inherited = 0; // distinct non-inherited map2 entries
std::unordered_map<p_hash_type, std::string> scope2; // only if inherited
std::unordered_set<p_hash_type> inherited; // which are inherited
int num_non_inherited = 0; // distinct non-inherited map2 entries
// Tracks the set of distinct keys, to facilitate iterating over them.
// Each such key also has an entry in map2.
@ -92,6 +100,6 @@ private:
// If non-nil, the mapper to consult for previous names.
VarMapper* mapper;
};
};
} // zeek::detail
} // zeek::detail

View file

@ -2,8 +2,8 @@
#include "zeek/script_opt/CPP/Compile.h"
namespace zeek::detail {
namespace zeek::detail
{
using namespace std;
@ -12,40 +12,41 @@ bool CPPCompile::IsNativeType(const TypePtr& t) const
if ( ! t )
return true;
switch ( t->Tag() ) {
case TYPE_BOOL:
case TYPE_COUNT:
case TYPE_DOUBLE:
case TYPE_ENUM:
case TYPE_INT:
case TYPE_INTERVAL:
case TYPE_PORT:
case TYPE_TIME:
case TYPE_VOID:
return true;
switch ( t->Tag() )
{
case TYPE_BOOL:
case TYPE_COUNT:
case TYPE_DOUBLE:
case TYPE_ENUM:
case TYPE_INT:
case TYPE_INTERVAL:
case TYPE_PORT:
case TYPE_TIME:
case TYPE_VOID:
return true;
case TYPE_ADDR:
case TYPE_ANY:
case TYPE_FILE:
case TYPE_FUNC:
case TYPE_OPAQUE:
case TYPE_PATTERN:
case TYPE_RECORD:
case TYPE_STRING:
case TYPE_SUBNET:
case TYPE_TABLE:
case TYPE_TYPE:
case TYPE_VECTOR:
return false;
case TYPE_ADDR:
case TYPE_ANY:
case TYPE_FILE:
case TYPE_FUNC:
case TYPE_OPAQUE:
case TYPE_PATTERN:
case TYPE_RECORD:
case TYPE_STRING:
case TYPE_SUBNET:
case TYPE_TABLE:
case TYPE_TYPE:
case TYPE_VECTOR:
return false;
case TYPE_LIST:
// These occur when initializing tables.
return false;
case TYPE_LIST:
// These occur when initializing tables.
return false;
default:
reporter->InternalError("bad type in CPPCompile::IsNativeType");
return false;
}
default:
reporter->InternalError("bad type in CPPCompile::IsNativeType");
return false;
}
}
string CPPCompile::NativeToGT(const string& expr, const TypePtr& t, GenType gt)
@ -57,85 +58,84 @@ string CPPCompile::NativeToGT(const string& expr, const TypePtr& t, GenType gt)
return expr;
// Need to convert to a ValPtr.
switch ( t->Tag() ) {
case TYPE_VOID:
return expr;
switch ( t->Tag() )
{
case TYPE_VOID:
return expr;
case TYPE_BOOL:
return string("val_mgr->Bool(") + expr + ")";
case TYPE_BOOL:
return string("val_mgr->Bool(") + expr + ")";
case TYPE_INT:
return string("val_mgr->Int(") + expr + ")";
case TYPE_INT:
return string("val_mgr->Int(") + expr + ")";
case TYPE_COUNT:
return string("val_mgr->Count(") + expr + ")";
case TYPE_COUNT:
return string("val_mgr->Count(") + expr + ")";
case TYPE_PORT:
return string("val_mgr->Port(") + expr + ")";
case TYPE_PORT:
return string("val_mgr->Port(") + expr + ")";
case TYPE_ENUM:
return string("make_enum__CPP(") + GenTypeName(t) + ", " +
expr + ")";
case TYPE_ENUM:
return string("make_enum__CPP(") + GenTypeName(t) + ", " + expr + ")";
default:
return string("make_intrusive<") + IntrusiveVal(t) +
">(" + expr + ")";
}
default:
return string("make_intrusive<") + IntrusiveVal(t) + ">(" + expr + ")";
}
}
string CPPCompile::GenericValPtrToGT(const string& expr, const TypePtr& t,
GenType gt)
string CPPCompile::GenericValPtrToGT(const string& expr, const TypePtr& t, GenType gt)
{
if ( gt != GEN_VAL_PTR && IsNativeType(t) )
return expr + NativeAccessor(t);
else
return string("cast_intrusive<") + IntrusiveVal(t) +
">(" + expr + ")";
return string("cast_intrusive<") + IntrusiveVal(t) + ">(" + expr + ")";
}
void CPPCompile::ExpandTypeVar(const TypePtr& t)
{
auto tn = GenTypeName(t);
switch ( t->Tag() ) {
case TYPE_LIST:
ExpandListTypeVar(t, tn);
break;
switch ( t->Tag() )
{
case TYPE_LIST:
ExpandListTypeVar(t, tn);
break;
case TYPE_RECORD:
ExpandRecordTypeVar(t, tn);
break;
case TYPE_RECORD:
ExpandRecordTypeVar(t, tn);
break;
case TYPE_ENUM:
ExpandEnumTypeVar(t, tn);
break;
case TYPE_ENUM:
ExpandEnumTypeVar(t, tn);
break;
case TYPE_TABLE:
ExpandTableTypeVar(t, tn);
break;
case TYPE_TABLE:
ExpandTableTypeVar(t, tn);
break;
case TYPE_FUNC:
ExpandFuncTypeVar(t, tn);
break;
case TYPE_FUNC:
ExpandFuncTypeVar(t, tn);
break;
case TYPE_TYPE:
AddInit(t, tn, string("make_intrusive<TypeType>(") +
GenTypeName(t->AsTypeType()->GetType()) + ")");
break;
case TYPE_TYPE:
AddInit(t, tn,
string("make_intrusive<TypeType>(") + GenTypeName(t->AsTypeType()->GetType()) +
")");
break;
case TYPE_VECTOR:
AddInit(t, tn, string("make_intrusive<VectorType>(") +
GenTypeName(t->AsVectorType()->Yield()) + ")");
break;
case TYPE_VECTOR:
AddInit(t, tn,
string("make_intrusive<VectorType>(") +
GenTypeName(t->AsVectorType()->Yield()) + ")");
break;
default:
break;
}
default:
break;
}
auto& script_type_name = t->GetName();
if ( ! script_type_name.empty() )
AddInit(t, "register_type__CPP(" + tn + ", \"" +
script_type_name + "\");");
AddInit(t, "register_type__CPP(" + tn + ", \"" + script_type_name + "\");");
AddInit(t);
}
@ -183,9 +183,8 @@ void CPPCompile::ExpandEnumTypeVar(const TypePtr& t, string& tn)
AddInit(t, "if ( et->Names().empty() ) {");
for ( const auto& name_pair : et->Names() )
AddInit(t, string("\tet->AddNameInternal(\"") +
name_pair.first + "\", " +
Fmt(int(name_pair.second)) + ");");
AddInit(t, string("\tet->AddNameInternal(\"") + name_pair.first + "\", " +
Fmt(int(name_pair.second)) + ");");
AddInit(t, "}}");
}
@ -199,13 +198,12 @@ void CPPCompile::ExpandTableTypeVar(const TypePtr& t, string& tn)
if ( tbl->IsSet() )
AddInit(t, tn,
string("make_intrusive<SetType>(cast_intrusive<TypeList>(") +
GenTypeName(indices) + " ), nullptr)");
string("make_intrusive<SetType>(cast_intrusive<TypeList>(") + GenTypeName(indices) +
" ), nullptr)");
else
AddInit(t, tn,
string("make_intrusive<TableType>(cast_intrusive<TypeList>(") +
GenTypeName(indices) + "), " +
GenTypeName(yield) + ")");
GenTypeName(indices) + "), " + GenTypeName(yield) + ")");
}
void CPPCompile::ExpandFuncTypeVar(const TypePtr& t, string& tn)
@ -233,8 +231,7 @@ void CPPCompile::ExpandFuncTypeVar(const TypePtr& t, string& tn)
fl_name = "FUNC_FLAVOR_HOOK";
auto type_init = string("make_intrusive<FuncType>(cast_intrusive<RecordType>(") +
args_type_accessor + "), " +
yield_type_accessor + ", " + fl_name + ")";
args_type_accessor + "), " + yield_type_accessor + ", " + fl_name + ")";
AddInit(t, tn, type_init);
}
@ -246,12 +243,10 @@ string CPPCompile::GenTypeDecl(const TypeDecl* td)
auto td_name = string("util::copy_string(\"") + td->id + "\")";
if ( td->attrs )
return string("tl.append(new TypeDecl(") +
td_name + ", " + type_accessor +
", " + AttrsName(td->attrs) +"));";
return string("tl.append(new TypeDecl(") + td_name + ", " + type_accessor + ", " +
AttrsName(td->attrs) + "));";
return string("tl.append(new TypeDecl(") + td_name + ", " +
type_accessor +"));";
return string("tl.append(new TypeDecl(") + td_name + ", " + type_accessor + "));";
}
string CPPCompile::GenTypeName(const Type* t)
@ -261,67 +256,113 @@ string CPPCompile::GenTypeName(const Type* t)
const char* CPPCompile::TypeTagName(TypeTag tag) const
{
switch ( tag ) {
case TYPE_ADDR: return "TYPE_ADDR";
case TYPE_ANY: return "TYPE_ANY";
case TYPE_BOOL: return "TYPE_BOOL";
case TYPE_COUNT: return "TYPE_COUNT";
case TYPE_DOUBLE: return "TYPE_DOUBLE";
case TYPE_ENUM: return "TYPE_ENUM";
case TYPE_ERROR: return "TYPE_ERROR";
case TYPE_FILE: return "TYPE_FILE";
case TYPE_FUNC: return "TYPE_FUNC";
case TYPE_INT: return "TYPE_INT";
case TYPE_INTERVAL: return "TYPE_INTERVAL";
case TYPE_OPAQUE: return "TYPE_OPAQUE";
case TYPE_PATTERN: return "TYPE_PATTERN";
case TYPE_PORT: return "TYPE_PORT";
case TYPE_RECORD: return "TYPE_RECORD";
case TYPE_STRING: return "TYPE_STRING";
case TYPE_SUBNET: return "TYPE_SUBNET";
case TYPE_TABLE: return "TYPE_TABLE";
case TYPE_TIME: return "TYPE_TIME";
case TYPE_TIMER: return "TYPE_TIMER";
case TYPE_TYPE: return "TYPE_TYPE";
case TYPE_VECTOR: return "TYPE_VECTOR";
case TYPE_VOID: return "TYPE_VOID";
switch ( tag )
{
case TYPE_ADDR:
return "TYPE_ADDR";
case TYPE_ANY:
return "TYPE_ANY";
case TYPE_BOOL:
return "TYPE_BOOL";
case TYPE_COUNT:
return "TYPE_COUNT";
case TYPE_DOUBLE:
return "TYPE_DOUBLE";
case TYPE_ENUM:
return "TYPE_ENUM";
case TYPE_ERROR:
return "TYPE_ERROR";
case TYPE_FILE:
return "TYPE_FILE";
case TYPE_FUNC:
return "TYPE_FUNC";
case TYPE_INT:
return "TYPE_INT";
case TYPE_INTERVAL:
return "TYPE_INTERVAL";
case TYPE_OPAQUE:
return "TYPE_OPAQUE";
case TYPE_PATTERN:
return "TYPE_PATTERN";
case TYPE_PORT:
return "TYPE_PORT";
case TYPE_RECORD:
return "TYPE_RECORD";
case TYPE_STRING:
return "TYPE_STRING";
case TYPE_SUBNET:
return "TYPE_SUBNET";
case TYPE_TABLE:
return "TYPE_TABLE";
case TYPE_TIME:
return "TYPE_TIME";
case TYPE_TIMER:
return "TYPE_TIMER";
case TYPE_TYPE:
return "TYPE_TYPE";
case TYPE_VECTOR:
return "TYPE_VECTOR";
case TYPE_VOID:
return "TYPE_VOID";
default:
reporter->InternalError("bad type in CPPCompile::TypeTagName");
return nullptr;
}
default:
reporter->InternalError("bad type in CPPCompile::TypeTagName");
return nullptr;
}
}
const char* CPPCompile::TypeName(const TypePtr& t)
{
switch ( t->Tag() ) {
case TYPE_BOOL: return "bool";
case TYPE_COUNT: return "bro_uint_t";
case TYPE_DOUBLE: return "double";
case TYPE_ENUM: return "int";
case TYPE_INT: return "bro_int_t";
case TYPE_INTERVAL: return "double";
case TYPE_PORT: return "bro_uint_t";
case TYPE_TIME: return "double";
case TYPE_VOID: return "void";
switch ( t->Tag() )
{
case TYPE_BOOL:
return "bool";
case TYPE_COUNT:
return "bro_uint_t";
case TYPE_DOUBLE:
return "double";
case TYPE_ENUM:
return "int";
case TYPE_INT:
return "bro_int_t";
case TYPE_INTERVAL:
return "double";
case TYPE_PORT:
return "bro_uint_t";
case TYPE_TIME:
return "double";
case TYPE_VOID:
return "void";
case TYPE_ADDR: return "AddrVal";
case TYPE_ANY: return "Val";
case TYPE_FILE: return "FileVal";
case TYPE_FUNC: return "FuncVal";
case TYPE_OPAQUE: return "OpaqueVal";
case TYPE_PATTERN: return "PatternVal";
case TYPE_RECORD: return "RecordVal";
case TYPE_STRING: return "StringVal";
case TYPE_SUBNET: return "SubNetVal";
case TYPE_TABLE: return "TableVal";
case TYPE_TYPE: return "TypeVal";
case TYPE_VECTOR: return "VectorVal";
case TYPE_ADDR:
return "AddrVal";
case TYPE_ANY:
return "Val";
case TYPE_FILE:
return "FileVal";
case TYPE_FUNC:
return "FuncVal";
case TYPE_OPAQUE:
return "OpaqueVal";
case TYPE_PATTERN:
return "PatternVal";
case TYPE_RECORD:
return "RecordVal";
case TYPE_STRING:
return "StringVal";
case TYPE_SUBNET:
return "SubNetVal";
case TYPE_TABLE:
return "TableVal";
case TYPE_TYPE:
return "TypeVal";
case TYPE_VECTOR:
return "VectorVal";
default:
reporter->InternalError("bad type in CPPCompile::TypeName");
return nullptr;
}
default:
reporter->InternalError("bad type in CPPCompile::TypeName");
return nullptr;
}
}
const char* CPPCompile::FullTypeName(const TypePtr& t)
@ -329,48 +370,65 @@ const char* CPPCompile::FullTypeName(const TypePtr& t)
if ( ! t )
return "void";
switch ( t->Tag() ) {
case TYPE_BOOL:
case TYPE_COUNT:
case TYPE_DOUBLE:
case TYPE_ENUM:
case TYPE_INT:
case TYPE_INTERVAL:
case TYPE_PORT:
case TYPE_TIME:
case TYPE_VOID:
return TypeName(t);
switch ( t->Tag() )
{
case TYPE_BOOL:
case TYPE_COUNT:
case TYPE_DOUBLE:
case TYPE_ENUM:
case TYPE_INT:
case TYPE_INTERVAL:
case TYPE_PORT:
case TYPE_TIME:
case TYPE_VOID:
return TypeName(t);
case TYPE_ADDR: return "AddrValPtr";
case TYPE_ANY: return "ValPtr";
case TYPE_FILE: return "FileValPtr";
case TYPE_FUNC: return "FuncValPtr";
case TYPE_OPAQUE: return "OpaqueValPtr";
case TYPE_PATTERN: return "PatternValPtr";
case TYPE_RECORD: return "RecordValPtr";
case TYPE_STRING: return "StringValPtr";
case TYPE_SUBNET: return "SubNetValPtr";
case TYPE_TABLE: return "TableValPtr";
case TYPE_TYPE: return "TypeValPtr";
case TYPE_VECTOR: return "VectorValPtr";
case TYPE_ADDR:
return "AddrValPtr";
case TYPE_ANY:
return "ValPtr";
case TYPE_FILE:
return "FileValPtr";
case TYPE_FUNC:
return "FuncValPtr";
case TYPE_OPAQUE:
return "OpaqueValPtr";
case TYPE_PATTERN:
return "PatternValPtr";
case TYPE_RECORD:
return "RecordValPtr";
case TYPE_STRING:
return "StringValPtr";
case TYPE_SUBNET:
return "SubNetValPtr";
case TYPE_TABLE:
return "TableValPtr";
case TYPE_TYPE:
return "TypeValPtr";
case TYPE_VECTOR:
return "VectorValPtr";
default:
reporter->InternalError("bad type in CPPCompile::FullTypeName");
return nullptr;
}
default:
reporter->InternalError("bad type in CPPCompile::FullTypeName");
return nullptr;
}
}
const char* CPPCompile::TypeType(const TypePtr& t)
{
switch ( t->Tag() ) {
case TYPE_RECORD: return "RecordType";
case TYPE_TABLE: return "TableType";
case TYPE_VECTOR: return "VectorType";
switch ( t->Tag() )
{
case TYPE_RECORD:
return "RecordType";
case TYPE_TABLE:
return "TableType";
case TYPE_VECTOR:
return "VectorType";
default:
reporter->InternalError("bad type in CPPCompile::TypeType");
return nullptr;
}
default:
reporter->InternalError("bad type in CPPCompile::TypeType");
return nullptr;
}
}
void CPPCompile::RegisterType(const TypePtr& tp)
@ -384,63 +442,64 @@ void CPPCompile::RegisterType(const TypePtr& tp)
// that reference each other.
processed_types.insert(t);
switch ( t->Tag() ) {
case TYPE_ADDR:
case TYPE_ANY:
case TYPE_BOOL:
case TYPE_COUNT:
case TYPE_DOUBLE:
case TYPE_ENUM:
case TYPE_ERROR:
case TYPE_INT:
case TYPE_INTERVAL:
case TYPE_PATTERN:
case TYPE_PORT:
case TYPE_STRING:
case TYPE_TIME:
case TYPE_TIMER:
case TYPE_VOID:
case TYPE_OPAQUE:
case TYPE_SUBNET:
case TYPE_FILE:
// Nothing to do.
break;
case TYPE_TYPE:
switch ( t->Tag() )
{
const auto& tt = t->AsTypeType()->GetType();
NoteNonRecordInitDependency(t, tt);
RegisterType(tt);
case TYPE_ADDR:
case TYPE_ANY:
case TYPE_BOOL:
case TYPE_COUNT:
case TYPE_DOUBLE:
case TYPE_ENUM:
case TYPE_ERROR:
case TYPE_INT:
case TYPE_INTERVAL:
case TYPE_PATTERN:
case TYPE_PORT:
case TYPE_STRING:
case TYPE_TIME:
case TYPE_TIMER:
case TYPE_VOID:
case TYPE_OPAQUE:
case TYPE_SUBNET:
case TYPE_FILE:
// Nothing to do.
break;
case TYPE_TYPE:
{
const auto& tt = t->AsTypeType()->GetType();
NoteNonRecordInitDependency(t, tt);
RegisterType(tt);
}
break;
case TYPE_VECTOR:
{
const auto& yield = t->AsVectorType()->Yield();
NoteNonRecordInitDependency(t, yield);
RegisterType(yield);
}
break;
case TYPE_LIST:
RegisterListType(tp);
break;
case TYPE_TABLE:
RegisterTableType(tp);
break;
case TYPE_RECORD:
RegisterRecordType(tp);
break;
case TYPE_FUNC:
RegisterFuncType(tp);
break;
default:
reporter->InternalError("bad type in CPPCompile::RegisterType");
}
break;
case TYPE_VECTOR:
{
const auto& yield = t->AsVectorType()->Yield();
NoteNonRecordInitDependency(t, yield);
RegisterType(yield);
}
break;
case TYPE_LIST:
RegisterListType(tp);
break;
case TYPE_TABLE:
RegisterTableType(tp);
break;
case TYPE_RECORD:
RegisterRecordType(tp);
break;
case TYPE_FUNC:
RegisterFuncType(tp);
break;
default:
reporter->InternalError("bad type in CPPCompile::RegisterType");
}
AddInit(t);
@ -517,67 +576,110 @@ void CPPCompile::RegisterFuncType(const TypePtr& t)
const char* CPPCompile::NativeAccessor(const TypePtr& t)
{
switch ( t->Tag() ) {
case TYPE_BOOL: return "->AsBool()";
case TYPE_COUNT: return "->AsCount()";
case TYPE_DOUBLE: return "->AsDouble()";
case TYPE_ENUM: return "->AsEnum()";
case TYPE_INT: return "->AsInt()";
case TYPE_INTERVAL: return "->AsDouble()";
case TYPE_PORT: return "->AsCount()";
case TYPE_TIME: return "->AsDouble()";
switch ( t->Tag() )
{
case TYPE_BOOL:
return "->AsBool()";
case TYPE_COUNT:
return "->AsCount()";
case TYPE_DOUBLE:
return "->AsDouble()";
case TYPE_ENUM:
return "->AsEnum()";
case TYPE_INT:
return "->AsInt()";
case TYPE_INTERVAL:
return "->AsDouble()";
case TYPE_PORT:
return "->AsCount()";
case TYPE_TIME:
return "->AsDouble()";
case TYPE_ADDR: return "->AsAddrVal()";
case TYPE_FILE: return "->AsFileVal()";
case TYPE_FUNC: return "->AsFuncVal()";
case TYPE_OPAQUE: return "->AsOpaqueVal()";
case TYPE_PATTERN: return "->AsPatternVal()";
case TYPE_RECORD: return "->AsRecordVal()";
case TYPE_STRING: return "->AsStringVal()";
case TYPE_SUBNET: return "->AsSubNetVal()";
case TYPE_TABLE: return "->AsTableVal()";
case TYPE_TYPE: return "->AsTypeVal()";
case TYPE_VECTOR: return "->AsVectorVal()";
case TYPE_ADDR:
return "->AsAddrVal()";
case TYPE_FILE:
return "->AsFileVal()";
case TYPE_FUNC:
return "->AsFuncVal()";
case TYPE_OPAQUE:
return "->AsOpaqueVal()";
case TYPE_PATTERN:
return "->AsPatternVal()";
case TYPE_RECORD:
return "->AsRecordVal()";
case TYPE_STRING:
return "->AsStringVal()";
case TYPE_SUBNET:
return "->AsSubNetVal()";
case TYPE_TABLE:
return "->AsTableVal()";
case TYPE_TYPE:
return "->AsTypeVal()";
case TYPE_VECTOR:
return "->AsVectorVal()";
case TYPE_ANY: return ".get()";
case TYPE_ANY:
return ".get()";
case TYPE_VOID: return "";
case TYPE_VOID:
return "";
default:
reporter->InternalError("bad type in CPPCompile::NativeAccessor");
return nullptr;
}
default:
reporter->InternalError("bad type in CPPCompile::NativeAccessor");
return nullptr;
}
}
const char* CPPCompile::IntrusiveVal(const TypePtr& t)
{
switch ( t->Tag() ) {
case TYPE_BOOL: return "BoolVal";
case TYPE_COUNT: return "CountVal";
case TYPE_DOUBLE: return "DoubleVal";
case TYPE_ENUM: return "EnumVal";
case TYPE_INT: return "IntVal";
case TYPE_INTERVAL: return "IntervalVal";
case TYPE_PORT: return "PortVal";
case TYPE_TIME: return "TimeVal";
switch ( t->Tag() )
{
case TYPE_BOOL:
return "BoolVal";
case TYPE_COUNT:
return "CountVal";
case TYPE_DOUBLE:
return "DoubleVal";
case TYPE_ENUM:
return "EnumVal";
case TYPE_INT:
return "IntVal";
case TYPE_INTERVAL:
return "IntervalVal";
case TYPE_PORT:
return "PortVal";
case TYPE_TIME:
return "TimeVal";
case TYPE_ADDR: return "AddrVal";
case TYPE_ANY: return "Val";
case TYPE_FILE: return "FileVal";
case TYPE_FUNC: return "FuncVal";
case TYPE_OPAQUE: return "OpaqueVal";
case TYPE_PATTERN: return "PatternVal";
case TYPE_RECORD: return "RecordVal";
case TYPE_STRING: return "StringVal";
case TYPE_SUBNET: return "SubNetVal";
case TYPE_TABLE: return "TableVal";
case TYPE_TYPE: return "TypeVal";
case TYPE_VECTOR: return "VectorVal";
case TYPE_ADDR:
return "AddrVal";
case TYPE_ANY:
return "Val";
case TYPE_FILE:
return "FileVal";
case TYPE_FUNC:
return "FuncVal";
case TYPE_OPAQUE:
return "OpaqueVal";
case TYPE_PATTERN:
return "PatternVal";
case TYPE_RECORD:
return "RecordVal";
case TYPE_STRING:
return "StringVal";
case TYPE_SUBNET:
return "SubNetVal";
case TYPE_TABLE:
return "TableVal";
case TYPE_TYPE:
return "TypeVal";
case TYPE_VECTOR:
return "VectorVal";
default:
reporter->InternalError("bad type in CPPCompile::IntrusiveVal");
return nullptr;
}
default:
reporter->InternalError("bad type in CPPCompile::IntrusiveVal");
return nullptr;
}
}
} // zeek::detail
} // zeek::detail

View file

@ -1,12 +1,13 @@
// See the file "COPYING" in the main distribution directory for copyright.
#include <errno.h>
#include <unistd.h>
#include <sys/file.h>
#include "zeek/script_opt/CPP/Util.h"
namespace zeek::detail {
#include <errno.h>
#include <sys/file.h>
#include <unistd.h>
namespace zeek::detail
{
using namespace std;
@ -74,4 +75,4 @@ void unlock_file(const string& fname, FILE* f)
}
}
} // zeek::detail
} // zeek::detail

View file

@ -6,11 +6,18 @@
#include "zeek/script_opt/ProfileFunc.h"
namespace zeek::detail {
namespace zeek::detail
{
// Conversions to strings.
inline std::string Fmt(int i) { return std::to_string(i); }
inline std::string Fmt(p_hash_type u) { return std::to_string(u) + "ULL"; }
inline std::string Fmt(int i)
{
return std::to_string(i);
}
inline std::string Fmt(p_hash_type u)
{
return std::to_string(u) + "ULL";
}
extern std::string Fmt(double d);
// Returns the prefix for the scoping used by the compiler.
@ -22,12 +29,11 @@ extern std::string scope_prefix(int scope);
// True if the given function is compilable to C++. If it isn't, and
// the second argument is non-nil, then on return it points to text
// explaining why not.
extern bool is_CPP_compilable(const ProfileFunc* pf,
const char** reason = nullptr);
extern bool is_CPP_compilable(const ProfileFunc* pf, const char** reason = nullptr);
// Helper utilities for file locking, to ensure that hash files
// don't receive conflicting writes due to concurrent compilations.
extern void lock_file(const std::string& fname, FILE* f);
extern void unlock_file(const std::string& fname, FILE* f);
} // zeek::detail
} // zeek::detail

View file

@ -1,14 +1,14 @@
// See the file "COPYING" in the main distribution directory for copyright.
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <unistd.h>
#include "zeek/script_opt/ProfileFunc.h"
#include "zeek/script_opt/CPP/Compile.h"
#include "zeek/script_opt/ProfileFunc.h"
namespace zeek::detail {
namespace zeek::detail
{
using namespace std;
@ -33,9 +33,9 @@ bool CPPCompile::CheckForCollisions()
if ( ht != ht_orig || hv != hv_orig )
{
fprintf(stderr, "%s: hash clash for global %s (%llu/%llu vs. %llu/%llu)\n",
working_dir.c_str(), gn.c_str(),
ht, hv, ht_orig, hv_orig);
fprintf(stderr, "val: %s\n", g->GetVal() ? obj_desc(g->GetVal().get()).c_str() : "<none>");
working_dir.c_str(), gn.c_str(), ht, hv, ht_orig, hv_orig);
fprintf(stderr, "val: %s\n",
g->GetVal() ? obj_desc(g->GetVal().get()).c_str() : "<none>");
return true;
}
}
@ -67,8 +67,8 @@ bool CPPCompile::CheckForCollisions()
// No inconsistency.
continue;
fprintf(stderr, "%s: type \"%s\" collides with compiled global\n",
working_dir.c_str(), tn.c_str());
fprintf(stderr, "%s: type \"%s\" collides with compiled global\n", working_dir.c_str(),
tn.c_str());
return true;
}
@ -112,8 +112,8 @@ void CPPCompile::CreateGlobal(const ID* g)
auto exported = g->IsExport() ? "true" : "false";
AddInit(g, globals[gn],
string("lookup_global__CPP(\"") + gn + "\", " +
GenTypeName(t) + ", " + exported + ")");
string("lookup_global__CPP(\"") + gn + "\", " + GenTypeName(t) + ", " + exported +
")");
}
if ( is_bif )
@ -165,7 +165,7 @@ void CPPCompile::AddBiF(const ID* b, bool is_var)
auto bn = b->Name();
auto n = string(bn);
if ( is_var )
n = n + "_"; // make the name distinct
n = n + "_"; // make the name distinct
if ( AddGlobal(n, "bif", true) )
Emit("Func* %s;", globals[n]);
@ -193,8 +193,7 @@ bool CPPCompile::AddGlobal(const string& g, const char* suffix, bool track)
new_var = true;
if ( track && update )
fprintf(hm.HashFile(), "global-var\n%s\n%d\n",
gn.c_str(), addl_tag);
fprintf(hm.HashFile(), "global-var\n%s\n%d\n", gn.c_str(), addl_tag);
}
globals.emplace(g, gn);
@ -255,4 +254,4 @@ string CPPCompile::Canonicalize(const char* name) const
return cname + "_";
}
} // zeek::detail
} // zeek::detail