factor script optimization Expr AST nodes out of main AST header

This commit is contained in:
Vern Paxson 2024-04-08 18:26:52 -04:00 committed by Tim Wojtulewicz
parent 01fd30dda9
commit 7c8c83efc4
12 changed files with 276 additions and 270 deletions

View file

@ -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 {

View file

@ -1588,108 +1588,6 @@ private:
TypePtr t;
};
class InlineExpr : public Expr {
public:
InlineExpr(ScriptFuncPtr sf, ListExprPtr arg_args, std::vector<IDPtr> params, std::vector<bool> 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<IDPtr> params;
std::vector<bool> 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);

View file

@ -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<const AddToExpr*>(e)->IsVectorElemAppend() )
add_to_func = "vector_append__CPP";
else
add_to_func = "vector_vec_append__CPP";

View file

@ -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<ProfileFuncs> _pfs, const std::vector<const ID*>& _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<const FieldLHSAssignExpr*>(e)->Field();
if ( CheckID(lhs_aggr_id, true) )
return TC_ABORTALL;

View file

@ -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<FieldAssignExpr> 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<ConstExprPtr>& patterns) {
static bool is_pattern_cascade(const Expr* e, IDPtr& id, std::vector<ConstExprPtr>& patterns) {
auto lhs = e->GetOp1();
auto rhs = e->GetOp2();
@ -1016,7 +962,7 @@ static bool is_pattern_cascade(const ExprPtr& e, IDPtr& id, std::vector<ConstExp
if ( e->Tag() != 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<ConstExprPtr> 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<ConstExprPtr> 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<NameExpr>(common_id), this);
auto new_node = with_location_of(make_intrusive<InExpr>(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<ConstExprPtr> 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<NameExpr>(common_id), this);
auto new_node = with_location_of(make_intrusive<InExpr>(new_pat, new_id), this);
return new_node->Reduce(c, red_stmt);
}
bool BoolExpr::IsTrue(const ExprPtr& e) const {
if ( ! e->IsConst() )
return false;

225
src/script_opt/Expr.h Normal file
View file

@ -0,0 +1,225 @@
#include "zeek/Expr.h"
namespace zeek::detail {
class InlineExpr : public Expr {
public:
InlineExpr(ScriptFuncPtr sf, ListExprPtr arg_args, std::vector<IDPtr> params, std::vector<bool> 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<IDPtr> params;
std::vector<bool> 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<ExprSideEffects> side_effects;
};
}; // namespace zeek::detail

View file

@ -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<ExprSideEffects> side_effects;
};
} // namespace zeek::detail

View file

@ -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"

View file

@ -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"

View file

@ -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"

View file

@ -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"

View file

@ -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<const IndexAssignExpr*>(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<const IndexAssignExpr*>(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<const TableConstructorExpr*>(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<const SetConstructorExpr*>(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<const RecordConstructorExpr*>(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<const RecordCoerceExpr*>(e);
auto op = r->GetOp1()->AsNameExpr();
int op_slot = FrameSlot(op);