diff --git a/src/script_opt/CPP/Exprs.cc b/src/script_opt/CPP/Exprs.cc index ad8f49e513..f65be5eb84 100644 --- a/src/script_opt/CPP/Exprs.cc +++ b/src/script_opt/CPP/Exprs.cc @@ -580,13 +580,13 @@ string CPPCompile::GenArithCoerceExpr(const Expr* e, GenType gt) if ( same_type(t, op->GetType()) ) return GenExpr(op, gt); - bool is_vec = t->Tag() == TYPE_VECTOR; - - auto coerce_t = is_vec ? t->Yield() : t; + if ( t->Tag() == TYPE_VECTOR ) + return string("vector_coerce_to__CPP(") + GenExpr(op, GEN_NATIVE) + ", " + GenTypeName(t) + + ")"; string cast_name; - switch ( coerce_t->InternalType() ) + switch ( t->InternalType() ) { case TYPE_INTERNAL_INT: cast_name = "bro_int_t"; @@ -602,10 +602,6 @@ string CPPCompile::GenArithCoerceExpr(const Expr* e, GenType gt) reporter->InternalError("bad type in arithmetic coercion"); } - if ( is_vec ) - return string("vec_coerce_to_") + cast_name + "__CPP(" + GenExpr(op, GEN_NATIVE) + ", " + - GenTypeName(t) + ")"; - return NativeToGT(cast_name + "(" + GenExpr(op, GEN_NATIVE) + ")", t, gt); } @@ -1115,10 +1111,12 @@ string CPPCompile::GenListAssign(const ExprPtr& lhs, const ExprPtr& rhs) string CPPCompile::GenVectorOp(const Expr* e, string op, const char* vec_op) { - auto gen = string("vec_op_") + vec_op + "__CPP(" + op + ")"; + auto t = e->GetType(); + auto gen_t = GenTypeName(t); + auto gen = string("vec_op_") + vec_op + "__CPP(" + op + ", " + gen_t + ")"; - if ( ! IsArithmetic(e->GetType()->Yield()->Tag()) ) - gen = string("vector_coerce_to__CPP(") + gen + ", " + GenTypeName(e->GetType()) + ")"; + if ( ! IsArithmetic(t->Yield()->Tag()) ) + gen = string("vector_coerce_to__CPP(") + gen + ", " + gen_t + ")"; return gen; } diff --git a/src/script_opt/CPP/RuntimeVec.cc b/src/script_opt/CPP/RuntimeVec.cc index c8279e7988..2607a2fb87 100644 --- a/src/script_opt/CPP/RuntimeVec.cc +++ b/src/script_opt/CPP/RuntimeVec.cc @@ -47,8 +47,9 @@ static VectorTypePtr base_vector_type__CPP(const VectorTypePtr& vt) #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(op v_i)); \ + auto v_i = v->ValAt(i); \ + if ( v_i ) \ + v_result->Assign(i, make_intrusive(op v_i->accessor())); \ } // A macro (since it's beyond my templating skillz to deal with the @@ -58,9 +59,9 @@ static VectorTypePtr base_vector_type__CPP(const VectorTypePtr& vt) // 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) \ + VectorValPtr vec_op_##name##__CPP(const VectorValPtr& v, const TypePtr& t) \ { \ - auto vt = base_vector_type__CPP(v->GetType()); \ + auto vt = base_vector_type__CPP(cast_intrusive(t)); \ auto v_result = make_intrusive(vt); \ \ switch ( vt->Yield()->InternalType() ) \ @@ -105,9 +106,10 @@ VEC_OP1(comp, ~, ) #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(v1_i op v2_i)); \ + auto v1_i = v1->ValAt(i); \ + auto v2_i = v2->ValAt(i); \ + if ( v1_i && v2_i ) \ + v_result->Assign(i, make_intrusive(v1_i->accessor() op v2_i->accessor())); \ } // Analogous to VEC_OP1, instantiates a function for a given binary operation, @@ -387,27 +389,42 @@ VectorValPtr vector_coerce_to__CPP(const VectorValPtr& v, const TypePtr& targ) for ( unsigned int i = 0; i < n; ++i ) { ValPtr v_i = v->ValAt(i); + if ( ! v_i ) + continue; + ValPtr r_i; switch ( ytag ) { case TYPE_BOOL: - r_i = val_mgr->Bool(v_i->AsBool()); + r_i = val_mgr->Bool(v_i->CoerceToInt() != 0); + break; + + case TYPE_INT: + r_i = val_mgr->Int(v_i->CoerceToInt()); + break; + + case TYPE_COUNT: + r_i = val_mgr->Count(v_i->CoerceToUnsigned()); break; case TYPE_ENUM: - r_i = yt->AsEnumType()->GetEnumVal(v_i->AsInt()); + r_i = yt->AsEnumType()->GetEnumVal(v_i->CoerceToInt()); break; case TYPE_PORT: - r_i = make_intrusive(v_i->AsCount()); + r_i = make_intrusive(v_i->CoerceToUnsigned()); + break; + + case TYPE_DOUBLE: + r_i = make_intrusive(v_i->CoerceToDouble()); break; case TYPE_INTERVAL: - r_i = make_intrusive(v_i->AsDouble()); + r_i = make_intrusive(v_i->CoerceToDouble()); break; case TYPE_TIME: - r_i = make_intrusive(v_i->AsDouble()); + r_i = make_intrusive(v_i->CoerceToDouble()); break; default: @@ -420,40 +437,10 @@ VectorValPtr vector_coerce_to__CPP(const VectorValPtr& v, const TypePtr& targ) return v_result; } -VectorValPtr vec_coerce_to_bro_int_t__CPP(const VectorValPtr& v, TypePtr targ) +VectorValPtr vec_scalar_mixed_with_vector() { - auto res_t = cast_intrusive(targ); - auto v_result = make_intrusive(move(res_t)); - auto n = v->Size(); - - for ( unsigned int i = 0; i < n; ++i ) - v_result->Assign(i, val_mgr->Int(v->IntAt(i))); - - return v_result; - } - -VectorValPtr vec_coerce_to_bro_uint_t__CPP(const VectorValPtr& v, TypePtr targ) - { - auto res_t = cast_intrusive(targ); - auto v_result = make_intrusive(move(res_t)); - auto n = v->Size(); - - for ( unsigned int i = 0; i < n; ++i ) - v_result->Assign(i, val_mgr->Count(v->CountAt(i))); - - return v_result; - } - -VectorValPtr vec_coerce_to_double__CPP(const VectorValPtr& v, TypePtr targ) - { - auto res_t = cast_intrusive(targ); - auto v_result = make_intrusive(move(res_t)); - auto n = v->Size(); - - for ( unsigned int i = 0; i < n; ++i ) - v_result->Assign(i, make_intrusive(v->DoubleAt(i))); - - return v_result; + reporter->CPPRuntimeError("vector-mixed-with-scalar operations not supported"); + return nullptr; } } // namespace zeek::detail diff --git a/src/script_opt/CPP/RuntimeVec.h b/src/script_opt/CPP/RuntimeVec.h index 96cc1cfc67..2dfe1374c3 100644 --- a/src/script_opt/CPP/RuntimeVec.h +++ b/src/script_opt/CPP/RuntimeVec.h @@ -22,10 +22,10 @@ inline ValPtr vector_append__CPP(VectorValPtr v1, ValPtr v2) } // Unary vector operations. -extern VectorValPtr vec_op_pos__CPP(const VectorValPtr& v); -extern VectorValPtr vec_op_neg__CPP(const VectorValPtr& v); -extern VectorValPtr vec_op_not__CPP(const VectorValPtr& v); -extern VectorValPtr vec_op_comp__CPP(const VectorValPtr& v); +extern VectorValPtr vec_op_pos__CPP(const VectorValPtr& v, const TypePtr& t); +extern VectorValPtr vec_op_neg__CPP(const VectorValPtr& v, const TypePtr& t); +extern VectorValPtr vec_op_not__CPP(const VectorValPtr& v, const TypePtr& t); +extern VectorValPtr vec_op_comp__CPP(const VectorValPtr& v, const TypePtr& t); // Binary vector operations. extern VectorValPtr vec_op_add__CPP(const VectorValPtr& v1, const VectorValPtr& v2); @@ -81,8 +81,7 @@ extern VectorValPtr vec_coerce_to_bro_uint_t__CPP(const VectorValPtr& v, TypePtr extern VectorValPtr vec_coerce_to_double__CPP(const VectorValPtr& v, TypePtr targ); // A dummy function used during code generation for unsupported operations -// that mix vector and scalar arguments. We don't define it in RuntimeVec.cc -// so that it'll generate a linking error. +// that mix vector and scalar arguments. extern VectorValPtr vec_scalar_mixed_with_vector(); } // namespace zeek::detail