From f48f3af79abd24e44f86e49c6e8ba5780549ea3f Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Fri, 7 Mar 2025 09:55:15 -0800 Subject: [PATCH] -O gen-C++ support for pattern vector comparisons --- src/script_opt/CPP/Exprs.cc | 6 +++++- src/script_opt/CPP/RuntimeVec.cc | 31 +++++++++++++++++++++++++++++++ src/script_opt/CPP/RuntimeVec.h | 4 ++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/script_opt/CPP/Exprs.cc b/src/script_opt/CPP/Exprs.cc index 5a39d4d850..df3fda0aa8 100644 --- a/src/script_opt/CPP/Exprs.cc +++ b/src/script_opt/CPP/Exprs.cc @@ -1156,8 +1156,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; diff --git a/src/script_opt/CPP/RuntimeVec.cc b/src/script_opt/CPP/RuntimeVec.cc index fc5ccc6f1f..7c6e6ab717 100644 --- a/src/script_opt/CPP/RuntimeVec.cc +++ b/src/script_opt/CPP/RuntimeVec.cc @@ -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(base_type(TYPE_BOOL)); + auto v_result = make_intrusive(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(); auto v_result = make_intrusive(vt); diff --git a/src/script_opt/CPP/RuntimeVec.h b/src/script_opt/CPP/RuntimeVec.h index 14c852b9c8..1e83159f55 100644 --- a/src/script_opt/CPP/RuntimeVec.h +++ b/src/script_opt/CPP/RuntimeVec.h @@ -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.