mirror of
https://github.com/zeek/zeek.git
synced 2025-10-07 00:58:19 +00:00

Fixed a few small bugs - Modifiable had an uninitialized member and the Registry looped over a map while deleting elements from it. Fixes GH-319 * remotes/origin/topic/robin/gh59-when: Renaming src/StateAccess.{h,cc} to src/Notifier.{h,cc}. Clean up new code. Remove MutableVal class. Redo API for notifiers. Remove most of MutableVal (but not the class itelf yet) Remove enum Opcode. Remove StateAccess class. Redo NotfifierRegistry to no longer rely on StateAccess. Add new test for when-statement watching global variables. Couple of compile fixes.
1083 lines
24 KiB
C++
1083 lines
24 KiB
C++
// See the file "COPYING" in the main distribution directory for copyright.
|
|
|
|
#ifndef expr_h
|
|
#define expr_h
|
|
|
|
// BRO expressions.
|
|
|
|
#include "BroList.h"
|
|
#include "ID.h"
|
|
#include "Timer.h"
|
|
#include "Val.h"
|
|
#include "Debug.h"
|
|
#include "EventHandler.h"
|
|
#include "TraverseTypes.h"
|
|
|
|
typedef enum {
|
|
EXPR_ANY = -1,
|
|
EXPR_NAME, EXPR_CONST,
|
|
EXPR_CLONE,
|
|
EXPR_INCR, EXPR_DECR,
|
|
EXPR_NOT, EXPR_COMPLEMENT,
|
|
EXPR_POSITIVE, EXPR_NEGATE,
|
|
EXPR_ADD, EXPR_SUB, EXPR_ADD_TO, EXPR_REMOVE_FROM,
|
|
EXPR_TIMES, EXPR_DIVIDE, EXPR_MOD,
|
|
EXPR_AND, EXPR_OR, EXPR_XOR,
|
|
EXPR_AND_AND, EXPR_OR_OR,
|
|
EXPR_LT, EXPR_LE, EXPR_EQ, EXPR_NE, EXPR_GE, EXPR_GT,
|
|
EXPR_COND,
|
|
EXPR_REF,
|
|
EXPR_ASSIGN,
|
|
EXPR_MATCH,
|
|
EXPR_INDEX,
|
|
EXPR_FIELD, EXPR_HAS_FIELD,
|
|
EXPR_RECORD_CONSTRUCTOR,
|
|
EXPR_TABLE_CONSTRUCTOR,
|
|
EXPR_SET_CONSTRUCTOR,
|
|
EXPR_VECTOR_CONSTRUCTOR,
|
|
EXPR_FIELD_ASSIGN,
|
|
EXPR_IN,
|
|
EXPR_LIST,
|
|
EXPR_CALL,
|
|
EXPR_EVENT,
|
|
EXPR_SCHEDULE,
|
|
EXPR_ARITH_COERCE,
|
|
EXPR_RECORD_COERCE,
|
|
EXPR_TABLE_COERCE,
|
|
EXPR_VECTOR_COERCE,
|
|
EXPR_SIZE,
|
|
EXPR_FLATTEN,
|
|
EXPR_CAST,
|
|
EXPR_IS,
|
|
EXPR_INDEX_SLICE_ASSIGN,
|
|
#define NUM_EXPRS (int(EXPR_INDEX_SLICE_ASSIGN) + 1)
|
|
} BroExprTag;
|
|
|
|
extern const char* expr_name(BroExprTag t);
|
|
|
|
class Stmt;
|
|
class Frame;
|
|
class ListExpr;
|
|
class NameExpr;
|
|
class IndexExpr;
|
|
class AssignExpr;
|
|
class CallExpr;
|
|
class EventExpr;
|
|
|
|
|
|
class Expr : public BroObj {
|
|
public:
|
|
BroType* Type() const { return type; }
|
|
BroExprTag Tag() const { return tag; }
|
|
|
|
~Expr() override;
|
|
|
|
Expr* Ref() { ::Ref(this); return this; }
|
|
|
|
// Evaluates the expression and returns a corresponding Val*,
|
|
// or nil if the expression's value isn't fixed.
|
|
virtual Val* Eval(Frame* f) const = 0;
|
|
|
|
// Same, but the context is that we are adding an element
|
|
// into the given aggregate of the given type. Note that
|
|
// return type is void since it's updating an existing
|
|
// value, rather than creating a new one.
|
|
virtual void EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f)
|
|
const;
|
|
|
|
// Assign to the given value, if appropriate.
|
|
virtual void Assign(Frame* f, Val* v);
|
|
|
|
// Returns the type corresponding to this expression interpreted
|
|
// as an initialization. The type should be Unref()'d when done
|
|
// using it. Returns nil if the initialization is illegal.
|
|
virtual BroType* InitType() const;
|
|
|
|
// Returns true if this expression, interpreted as an initialization,
|
|
// constitutes a record element, false otherwise. If the TypeDecl*
|
|
// is non-nil and the expression is a record element, fills in the
|
|
// TypeDecl with a description of the element.
|
|
virtual int IsRecordElement(TypeDecl* td) const;
|
|
|
|
// Returns a value corresponding to this expression interpreted
|
|
// as an initialization, or nil if the expression is inconsistent
|
|
// with the given type. If "aggr" is non-nil, then this expression
|
|
// is an element of the given aggregate, and it is added to it
|
|
// accordingly.
|
|
virtual Val* InitVal(const BroType* t, Val* aggr) const;
|
|
|
|
// True if the expression has no side effects, false otherwise.
|
|
virtual int IsPure() const;
|
|
|
|
// True if the expression is a constant, false otherwise.
|
|
int IsConst() const { return tag == EXPR_CONST; }
|
|
|
|
// True if the expression is in error (to alleviate error propagation).
|
|
int IsError() const { return type && type->Tag() == TYPE_ERROR; }
|
|
|
|
// Mark expression as in error.
|
|
void SetError() { SetType(error_type()); }
|
|
void SetError(const char* msg);
|
|
|
|
// Returns the expression's constant value, or complains
|
|
// if it's not a constant.
|
|
inline Val* ExprVal() const;
|
|
|
|
// True if the expression is a constant zero, false otherwise.
|
|
int IsZero() const
|
|
{
|
|
return IsConst() && ExprVal()->IsZero();
|
|
}
|
|
|
|
// True if the expression is a constant one, false otherwise.
|
|
int IsOne() const
|
|
{
|
|
return IsConst() && ExprVal()->IsOne();
|
|
}
|
|
|
|
// True if the expression supports the "add" or "delete" operations,
|
|
// false otherwise.
|
|
virtual int CanAdd() const;
|
|
virtual int CanDel() const;
|
|
|
|
virtual void Add(Frame* f); // perform add operation
|
|
virtual void Delete(Frame* f); // perform delete operation
|
|
|
|
// Return the expression converted to L-value form. If expr
|
|
// cannot be used as an L-value, reports an error and returns
|
|
// the current value of expr (this is the default method).
|
|
virtual Expr* MakeLvalue();
|
|
|
|
// Marks the expression as one requiring (or at least appearing
|
|
// with) parentheses. Used for pretty-printing.
|
|
void MarkParen() { paren = 1; }
|
|
int IsParen() const { return paren; }
|
|
|
|
const ListExpr* AsListExpr() const
|
|
{
|
|
CHECK_TAG(tag, EXPR_LIST, "ExprVal::AsListExpr", expr_name)
|
|
return (const ListExpr*) this;
|
|
}
|
|
|
|
ListExpr* AsListExpr()
|
|
{
|
|
CHECK_TAG(tag, EXPR_LIST, "ExprVal::AsListExpr", expr_name)
|
|
return (ListExpr*) this;
|
|
}
|
|
|
|
const NameExpr* AsNameExpr() const
|
|
{
|
|
CHECK_TAG(tag, EXPR_NAME, "ExprVal::AsNameExpr", expr_name)
|
|
return (const NameExpr*) this;
|
|
}
|
|
|
|
NameExpr* AsNameExpr()
|
|
{
|
|
CHECK_TAG(tag, EXPR_NAME, "ExprVal::AsNameExpr", expr_name)
|
|
return (NameExpr*) this;
|
|
}
|
|
|
|
const AssignExpr* AsAssignExpr() const
|
|
{
|
|
CHECK_TAG(tag, EXPR_ASSIGN, "ExprVal::AsAssignExpr", expr_name)
|
|
return (const AssignExpr*) this;
|
|
}
|
|
|
|
AssignExpr* AsAssignExpr()
|
|
{
|
|
CHECK_TAG(tag, EXPR_ASSIGN, "ExprVal::AsAssignExpr", expr_name)
|
|
return (AssignExpr*) this;
|
|
}
|
|
|
|
const IndexExpr* AsIndexExpr() const
|
|
{
|
|
CHECK_TAG(tag, EXPR_INDEX, "ExprVal::AsIndexExpr", expr_name)
|
|
return (const IndexExpr*) this;
|
|
}
|
|
|
|
IndexExpr* AsIndexExpr()
|
|
{
|
|
CHECK_TAG(tag, EXPR_INDEX, "ExprVal::AsIndexExpr", expr_name)
|
|
return (IndexExpr*) this;
|
|
}
|
|
|
|
void Describe(ODesc* d) const override;
|
|
|
|
virtual TraversalCode Traverse(TraversalCallback* cb) const = 0;
|
|
|
|
protected:
|
|
Expr() { type = 0; }
|
|
explicit Expr(BroExprTag arg_tag);
|
|
|
|
virtual void ExprDescribe(ODesc* d) const = 0;
|
|
void AddTag(ODesc* d) const;
|
|
|
|
// Puts the expression in canonical form.
|
|
virtual void Canonicize();
|
|
|
|
void SetType(BroType* t);
|
|
|
|
// Reports the given error and sets the expression's type to
|
|
// TYPE_ERROR.
|
|
void ExprError(const char msg[]);
|
|
|
|
void RuntimeError(const std::string& msg) const;
|
|
|
|
void RuntimeErrorWithCallStack(const std::string& msg) const;
|
|
|
|
BroExprTag tag;
|
|
BroType* type;
|
|
|
|
int paren;
|
|
};
|
|
|
|
class NameExpr : public Expr {
|
|
public:
|
|
explicit NameExpr(ID* id, bool const_init = false);
|
|
~NameExpr() override;
|
|
|
|
ID* Id() const { return id; }
|
|
|
|
Val* Eval(Frame* f) const override;
|
|
void Assign(Frame* f, Val* v) override;
|
|
Expr* MakeLvalue() override;
|
|
int IsPure() const override;
|
|
|
|
TraversalCode Traverse(TraversalCallback* cb) const override;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
NameExpr() { id = 0; }
|
|
|
|
void ExprDescribe(ODesc* d) const override;
|
|
|
|
ID* id;
|
|
bool in_const_init;
|
|
};
|
|
|
|
class ConstExpr : public Expr {
|
|
public:
|
|
explicit ConstExpr(Val* val);
|
|
~ConstExpr() override;
|
|
|
|
Val* Value() const { return val; }
|
|
|
|
Val* Eval(Frame* f) const override;
|
|
|
|
TraversalCode Traverse(TraversalCallback* cb) const override;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
ConstExpr() { val = 0; }
|
|
|
|
void ExprDescribe(ODesc* d) const override;
|
|
Val* val;
|
|
};
|
|
|
|
class UnaryExpr : public Expr {
|
|
public:
|
|
Expr* Op() const { return op; }
|
|
|
|
// UnaryExpr::Eval correctly handles vector types. Any child
|
|
// class that overrides Eval() should be modified to handle
|
|
// vectors correctly as necessary.
|
|
Val* Eval(Frame* f) const override;
|
|
|
|
int IsPure() const override;
|
|
|
|
TraversalCode Traverse(TraversalCallback* cb) const override;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
UnaryExpr() { op = 0; }
|
|
|
|
UnaryExpr(BroExprTag arg_tag, Expr* arg_op);
|
|
~UnaryExpr() override;
|
|
|
|
void ExprDescribe(ODesc* d) const override;
|
|
|
|
// Returns the expression folded using the given constant.
|
|
virtual Val* Fold(Val* v) const;
|
|
|
|
Expr* op;
|
|
};
|
|
|
|
class BinaryExpr : public Expr {
|
|
public:
|
|
Expr* Op1() const { return op1; }
|
|
Expr* Op2() const { return op2; }
|
|
|
|
int IsPure() const override;
|
|
|
|
// BinaryExpr::Eval correctly handles vector types. Any child
|
|
// class that overrides Eval() should be modified to handle
|
|
// vectors correctly as necessary.
|
|
Val* Eval(Frame* f) const override;
|
|
|
|
TraversalCode Traverse(TraversalCallback* cb) const override;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
BinaryExpr() { op1 = op2 = 0; }
|
|
|
|
BinaryExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2)
|
|
: Expr(arg_tag), op1(arg_op1), op2(arg_op2)
|
|
{
|
|
if ( ! (arg_op1 && arg_op2) )
|
|
return;
|
|
if ( op1->IsError() || op2->IsError() )
|
|
SetError();
|
|
}
|
|
~BinaryExpr() override;
|
|
|
|
// Returns the expression folded using the given constants.
|
|
virtual Val* Fold(Val* v1, Val* v2) const;
|
|
|
|
// Same for when the constants are strings.
|
|
virtual Val* StringFold(Val* v1, Val* v2) const;
|
|
|
|
// Same for when the constants are patterns.
|
|
virtual Val* PatternFold(Val* v1, Val* v2) const;
|
|
|
|
// Same for when the constants are sets.
|
|
virtual Val* SetFold(Val* v1, Val* v2) const;
|
|
|
|
// Same for when the constants are addresses or subnets.
|
|
virtual Val* AddrFold(Val* v1, Val* v2) const;
|
|
virtual Val* SubNetFold(Val* v1, Val* v2) const;
|
|
|
|
int BothConst() const { return op1->IsConst() && op2->IsConst(); }
|
|
|
|
// Exchange op1 and op2.
|
|
void SwapOps();
|
|
|
|
// Promote the operands to the given type tag, if necessary.
|
|
void PromoteOps(TypeTag t);
|
|
|
|
// Promote the expression to the given type tag (i.e., promote
|
|
// operands and also set expression's type).
|
|
void PromoteType(TypeTag t, bool is_vector);
|
|
|
|
void ExprDescribe(ODesc* d) const override;
|
|
|
|
Expr* op1;
|
|
Expr* op2;
|
|
};
|
|
|
|
class CloneExpr : public UnaryExpr {
|
|
public:
|
|
explicit CloneExpr(Expr* op);
|
|
Val* Eval(Frame* f) const override;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
CloneExpr() { }
|
|
|
|
Val* Fold(Val* v) const override;
|
|
};
|
|
|
|
class IncrExpr : public UnaryExpr {
|
|
public:
|
|
IncrExpr(BroExprTag tag, Expr* op);
|
|
|
|
Val* Eval(Frame* f) const override;
|
|
Val* DoSingleEval(Frame* f, Val* v) const;
|
|
int IsPure() const override;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
IncrExpr() { }
|
|
};
|
|
|
|
class ComplementExpr : public UnaryExpr {
|
|
public:
|
|
explicit ComplementExpr(Expr* op);
|
|
|
|
protected:
|
|
friend class Expr;
|
|
ComplementExpr() { }
|
|
|
|
Val* Fold(Val* v) const override;
|
|
};
|
|
|
|
class NotExpr : public UnaryExpr {
|
|
public:
|
|
explicit NotExpr(Expr* op);
|
|
|
|
protected:
|
|
friend class Expr;
|
|
NotExpr() { }
|
|
|
|
Val* Fold(Val* v) const override;
|
|
};
|
|
|
|
class PosExpr : public UnaryExpr {
|
|
public:
|
|
explicit PosExpr(Expr* op);
|
|
|
|
protected:
|
|
friend class Expr;
|
|
PosExpr() { }
|
|
|
|
Val* Fold(Val* v) const override;
|
|
};
|
|
|
|
class NegExpr : public UnaryExpr {
|
|
public:
|
|
explicit NegExpr(Expr* op);
|
|
|
|
protected:
|
|
friend class Expr;
|
|
NegExpr() { }
|
|
|
|
Val* Fold(Val* v) const override;
|
|
};
|
|
|
|
class SizeExpr : public UnaryExpr {
|
|
public:
|
|
explicit SizeExpr(Expr* op);
|
|
Val* Eval(Frame* f) const override;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
SizeExpr() { }
|
|
|
|
Val* Fold(Val* v) const override;
|
|
};
|
|
|
|
class AddExpr : public BinaryExpr {
|
|
public:
|
|
AddExpr(Expr* op1, Expr* op2);
|
|
void Canonicize() override;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
AddExpr() { }
|
|
};
|
|
|
|
class AddToExpr : public BinaryExpr {
|
|
public:
|
|
AddToExpr(Expr* op1, Expr* op2);
|
|
Val* Eval(Frame* f) const override;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
AddToExpr() { }
|
|
};
|
|
|
|
class RemoveFromExpr : public BinaryExpr {
|
|
public:
|
|
RemoveFromExpr(Expr* op1, Expr* op2);
|
|
Val* Eval(Frame* f) const override;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
RemoveFromExpr() { }
|
|
};
|
|
|
|
class SubExpr : public BinaryExpr {
|
|
public:
|
|
SubExpr(Expr* op1, Expr* op2);
|
|
|
|
protected:
|
|
friend class Expr;
|
|
SubExpr() { }
|
|
};
|
|
|
|
class TimesExpr : public BinaryExpr {
|
|
public:
|
|
TimesExpr(Expr* op1, Expr* op2);
|
|
void Canonicize() override;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
TimesExpr() { }
|
|
};
|
|
|
|
class DivideExpr : public BinaryExpr {
|
|
public:
|
|
DivideExpr(Expr* op1, Expr* op2);
|
|
|
|
protected:
|
|
friend class Expr;
|
|
DivideExpr() { }
|
|
|
|
Val* AddrFold(Val* v1, Val* v2) const override;
|
|
};
|
|
|
|
class ModExpr : public BinaryExpr {
|
|
public:
|
|
ModExpr(Expr* op1, Expr* op2);
|
|
|
|
protected:
|
|
friend class Expr;
|
|
ModExpr() { }
|
|
};
|
|
|
|
class BoolExpr : public BinaryExpr {
|
|
public:
|
|
BoolExpr(BroExprTag tag, Expr* op1, Expr* op2);
|
|
|
|
Val* Eval(Frame* f) const override;
|
|
Val* DoSingleEval(Frame* f, Val* v1, Expr* op2) const;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
BoolExpr() { }
|
|
};
|
|
|
|
class BitExpr : public BinaryExpr {
|
|
public:
|
|
BitExpr(BroExprTag tag, Expr* op1, Expr* op2);
|
|
|
|
protected:
|
|
friend class Expr;
|
|
BitExpr() { }
|
|
};
|
|
|
|
class EqExpr : public BinaryExpr {
|
|
public:
|
|
EqExpr(BroExprTag tag, Expr* op1, Expr* op2);
|
|
void Canonicize() override;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
EqExpr() { }
|
|
|
|
Val* Fold(Val* v1, Val* v2) const override;
|
|
};
|
|
|
|
class RelExpr : public BinaryExpr {
|
|
public:
|
|
RelExpr(BroExprTag tag, Expr* op1, Expr* op2);
|
|
void Canonicize() override;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
RelExpr() { }
|
|
};
|
|
|
|
class CondExpr : public Expr {
|
|
public:
|
|
CondExpr(Expr* op1, Expr* op2, Expr* op3);
|
|
~CondExpr() override;
|
|
|
|
const Expr* Op1() const { return op1; }
|
|
const Expr* Op2() const { return op2; }
|
|
const Expr* Op3() const { return op3; }
|
|
|
|
Val* Eval(Frame* f) const override;
|
|
int IsPure() const override;
|
|
|
|
TraversalCode Traverse(TraversalCallback* cb) const override;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
CondExpr() { op1 = op2 = op3 = 0; }
|
|
|
|
void ExprDescribe(ODesc* d) const override;
|
|
|
|
Expr* op1;
|
|
Expr* op2;
|
|
Expr* op3;
|
|
};
|
|
|
|
class RefExpr : public UnaryExpr {
|
|
public:
|
|
explicit RefExpr(Expr* op);
|
|
|
|
void Assign(Frame* f, Val* v) override;
|
|
Expr* MakeLvalue() override;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
RefExpr() { }
|
|
};
|
|
|
|
class AssignExpr : public BinaryExpr {
|
|
public:
|
|
// If val is given, evaluating this expression will always yield the val
|
|
// yet still perform the assignment. Used for triggers.
|
|
AssignExpr(Expr* op1, Expr* op2, int is_init, Val* val = 0, attr_list* attrs = 0);
|
|
~AssignExpr() override { Unref(val); }
|
|
|
|
Val* Eval(Frame* f) const override;
|
|
void EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f) const override;
|
|
BroType* InitType() const override;
|
|
int IsRecordElement(TypeDecl* td) const override;
|
|
Val* InitVal(const BroType* t, Val* aggr) const override;
|
|
int IsPure() const override;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
AssignExpr() { }
|
|
|
|
bool TypeCheck(attr_list* attrs = 0);
|
|
bool TypeCheckArithmetics(TypeTag bt1, TypeTag bt2);
|
|
|
|
int is_init;
|
|
Val* val; // optional
|
|
};
|
|
|
|
class IndexSliceAssignExpr : public AssignExpr {
|
|
public:
|
|
IndexSliceAssignExpr(Expr* op1, Expr* op2, int is_init);
|
|
Val* Eval(Frame* f) const override;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
IndexSliceAssignExpr() {}
|
|
};
|
|
|
|
class IndexExpr : public BinaryExpr {
|
|
public:
|
|
IndexExpr(Expr* op1, ListExpr* op2, bool is_slice = false);
|
|
|
|
int CanAdd() const override;
|
|
int CanDel() const override;
|
|
|
|
void Add(Frame* f) override;
|
|
void Delete(Frame* f) override;
|
|
|
|
void Assign(Frame* f, Val* v) override;
|
|
Expr* MakeLvalue() override;
|
|
|
|
// Need to override Eval since it can take a vector arg but does
|
|
// not necessarily return a vector.
|
|
Val* Eval(Frame* f) const override;
|
|
|
|
TraversalCode Traverse(TraversalCallback* cb) const override;
|
|
|
|
bool IsSlice() const { return is_slice; }
|
|
|
|
protected:
|
|
friend class Expr;
|
|
IndexExpr() { }
|
|
|
|
Val* Fold(Val* v1, Val* v2) const override;
|
|
|
|
void ExprDescribe(ODesc* d) const override;
|
|
|
|
bool is_slice;
|
|
};
|
|
|
|
class FieldExpr : public UnaryExpr {
|
|
public:
|
|
FieldExpr(Expr* op, const char* field_name);
|
|
~FieldExpr() override;
|
|
|
|
int Field() const { return field; }
|
|
const char* FieldName() const { return field_name; }
|
|
|
|
int CanDel() const override;
|
|
|
|
void Assign(Frame* f, Val* v) override;
|
|
void Delete(Frame* f) override;
|
|
|
|
Expr* MakeLvalue() override;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
FieldExpr() { field_name = 0; td = 0; }
|
|
|
|
Val* Fold(Val* v) const override;
|
|
|
|
void ExprDescribe(ODesc* d) const override;
|
|
|
|
const char* field_name;
|
|
const TypeDecl* td;
|
|
int field; // -1 = attributes
|
|
};
|
|
|
|
// "rec?$fieldname" is true if the value of $fieldname in rec is not nil.
|
|
// "rec?$$attrname" is true if the attribute attrname is not nil.
|
|
class HasFieldExpr : public UnaryExpr {
|
|
public:
|
|
HasFieldExpr(Expr* op, const char* field_name);
|
|
~HasFieldExpr() override;
|
|
|
|
const char* FieldName() const { return field_name; }
|
|
|
|
protected:
|
|
friend class Expr;
|
|
HasFieldExpr() { field_name = 0; }
|
|
|
|
Val* Fold(Val* v) const override;
|
|
|
|
void ExprDescribe(ODesc* d) const override;
|
|
|
|
const char* field_name;
|
|
int field;
|
|
};
|
|
|
|
class RecordConstructorExpr : public UnaryExpr {
|
|
public:
|
|
explicit RecordConstructorExpr(ListExpr* constructor_list);
|
|
~RecordConstructorExpr() override;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
RecordConstructorExpr() { }
|
|
|
|
Val* InitVal(const BroType* t, Val* aggr) const override;
|
|
Val* Fold(Val* v) const override;
|
|
|
|
void ExprDescribe(ODesc* d) const override;
|
|
};
|
|
|
|
class TableConstructorExpr : public UnaryExpr {
|
|
public:
|
|
TableConstructorExpr(ListExpr* constructor_list, attr_list* attrs,
|
|
BroType* arg_type = 0);
|
|
~TableConstructorExpr() override { Unref(attrs); }
|
|
|
|
Attributes* Attrs() { return attrs; }
|
|
|
|
Val* Eval(Frame* f) const override;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
TableConstructorExpr() { }
|
|
|
|
Val* InitVal(const BroType* t, Val* aggr) const override;
|
|
|
|
void ExprDescribe(ODesc* d) const override;
|
|
|
|
Attributes* attrs;
|
|
};
|
|
|
|
class SetConstructorExpr : public UnaryExpr {
|
|
public:
|
|
SetConstructorExpr(ListExpr* constructor_list, attr_list* attrs,
|
|
BroType* arg_type = 0);
|
|
~SetConstructorExpr() override { Unref(attrs); }
|
|
|
|
Attributes* Attrs() { return attrs; }
|
|
|
|
Val* Eval(Frame* f) const override;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
SetConstructorExpr() { }
|
|
|
|
Val* InitVal(const BroType* t, Val* aggr) const override;
|
|
|
|
void ExprDescribe(ODesc* d) const override;
|
|
|
|
Attributes* attrs;
|
|
};
|
|
|
|
class VectorConstructorExpr : public UnaryExpr {
|
|
public:
|
|
explicit VectorConstructorExpr(ListExpr* constructor_list, BroType* arg_type = 0);
|
|
|
|
Val* Eval(Frame* f) const override;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
VectorConstructorExpr() { }
|
|
|
|
Val* InitVal(const BroType* t, Val* aggr) const override;
|
|
|
|
void ExprDescribe(ODesc* d) const override;
|
|
};
|
|
|
|
class FieldAssignExpr : public UnaryExpr {
|
|
public:
|
|
FieldAssignExpr(const char* field_name, Expr* value);
|
|
|
|
const char* FieldName() const { return field_name.c_str(); }
|
|
|
|
void EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f) const override;
|
|
int IsRecordElement(TypeDecl* td) const override;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
FieldAssignExpr() { }
|
|
|
|
void ExprDescribe(ODesc* d) const override;
|
|
|
|
string field_name;
|
|
};
|
|
|
|
class ArithCoerceExpr : public UnaryExpr {
|
|
public:
|
|
ArithCoerceExpr(Expr* op, TypeTag t);
|
|
|
|
protected:
|
|
friend class Expr;
|
|
ArithCoerceExpr() { }
|
|
|
|
Val* FoldSingleVal(Val* v, InternalTypeTag t) const;
|
|
Val* Fold(Val* v) const override;
|
|
};
|
|
|
|
class RecordCoerceExpr : public UnaryExpr {
|
|
public:
|
|
RecordCoerceExpr(Expr* op, RecordType* r);
|
|
~RecordCoerceExpr() override;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
RecordCoerceExpr() { map = 0; }
|
|
|
|
Val* InitVal(const BroType* t, Val* aggr) const override;
|
|
Val* Fold(Val* v) const override;
|
|
|
|
// For each super-record slot, gives subrecord slot with which to
|
|
// fill it.
|
|
int* map;
|
|
int map_size; // equivalent to Type()->AsRecordType()->NumFields()
|
|
};
|
|
|
|
class TableCoerceExpr : public UnaryExpr {
|
|
public:
|
|
TableCoerceExpr(Expr* op, TableType* r);
|
|
~TableCoerceExpr() override;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
TableCoerceExpr() { }
|
|
|
|
Val* Fold(Val* v) const override;
|
|
};
|
|
|
|
class VectorCoerceExpr : public UnaryExpr {
|
|
public:
|
|
VectorCoerceExpr(Expr* op, VectorType* v);
|
|
~VectorCoerceExpr() override;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
VectorCoerceExpr() { }
|
|
|
|
Val* Fold(Val* v) const override;
|
|
};
|
|
|
|
// An internal operator for flattening array indices that are records
|
|
// into a list of individual values.
|
|
class FlattenExpr : public UnaryExpr {
|
|
public:
|
|
explicit FlattenExpr(Expr* op);
|
|
|
|
protected:
|
|
friend class Expr;
|
|
FlattenExpr() { }
|
|
|
|
Val* Fold(Val* v) const override;
|
|
|
|
int num_fields;
|
|
};
|
|
|
|
class EventHandler;
|
|
|
|
class ScheduleTimer : public Timer {
|
|
public:
|
|
ScheduleTimer(EventHandlerPtr event, val_list* args, double t,
|
|
TimerMgr* tmgr);
|
|
~ScheduleTimer() override;
|
|
|
|
void Dispatch(double t, int is_expire) override;
|
|
|
|
protected:
|
|
EventHandlerPtr event;
|
|
val_list args;
|
|
TimerMgr* tmgr;
|
|
};
|
|
|
|
class ScheduleExpr : public Expr {
|
|
public:
|
|
ScheduleExpr(Expr* when, EventExpr* event);
|
|
~ScheduleExpr() override;
|
|
|
|
int IsPure() const override;
|
|
|
|
Val* Eval(Frame* f) const override;
|
|
|
|
Expr* When() const { return when; }
|
|
EventExpr* Event() const { return event; }
|
|
|
|
TraversalCode Traverse(TraversalCallback* cb) const override;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
ScheduleExpr() { when = 0; event = 0; }
|
|
|
|
void ExprDescribe(ODesc* d) const override;
|
|
|
|
Expr* when;
|
|
EventExpr* event;
|
|
};
|
|
|
|
class InExpr : public BinaryExpr {
|
|
public:
|
|
InExpr(Expr* op1, Expr* op2);
|
|
|
|
protected:
|
|
friend class Expr;
|
|
InExpr() { }
|
|
|
|
Val* Fold(Val* v1, Val* v2) const override;
|
|
|
|
};
|
|
|
|
class CallExpr : public Expr {
|
|
public:
|
|
CallExpr(Expr* func, ListExpr* args, bool in_hook = false);
|
|
~CallExpr() override;
|
|
|
|
Expr* Func() const { return func; }
|
|
ListExpr* Args() const { return args; }
|
|
|
|
int IsPure() const override;
|
|
|
|
Val* Eval(Frame* f) const override;
|
|
|
|
TraversalCode Traverse(TraversalCallback* cb) const override;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
CallExpr() { func = 0; args = 0; }
|
|
|
|
void ExprDescribe(ODesc* d) const override;
|
|
|
|
Expr* func;
|
|
ListExpr* args;
|
|
};
|
|
|
|
class EventExpr : public Expr {
|
|
public:
|
|
EventExpr(const char* name, ListExpr* args);
|
|
~EventExpr() override;
|
|
|
|
const char* Name() const { return name.c_str(); }
|
|
ListExpr* Args() const { return args; }
|
|
EventHandlerPtr Handler() const { return handler; }
|
|
|
|
Val* Eval(Frame* f) const override;
|
|
|
|
TraversalCode Traverse(TraversalCallback* cb) const override;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
EventExpr() { args = 0; }
|
|
|
|
void ExprDescribe(ODesc* d) const override;
|
|
|
|
string name;
|
|
EventHandlerPtr handler;
|
|
ListExpr* args;
|
|
};
|
|
|
|
class ListExpr : public Expr {
|
|
public:
|
|
ListExpr();
|
|
explicit ListExpr(Expr* e);
|
|
~ListExpr() override;
|
|
|
|
void Append(Expr* e);
|
|
|
|
const expr_list& Exprs() const { return exprs; }
|
|
expr_list& Exprs() { return exprs; }
|
|
|
|
// True if the entire list represents pure values.
|
|
int IsPure() const override;
|
|
|
|
// True if the entire list represents constant values.
|
|
int AllConst() const;
|
|
|
|
Val* Eval(Frame* f) const override;
|
|
|
|
BroType* InitType() const override;
|
|
Val* InitVal(const BroType* t, Val* aggr) const override;
|
|
Expr* MakeLvalue() override;
|
|
void Assign(Frame* f, Val* v) override;
|
|
|
|
TraversalCode Traverse(TraversalCallback* cb) const override;
|
|
|
|
protected:
|
|
Val* AddSetInit(const BroType* t, Val* aggr) const;
|
|
|
|
void ExprDescribe(ODesc* d) const override;
|
|
|
|
expr_list exprs;
|
|
};
|
|
|
|
|
|
class RecordAssignExpr : public ListExpr {
|
|
public:
|
|
RecordAssignExpr(Expr* record, Expr* init_list, int is_init);
|
|
|
|
Val* Eval(Frame* f) const override { return ListExpr::Eval(f); }
|
|
|
|
protected:
|
|
friend class Expr;
|
|
RecordAssignExpr() { }
|
|
};
|
|
|
|
class CastExpr : public UnaryExpr {
|
|
public:
|
|
CastExpr(Expr* op, BroType* t);
|
|
|
|
protected:
|
|
friend class Expr;
|
|
CastExpr() { }
|
|
|
|
Val* Eval(Frame* f) const override;
|
|
void ExprDescribe(ODesc* d) const override;
|
|
};
|
|
|
|
class IsExpr : public UnaryExpr {
|
|
public:
|
|
IsExpr(Expr* op, BroType* t);
|
|
virtual ~IsExpr();
|
|
|
|
protected:
|
|
friend class Expr;
|
|
IsExpr() { }
|
|
|
|
Val* Fold(Val* v) const override;
|
|
void ExprDescribe(ODesc* d) const override;
|
|
|
|
private:
|
|
BroType* t;
|
|
};
|
|
|
|
inline Val* Expr::ExprVal() const
|
|
{
|
|
if ( ! IsConst() )
|
|
BadTag("ExprVal::Val", expr_name(tag), expr_name(EXPR_CONST));
|
|
return ((ConstExpr*) this)->Value();
|
|
}
|
|
|
|
// Decides whether to return an AssignExpr or a RecordAssignExpr.
|
|
Expr* get_assign_expr(Expr* op1, Expr* op2, int is_init);
|
|
|
|
// Type-check the given expression(s) against the given type(s). Complain
|
|
// if the expression cannot match the given type, returning 0. If it can
|
|
// match, promote it as necessary (modifying the ref parameter accordingly)
|
|
// and return 1.
|
|
//
|
|
// The second, third, and fourth forms are for promoting a list of
|
|
// expressions (which is updated in place) to either match a list of
|
|
// types or a single type.
|
|
//
|
|
// Note, the type is not "const" because it can be ref'd.
|
|
extern int check_and_promote_expr(Expr*& e, BroType* t);
|
|
extern int check_and_promote_exprs(ListExpr*& elements, TypeList* types);
|
|
extern int check_and_promote_args(ListExpr*& args, RecordType* types);
|
|
extern int check_and_promote_exprs_to_type(ListExpr*& elements, BroType* type);
|
|
|
|
// Returns a ListExpr simplified down to a list a values, or a nil
|
|
// pointer if they couldn't all be reduced.
|
|
val_list* eval_list(Frame* f, const ListExpr* l);
|
|
|
|
// Returns true if e1 is "greater" than e2 - here "greater" is just
|
|
// a heuristic, used with commutative operators to put them into
|
|
// a canonical form.
|
|
extern int expr_greater(const Expr* e1, const Expr* e2);
|
|
|
|
// True if the given Val* has a vector type
|
|
inline bool is_vector(Expr* e) { return e->Type()->Tag() == TYPE_VECTOR; }
|
|
|
|
#endif
|