diff --git a/src/Expr.cc b/src/Expr.cc index e5608af449..8e48882a38 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -24,7 +24,7 @@ #include "zeek/broker/Data.h" #include "zeek/digest.h" #include "zeek/module_util.h" -#include "zeek/script_opt/ExprOptInfo.h" +#include "zeek/script_opt/Expr.h" #include "zeek/script_opt/ScriptOpt.h" namespace zeek::detail { diff --git a/src/Expr.h b/src/Expr.h index a8e3196e94..535a540900 100644 --- a/src/Expr.h +++ b/src/Expr.h @@ -1588,108 +1588,6 @@ private: TypePtr t; }; -class InlineExpr : public Expr { -public: - InlineExpr(ScriptFuncPtr sf, ListExprPtr arg_args, std::vector params, std::vector param_is_modified, - StmtPtr body, int frame_offset, TypePtr ret_type); - - bool IsPure() const override; - - const ScriptFuncPtr& Func() const { return sf; } - ListExprPtr Args() const { return args; } - StmtPtr Body() const { return body; } - - ValPtr Eval(Frame* f) const override; - - ExprPtr Duplicate() override; - - bool IsReduced(Reducer* c) const override; - bool HasReducedOps(Reducer* c) const override { return false; } - bool WillTransform(Reducer* c) const override { return true; } - ExprPtr Reduce(Reducer* c, StmtPtr& red_stmt) override; - - TraversalCode Traverse(TraversalCallback* cb) const override; - -protected: - void ExprDescribe(ODesc* d) const override; - - std::vector params; - std::vector param_is_modified; - int frame_offset; - ScriptFuncPtr sf; - ListExprPtr args; - StmtPtr body; -}; - -// A companion to AddToExpr that's for vector-append, instantiated during -// the reduction process. -class AppendToExpr : public BinaryExpr { -public: - AppendToExpr(ExprPtr op1, ExprPtr op2); - ValPtr Eval(Frame* f) const override; - - ExprPtr Duplicate() override; - - bool IsPure() const override { return false; } - bool IsReduced(Reducer* c) const override; - ExprPtr Reduce(Reducer* c, StmtPtr& red_stmt) override; - ExprPtr ReduceToSingleton(Reducer* c, StmtPtr& red_stmt) override; -}; - -// An internal class for reduced form. -class IndexAssignExpr : public BinaryExpr { -public: - // "op1[op2] = op3", all reduced. - IndexAssignExpr(ExprPtr op1, ExprPtr op2, ExprPtr op3); - - ValPtr Eval(Frame* f) const override; - - ExprPtr Duplicate() override; - - bool IsPure() const override { return false; } - bool IsReduced(Reducer* c) const override; - bool HasReducedOps(Reducer* c) const override; - ExprPtr Reduce(Reducer* c, StmtPtr& red_stmt) override; - ExprPtr ReduceToSingleton(Reducer* c, StmtPtr& red_stmt) override; - - ExprPtr GetOp3() const override final { return op3; } - void SetOp3(ExprPtr _op) override final { op3 = std::move(_op); } - - TraversalCode Traverse(TraversalCallback* cb) const override; - -protected: - void ExprDescribe(ODesc* d) const override; - - ExprPtr op3; // assignment RHS -}; - -// An internal class for reduced form. -class FieldLHSAssignExpr : public BinaryExpr { -public: - // "op1$field = RHS", where RHS is reduced with respect to - // ReduceToFieldAssignment(). - FieldLHSAssignExpr(ExprPtr op1, ExprPtr op2, const char* field_name, int field); - - const char* FieldName() const { return field_name; } - int Field() const { return field; } - - ValPtr Eval(Frame* f) const override; - - ExprPtr Duplicate() override; - - bool IsPure() const override { return false; } - bool IsReduced(Reducer* c) const override; - bool HasReducedOps(Reducer* c) const override; - ExprPtr Reduce(Reducer* c, StmtPtr& red_stmt) override; - ExprPtr ReduceToSingleton(Reducer* c, StmtPtr& red_stmt) override; - -protected: - void ExprDescribe(ODesc* d) const override; - - const char* field_name; - int field; -}; - // Expression to explicitly capture conversion to an "any" type, rather // than it occurring implicitly during script interpretation. class CoerceToAnyExpr : public UnaryExpr { @@ -1713,53 +1611,6 @@ protected: ExprPtr Duplicate() override; }; -// ... and for conversion from a "vector of any" type. -class CoerceFromAnyVecExpr : public UnaryExpr { -public: - // to_type is yield type, not VectorType. - CoerceFromAnyVecExpr(ExprPtr op, TypePtr to_type); - - // Can't use UnaryExpr's Eval() because it will do folding - // over the individual vector elements. - ValPtr Eval(Frame* f) const override; - -protected: - ExprPtr Duplicate() override; -}; - -// Expression used to explicitly capture [a, b, c, ...] = x assignments. -class AnyIndexExpr : public UnaryExpr { -public: - AnyIndexExpr(ExprPtr op, int index); - - int Index() const { return index; } - -protected: - ValPtr Fold(Val* v) const override; - - void ExprDescribe(ODesc* d) const override; - - ExprPtr Duplicate() override; - ExprPtr Reduce(Reducer* c, StmtPtr& red_stmt) override; - - int index; -}; - -// Used internally for optimization, when a placeholder is needed. -class NopExpr : public Expr { -public: - explicit NopExpr() : Expr(EXPR_NOP) {} - - ValPtr Eval(Frame* f) const override; - - ExprPtr Duplicate() override; - - TraversalCode Traverse(TraversalCallback* cb) const override; - -protected: - void ExprDescribe(ODesc* d) const override; -}; - // Assigns v1[v2] = v3. Returns an error message, or nullptr on success. // Factored out so that compiled code can call it as well as the interpreter. extern const char* assign_to_index(ValPtr v1, ValPtr v2, ValPtr v3, bool& iterators_invalidated); diff --git a/src/script_opt/CPP/Exprs.cc b/src/script_opt/CPP/Exprs.cc index 91e6cee6c7..24ab36f4b4 100644 --- a/src/script_opt/CPP/Exprs.cc +++ b/src/script_opt/CPP/Exprs.cc @@ -481,7 +481,8 @@ string CPPCompile::GenAddToExpr(const Expr* e, GenType gt, bool top_level) { if ( t->Tag() == TYPE_VECTOR ) { auto& rt = rhs->GetType(); - if ( e->AsAddToExpr()->IsVectorElemAppend() ) + ASSERT(e->Tag() == EXPR_ADD_TO); + if ( static_cast(e)->IsVectorElemAppend() ) add_to_func = "vector_append__CPP"; else add_to_func = "vector_vec_append__CPP"; diff --git a/src/script_opt/CSE.cc b/src/script_opt/CSE.cc index 3433ed1323..2d97038670 100644 --- a/src/script_opt/CSE.cc +++ b/src/script_opt/CSE.cc @@ -2,6 +2,8 @@ #include "zeek/script_opt/CSE.h" +#include "zeek/script_opt/Expr.h" + namespace zeek::detail { CSE_ValidityChecker::CSE_ValidityChecker(std::shared_ptr _pfs, const std::vector& _ids, @@ -108,7 +110,7 @@ TraversalCode CSE_ValidityChecker::PreExpr(const Expr* e) { case EXPR_FIELD_LHS_ASSIGN: { auto lhs = e->GetOp1(); auto lhs_aggr_id = lhs->AsNameExpr()->Id(); - auto lhs_field = e->AsFieldLHSAssignExpr()->Field(); + auto lhs_field = static_cast(e)->Field(); if ( CheckID(lhs_aggr_id, true) ) return TC_ABORTALL; diff --git a/src/script_opt/Expr.cc b/src/script_opt/Expr.cc index c68739af3a..6904da0337 100644 --- a/src/script_opt/Expr.cc +++ b/src/script_opt/Expr.cc @@ -2,7 +2,7 @@ // Optimization-related methods for Expr classes. -#include "zeek/Expr.h" +#include "zeek/script_opt/Expr.h" #include "zeek/Desc.h" #include "zeek/Frame.h" @@ -11,6 +11,7 @@ #include "zeek/Scope.h" #include "zeek/Stmt.h" #include "zeek/Traverse.h" +#include "zeek/script_opt/FuncInfo.h" #include "zeek/script_opt/Inline.h" #include "zeek/script_opt/Reduce.h" @@ -33,21 +34,16 @@ FieldExpr* Expr::AsFieldExpr() { return (FieldExpr*)this; } +FieldAssignExpr* Expr::AsFieldAssignExpr() { + CHECK_TAG(tag, EXPR_FIELD_ASSIGN, "ExprVal::AsFieldAssignExpr", expr_name) + return (FieldAssignExpr*)this; +} + IntrusivePtr Expr::AsFieldAssignExprPtr() { CHECK_TAG(tag, EXPR_FIELD_ASSIGN, "ExprVal::AsFieldAssignExpr", expr_name) return {NewRef{}, (FieldAssignExpr*)this}; } -const IndexAssignExpr* Expr::AsIndexAssignExpr() const { - CHECK_TAG(tag, EXPR_INDEX_ASSIGN, "ExprVal::AsIndexAssignExpr", expr_name) - return (const IndexAssignExpr*)this; -} - -const FieldLHSAssignExpr* Expr::AsFieldLHSAssignExpr() const { - CHECK_TAG(tag, EXPR_FIELD_LHS_ASSIGN, "ExprVal::AsFieldLHSAssignExpr", expr_name) - return (const FieldLHSAssignExpr*)this; -} - HasFieldExpr* Expr::AsHasFieldExpr() { CHECK_TAG(tag, EXPR_HAS_FIELD, "ExprVal::AsHasFieldExpr", expr_name) return (HasFieldExpr*)this; @@ -58,11 +54,6 @@ const HasFieldExpr* Expr::AsHasFieldExpr() const { return (const HasFieldExpr*)this; } -const AddToExpr* Expr::AsAddToExpr() const { - CHECK_TAG(tag, EXPR_ADD_TO, "ExprVal::AsAddToExpr", expr_name) - return (const AddToExpr*)this; -} - const IsExpr* Expr::AsIsExpr() const { CHECK_TAG(tag, EXPR_IS, "ExprVal::AsIsExpr", expr_name) return (const IsExpr*)this; @@ -73,56 +64,11 @@ CallExpr* Expr::AsCallExpr() { return (CallExpr*)this; } -FieldAssignExpr* Expr::AsFieldAssignExpr() { - CHECK_TAG(tag, EXPR_FIELD_ASSIGN, "ExprVal::AsFieldAssignExpr", expr_name) - return (FieldAssignExpr*)this; -} - -const RecordCoerceExpr* Expr::AsRecordCoerceExpr() const { - CHECK_TAG(tag, EXPR_RECORD_COERCE, "ExprVal::AsRecordCoerceExpr", expr_name) - return (const RecordCoerceExpr*)this; -} - -RecordConstructorExpr* Expr::AsRecordConstructorExpr() { - CHECK_TAG(tag, EXPR_RECORD_CONSTRUCTOR, "ExprVal::AsRecordConstructorExpr", expr_name) - return (RecordConstructorExpr*)this; -} - -const RecordConstructorExpr* Expr::AsRecordConstructorExpr() const { - CHECK_TAG(tag, EXPR_RECORD_CONSTRUCTOR, "ExprVal::AsRecordConstructorExpr", expr_name) - return (const RecordConstructorExpr*)this; -} - -const TableConstructorExpr* Expr::AsTableConstructorExpr() const { - CHECK_TAG(tag, EXPR_TABLE_CONSTRUCTOR, "ExprVal::AsTableConstructorExpr", expr_name) - return (const TableConstructorExpr*)this; -} - -const SetConstructorExpr* Expr::AsSetConstructorExpr() const { - CHECK_TAG(tag, EXPR_SET_CONSTRUCTOR, "ExprVal::AsSetConstructorExpr", expr_name) - return (const SetConstructorExpr*)this; -} - RefExpr* Expr::AsRefExpr() { CHECK_TAG(tag, EXPR_REF, "ExprVal::AsRefExpr", expr_name) return (RefExpr*)this; } -const InlineExpr* Expr::AsInlineExpr() const { - CHECK_TAG(tag, EXPR_INLINE, "ExprVal::AsInlineExpr", expr_name) - return (const InlineExpr*)this; -} - -AnyIndexExpr* Expr::AsAnyIndexExpr() { - CHECK_TAG(tag, EXPR_ANY_INDEX, "ExprVal::AsAnyIndexExpr", expr_name) - return (AnyIndexExpr*)this; -} - -const AnyIndexExpr* Expr::AsAnyIndexExpr() const { - CHECK_TAG(tag, EXPR_ANY_INDEX, "ExprVal::AsAnyIndexExpr", expr_name) - return (const AnyIndexExpr*)this; -} - LambdaExpr* Expr::AsLambdaExpr() { CHECK_TAG(tag, EXPR_LAMBDA, "ExprVal::AsLambdaExpr", expr_name) return (LambdaExpr*)this; @@ -994,7 +940,7 @@ ExprPtr ModExpr::Duplicate() { // nullptr, and the caller should have ensured that the starting point is // a disjunction (since a bare "/pat/ in var" by itself isn't a "cascade" // and doesn't present a potential optimization opportunity. -static bool is_pattern_cascade(const ExprPtr& e, IDPtr& id, std::vector& patterns) { +static bool is_pattern_cascade(const Expr* e, IDPtr& id, std::vector& patterns) { auto lhs = e->GetOp1(); auto rhs = e->GetOp2(); @@ -1016,7 +962,7 @@ static bool is_pattern_cascade(const ExprPtr& e, IDPtr& id, std::vectorTag() != EXPR_OR_OR ) return false; - return is_pattern_cascade(lhs, id, patterns) && is_pattern_cascade(rhs, id, patterns); + return is_pattern_cascade(lhs.get(), id, patterns) && is_pattern_cascade(rhs.get(), id, patterns); } // Given a set of pattern constants, returns a disjunction that @@ -1043,10 +989,7 @@ bool BoolExpr::WillTransform(Reducer* c) const { return ! IsVector(op1->GetType( bool BoolExpr::WillTransformInConditional(Reducer* c) const { IDPtr common_id; std::vector patterns; - - ExprPtr e_ptr = {NewRef{}, (Expr*)this}; - - return tag == EXPR_OR_OR && is_pattern_cascade(e_ptr, common_id, patterns); + return tag == EXPR_OR_OR && is_pattern_cascade(this, common_id, patterns); } ExprPtr BoolExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { @@ -1055,12 +998,8 @@ ExprPtr BoolExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { // efficient to match. IDPtr common_id = nullptr; std::vector patterns; - if ( tag == EXPR_OR_OR && is_pattern_cascade(ThisPtr(), common_id, patterns) ) { - auto new_pat = build_disjunction(patterns, this); - auto new_id = with_location_of(make_intrusive(common_id), this); - auto new_node = with_location_of(make_intrusive(new_pat, new_id), this); - return new_node->Reduce(c, red_stmt); - } + if ( tag == EXPR_OR_OR && is_pattern_cascade(this, common_id, patterns) ) + return TransformToConditional(c, red_stmt); // It's either an EXPR_AND_AND or an EXPR_OR_OR. bool is_and = (tag == EXPR_AND_AND); @@ -1115,6 +1054,23 @@ ExprPtr BoolExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { return TransformMe(cond_red, c, red_stmt); } +ExprPtr BoolExpr::TransformToConditional(Reducer* c, StmtPtr& red_stmt) { + // This only happens for pattern cascades. + + // Here in some contexts we're re-doing work that our caller did, but + // these cascades are quite rare, and re-doing the work keeps the + // coupling simpler. + IDPtr common_id = nullptr; + std::vector patterns; + auto is_cascade = is_pattern_cascade(this, common_id, patterns); + ASSERT(is_cascade); + + auto new_pat = build_disjunction(patterns, this); + auto new_id = with_location_of(make_intrusive(common_id), this); + auto new_node = with_location_of(make_intrusive(new_pat, new_id), this); + return new_node->Reduce(c, red_stmt); +} + bool BoolExpr::IsTrue(const ExprPtr& e) const { if ( ! e->IsConst() ) return false; diff --git a/src/script_opt/Expr.h b/src/script_opt/Expr.h new file mode 100644 index 0000000000..3d7bc382c0 --- /dev/null +++ b/src/script_opt/Expr.h @@ -0,0 +1,225 @@ +#include "zeek/Expr.h" + +namespace zeek::detail { + +class InlineExpr : public Expr { +public: + InlineExpr(ScriptFuncPtr sf, ListExprPtr arg_args, std::vector params, std::vector param_is_modified, + StmtPtr body, int frame_offset, TypePtr ret_type); + + bool IsPure() const override; + + const ScriptFuncPtr& Func() const { return sf; } + ListExprPtr Args() const { return args; } + StmtPtr Body() const { return body; } + + ValPtr Eval(Frame* f) const override; + + ExprPtr Duplicate() override; + + bool IsReduced(Reducer* c) const override; + bool HasReducedOps(Reducer* c) const override { return false; } + bool WillTransform(Reducer* c) const override { return true; } + ExprPtr Reduce(Reducer* c, StmtPtr& red_stmt) override; + + TraversalCode Traverse(TraversalCallback* cb) const override; + +protected: + void ExprDescribe(ODesc* d) const override; + + std::vector params; + std::vector param_is_modified; + int frame_offset; + ScriptFuncPtr sf; + ListExprPtr args; + StmtPtr body; +}; + +// A companion to AddToExpr that's for vector-append, instantiated during +// the reduction process. +class AppendToExpr : public BinaryExpr { +public: + AppendToExpr(ExprPtr op1, ExprPtr op2); + ValPtr Eval(Frame* f) const override; + + ExprPtr Duplicate() override; + + bool IsPure() const override { return false; } + bool IsReduced(Reducer* c) const override; + ExprPtr Reduce(Reducer* c, StmtPtr& red_stmt) override; + ExprPtr ReduceToSingleton(Reducer* c, StmtPtr& red_stmt) override; +}; + +// An internal class for reduced form. +class IndexAssignExpr : public BinaryExpr { +public: + // "op1[op2] = op3", all reduced. + IndexAssignExpr(ExprPtr op1, ExprPtr op2, ExprPtr op3); + + ValPtr Eval(Frame* f) const override; + + ExprPtr Duplicate() override; + + bool IsPure() const override { return false; } + bool IsReduced(Reducer* c) const override; + bool HasReducedOps(Reducer* c) const override; + ExprPtr Reduce(Reducer* c, StmtPtr& red_stmt) override; + ExprPtr ReduceToSingleton(Reducer* c, StmtPtr& red_stmt) override; + + ExprPtr GetOp3() const override final { return op3; } + void SetOp3(ExprPtr _op) override final { op3 = std::move(_op); } + + TraversalCode Traverse(TraversalCallback* cb) const override; + +protected: + void ExprDescribe(ODesc* d) const override; + + ExprPtr op3; // assignment RHS +}; + +// An internal class for reduced form. +class FieldLHSAssignExpr : public BinaryExpr { +public: + // "op1$field = RHS", where RHS is reduced with respect to + // ReduceToFieldAssignment(). + FieldLHSAssignExpr(ExprPtr op1, ExprPtr op2, const char* field_name, int field); + + const char* FieldName() const { return field_name; } + int Field() const { return field; } + + ValPtr Eval(Frame* f) const override; + + ExprPtr Duplicate() override; + + bool IsPure() const override { return false; } + bool IsReduced(Reducer* c) const override; + bool HasReducedOps(Reducer* c) const override; + ExprPtr Reduce(Reducer* c, StmtPtr& red_stmt) override; + ExprPtr ReduceToSingleton(Reducer* c, StmtPtr& red_stmt) override; + +protected: + void ExprDescribe(ODesc* d) const override; + + const char* field_name; + int field; +}; + +// ... and for conversion from a "vector of any" type. +class CoerceFromAnyVecExpr : public UnaryExpr { +public: + // to_type is yield type, not VectorType. + CoerceFromAnyVecExpr(ExprPtr op, TypePtr to_type); + + // Can't use UnaryExpr's Eval() because it will do folding + // over the individual vector elements. + ValPtr Eval(Frame* f) const override; + +protected: + ExprPtr Duplicate() override; +}; + +// Expression used to explicitly capture [a, b, c, ...] = x assignments. +class AnyIndexExpr : public UnaryExpr { +public: + AnyIndexExpr(ExprPtr op, int index); + + int Index() const { return index; } + +protected: + ValPtr Fold(Val* v) const override; + + void ExprDescribe(ODesc* d) const override; + + ExprPtr Duplicate() override; + ExprPtr Reduce(Reducer* c, StmtPtr& red_stmt) override; + + int index; +}; + +class ScriptOptBuiltinExpr : public Expr { +public: + enum SOBuiltInTag { + MINIMUM, + MAXIMUM, + HAS_ELEMENTS, + FUNC_ID_STRING, + }; + + ScriptOptBuiltinExpr(SOBuiltInTag tag, ExprPtr arg1, ExprPtr arg2 = nullptr); + ScriptOptBuiltinExpr(SOBuiltInTag tag, CallExprPtr call); + + auto Tag() const { return tag; } + + ExprPtr GetOp1() const override final { return arg1; } + ExprPtr GetOp2() const override final { return arg2; } + + void SetOp1(ExprPtr op) override final { arg1 = std::move(op); } + void SetOp2(ExprPtr op) override final { arg2 = std::move(op); } + + ValPtr Eval(Frame* f) const override; + +protected: + void ExprDescribe(ODesc* d) const override; + + TraversalCode Traverse(TraversalCallback* cb) const override; + bool IsPure() const override; + + // Optimization-related: + ExprPtr Duplicate() override; + bool IsReduced(Reducer* c) const override; + bool HasReducedOps(Reducer* c) const override { return IsReduced(c); } + ExprPtr Reduce(Reducer* c, StmtPtr& red_stmt) override; + + void BuildEvalExpr(); + + SOBuiltInTag tag; + ExprPtr arg1; + ExprPtr arg2; + ExprPtr eval_expr; + CallExprPtr call; +}; + +// Used internally for optimization, when a placeholder is needed. +class NopExpr : public Expr { +public: + explicit NopExpr() : Expr(EXPR_NOP) {} + + ValPtr Eval(Frame* f) const override; + + ExprPtr Duplicate() override; + + TraversalCode Traverse(TraversalCallback* cb) const override; + +protected: + void ExprDescribe(ODesc* d) const override; +}; + +// Class for tracking whether a given expression has side effects. Currently, +// we just need to know whether Yes-it-does or No-it-doesn't, so the structure +// is very simple. + +class ExprSideEffects { +public: + ExprSideEffects(bool _has_side_effects) : has_side_effects(_has_side_effects) {} + + bool HasSideEffects() const { return has_side_effects; } + +protected: + bool has_side_effects; +}; + +class ExprOptInfo { +public: + // The AST number of the statement in which this expression + // appears. + int stmt_num = -1; // -1 = not assigned yet + + auto& SideEffects() { return side_effects; } + +protected: + // This optional value missing means "we haven't yet determined the + // side effects". + std::optional side_effects; +}; + +}; // namespace zeek::detail diff --git a/src/script_opt/ExprOptInfo.h b/src/script_opt/ExprOptInfo.h deleted file mode 100644 index be304f0bb5..0000000000 --- a/src/script_opt/ExprOptInfo.h +++ /dev/null @@ -1,38 +0,0 @@ -// See the file "COPYING" in the main distribution directory for copyright. - -// Auxiliary information associated with expressions to aid script -// optimization. - -#pragma once - -namespace zeek::detail { - -// Class for tracking whether a given expression has side effects. Currently, -// we just need to know whether Yes-it-does or No-it-doesn't, so the structure -// is very simple. - -class ExprSideEffects { -public: - ExprSideEffects(bool _has_side_effects) : has_side_effects(_has_side_effects) {} - - bool HasSideEffects() const { return has_side_effects; } - -protected: - bool has_side_effects; -}; - -class ExprOptInfo { -public: - // The AST number of the statement in which this expression - // appears. - int stmt_num = -1; // -1 = not assigned yet - - auto& SideEffects() { return side_effects; } - -protected: - // This optional value missing means "we haven't yet determined the - // side effects". - std::optional side_effects; -}; - -} // namespace zeek::detail diff --git a/src/script_opt/GenIDDefs.cc b/src/script_opt/GenIDDefs.cc index 9fb93e61fd..fde76e9c95 100644 --- a/src/script_opt/GenIDDefs.cc +++ b/src/script_opt/GenIDDefs.cc @@ -6,7 +6,7 @@ #include "zeek/Expr.h" #include "zeek/Reporter.h" #include "zeek/Scope.h" -#include "zeek/script_opt/ExprOptInfo.h" +#include "zeek/script_opt/Expr.h" #include "zeek/script_opt/ScriptOpt.h" #include "zeek/script_opt/StmtOptInfo.h" diff --git a/src/script_opt/Inline.cc b/src/script_opt/Inline.cc index 8cf2479bd5..fb5c3fb61d 100644 --- a/src/script_opt/Inline.cc +++ b/src/script_opt/Inline.cc @@ -5,6 +5,7 @@ #include "zeek/Desc.h" #include "zeek/EventRegistry.h" #include "zeek/module_util.h" +#include "zeek/script_opt/Expr.h" #include "zeek/script_opt/FuncInfo.h" #include "zeek/script_opt/ProfileFunc.h" #include "zeek/script_opt/ScriptOpt.h" diff --git a/src/script_opt/Stmt.cc b/src/script_opt/Stmt.cc index 4593a8133c..e95395e7d4 100644 --- a/src/script_opt/Stmt.cc +++ b/src/script_opt/Stmt.cc @@ -9,6 +9,7 @@ #include "zeek/Frame.h" #include "zeek/Reporter.h" #include "zeek/Traverse.h" +#include "zeek/script_opt/Expr.h" #include "zeek/script_opt/IDOptInfo.h" #include "zeek/script_opt/Reduce.h" diff --git a/src/script_opt/ZAM/Compile.h b/src/script_opt/ZAM/Compile.h index ba9fd8f08f..47c34e4a7f 100644 --- a/src/script_opt/ZAM/Compile.h +++ b/src/script_opt/ZAM/Compile.h @@ -5,6 +5,7 @@ #pragma once #include "zeek/Event.h" +#include "zeek/script_opt/Expr.h" #include "zeek/script_opt/ProfileFunc.h" #include "zeek/script_opt/UseDefs.h" #include "zeek/script_opt/ZAM/ZBody.h" diff --git a/src/script_opt/ZAM/Expr.cc b/src/script_opt/ZAM/Expr.cc index 65530ca56b..50e64f698a 100644 --- a/src/script_opt/ZAM/Expr.cc +++ b/src/script_opt/ZAM/Expr.cc @@ -835,7 +835,8 @@ const ZAMStmt ZAMCompiler::BuildLambda(int n_slot, LambdaExpr* le) { } const ZAMStmt ZAMCompiler::AssignVecElems(const Expr* e) { - auto index_assign = e->AsIndexAssignExpr(); + ASSERT(e->Tag() == EXPR_INDEX_ASSIGN); + auto index_assign = static_cast(e); auto op1 = index_assign->GetOp1(); const auto& t1 = op1->GetType(); @@ -925,7 +926,8 @@ const ZAMStmt ZAMCompiler::AssignVecElems(const Expr* e) { } const ZAMStmt ZAMCompiler::AssignTableElem(const Expr* e) { - auto index_assign = e->AsIndexAssignExpr(); + ASSERT(e->Tag() == EXPR_INDEX_ASSIGN); + auto index_assign = static_cast(e); auto op1 = index_assign->GetOp1()->AsNameExpr(); auto op2 = index_assign->GetOp2()->AsListExpr(); @@ -1153,7 +1155,8 @@ const ZAMStmt ZAMCompiler::ConstructTable(const NameExpr* n, const Expr* e) { auto z = GenInst(OP_CONSTRUCT_TABLE_VV, n, width); z.aux = InternalBuildVals(con, width + 1); z.t = tt; - z.aux->attrs = e->AsTableConstructorExpr()->GetAttrs(); + ASSERT(e->Tag() == EXPR_TABLE_CONSTRUCTOR); + z.aux->attrs = static_cast(e)->GetAttrs(); auto zstmt = AddInst(z); @@ -1191,13 +1194,15 @@ const ZAMStmt ZAMCompiler::ConstructSet(const NameExpr* n, const Expr* e) { auto z = GenInst(OP_CONSTRUCT_SET_VV, n, width); z.aux = InternalBuildVals(con, width); z.t = e->GetType(); - z.aux->attrs = e->AsSetConstructorExpr()->GetAttrs(); + ASSERT(e->Tag() == EXPR_SET_CONSTRUCTOR); + z.aux->attrs = static_cast(e)->GetAttrs(); return AddInst(z); } const ZAMStmt ZAMCompiler::ConstructRecord(const NameExpr* n, const Expr* e) { - auto rc = e->AsRecordConstructorExpr(); + ASSERT(e->Tag() == EXPR_RECORD_CONSTRUCTOR); + auto rc = static_cast(e); auto rt = e->GetType()->AsRecordType(); auto aux = InternalBuildVals(rc->Op().get()); @@ -1352,7 +1357,8 @@ const ZAMStmt ZAMCompiler::ArithCoerce(const NameExpr* n, const Expr* e) { } const ZAMStmt ZAMCompiler::RecordCoerce(const NameExpr* n, const Expr* e) { - auto r = e->AsRecordCoerceExpr(); + ASSERT(e->Tag() == EXPR_RECORD_COERCE); + auto r = static_cast(e); auto op = r->GetOp1()->AsNameExpr(); int op_slot = FrameSlot(op);