mirror of
https://github.com/zeek/zeek.git
synced 2025-10-05 08:08:19 +00:00
Reformat the world
This commit is contained in:
parent
194cb24547
commit
b2f171ec69
714 changed files with 35149 additions and 35203 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue