Merge remote-tracking branch 'origin/topic/vern/CPP-maint.Mar25'

* origin/topic/vern/CPP-maint.Mar25:
  minor baseline updates for -O gen-C++
  -O gen-C++ support for pattern-to-pattern comparison
  -O gen-C++ support for pattern vector comparisons
  -O gen-C++ support for type expressions
This commit is contained in:
Tim Wojtulewicz 2025-03-19 12:46:41 -07:00
commit 38484b6dc6
23 changed files with 172 additions and 7 deletions

View file

@ -103,6 +103,8 @@ shared_ptr<CPP_InitInfo> CPPCompile::RegisterConstant(const ValPtr& vp, int& con
case TYPE_FUNC: gi = make_shared<FuncConstInfo>(this, vp); break;
case TYPE_TYPE: gi = make_shared<TypeConstInfo>(this, vp); break;
default: reporter->InternalError("bad constant type in CPPCompile::AddConstant"); break;
}

View file

@ -294,6 +294,7 @@ void CPPCompile::GenProlog() {
const_info[TYPE_TABLE] = CreateCompoundInitInfo("Table", "ValPtr");
const_info[TYPE_FUNC] = CreateCompoundInitInfo("Func", "ValPtr");
const_info[TYPE_FILE] = CreateCompoundInitInfo("File", "ValPtr");
const_info[TYPE_TYPE] = CreateCompoundInitInfo("TypeVal", "Ptr");
type_info = CreateCompoundInitInfo("Type", "Ptr");
attr_info = CreateCompoundInitInfo("Attr", "Ptr");

View file

@ -998,10 +998,23 @@ string CPPCompile::GenEQ(const Expr* e, GenType gt, const char* op, const char*
auto tag = op1->GetType()->Tag();
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())",
e->GetType(), gt);
if ( tag == TYPE_PATTERN ) {
auto gen1 = GenExpr(op1, GEN_DONT_CARE);
auto gen2 = GenExpr(op2, GEN_DONT_CARE);
string gen;
if ( op2->GetType()->Tag() == TYPE_PATTERN ) {
gen1 += "->AsPattern()->PatternText()";
gen2 += "->AsPattern()->PatternText()";
gen = "(strcmp(" + gen1 + ", " + gen2 + ") == 0)";
}
else
gen = gen1 + "->MatchExactly(" + gen2 + "->AsString())";
return NativeToGT(negated + gen, e->GetType(), gt);
}
if ( tag == TYPE_FUNC ) {
auto gen_f1 = GenExpr(op1, GEN_DONT_CARE);
@ -1156,8 +1169,12 @@ string CPPCompile::GenVectorOp(const Expr* e, string op1, string op2, const char
auto invoke = string(vec_op) + "__CPP(" + op1 + ", " + op2 + ")";
if ( op2_t->Yield()->Tag() == TYPE_STRING )
auto tag2 = op2_t->Yield()->Tag();
if ( tag2 == TYPE_STRING )
return string("str_vec_op_") + invoke;
if ( tag2 == TYPE_PATTERN )
return string("pat_vec_op_") + invoke;
auto gen = string("vec_op_") + invoke;

View file

@ -299,6 +299,11 @@ void FuncConstInfo::InitializerVals(std::vector<std::string>& ivs) const {
}
}
void TypeConstInfo::InitializerVals(std::vector<std::string>& ivs) const {
auto& t = tv->GetType()->AsTypeType()->GetType();
ivs.emplace_back(Fmt(t->Tag()));
}
AttrInfo::AttrInfo(CPPCompile* _c, const AttrPtr& attr) : CompoundItemInfo(_c) {
vals.emplace_back(Fmt(static_cast<int>(attr->Tag())));
auto a_e = attr->GetExpr();

View file

@ -467,6 +467,16 @@ private:
FuncVal* fv;
};
class TypeConstInfo : public CompoundItemInfo {
public:
TypeConstInfo(CPPCompile* _c, ValPtr v) : CompoundItemInfo(_c, v), tv(v->AsTypeVal()) {}
void InitializerVals(std::vector<std::string>& ivs) const override;
private:
TypeVal* tv;
};
// Initialization information for single attributes and sets of attributes.
class AttrInfo : public CompoundItemInfo {
public:

View file

@ -149,6 +149,14 @@ void CPP_IndexedInits<T>::Generate(InitsManager* im, std::vector<FuncValPtr>& iv
ivec[offset] = lookup_func__CPP(fn, num_bodies, hashes, im->Types(t));
}
template<class T>
void CPP_IndexedInits<T>::Generate(InitsManager* im, std::vector<TypeValPtr>& ivec, int offset,
ValElemVec& init_vals) const {
auto bt = base_type(static_cast<TypeTag>(init_vals[0]));
auto t = make_intrusive<TypeType>(bt);
ivec[offset] = make_intrusive<TypeVal>(t);
}
template<class T>
void CPP_IndexedInits<T>::Generate(InitsManager* im, std::vector<AttrPtr>& ivec, int offset,
ValElemVec& init_vals) const {
@ -216,6 +224,7 @@ template class CPP_IndexedInits<RecordValPtr>;
template class CPP_IndexedInits<TableValPtr>;
template class CPP_IndexedInits<FileValPtr>;
template class CPP_IndexedInits<FuncValPtr>;
template class CPP_IndexedInits<TypeValPtr>;
template class CPP_IndexedInits<AttrPtr>;
template class CPP_IndexedInits<AttributesPtr>;
template class CPP_IndexedInits<TypePtr>;

View file

@ -16,6 +16,7 @@ namespace zeek::detail {
using FileValPtr = IntrusivePtr<FileVal>;
using FuncValPtr = IntrusivePtr<FuncVal>;
using TypeValPtr = IntrusivePtr<TypeVal>;
class InitsManager;
@ -274,6 +275,7 @@ protected:
void Generate(InitsManager* im, std::vector<TableValPtr>& ivec, int offset, ValElemVec& init_vals) const;
void Generate(InitsManager* im, std::vector<FileValPtr>& ivec, int offset, ValElemVec& init_vals) const;
void Generate(InitsManager* im, std::vector<FuncValPtr>& ivec, int offset, ValElemVec& init_vals) const;
void Generate(InitsManager* im, std::vector<TypeValPtr>& ivec, int offset, ValElemVec& init_vals) const;
void Generate(InitsManager* im, std::vector<AttrPtr>& ivec, int offset, ValElemVec& init_vals) const;
void Generate(InitsManager* im, std::vector<AttributesPtr>& ivec, int offset, ValElemVec& init_vals) const;

View file

@ -3,6 +3,7 @@
#include "zeek/script_opt/CPP/RuntimeVec.h"
#include "zeek/Overflow.h"
#include "zeek/RE.h"
#include "zeek/ZeekString.h"
namespace zeek::detail {
@ -320,6 +321,29 @@ static VectorValPtr str_vec_op_kernel__CPP(const VectorValPtr& v1, const VectorV
return v_result;
}
// Kernel for element-by-element pattern relationals. "is_eq" governs
// whether the operation is equality (true) or inequality (false).
static VectorValPtr pat_vec_op_kernel__CPP(const VectorValPtr& v1, const VectorValPtr& v2, bool is_eq) {
auto res_type = make_intrusive<VectorType>(base_type(TYPE_BOOL));
auto v_result = make_intrusive<VectorVal>(res_type);
auto n = v1->Size();
for ( unsigned int i = 0; i < n; ++i ) {
auto v1_i = v1->ValAt(i);
auto v2_i = v2->ValAt(i);
if ( ! v1_i || ! v2_i )
continue;
auto p1 = v1_i->AsPattern();
auto p2 = v2_i->AsPattern();
bool elem_eq = strcmp(p1->PatternText(), p2->PatternText()) == 0;
v_result->Assign(i, val_mgr->Bool(elem_eq == is_eq));
}
return v_result;
}
VectorValPtr str_vec_op_lt__CPP(const VectorValPtr& v1, const VectorValPtr& v2) {
return str_vec_op_kernel__CPP(v1, v2, -1, -1);
}
@ -339,6 +363,13 @@ VectorValPtr str_vec_op_ge__CPP(const VectorValPtr& v1, const VectorValPtr& v2)
return str_vec_op_kernel__CPP(v1, v2, 0, 1);
}
VectorValPtr pat_vec_op_eq__CPP(const VectorValPtr& v1, const VectorValPtr& v2) {
return pat_vec_op_kernel__CPP(v1, v2, true);
}
VectorValPtr pat_vec_op_ne__CPP(const VectorValPtr& v1, const VectorValPtr& v2) {
return pat_vec_op_kernel__CPP(v1, v2, false);
}
VectorValPtr vector_select__CPP(const VectorValPtr& v1, VectorValPtr v2, VectorValPtr v3) {
auto vt = v2->GetType<VectorType>();
auto v_result = make_intrusive<VectorVal>(vt);

View file

@ -72,6 +72,10 @@ extern VectorValPtr str_vec_op_ne__CPP(const VectorValPtr& v1, const VectorValPt
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);
// Pattern vector relationals.
extern VectorValPtr pat_vec_op_eq__CPP(const VectorValPtr& v1, const VectorValPtr& v2);
extern VectorValPtr pat_vec_op_ne__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.