mirror of
https://github.com/zeek/zeek.git
synced 2025-10-07 17:18:20 +00:00

This new flavor of function behaves like a "synchronous event". See documentation for more details on usage.
1116 lines
24 KiB
C++
1116 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_POSITIVE, EXPR_NEGATE,
|
|
EXPR_ADD, EXPR_SUB, EXPR_ADD_TO, EXPR_REMOVE_FROM,
|
|
EXPR_TIMES, EXPR_DIVIDE, EXPR_MOD,
|
|
EXPR_AND, EXPR_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,
|
|
#define NUM_EXPRS (int(EXPR_FLATTEN) + 1)
|
|
} BroExprTag;
|
|
|
|
typedef enum {
|
|
SIMPLIFY_GENERAL, // regular simplification
|
|
SIMPLIFY_LHS, // simplify as the LHS of an assignment
|
|
} SimplifyType;
|
|
|
|
extern const char* expr_name(BroExprTag t);
|
|
|
|
class Stmt;
|
|
class Frame;
|
|
class ListExpr;
|
|
class CallExpr;
|
|
class EventExpr;
|
|
|
|
|
|
class Expr : public BroObj {
|
|
public:
|
|
BroType* Type() const { return type; }
|
|
BroExprTag Tag() const { return tag; }
|
|
|
|
virtual ~Expr();
|
|
|
|
Expr* Ref() { ::Ref(this); return this; }
|
|
|
|
// Returns a fully simplified version of the expression (this
|
|
// may be the same expression, or a newly created one). simp_type
|
|
// gives the context of the simplification.
|
|
virtual Expr* Simplify(SimplifyType simp_type) = 0;
|
|
|
|
// 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, Opcode op = OP_ASSIGN);
|
|
|
|
// 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;
|
|
}
|
|
|
|
void Describe(ODesc* d) const;
|
|
|
|
bool Serialize(SerialInfo* info) const;
|
|
static Expr* Unserialize(UnserialInfo* info, BroExprTag want = EXPR_ANY);
|
|
|
|
virtual TraversalCode Traverse(TraversalCallback* cb) const = 0;
|
|
|
|
protected:
|
|
Expr() { type = 0; }
|
|
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[]);
|
|
|
|
DECLARE_ABSTRACT_SERIAL(Expr);
|
|
|
|
BroExprTag tag;
|
|
BroType* type;
|
|
|
|
int paren;
|
|
};
|
|
|
|
class NameExpr : public Expr {
|
|
public:
|
|
NameExpr(ID* id);
|
|
~NameExpr();
|
|
|
|
ID* Id() const { return id; }
|
|
|
|
Expr* Simplify(SimplifyType simp_type);
|
|
Val* Eval(Frame* f) const;
|
|
void Assign(Frame* f, Val* v, Opcode op = OP_ASSIGN);
|
|
Expr* MakeLvalue();
|
|
int IsPure() const;
|
|
|
|
TraversalCode Traverse(TraversalCallback* cb) const;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
NameExpr() { id = 0; }
|
|
|
|
void ExprDescribe(ODesc* d) const;
|
|
|
|
DECLARE_SERIAL(NameExpr);
|
|
|
|
ID* id;
|
|
};
|
|
|
|
class ConstExpr : public Expr {
|
|
public:
|
|
ConstExpr(Val* val);
|
|
~ConstExpr();
|
|
|
|
Val* Value() const { return val; }
|
|
|
|
Expr* Simplify(SimplifyType simp_type);
|
|
Val* Eval(Frame* f) const;
|
|
|
|
TraversalCode Traverse(TraversalCallback* cb) const;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
ConstExpr() { val = 0; }
|
|
|
|
void ExprDescribe(ODesc* d) const;
|
|
DECLARE_SERIAL(ConstExpr);
|
|
|
|
Val* val;
|
|
};
|
|
|
|
class UnaryExpr : public Expr {
|
|
public:
|
|
Expr* Op() const { return op; }
|
|
|
|
// Simplifies the operand and calls DoSimplify().
|
|
virtual Expr* Simplify(SimplifyType simp_type);
|
|
|
|
// 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;
|
|
|
|
int IsPure() const;
|
|
|
|
TraversalCode Traverse(TraversalCallback* cb) const;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
UnaryExpr() { op = 0; }
|
|
|
|
UnaryExpr(BroExprTag arg_tag, Expr* arg_op);
|
|
virtual ~UnaryExpr();
|
|
|
|
void ExprDescribe(ODesc* d) const;
|
|
|
|
// Can be overridden by subclasses that want to take advantage
|
|
// of UnaryExpr's Simplify() method.
|
|
virtual Expr* DoSimplify();
|
|
|
|
// Returns the expression folded using the given constant.
|
|
virtual Val* Fold(Val* v) const;
|
|
|
|
DECLARE_SERIAL(UnaryExpr);
|
|
|
|
Expr* op;
|
|
};
|
|
|
|
class BinaryExpr : public Expr {
|
|
public:
|
|
Expr* Op1() const { return op1; }
|
|
Expr* Op2() const { return op2; }
|
|
|
|
// Simplifies both operands, folds them if constant,
|
|
// otherwise calls DoSimplify().
|
|
virtual Expr* Simplify(SimplifyType simp_type);
|
|
int IsPure() const;
|
|
|
|
// 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;
|
|
|
|
TraversalCode Traverse(TraversalCallback* cb) const;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
BinaryExpr() { op1 = op2 = 0; }
|
|
|
|
BinaryExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2)
|
|
: Expr(arg_tag)
|
|
{
|
|
if ( ! (arg_op1 && arg_op2) )
|
|
return;
|
|
op1 = arg_op1;
|
|
op2 = arg_op2;
|
|
if ( op1->IsError() || op2->IsError() )
|
|
SetError();
|
|
}
|
|
virtual ~BinaryExpr();
|
|
|
|
// Can be overridden by subclasses that want to take advantage
|
|
// of BinaryExpr's Simplify() method.
|
|
virtual Expr* DoSimplify();
|
|
|
|
// 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 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(); }
|
|
|
|
// Simplify both operands and canonicize.
|
|
void SimplifyOps();
|
|
|
|
// 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;
|
|
|
|
DECLARE_SERIAL(BinaryExpr);
|
|
|
|
Expr* op1;
|
|
Expr* op2;
|
|
};
|
|
|
|
class CloneExpr : public UnaryExpr {
|
|
public:
|
|
CloneExpr(Expr* op);
|
|
Val* Eval(Frame* f) const;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
CloneExpr() { }
|
|
|
|
Val* Fold(Val* v) const;
|
|
|
|
DECLARE_SERIAL(CloneExpr);
|
|
};
|
|
|
|
class IncrExpr : public UnaryExpr {
|
|
public:
|
|
IncrExpr(BroExprTag tag, Expr* op);
|
|
|
|
Val* Eval(Frame* f) const;
|
|
Val* DoSingleEval(Frame* f, Val* v) const;
|
|
int IsPure() const;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
IncrExpr() { }
|
|
|
|
DECLARE_SERIAL(IncrExpr);
|
|
};
|
|
|
|
class NotExpr : public UnaryExpr {
|
|
public:
|
|
NotExpr(Expr* op);
|
|
|
|
protected:
|
|
friend class Expr;
|
|
NotExpr() { }
|
|
|
|
Expr* DoSimplify();
|
|
Val* Fold(Val* v) const;
|
|
|
|
DECLARE_SERIAL(NotExpr);
|
|
};
|
|
|
|
class PosExpr : public UnaryExpr {
|
|
public:
|
|
PosExpr(Expr* op);
|
|
|
|
protected:
|
|
friend class Expr;
|
|
PosExpr() { }
|
|
|
|
Expr* DoSimplify();
|
|
Val* Fold(Val* v) const;
|
|
|
|
DECLARE_SERIAL(PosExpr);
|
|
};
|
|
|
|
class NegExpr : public UnaryExpr {
|
|
public:
|
|
NegExpr(Expr* op);
|
|
|
|
protected:
|
|
friend class Expr;
|
|
NegExpr() { }
|
|
|
|
Expr* DoSimplify();
|
|
Val* Fold(Val* v) const;
|
|
|
|
DECLARE_SERIAL(NegExpr);
|
|
};
|
|
|
|
class SizeExpr : public UnaryExpr {
|
|
public:
|
|
SizeExpr(Expr* op);
|
|
Val* Eval(Frame* f) const;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
SizeExpr() { }
|
|
|
|
Val* Fold(Val* v) const;
|
|
DECLARE_SERIAL(SizeExpr);
|
|
};
|
|
|
|
class AddExpr : public BinaryExpr {
|
|
public:
|
|
AddExpr(Expr* op1, Expr* op2);
|
|
void Canonicize();
|
|
|
|
protected:
|
|
friend class Expr;
|
|
AddExpr() { }
|
|
|
|
Expr* DoSimplify();
|
|
|
|
DECLARE_SERIAL(AddExpr);
|
|
|
|
};
|
|
|
|
class AddToExpr : public BinaryExpr {
|
|
public:
|
|
AddToExpr(Expr* op1, Expr* op2);
|
|
Val* Eval(Frame* f) const;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
AddToExpr() { }
|
|
|
|
DECLARE_SERIAL(AddToExpr);
|
|
};
|
|
|
|
class RemoveFromExpr : public BinaryExpr {
|
|
public:
|
|
RemoveFromExpr(Expr* op1, Expr* op2);
|
|
Val* Eval(Frame* f) const;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
RemoveFromExpr() { }
|
|
|
|
DECLARE_SERIAL(RemoveFromExpr);
|
|
};
|
|
|
|
class SubExpr : public BinaryExpr {
|
|
public:
|
|
SubExpr(Expr* op1, Expr* op2);
|
|
|
|
protected:
|
|
friend class Expr;
|
|
SubExpr() { }
|
|
|
|
Expr* DoSimplify();
|
|
|
|
DECLARE_SERIAL(SubExpr);
|
|
|
|
};
|
|
|
|
class TimesExpr : public BinaryExpr {
|
|
public:
|
|
TimesExpr(Expr* op1, Expr* op2);
|
|
void Canonicize();
|
|
|
|
protected:
|
|
friend class Expr;
|
|
TimesExpr() { }
|
|
|
|
Expr* DoSimplify();
|
|
|
|
DECLARE_SERIAL(TimesExpr);
|
|
|
|
};
|
|
|
|
class DivideExpr : public BinaryExpr {
|
|
public:
|
|
DivideExpr(Expr* op1, Expr* op2);
|
|
|
|
protected:
|
|
friend class Expr;
|
|
DivideExpr() { }
|
|
|
|
Val* AddrFold(Val* v1, Val* v2) const;
|
|
Expr* DoSimplify();
|
|
|
|
DECLARE_SERIAL(DivideExpr);
|
|
|
|
};
|
|
|
|
class ModExpr : public BinaryExpr {
|
|
public:
|
|
ModExpr(Expr* op1, Expr* op2);
|
|
|
|
protected:
|
|
friend class Expr;
|
|
ModExpr() { }
|
|
|
|
Expr* DoSimplify();
|
|
|
|
DECLARE_SERIAL(ModExpr);
|
|
};
|
|
|
|
class BoolExpr : public BinaryExpr {
|
|
public:
|
|
BoolExpr(BroExprTag tag, Expr* op1, Expr* op2);
|
|
|
|
Val* Eval(Frame* f) const;
|
|
Val* DoSingleEval(Frame* f, Val* v1, Expr* op2) const;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
BoolExpr() { }
|
|
|
|
Expr* DoSimplify();
|
|
|
|
DECLARE_SERIAL(BoolExpr);
|
|
};
|
|
|
|
class EqExpr : public BinaryExpr {
|
|
public:
|
|
EqExpr(BroExprTag tag, Expr* op1, Expr* op2);
|
|
void Canonicize();
|
|
|
|
protected:
|
|
friend class Expr;
|
|
EqExpr() { }
|
|
|
|
Expr* DoSimplify();
|
|
|
|
Val* Fold(Val* v1, Val* v2) const;
|
|
|
|
DECLARE_SERIAL(EqExpr);
|
|
};
|
|
|
|
class RelExpr : public BinaryExpr {
|
|
public:
|
|
RelExpr(BroExprTag tag, Expr* op1, Expr* op2);
|
|
void Canonicize();
|
|
|
|
protected:
|
|
friend class Expr;
|
|
RelExpr() { }
|
|
|
|
Expr* DoSimplify();
|
|
|
|
DECLARE_SERIAL(RelExpr);
|
|
};
|
|
|
|
class CondExpr : public Expr {
|
|
public:
|
|
CondExpr(Expr* op1, Expr* op2, Expr* op3);
|
|
~CondExpr();
|
|
|
|
Expr* Simplify(SimplifyType simp_type);
|
|
Val* Eval(Frame* f) const;
|
|
int IsPure() const;
|
|
|
|
TraversalCode Traverse(TraversalCallback* cb) const;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
CondExpr() { op1 = op2 = op3 = 0; }
|
|
|
|
void ExprDescribe(ODesc* d) const;
|
|
|
|
DECLARE_SERIAL(CondExpr);
|
|
|
|
Expr* op1;
|
|
Expr* op2;
|
|
Expr* op3;
|
|
};
|
|
|
|
class RefExpr : public UnaryExpr {
|
|
public:
|
|
RefExpr(Expr* op);
|
|
|
|
void Assign(Frame* f, Val* v, Opcode op = OP_ASSIGN);
|
|
Expr* MakeLvalue();
|
|
|
|
protected:
|
|
friend class Expr;
|
|
RefExpr() { }
|
|
|
|
DECLARE_SERIAL(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);
|
|
virtual ~AssignExpr() { Unref(val); }
|
|
|
|
Expr* Simplify(SimplifyType simp_type);
|
|
Val* Eval(Frame* f) const;
|
|
void EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f) const;
|
|
BroType* InitType() const;
|
|
int IsRecordElement(TypeDecl* td) const;
|
|
Val* InitVal(const BroType* t, Val* aggr) const;
|
|
int IsPure() const;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
AssignExpr() { }
|
|
|
|
bool TypeCheck(attr_list* attrs = 0);
|
|
bool TypeCheckArithmetics(TypeTag bt1, TypeTag bt2);
|
|
|
|
DECLARE_SERIAL(AssignExpr);
|
|
|
|
int is_init;
|
|
Val* val; // optional
|
|
};
|
|
|
|
class IndexExpr : public BinaryExpr {
|
|
public:
|
|
IndexExpr(Expr* op1, ListExpr* op2);
|
|
|
|
int CanAdd() const;
|
|
int CanDel() const;
|
|
|
|
void Add(Frame* f);
|
|
void Delete(Frame* f);
|
|
|
|
Expr* Simplify(SimplifyType simp_type);
|
|
void Assign(Frame* f, Val* v, Opcode op = OP_ASSIGN);
|
|
Expr* MakeLvalue();
|
|
|
|
// Need to override Eval since it can take a vector arg but does
|
|
// not necessarily return a vector.
|
|
Val* Eval(Frame* f) const;
|
|
|
|
TraversalCode Traverse(TraversalCallback* cb) const;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
IndexExpr() { }
|
|
|
|
Val* Fold(Val* v1, Val* v2) const;
|
|
|
|
void ExprDescribe(ODesc* d) const;
|
|
|
|
DECLARE_SERIAL(IndexExpr);
|
|
};
|
|
|
|
class FieldExpr : public UnaryExpr {
|
|
public:
|
|
FieldExpr(Expr* op, const char* field_name);
|
|
~FieldExpr();
|
|
|
|
int Field() const { return field; }
|
|
|
|
int CanDel() const;
|
|
|
|
Expr* Simplify(SimplifyType simp_type);
|
|
void Assign(Frame* f, Val* v, Opcode op = OP_ASSIGN);
|
|
void Delete(Frame* f);
|
|
|
|
Expr* MakeLvalue();
|
|
|
|
protected:
|
|
friend class Expr;
|
|
FieldExpr() { field_name = 0; td = 0; }
|
|
|
|
Val* Fold(Val* v) const;
|
|
|
|
void ExprDescribe(ODesc* d) const;
|
|
|
|
DECLARE_SERIAL(FieldExpr);
|
|
|
|
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();
|
|
|
|
protected:
|
|
friend class Expr;
|
|
HasFieldExpr() { field_name = 0; }
|
|
|
|
Val* Fold(Val* v) const;
|
|
|
|
void ExprDescribe(ODesc* d) const;
|
|
|
|
DECLARE_SERIAL(HasFieldExpr);
|
|
|
|
bool is_attr;
|
|
const char* field_name;
|
|
int field;
|
|
};
|
|
|
|
class RecordConstructorExpr : public UnaryExpr {
|
|
public:
|
|
RecordConstructorExpr(ListExpr* constructor_list);
|
|
|
|
protected:
|
|
friend class Expr;
|
|
RecordConstructorExpr() { }
|
|
|
|
Val* InitVal(const BroType* t, Val* aggr) const;
|
|
Val* Fold(Val* v) const;
|
|
|
|
void ExprDescribe(ODesc* d) const;
|
|
|
|
DECLARE_SERIAL(RecordConstructorExpr);
|
|
};
|
|
|
|
class TableConstructorExpr : public UnaryExpr {
|
|
public:
|
|
TableConstructorExpr(ListExpr* constructor_list, attr_list* attrs);
|
|
~TableConstructorExpr() { Unref(attrs); }
|
|
|
|
Val* Eval(Frame* f) const;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
TableConstructorExpr() { }
|
|
|
|
Val* InitVal(const BroType* t, Val* aggr) const;
|
|
|
|
void ExprDescribe(ODesc* d) const;
|
|
|
|
DECLARE_SERIAL(TableConstructorExpr);
|
|
|
|
Attributes* attrs;
|
|
};
|
|
|
|
class SetConstructorExpr : public UnaryExpr {
|
|
public:
|
|
SetConstructorExpr(ListExpr* constructor_list, attr_list* attrs);
|
|
~SetConstructorExpr() { Unref(attrs); }
|
|
|
|
Val* Eval(Frame* f) const;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
SetConstructorExpr() { }
|
|
|
|
Val* InitVal(const BroType* t, Val* aggr) const;
|
|
|
|
void ExprDescribe(ODesc* d) const;
|
|
|
|
DECLARE_SERIAL(SetConstructorExpr);
|
|
|
|
Attributes* attrs;
|
|
};
|
|
|
|
class VectorConstructorExpr : public UnaryExpr {
|
|
public:
|
|
VectorConstructorExpr(ListExpr* constructor_list);
|
|
|
|
Val* Eval(Frame* f) const;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
VectorConstructorExpr() { }
|
|
|
|
Val* InitVal(const BroType* t, Val* aggr) const;
|
|
|
|
void ExprDescribe(ODesc* d) const;
|
|
|
|
DECLARE_SERIAL(VectorConstructorExpr);
|
|
};
|
|
|
|
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;
|
|
int IsRecordElement(TypeDecl* td) const;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
FieldAssignExpr() { }
|
|
|
|
void ExprDescribe(ODesc* d) const;
|
|
|
|
DECLARE_SERIAL(FieldAssignExpr);
|
|
|
|
string field_name;
|
|
};
|
|
|
|
class ArithCoerceExpr : public UnaryExpr {
|
|
public:
|
|
ArithCoerceExpr(Expr* op, TypeTag t);
|
|
|
|
protected:
|
|
friend class Expr;
|
|
ArithCoerceExpr() { }
|
|
|
|
Expr* DoSimplify();
|
|
|
|
Val* FoldSingleVal(Val* v, InternalTypeTag t) const;
|
|
Val* Fold(Val* v) const;
|
|
|
|
DECLARE_SERIAL(ArithCoerceExpr);
|
|
};
|
|
|
|
class RecordCoerceExpr : public UnaryExpr {
|
|
public:
|
|
RecordCoerceExpr(Expr* op, RecordType* r);
|
|
~RecordCoerceExpr();
|
|
|
|
protected:
|
|
friend class Expr;
|
|
RecordCoerceExpr() { map = 0; }
|
|
|
|
Val* Fold(Val* v) const;
|
|
|
|
DECLARE_SERIAL(RecordCoerceExpr);
|
|
|
|
// 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();
|
|
|
|
protected:
|
|
friend class Expr;
|
|
TableCoerceExpr() { }
|
|
|
|
Val* Fold(Val* v) const;
|
|
|
|
DECLARE_SERIAL(TableCoerceExpr);
|
|
};
|
|
|
|
class VectorCoerceExpr : public UnaryExpr {
|
|
public:
|
|
VectorCoerceExpr(Expr* op, VectorType* v);
|
|
~VectorCoerceExpr();
|
|
|
|
protected:
|
|
friend class Expr;
|
|
VectorCoerceExpr() { }
|
|
|
|
Val* Fold(Val* v) const;
|
|
|
|
DECLARE_SERIAL(VectorCoerceExpr);
|
|
};
|
|
|
|
// An internal operator for flattening array indices that are records
|
|
// into a list of individual values.
|
|
class FlattenExpr : public UnaryExpr {
|
|
public:
|
|
FlattenExpr(Expr* op);
|
|
|
|
protected:
|
|
friend class Expr;
|
|
FlattenExpr() { }
|
|
|
|
Val* Fold(Val* v) const;
|
|
|
|
DECLARE_SERIAL(FlattenExpr);
|
|
|
|
int num_fields;
|
|
};
|
|
|
|
class EventHandler;
|
|
|
|
class ScheduleTimer : public Timer {
|
|
public:
|
|
ScheduleTimer(EventHandlerPtr event, val_list* args, double t,
|
|
TimerMgr* tmgr);
|
|
~ScheduleTimer();
|
|
|
|
void Dispatch(double t, int is_expire);
|
|
|
|
protected:
|
|
EventHandlerPtr event;
|
|
val_list* args;
|
|
TimerMgr* tmgr;
|
|
};
|
|
|
|
class ScheduleExpr : public Expr {
|
|
public:
|
|
ScheduleExpr(Expr* when, EventExpr* event);
|
|
~ScheduleExpr();
|
|
|
|
int IsPure() const;
|
|
|
|
Expr* Simplify(SimplifyType simp_type);
|
|
|
|
Val* Eval(Frame* f) const;
|
|
|
|
Expr* When() const { return when; }
|
|
EventExpr* Event() const { return event; }
|
|
|
|
TraversalCode Traverse(TraversalCallback* cb) const;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
ScheduleExpr() { when = 0; event = 0; }
|
|
|
|
void ExprDescribe(ODesc* d) const;
|
|
|
|
DECLARE_SERIAL(ScheduleExpr);
|
|
|
|
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;
|
|
|
|
DECLARE_SERIAL(InExpr);
|
|
|
|
};
|
|
|
|
class CallExpr : public Expr {
|
|
public:
|
|
CallExpr(Expr* func, ListExpr* args, bool in_hook = false);
|
|
~CallExpr();
|
|
|
|
Expr* Func() const { return func; }
|
|
ListExpr* Args() const { return args; }
|
|
|
|
int IsPure() const;
|
|
|
|
Expr* Simplify(SimplifyType simp_type);
|
|
Val* Eval(Frame* f) const;
|
|
|
|
TraversalCode Traverse(TraversalCallback* cb) const;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
CallExpr() { func = 0; args = 0; }
|
|
|
|
void ExprDescribe(ODesc* d) const;
|
|
|
|
DECLARE_SERIAL(CallExpr);
|
|
|
|
Expr* func;
|
|
ListExpr* args;
|
|
};
|
|
|
|
class EventExpr : public Expr {
|
|
public:
|
|
EventExpr(const char* name, ListExpr* args);
|
|
~EventExpr();
|
|
|
|
const char* Name() const { return name.c_str(); }
|
|
ListExpr* Args() const { return args; }
|
|
EventHandlerPtr Handler() const { return handler; }
|
|
|
|
Expr* Simplify(SimplifyType simp_type);
|
|
Val* Eval(Frame* f) const;
|
|
|
|
TraversalCode Traverse(TraversalCallback* cb) const;
|
|
|
|
protected:
|
|
friend class Expr;
|
|
EventExpr() { args = 0; }
|
|
|
|
void ExprDescribe(ODesc* d) const;
|
|
|
|
DECLARE_SERIAL(EventExpr);
|
|
|
|
string name;
|
|
EventHandlerPtr handler;
|
|
ListExpr* args;
|
|
};
|
|
|
|
class ListExpr : public Expr {
|
|
public:
|
|
ListExpr();
|
|
ListExpr(Expr* e);
|
|
~ListExpr();
|
|
|
|
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;
|
|
|
|
// True if the entire list represents constant values.
|
|
int AllConst() const;
|
|
|
|
Expr* Simplify(SimplifyType simp_type);
|
|
Val* Eval(Frame* f) const;
|
|
|
|
BroType* InitType() const;
|
|
Val* InitVal(const BroType* t, Val* aggr) const;
|
|
Expr* MakeLvalue();
|
|
void Assign(Frame* f, Val* v, Opcode op = OP_ASSIGN);
|
|
|
|
TraversalCode Traverse(TraversalCallback* cb) const;
|
|
|
|
protected:
|
|
Val* AddSetInit(const BroType* t, Val* aggr) const;
|
|
|
|
void ExprDescribe(ODesc* d) const;
|
|
|
|
DECLARE_SERIAL(ListExpr);
|
|
|
|
expr_list exprs;
|
|
};
|
|
|
|
|
|
class RecordAssignExpr : public ListExpr {
|
|
public:
|
|
RecordAssignExpr(Expr* record, Expr* init_list, int is_init);
|
|
|
|
Val* Eval(Frame* f) const { return ListExpr::Eval(f); }
|
|
|
|
protected:
|
|
friend class Expr;
|
|
RecordAssignExpr() { }
|
|
|
|
DECLARE_SERIAL(RecordAssignExpr);
|
|
};
|
|
|
|
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 and third 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_exprs_to_type(ListExpr*& elements, BroType* type);
|
|
|
|
// Returns a fully simplified form of the expression. Note that passed
|
|
// expression and its subexpressions may be modified, Unref()'d, etc.
|
|
Expr* simplify_expr(Expr* e, SimplifyType simp_type);
|
|
|
|
// Returns a simplified ListExpr - guaranteed to still be a ListExpr,
|
|
// even if it only contains one expr.
|
|
ListExpr* simplify_expr_list(ListExpr* l, SimplifyType simp_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 two expressions are identical.
|
|
extern int same_expr(const Expr* e1, const Expr* e2);
|
|
|
|
// 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);
|
|
|
|
// Return constants of the given type.
|
|
Expr* make_zero(BroType* t);
|
|
Expr* make_one(BroType* t);
|
|
|
|
// True if the given Val* has a vector type
|
|
inline bool is_vector(Expr* e) { return e->Type()->Tag() == TYPE_VECTOR; }
|
|
|
|
#endif
|