Expr: use class IntrusivePtr

As a side effect, this fixes lots of memory leaks in
`*Expr::InitVal()` because in most implementations, the `aggr`
parameter leaks.
This commit is contained in:
Max Kellermann 2020-02-26 19:12:57 +01:00
parent 7be3641f1d
commit c3ea246237
17 changed files with 885 additions and 1206 deletions

View file

@ -6,6 +6,7 @@
#include "Expr.h"
#include "Desc.h"
#include "Val.h"
#include "IntrusivePtr.h"
#include "threading/SerialTypes.h"
const char* attr_name(attr_tag t)
@ -109,10 +110,8 @@ void Attr::DescribeReST(ODesc* d, bool shorten) const
else
{
Val* v = expr->Eval(0);
ODesc dd;
v->Describe(&dd);
Unref(v);
expr->Eval(0)->Describe(&dd);
string s = dd.Description();
for ( size_t i = 0; i < s.size(); ++i )

View file

@ -13,6 +13,7 @@
#include "Scope.h"
#include "Frame.h"
#include "Func.h"
#include "IntrusivePtr.h"
#include "Val.h"
#include "Stmt.h"
#include "Timer.h"
@ -246,7 +247,7 @@ BreakCode DbgBreakpoint::HasHit()
if ( condition.size() )
{
// TODO: ### evaluate using debugger frame too
Val* yes = dbg_eval_expr(condition.c_str());
auto yes = dbg_eval_expr(condition.c_str());
if ( ! yes )
{
@ -260,7 +261,6 @@ BreakCode DbgBreakpoint::HasHit()
if ( ! IsIntegral(yes->Type()->Tag()) &&
! IsBool(yes->Type()->Tag()) )
{
Unref(yes);
PrintHitMsg();
debug_msg("Breakpoint condition should return an integral type");
return bcHitAndDelete;
@ -269,11 +269,8 @@ BreakCode DbgBreakpoint::HasHit()
yes->CoerceToInt();
if ( yes->IsZero() )
{
Unref(yes);
return bcNoHit;
}
Unref(yes);
}
int repcount = GetRepeatCount();

View file

@ -16,6 +16,7 @@ using namespace std;
#include "DebugCmds.h"
#include "DbgBreakpoint.h"
#include "ID.h"
#include "IntrusivePtr.h"
#include "Expr.h"
#include "Stmt.h"
#include "Frame.h"
@ -946,7 +947,7 @@ extern YYLTYPE yylloc; // holds start line and column of token
extern int line_number;
extern const char* filename;
Val* dbg_eval_expr(const char* expr)
IntrusivePtr<Val> dbg_eval_expr(const char* expr)
{
// Push the current frame's associated scope.
// Note: g_debugger_state.curr_frame_idx is the user-visible number,
@ -981,7 +982,7 @@ Val* dbg_eval_expr(const char* expr)
yylloc.first_line = yylloc.last_line = line_number = 1;
// Parse the thing into an expr.
Val* result = 0;
IntrusivePtr<Val> result;
if ( yyparse() )
{
if ( g_curr_debug_error )

View file

@ -10,6 +10,7 @@
#include <map>
#include <string>
template <class T> class IntrusivePtr;
class Val;
class Stmt;
@ -159,7 +160,7 @@ int dbg_handle_debug_input(); // read a line and then have it executed
int dbg_execute_command(const char* cmd);
// Interactive expression evaluation.
Val* dbg_eval_expr(const char* expr);
IntrusivePtr<Val> dbg_eval_expr(const char* expr);
// Extra debugging facilities.
// TODO: current connections, memory allocated, other internal data structures.

View file

@ -15,6 +15,7 @@
#include "Desc.h"
#include "DbgBreakpoint.h"
#include "ID.h"
#include "IntrusivePtr.h"
#include "Frame.h"
#include "Func.h"
#include "Stmt.h"
@ -564,13 +565,12 @@ int dbg_cmd_print(DebugCmd cmd, const vector<string>& args)
expr += " ";
}
Val* val = dbg_eval_expr(expr.c_str());
auto val = dbg_eval_expr(expr.c_str());
if ( val )
{
ODesc d;
val->Describe(&d);
Unref(val);
debug_msg("%s\n", d.Description());
}
else

File diff suppressed because it is too large Load diff

View file

@ -5,6 +5,7 @@
// BRO expressions.
#include "BroList.h"
#include "IntrusivePtr.h"
#include "Timer.h"
#include "Type.h"
#include "EventHandler.h"
@ -58,6 +59,7 @@ typedef enum {
extern const char* expr_name(BroExprTag t);
template <class T> class IntrusivePtr;
class Stmt;
class Frame;
class ListExpr;
@ -72,16 +74,14 @@ struct function_ingredients;
class Expr : public BroObj {
public:
BroType* Type() const { return type; }
BroType* Type() const { return type.get(); }
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;
virtual IntrusivePtr<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
@ -91,12 +91,11 @@ public:
const;
// Assign to the given value, if appropriate.
virtual void Assign(Frame* f, Val* v);
virtual void Assign(Frame* f, IntrusivePtr<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;
// as an initialization. Returns nil if the initialization is illegal.
virtual IntrusivePtr<BroType> InitType() const;
// Returns true if this expression, interpreted as an initialization,
// constitutes a record element, false otherwise. If the TypeDecl*
@ -109,7 +108,7 @@ public:
// 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;
virtual IntrusivePtr<Val> InitVal(const BroType* t, IntrusivePtr<Val> aggr) const;
// True if the expression has no side effects, false otherwise.
virtual int IsPure() const;
@ -145,7 +144,7 @@ public:
// 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();
virtual IntrusivePtr<Expr> MakeLvalue();
// Marks the expression as one requiring (or at least appearing
// with) parentheses. Used for pretty-printing.
@ -214,7 +213,7 @@ protected:
// Puts the expression in canonical form.
virtual void Canonicize();
void SetType(BroType* t);
void SetType(IntrusivePtr<BroType> t);
// Reports the given error and sets the expression's type to
// TYPE_ERROR.
@ -225,21 +224,20 @@ protected:
void RuntimeErrorWithCallStack(const std::string& msg) const;
BroExprTag tag;
BroType* type;
IntrusivePtr<BroType> type;
int paren;
};
class NameExpr : public Expr {
public:
explicit NameExpr(ID* id, bool const_init = false);
~NameExpr() override;
explicit NameExpr(IntrusivePtr<ID> id, bool const_init = false);
ID* Id() const { return id; }
ID* Id() const { return id.get(); }
Val* Eval(Frame* f) const override;
void Assign(Frame* f, Val* v) override;
Expr* MakeLvalue() override;
IntrusivePtr<Val> Eval(Frame* f) const override;
void Assign(Frame* f, IntrusivePtr<Val> v) override;
IntrusivePtr<Expr> MakeLvalue() override;
int IsPure() const override;
TraversalCode Traverse(TraversalCallback* cb) const override;
@ -247,91 +245,88 @@ public:
protected:
void ExprDescribe(ODesc* d) const override;
ID* id;
IntrusivePtr<ID> id;
bool in_const_init;
};
class ConstExpr : public Expr {
public:
explicit ConstExpr(Val* val);
~ConstExpr() override;
explicit ConstExpr(IntrusivePtr<Val> val);
Val* Value() const { return val; }
Val* Value() const { return val.get(); }
Val* Eval(Frame* f) const override;
IntrusivePtr<Val> Eval(Frame* f) const override;
TraversalCode Traverse(TraversalCallback* cb) const override;
protected:
void ExprDescribe(ODesc* d) const override;
Val* val;
IntrusivePtr<Val> val;
};
class UnaryExpr : public Expr {
public:
Expr* Op() const { return op; }
Expr* Op() const { return op.get(); }
// 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;
IntrusivePtr<Val> Eval(Frame* f) const override;
int IsPure() const override;
TraversalCode Traverse(TraversalCallback* cb) const override;
protected:
UnaryExpr(BroExprTag arg_tag, Expr* arg_op);
~UnaryExpr() override;
UnaryExpr(BroExprTag arg_tag, IntrusivePtr<Expr> arg_op);
void ExprDescribe(ODesc* d) const override;
// Returns the expression folded using the given constant.
virtual Val* Fold(Val* v) const;
virtual IntrusivePtr<Val> Fold(Val* v) const;
Expr* op;
IntrusivePtr<Expr> op;
};
class BinaryExpr : public Expr {
public:
Expr* Op1() const { return op1; }
Expr* Op2() const { return op2; }
Expr* Op1() const { return op1.get(); }
Expr* Op2() const { return op2.get(); }
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;
IntrusivePtr<Val> Eval(Frame* f) const override;
TraversalCode Traverse(TraversalCallback* cb) const override;
protected:
BinaryExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2)
: Expr(arg_tag), op1(arg_op1), op2(arg_op2)
BinaryExpr(BroExprTag arg_tag, IntrusivePtr<Expr> arg_op1, IntrusivePtr<Expr> arg_op2)
: Expr(arg_tag), op1(std::move(arg_op1)), op2(std::move(arg_op2))
{
if ( ! (arg_op1 && arg_op2) )
if ( ! (op1 && 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;
virtual IntrusivePtr<Val> Fold(Val* v1, Val* v2) const;
// Same for when the constants are strings.
virtual Val* StringFold(Val* v1, Val* v2) const;
virtual IntrusivePtr<Val> StringFold(Val* v1, Val* v2) const;
// Same for when the constants are patterns.
virtual Val* PatternFold(Val* v1, Val* v2) const;
virtual IntrusivePtr<Val> PatternFold(Val* v1, Val* v2) const;
// Same for when the constants are sets.
virtual Val* SetFold(Val* v1, Val* v2) const;
virtual IntrusivePtr<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;
virtual IntrusivePtr<Val> AddrFold(Val* v1, Val* v2) const;
virtual IntrusivePtr<Val> SubNetFold(Val* v1, Val* v2) const;
int BothConst() const { return op1->IsConst() && op2->IsConst(); }
@ -347,149 +342,148 @@ protected:
void ExprDescribe(ODesc* d) const override;
Expr* op1;
Expr* op2;
IntrusivePtr<Expr> op1;
IntrusivePtr<Expr> op2;
};
class CloneExpr : public UnaryExpr {
public:
explicit CloneExpr(Expr* op);
Val* Eval(Frame* f) const override;
explicit CloneExpr(IntrusivePtr<Expr> op);
IntrusivePtr<Val> Eval(Frame* f) const override;
protected:
Val* Fold(Val* v) const override;
IntrusivePtr<Val> Fold(Val* v) const override;
};
class IncrExpr : public UnaryExpr {
public:
IncrExpr(BroExprTag tag, Expr* op);
IncrExpr(BroExprTag tag, IntrusivePtr<Expr> op);
Val* Eval(Frame* f) const override;
Val* DoSingleEval(Frame* f, Val* v) const;
IntrusivePtr<Val> Eval(Frame* f) const override;
IntrusivePtr<Val> DoSingleEval(Frame* f, Val* v) const;
int IsPure() const override;
};
class ComplementExpr : public UnaryExpr {
public:
explicit ComplementExpr(Expr* op);
explicit ComplementExpr(IntrusivePtr<Expr> op);
protected:
Val* Fold(Val* v) const override;
IntrusivePtr<Val> Fold(Val* v) const override;
};
class NotExpr : public UnaryExpr {
public:
explicit NotExpr(Expr* op);
explicit NotExpr(IntrusivePtr<Expr> op);
protected:
Val* Fold(Val* v) const override;
IntrusivePtr<Val> Fold(Val* v) const override;
};
class PosExpr : public UnaryExpr {
public:
explicit PosExpr(Expr* op);
explicit PosExpr(IntrusivePtr<Expr> op);
protected:
Val* Fold(Val* v) const override;
IntrusivePtr<Val> Fold(Val* v) const override;
};
class NegExpr : public UnaryExpr {
public:
explicit NegExpr(Expr* op);
explicit NegExpr(IntrusivePtr<Expr> op);
protected:
Val* Fold(Val* v) const override;
IntrusivePtr<Val> Fold(Val* v) const override;
};
class SizeExpr : public UnaryExpr {
public:
explicit SizeExpr(Expr* op);
Val* Eval(Frame* f) const override;
explicit SizeExpr(IntrusivePtr<Expr> op);
IntrusivePtr<Val> Eval(Frame* f) const override;
protected:
Val* Fold(Val* v) const override;
IntrusivePtr<Val> Fold(Val* v) const override;
};
class AddExpr : public BinaryExpr {
public:
AddExpr(Expr* op1, Expr* op2);
AddExpr(IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2);
void Canonicize() override;
};
class AddToExpr : public BinaryExpr {
public:
AddToExpr(Expr* op1, Expr* op2);
Val* Eval(Frame* f) const override;
AddToExpr(IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2);
IntrusivePtr<Val> Eval(Frame* f) const override;
};
class RemoveFromExpr : public BinaryExpr {
public:
RemoveFromExpr(Expr* op1, Expr* op2);
Val* Eval(Frame* f) const override;
RemoveFromExpr(IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2);
IntrusivePtr<Val> Eval(Frame* f) const override;
};
class SubExpr : public BinaryExpr {
public:
SubExpr(Expr* op1, Expr* op2);
SubExpr(IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2);
};
class TimesExpr : public BinaryExpr {
public:
TimesExpr(Expr* op1, Expr* op2);
TimesExpr(IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2);
void Canonicize() override;
};
class DivideExpr : public BinaryExpr {
public:
DivideExpr(Expr* op1, Expr* op2);
DivideExpr(IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2);
protected:
Val* AddrFold(Val* v1, Val* v2) const override;
IntrusivePtr<Val> AddrFold(Val* v1, Val* v2) const override;
};
class ModExpr : public BinaryExpr {
public:
ModExpr(Expr* op1, Expr* op2);
ModExpr(IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2);
};
class BoolExpr : public BinaryExpr {
public:
BoolExpr(BroExprTag tag, Expr* op1, Expr* op2);
BoolExpr(BroExprTag tag, IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2);
Val* Eval(Frame* f) const override;
Val* DoSingleEval(Frame* f, Val* v1, Expr* op2) const;
IntrusivePtr<Val> Eval(Frame* f) const override;
IntrusivePtr<Val> DoSingleEval(Frame* f, IntrusivePtr<Val> v1, Expr* op2) const;
};
class BitExpr : public BinaryExpr {
public:
BitExpr(BroExprTag tag, Expr* op1, Expr* op2);
BitExpr(BroExprTag tag, IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2);
};
class EqExpr : public BinaryExpr {
public:
EqExpr(BroExprTag tag, Expr* op1, Expr* op2);
EqExpr(BroExprTag tag, IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2);
void Canonicize() override;
protected:
Val* Fold(Val* v1, Val* v2) const override;
IntrusivePtr<Val> Fold(Val* v1, Val* v2) const override;
};
class RelExpr : public BinaryExpr {
public:
RelExpr(BroExprTag tag, Expr* op1, Expr* op2);
RelExpr(BroExprTag tag, IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2);
void Canonicize() override;
};
class CondExpr : public Expr {
public:
CondExpr(Expr* op1, Expr* op2, Expr* op3);
~CondExpr() override;
CondExpr(IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2, IntrusivePtr<Expr> op3);
const Expr* Op1() const { return op1; }
const Expr* Op2() const { return op2; }
const Expr* Op3() const { return op3; }
const Expr* Op1() const { return op1.get(); }
const Expr* Op2() const { return op2.get(); }
const Expr* Op3() const { return op3.get(); }
Val* Eval(Frame* f) const override;
IntrusivePtr<Val> Eval(Frame* f) const override;
int IsPure() const override;
TraversalCode Traverse(TraversalCallback* cb) const override;
@ -497,31 +491,30 @@ public:
protected:
void ExprDescribe(ODesc* d) const override;
Expr* op1;
Expr* op2;
Expr* op3;
IntrusivePtr<Expr> op1;
IntrusivePtr<Expr> op2;
IntrusivePtr<Expr> op3;
};
class RefExpr : public UnaryExpr {
public:
explicit RefExpr(Expr* op);
explicit RefExpr(IntrusivePtr<Expr> op);
void Assign(Frame* f, Val* v) override;
Expr* MakeLvalue() override;
void Assign(Frame* f, IntrusivePtr<Val> v) override;
IntrusivePtr<Expr> MakeLvalue() override;
};
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;
AssignExpr(IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2, int is_init, IntrusivePtr<Val> val = nullptr, attr_list* attrs = nullptr);
Val* Eval(Frame* f) const override;
IntrusivePtr<Val> Eval(Frame* f) const override;
void EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f) const override;
BroType* InitType() const override;
IntrusivePtr<BroType> InitType() const override;
int IsRecordElement(TypeDecl* td) const override;
Val* InitVal(const BroType* t, Val* aggr) const override;
IntrusivePtr<Val> InitVal(const BroType* t, IntrusivePtr<Val> aggr) const override;
int IsPure() const override;
protected:
@ -529,18 +522,18 @@ protected:
bool TypeCheckArithmetics(TypeTag bt1, TypeTag bt2);
int is_init;
Val* val; // optional
IntrusivePtr<Val> val; // optional
};
class IndexSliceAssignExpr : public AssignExpr {
public:
IndexSliceAssignExpr(Expr* op1, Expr* op2, int is_init);
Val* Eval(Frame* f) const override;
IndexSliceAssignExpr(IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2, int is_init);
IntrusivePtr<Val> Eval(Frame* f) const override;
};
class IndexExpr : public BinaryExpr {
public:
IndexExpr(Expr* op1, ListExpr* op2, bool is_slice = false);
IndexExpr(IntrusivePtr<Expr> op1, IntrusivePtr<ListExpr> op2, bool is_slice = false);
int CanAdd() const override;
int CanDel() const override;
@ -548,19 +541,19 @@ public:
void Add(Frame* f) override;
void Delete(Frame* f) override;
void Assign(Frame* f, Val* v) override;
Expr* MakeLvalue() override;
void Assign(Frame* f, IntrusivePtr<Val> v) override;
IntrusivePtr<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;
IntrusivePtr<Val> Eval(Frame* f) const override;
TraversalCode Traverse(TraversalCallback* cb) const override;
bool IsSlice() const { return is_slice; }
protected:
Val* Fold(Val* v1, Val* v2) const override;
IntrusivePtr<Val> Fold(Val* v1, Val* v2) const override;
void ExprDescribe(ODesc* d) const override;
@ -569,7 +562,7 @@ protected:
class FieldExpr : public UnaryExpr {
public:
FieldExpr(Expr* op, const char* field_name);
FieldExpr(IntrusivePtr<Expr> op, const char* field_name);
~FieldExpr() override;
int Field() const { return field; }
@ -577,13 +570,13 @@ public:
int CanDel() const override;
void Assign(Frame* f, Val* v) override;
void Assign(Frame* f, IntrusivePtr<Val> v) override;
void Delete(Frame* f) override;
Expr* MakeLvalue() override;
IntrusivePtr<Expr> MakeLvalue() override;
protected:
Val* Fold(Val* v) const override;
IntrusivePtr<Val> Fold(Val* v) const override;
void ExprDescribe(ODesc* d) const override;
@ -596,13 +589,13 @@ protected:
// "rec?$$attrname" is true if the attribute attrname is not nil.
class HasFieldExpr : public UnaryExpr {
public:
HasFieldExpr(Expr* op, const char* field_name);
HasFieldExpr(IntrusivePtr<Expr> op, const char* field_name);
~HasFieldExpr() override;
const char* FieldName() const { return field_name; }
protected:
Val* Fold(Val* v) const override;
IntrusivePtr<Val> Fold(Val* v) const override;
void ExprDescribe(ODesc* d) const override;
@ -612,28 +605,28 @@ protected:
class RecordConstructorExpr : public UnaryExpr {
public:
explicit RecordConstructorExpr(ListExpr* constructor_list);
explicit RecordConstructorExpr(IntrusivePtr<ListExpr> constructor_list);
~RecordConstructorExpr() override;
protected:
Val* InitVal(const BroType* t, Val* aggr) const override;
Val* Fold(Val* v) const override;
IntrusivePtr<Val> InitVal(const BroType* t, IntrusivePtr<Val> aggr) const override;
IntrusivePtr<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(IntrusivePtr<ListExpr> constructor_list, attr_list* attrs,
IntrusivePtr<BroType> arg_type = nullptr);
~TableConstructorExpr() override { Unref(attrs); }
Attributes* Attrs() { return attrs; }
Val* Eval(Frame* f) const override;
IntrusivePtr<Val> Eval(Frame* f) const override;
protected:
Val* InitVal(const BroType* t, Val* aggr) const override;
IntrusivePtr<Val> InitVal(const BroType* t, IntrusivePtr<Val> aggr) const override;
void ExprDescribe(ODesc* d) const override;
@ -642,16 +635,16 @@ protected:
class SetConstructorExpr : public UnaryExpr {
public:
SetConstructorExpr(ListExpr* constructor_list, attr_list* attrs,
BroType* arg_type = 0);
SetConstructorExpr(IntrusivePtr<ListExpr> constructor_list, attr_list* attrs,
IntrusivePtr<BroType> arg_type = nullptr);
~SetConstructorExpr() override { Unref(attrs); }
Attributes* Attrs() { return attrs; }
Val* Eval(Frame* f) const override;
IntrusivePtr<Val> Eval(Frame* f) const override;
protected:
Val* InitVal(const BroType* t, Val* aggr) const override;
IntrusivePtr<Val> InitVal(const BroType* t, IntrusivePtr<Val> aggr) const override;
void ExprDescribe(ODesc* d) const override;
@ -660,19 +653,19 @@ protected:
class VectorConstructorExpr : public UnaryExpr {
public:
explicit VectorConstructorExpr(ListExpr* constructor_list, BroType* arg_type = 0);
explicit VectorConstructorExpr(IntrusivePtr<ListExpr> constructor_list, IntrusivePtr<BroType> arg_type = nullptr);
Val* Eval(Frame* f) const override;
IntrusivePtr<Val> Eval(Frame* f) const override;
protected:
Val* InitVal(const BroType* t, Val* aggr) const override;
IntrusivePtr<Val> InitVal(const BroType* t, IntrusivePtr<Val> aggr) const override;
void ExprDescribe(ODesc* d) const override;
};
class FieldAssignExpr : public UnaryExpr {
public:
FieldAssignExpr(const char* field_name, Expr* value);
FieldAssignExpr(const char* field_name, IntrusivePtr<Expr> value);
const char* FieldName() const { return field_name.c_str(); }
@ -687,21 +680,21 @@ protected:
class ArithCoerceExpr : public UnaryExpr {
public:
ArithCoerceExpr(Expr* op, TypeTag t);
ArithCoerceExpr(IntrusivePtr<Expr> op, TypeTag t);
protected:
Val* FoldSingleVal(Val* v, InternalTypeTag t) const;
Val* Fold(Val* v) const override;
IntrusivePtr<Val> FoldSingleVal(Val* v, InternalTypeTag t) const;
IntrusivePtr<Val> Fold(Val* v) const override;
};
class RecordCoerceExpr : public UnaryExpr {
public:
RecordCoerceExpr(Expr* op, RecordType* r);
RecordCoerceExpr(IntrusivePtr<Expr> op, IntrusivePtr<RecordType> r);
~RecordCoerceExpr() override;
protected:
Val* InitVal(const BroType* t, Val* aggr) const override;
Val* Fold(Val* v) const override;
IntrusivePtr<Val> InitVal(const BroType* t, IntrusivePtr<Val> aggr) const override;
IntrusivePtr<Val> Fold(Val* v) const override;
// For each super-record slot, gives subrecord slot with which to
// fill it.
@ -711,30 +704,30 @@ protected:
class TableCoerceExpr : public UnaryExpr {
public:
TableCoerceExpr(Expr* op, TableType* r);
TableCoerceExpr(IntrusivePtr<Expr> op, IntrusivePtr<TableType> r);
~TableCoerceExpr() override;
protected:
Val* Fold(Val* v) const override;
IntrusivePtr<Val> Fold(Val* v) const override;
};
class VectorCoerceExpr : public UnaryExpr {
public:
VectorCoerceExpr(Expr* op, VectorType* v);
VectorCoerceExpr(IntrusivePtr<Expr> op, IntrusivePtr<VectorType> v);
~VectorCoerceExpr() override;
protected:
Val* Fold(Val* v) const override;
IntrusivePtr<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);
explicit FlattenExpr(IntrusivePtr<Expr> op);
protected:
Val* Fold(Val* v) const override;
IntrusivePtr<Val> Fold(Val* v) const override;
int num_fields;
};
@ -755,53 +748,51 @@ protected:
class ScheduleExpr : public Expr {
public:
ScheduleExpr(Expr* when, EventExpr* event);
~ScheduleExpr() override;
ScheduleExpr(IntrusivePtr<Expr> when, IntrusivePtr<EventExpr> event);
int IsPure() const override;
Val* Eval(Frame* f) const override;
IntrusivePtr<Val> Eval(Frame* f) const override;
Expr* When() const { return when; }
EventExpr* Event() const { return event; }
Expr* When() const { return when.get(); }
EventExpr* Event() const { return event.get(); }
TraversalCode Traverse(TraversalCallback* cb) const override;
protected:
void ExprDescribe(ODesc* d) const override;
Expr* when;
EventExpr* event;
IntrusivePtr<Expr> when;
IntrusivePtr<EventExpr> event;
};
class InExpr : public BinaryExpr {
public:
InExpr(Expr* op1, Expr* op2);
InExpr(IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2);
protected:
Val* Fold(Val* v1, Val* v2) const override;
IntrusivePtr<Val> Fold(Val* v1, Val* v2) const override;
};
class CallExpr : public Expr {
public:
CallExpr(Expr* func, ListExpr* args, bool in_hook = false);
~CallExpr() override;
CallExpr(IntrusivePtr<Expr> func, IntrusivePtr<ListExpr> args, bool in_hook = false);
Expr* Func() const { return func; }
ListExpr* Args() const { return args; }
Expr* Func() const { return func.get(); }
ListExpr* Args() const { return args.get(); }
int IsPure() const override;
Val* Eval(Frame* f) const override;
IntrusivePtr<Val> Eval(Frame* f) const override;
TraversalCode Traverse(TraversalCallback* cb) const override;
protected:
void ExprDescribe(ODesc* d) const override;
Expr* func;
ListExpr* args;
IntrusivePtr<Expr> func;
IntrusivePtr<ListExpr> args;
};
@ -815,7 +806,7 @@ public:
LambdaExpr(std::unique_ptr<function_ingredients> ingredients,
id_list outer_ids);
Val* Eval(Frame* f) const override;
IntrusivePtr<Val> Eval(Frame* f) const override;
TraversalCode Traverse(TraversalCallback* cb) const override;
protected:
@ -830,14 +821,13 @@ private:
class EventExpr : public Expr {
public:
EventExpr(const char* name, ListExpr* args);
~EventExpr() override;
EventExpr(const char* name, IntrusivePtr<ListExpr> args);
const char* Name() const { return name.c_str(); }
ListExpr* Args() const { return args; }
ListExpr* Args() const { return args.get(); }
EventHandlerPtr Handler() const { return handler; }
Val* Eval(Frame* f) const override;
IntrusivePtr<Val> Eval(Frame* f) const override;
TraversalCode Traverse(TraversalCallback* cb) const override;
@ -846,16 +836,16 @@ protected:
string name;
EventHandlerPtr handler;
ListExpr* args;
IntrusivePtr<ListExpr> args;
};
class ListExpr : public Expr {
public:
ListExpr();
explicit ListExpr(Expr* e);
explicit ListExpr(IntrusivePtr<Expr> e);
~ListExpr() override;
void Append(Expr* e);
void Append(IntrusivePtr<Expr> e);
const expr_list& Exprs() const { return exprs; }
expr_list& Exprs() { return exprs; }
@ -866,17 +856,17 @@ public:
// True if the entire list represents constant values.
int AllConst() const;
Val* Eval(Frame* f) const override;
IntrusivePtr<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;
IntrusivePtr<BroType> InitType() const override;
IntrusivePtr<Val> InitVal(const BroType* t, IntrusivePtr<Val> aggr) const override;
IntrusivePtr<Expr> MakeLvalue() override;
void Assign(Frame* f, IntrusivePtr<Val> v) override;
TraversalCode Traverse(TraversalCallback* cb) const override;
protected:
Val* AddSetInit(const BroType* t, Val* aggr) const;
IntrusivePtr<Val> AddSetInit(const BroType* t, IntrusivePtr<Val> aggr) const;
void ExprDescribe(ODesc* d) const override;
@ -886,29 +876,28 @@ protected:
class RecordAssignExpr : public ListExpr {
public:
RecordAssignExpr(Expr* record, Expr* init_list, int is_init);
RecordAssignExpr(IntrusivePtr<Expr> record, IntrusivePtr<Expr> init_list, int is_init);
};
class CastExpr : public UnaryExpr {
public:
CastExpr(Expr* op, BroType* t);
CastExpr(IntrusivePtr<Expr> op, IntrusivePtr<BroType> t);
protected:
Val* Eval(Frame* f) const override;
IntrusivePtr<Val> Eval(Frame* f) const override;
void ExprDescribe(ODesc* d) const override;
};
class IsExpr : public UnaryExpr {
public:
IsExpr(Expr* op, BroType* t);
virtual ~IsExpr();
IsExpr(IntrusivePtr<Expr> op, IntrusivePtr<BroType> t);
protected:
Val* Fold(Val* v) const override;
IntrusivePtr<Val> Fold(Val* v) const override;
void ExprDescribe(ODesc* d) const override;
private:
BroType* t;
IntrusivePtr<BroType> t;
};
inline Val* Expr::ExprVal() const
@ -919,7 +908,7 @@ inline Val* Expr::ExprVal() const
}
// Decides whether to return an AssignExpr or a RecordAssignExpr.
Expr* get_assign_expr(Expr* op1, Expr* op2, int is_init);
IntrusivePtr<Expr> get_assign_expr(IntrusivePtr<Expr> op1, IntrusivePtr<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

View file

@ -815,7 +815,7 @@ bool check_built_in_call(BuiltinFunc* f, CallExpr* call)
return false;
}
Val* fmt_str_val = fmt_str_arg->Eval(0);
auto fmt_str_val = fmt_str_arg->Eval(0);
if ( fmt_str_val )
{
@ -829,7 +829,6 @@ bool check_built_in_call(BuiltinFunc* f, CallExpr* call)
if ( ! *fmt_str )
{
Unref(fmt_str_val);
call->Error("format string ends with bare '%'");
return false;
}
@ -841,13 +840,11 @@ bool check_built_in_call(BuiltinFunc* f, CallExpr* call)
if ( args.length() != num_fmt + 1 )
{
Unref(fmt_str_val);
call->Error("mismatch between format string to fmt() and number of arguments passed");
return false;
}
}
Unref(fmt_str_val);
return true;
}
@ -868,7 +865,7 @@ static int get_func_priority(const attr_list& attrs)
continue;
}
Val* v = a->AttrExpr()->Eval(0);
auto v = a->AttrExpr()->Eval(0);
if ( ! v )
{
a->Error("cannot evaluate attribute expression");
@ -877,13 +874,11 @@ static int get_func_priority(const attr_list& attrs)
if ( ! IsIntegral(v->Type()->Tag()) )
{
Unref(v);
a->Error("expression is not of integral type");
continue;
}
priority = v->InternalInt();
Unref(v);
}
return priority;

View file

@ -278,15 +278,14 @@ void ID::SetOption()
void ID::EvalFunc(Expr* ef, Expr* ev)
{
Expr* arg1 = new ConstExpr(val->Ref());
ListExpr* args = new ListExpr();
args->Append(arg1);
args->Append(ev->Ref());
auto arg1 = make_intrusive<ConstExpr>(IntrusivePtr{NewRef{}, val});
auto args = make_intrusive<ListExpr>();
args->Append(std::move(arg1));
args->Append({NewRef{}, ev});
CallExpr* ce = new CallExpr(ef->Ref(), args);
auto ce = make_intrusive<CallExpr>(IntrusivePtr{NewRef{}, ef}, std::move(args));
SetVal(ce->Eval(0));
Unref(ce);
SetVal(ce->Eval(0).release());
}
#if 0

View file

@ -321,14 +321,10 @@ Val* ExprStmt::Exec(Frame* f, stmt_flow_type& flow) const
RegisterAccess();
flow = FLOW_NEXT;
Val* v = e->Eval(f);
auto v = e->Eval(f);
if ( v )
{
Val* ret_val = DoExec(f, v, flow);
Unref(v);
return ret_val;
}
return DoExec(f, v.get(), flow);
else
return 0;
}
@ -670,10 +666,10 @@ SwitchStmt::SwitchStmt(Expr* index, case_list* arg_cases) :
if ( ne->Id()->IsConst() )
{
Val* v = ne->Eval(0);
auto v = ne->Eval(0);
if ( v )
Unref(exprs.replace(j, new ConstExpr(v)));
Unref(exprs.replace(j, new ConstExpr(std::move(v))));
}
}
break;
@ -1068,15 +1064,12 @@ Val* WhileStmt::Exec(Frame* f, stmt_flow_type& flow) const
for ( ; ; )
{
Val* cond = loop_condition->Eval(f);
auto cond = loop_condition->Eval(f);
if ( ! cond )
break;
bool cont = cond->AsBool();
Unref(cond);
if ( ! cont )
if ( ! cond->AsBool() )
break;
flow = FLOW_NEXT;
@ -1481,7 +1474,7 @@ Val* ReturnStmt::Exec(Frame* f, stmt_flow_type& flow) const
flow = FLOW_RETURN;
if ( e )
return e->Eval(f);
return e->Eval(f).release();
else
return 0;
}

View file

@ -63,13 +63,10 @@ TraversalCode TriggerTraversalCallback::PreExpr(const Expr* expr)
try
{
Val* v = e->Eval(trigger->frame);
auto v = e->Eval(trigger->frame);
if ( v )
{
trigger->Register(v);
Unref(v);
}
trigger->Register(v.get());
}
catch ( InterpreterException& )
{ /* Already reported */ }
@ -157,7 +154,7 @@ Trigger::Trigger(Expr* arg_cond, Stmt* arg_body, Stmt* arg_timeout_stmts,
arg_frame->SetDelayed();
}
Val* timeout_val = nullptr;
IntrusivePtr<Val> timeout_val;
if ( arg_timeout )
{
@ -172,7 +169,6 @@ Trigger::Trigger(Expr* arg_cond, Stmt* arg_body, Stmt* arg_timeout_stmts,
if ( timeout_val )
{
timeout_value = timeout_val->AsInterval();
Unref(timeout_val);
}
// Make sure we don't get deleted if somebody calls a method like
@ -271,7 +267,7 @@ bool Trigger::Eval()
f->SetTrigger(this);
Val* v = nullptr;
IntrusivePtr<Val> v;
try
{
@ -294,7 +290,6 @@ bool Trigger::Eval()
{
// Not true. Perhaps next time...
DBG_LOG(DBG_NOTIFIERS, "%s: trigger condition is false", Name());
Unref(v);
Unref(f);
Init();
return false;
@ -303,13 +298,12 @@ bool Trigger::Eval()
DBG_LOG(DBG_NOTIFIERS, "%s: trigger condition is true, executing",
Name());
Unref(v);
v = 0;
v = nullptr;
stmt_flow_type flow;
try
{
v = body->Exec(f, flow);
v = {AdoptRef{}, body->Exec(f, flow)};
}
catch ( InterpreterException& e )
{ /* Already reported. */ }
@ -327,12 +321,11 @@ bool Trigger::Eval()
delete [] pname;
#endif
trigger->Cache(frame->GetCall(), v);
trigger->Cache(frame->GetCall(), v.get());
trigger->Release();
frame->ClearTrigger();
}
Unref(v);
Unref(f);
if ( timer )

View file

@ -705,7 +705,7 @@ Val* RecordType::FieldDefault(int field) const
const Attr* def_attr = td->attrs->FindAttr(ATTR_DEFAULT);
return def_attr ? def_attr->AttrExpr()->Eval(0) : 0;
return def_attr ? def_attr->AttrExpr()->Eval(0).release() : 0;
}
int RecordType::FieldOffset(const char* field) const
@ -2065,7 +2065,7 @@ BroType* init_type(Expr* init)
{
if ( init->Tag() != EXPR_LIST )
{
BroType* t = init->InitType();
auto t = init->InitType();
if ( ! t )
return 0;
@ -2073,11 +2073,10 @@ BroType* init_type(Expr* init)
t->AsTypeList()->Types()->length() != 1 )
{
init->Error("list used in scalar initialization");
Unref(t);
return 0;
}
return t;
return t.release();
}
ListExpr* init_list = init->AsListExpr();
@ -2094,47 +2093,25 @@ BroType* init_type(Expr* init)
if ( e0->IsRecordElement(0) )
// ListExpr's know how to build a record from their
// components.
return init_list->InitType();
return init_list->InitType().release();
BroType* t = e0->InitType();
auto t = e0->InitType();
if ( t )
{
BroType* old_t = t;
t = reduce_type(t);
if ( t )
// reduce_type() does not return a referenced pointer, but we want
// to own a reference, so create one here
Ref(t);
// reduce_type() does not adopt our reference passed as parameter, so
// we need to release it (after the Ref() call above)
Unref(old_t);
}
t = {NewRef{}, reduce_type(t.get())};
if ( ! t )
return 0;
for ( int i = 1; t && i < el.length(); ++i )
{
BroType* el_t = el[i]->InitType();
BroType* ti = el_t ? reduce_type(el_t) : 0;
auto el_t = el[i]->InitType();
BroType* ti = el_t ? reduce_type(el_t.get()) : 0;
if ( ! ti )
{
Unref(t);
return 0;
}
if ( same_type(t, ti) )
{
Unref(ti);
if ( same_type(t.get(), ti) )
continue;
}
BroType* t_merge = merge_types(t, ti);
Unref(t);
Unref(ti);
t = t_merge;
t = IntrusivePtr<BroType>{AdoptRef{}, merge_types(t.get(), ti)};
}
if ( ! t )
@ -2145,18 +2122,18 @@ BroType* init_type(Expr* init)
if ( t->Tag() == TYPE_TABLE && ! t->AsTableType()->IsSet() )
// A list of table elements.
return t;
return t.release();
// A set. If the index type isn't yet a type list, make
// it one, as that's what's required for creating a set type.
if ( t->Tag() != TYPE_LIST )
{
TypeList* tl = new TypeList(t);
tl->Append(t);
t = tl;
auto tl = make_intrusive<TypeList>(t.get()->Ref());
tl->Append(t.release());
t = std::move(tl);
}
return new SetType(t->AsTypeList(), 0);
return new SetType(t.release()->AsTypeList(), 0);
}
bool is_atomic_type(const BroType* t)

View file

@ -1745,14 +1745,14 @@ Val* TableVal::Default(Val* index)
record_promotion_compatible(dtype->AsRecordType(),
ytype->AsRecordType()) )
{
Expr* coerce = new RecordCoerceExpr(def_attr->AttrExpr()->Ref(),
ytype->AsRecordType());
def_val = coerce->Eval(0);
Expr* coerce = new RecordCoerceExpr({NewRef{}, def_attr->AttrExpr()},
{NewRef{}, ytype->AsRecordType()});
def_val = coerce->Eval(0).release();
Unref(coerce);
}
else
def_val = def_attr->AttrExpr()->Eval(0);
def_val = def_attr->AttrExpr()->Eval(0).release();
}
if ( ! def_val )
@ -1958,7 +1958,7 @@ void TableVal::CallChangeFunc(const Val* index, Val* old_value, OnChangeType tpe
try
{
IntrusivePtr<Val> thefunc{AdoptRef{}, change_func->Eval(nullptr)};
auto thefunc = change_func->Eval(nullptr);
if ( ! thefunc )
{
@ -2250,7 +2250,7 @@ void TableVal::InitDefaultFunc(Frame* f)
ytype->AsRecordType()) )
return; // TableVal::Default will handle this.
def_val = def_attr->AttrExpr()->Eval(f);
def_val = def_attr->AttrExpr()->Eval(f).release();
}
void TableVal::InitTimer(double delay)
@ -2375,9 +2375,8 @@ double TableVal::GetExpireTime()
try
{
Val* timeout = expire_time->Eval(0);
auto timeout = expire_time->Eval(0);
interval = (timeout ? timeout->AsInterval() : -1);
Unref(timeout);
}
catch ( InterpreterException& e )
{
@ -2407,7 +2406,7 @@ double TableVal::CallExpireFunc(Val* idx)
try
{
Val* vf = expire_func->Eval(0);
auto vf = expire_func->Eval(0);
if ( ! vf )
{
@ -2419,7 +2418,6 @@ double TableVal::CallExpireFunc(Val* idx)
if ( vf->Type()->Tag() != TYPE_FUNC )
{
vf->Error("not a function");
Unref(vf);
Unref(idx);
return 0;
}
@ -2467,8 +2465,6 @@ double TableVal::CallExpireFunc(Val* idx)
secs = result->AsInterval();
Unref(result);
}
Unref(vf);
}
catch ( InterpreterException& e )
@ -2575,7 +2571,7 @@ RecordVal::RecordVal(RecordType* t, bool init_fields) : Val(t)
{
Attributes* a = t->FieldDecl(i)->attrs;
Attr* def_attr = a ? a->FindAttr(ATTR_DEFAULT) : 0;
Val* def = def_attr ? def_attr->AttrExpr()->Eval(0) : 0;
auto def = def_attr ? def_attr->AttrExpr()->Eval(0) : 0;
BroType* type = t->FieldDecl(i)->type;
if ( def && type->Tag() == TYPE_RECORD &&
@ -2585,8 +2581,7 @@ RecordVal::RecordVal(RecordType* t, bool init_fields) : Val(t)
Val* tmp = def->AsRecordVal()->CoerceTo(type->AsRecordType());
if ( tmp )
{
Unref(def);
def = tmp;
def = {AdoptRef{}, tmp};
}
}
@ -2595,18 +2590,16 @@ RecordVal::RecordVal(RecordType* t, bool init_fields) : Val(t)
TypeTag tag = type->Tag();
if ( tag == TYPE_RECORD )
def = new RecordVal(type->AsRecordType());
def = make_intrusive<RecordVal>(type->AsRecordType());
else if ( tag == TYPE_TABLE )
def = new TableVal(type->AsTableType(), a);
def = make_intrusive<TableVal>(type->AsTableType(), a);
else if ( tag == TYPE_VECTOR )
def = new VectorVal(type->AsVectorType());
def = make_intrusive<VectorVal>(type->AsVectorType());
}
vl->push_back(def ? def->Ref() : 0);
Unref(def);
vl->push_back(def.release());
}
}
@ -2710,9 +2703,9 @@ RecordVal* RecordVal::CoerceTo(const RecordType* t, Val* aggr, bool allow_orphan
if ( ar_t->FieldType(t_i)->Tag() == TYPE_RECORD
&& ! same_type(ar_t->FieldType(t_i), v->Type()) )
{
Expr* rhs = new ConstExpr(v->Ref());
Expr* e = new RecordCoerceExpr(rhs, ar_t->FieldType(t_i)->AsRecordType());
ar->Assign(t_i, e->Eval(0));
auto rhs = make_intrusive<ConstExpr>(IntrusivePtr{NewRef{}, v});
auto e = make_intrusive<RecordCoerceExpr>(std::move(rhs), IntrusivePtr{NewRef{}, ar_t->FieldType(t_i)->AsRecordType()});
ar->Assign(t_i, e->Eval(0).release());
continue;
}

View file

@ -16,11 +16,11 @@
#include "Traverse.h"
#include "module_util.h"
static Val* init_val(Expr* init, const BroType* t, Val* aggr)
static IntrusivePtr<Val> init_val(Expr* init, const BroType* t, IntrusivePtr<Val> aggr)
{
try
{
return init->InitVal(t, aggr);
return init->InitVal(t, std::move(aggr));
}
catch ( InterpreterException& e )
{
@ -159,26 +159,23 @@ static void make_var(ID* id, IntrusivePtr<BroType> t, init_class c, IntrusivePtr
else if ( dt != VAR_REDEF || init || ! attr )
{
Val* aggr;
IntrusivePtr<Val> aggr;
if ( t->Tag() == TYPE_RECORD )
{
aggr = new RecordVal(t->AsRecordType());
aggr = make_intrusive<RecordVal>(t->AsRecordType());
if ( init && t )
// Have an initialization and type is not deduced.
init = make_intrusive<RecordCoerceExpr>(init.release(), t->AsRecordType());
init = make_intrusive<RecordCoerceExpr>(std::move(init), IntrusivePtr{NewRef{}, t->AsRecordType()});
}
else if ( t->Tag() == TYPE_TABLE )
aggr = new TableVal(t->AsTableType(), id->Attrs());
aggr = make_intrusive<TableVal>(t->AsTableType(), id->Attrs());
else if ( t->Tag() == TYPE_VECTOR )
aggr = new VectorVal(t->AsVectorType());
aggr = make_intrusive<VectorVal>(t->AsVectorType());
else
aggr = 0;
Val* v = 0;
IntrusivePtr<Val> v;
if ( init )
{
v = init_val(init.get(), t.get(), aggr);
@ -187,9 +184,9 @@ static void make_var(ID* id, IntrusivePtr<BroType> t, init_class c, IntrusivePtr
}
if ( aggr )
id->SetVal(aggr, c);
id->SetVal(aggr.release(), c);
else if ( v )
id->SetVal(v, c);
id->SetVal(v.release(), c);
}
}
@ -244,9 +241,9 @@ IntrusivePtr<Stmt> add_local(IntrusivePtr<ID> id, IntrusivePtr<BroType> t, init_
// may free "init"
const Location location = init->GetLocationInfo() != nullptr ? *init->GetLocationInfo() : no_location;
Expr* name_expr = new NameExpr(IntrusivePtr{id}.release(), dt == VAR_CONST);
auto name_expr = make_intrusive<NameExpr>(id, dt == VAR_CONST);
auto stmt =
make_intrusive<ExprStmt>(new AssignExpr(name_expr, init.release(), 0, 0,
make_intrusive<ExprStmt>(new AssignExpr(std::move(name_expr), std::move(init), 0, 0,
id->Attrs() ? id->Attrs()->Attrs() : 0 ));
stmt->SetLocationInfo(&location);
@ -262,8 +259,8 @@ IntrusivePtr<Stmt> add_local(IntrusivePtr<ID> id, IntrusivePtr<BroType> t, init_
extern IntrusivePtr<Expr> add_and_assign_local(IntrusivePtr<ID> id, IntrusivePtr<Expr> init, IntrusivePtr<Val> val)
{
make_var(id.get(), 0, INIT_FULL, IntrusivePtr{init}, 0, VAR_REGULAR, 0);
return make_intrusive<AssignExpr>(new NameExpr(id.release()), init.release(), 0, val.release());
make_var(id.get(), 0, INIT_FULL, init, 0, VAR_REGULAR, 0);
return make_intrusive<AssignExpr>(make_intrusive<NameExpr>(std::move(id)), std::move(init), 0, std::move(val));
}
void add_type(ID* id, IntrusivePtr<BroType> t, attr_list* attr)

View file

@ -973,7 +973,7 @@ bool Manager::UnrollRecordType(vector<Field*> *fields, const RecordType *rec,
{
string name = nameprepend + rec->FieldName(i);
const char* secondary = 0;
Val* c = nullptr;
IntrusivePtr<Val> c;
TypeTag ty = rec->FieldType(i)->Tag();
TypeTag st = TYPE_VOID;
bool optional = false;
@ -1001,7 +1001,6 @@ bool Manager::UnrollRecordType(vector<Field*> *fields, const RecordType *rec,
optional = true;
Field* field = new Field(name.c_str(), secondary, ty, st, optional);
Unref(c);
fields->push_back(field);
}
}

View file

@ -312,157 +312,157 @@ expr:
| TOK_COPY '(' expr ')'
{
set_location(@1, @4);
$$ = new CloneExpr($3);
$$ = new CloneExpr({AdoptRef{}, $3});
}
| TOK_INCR expr
{
set_location(@1, @2);
$$ = new IncrExpr(EXPR_INCR, $2);
$$ = new IncrExpr(EXPR_INCR, {AdoptRef{}, $2});
}
| TOK_DECR expr
{
set_location(@1, @2);
$$ = new IncrExpr(EXPR_DECR, $2);
$$ = new IncrExpr(EXPR_DECR, {AdoptRef{}, $2});
}
| '!' expr
{
set_location(@1, @2);
$$ = new NotExpr($2);
$$ = new NotExpr({AdoptRef{}, $2});
}
| '~' expr
{
set_location(@1, @2);
$$ = new ComplementExpr($2);
$$ = new ComplementExpr({AdoptRef{}, $2});
}
| '-' expr %prec '!'
{
set_location(@1, @2);
$$ = new NegExpr($2);
$$ = new NegExpr({AdoptRef{}, $2});
}
| '+' expr %prec '!'
{
set_location(@1, @2);
$$ = new PosExpr($2);
$$ = new PosExpr({AdoptRef{}, $2});
}
| expr '+' expr
{
set_location(@1, @3);
$$ = new AddExpr($1, $3);
$$ = new AddExpr({AdoptRef{}, $1}, {AdoptRef{}, $3});
}
| expr TOK_ADD_TO expr
{
set_location(@1, @3);
$$ = new AddToExpr($1, $3);
$$ = new AddToExpr({AdoptRef{}, $1}, {AdoptRef{}, $3});
}
| expr '-' expr
{
set_location(@1, @3);
$$ = new SubExpr($1, $3);
$$ = new SubExpr({AdoptRef{}, $1}, {AdoptRef{}, $3});
}
| expr TOK_REMOVE_FROM expr
{
set_location(@1, @3);
$$ = new RemoveFromExpr($1, $3);
$$ = new RemoveFromExpr({AdoptRef{}, $1}, {AdoptRef{}, $3});
}
| expr '*' expr
{
set_location(@1, @3);
$$ = new TimesExpr($1, $3);
$$ = new TimesExpr({AdoptRef{}, $1}, {AdoptRef{}, $3});
}
| expr '/' expr
{
set_location(@1, @3);
$$ = new DivideExpr($1, $3);
$$ = new DivideExpr({AdoptRef{}, $1}, {AdoptRef{}, $3});
}
| expr '%' expr
{
set_location(@1, @3);
$$ = new ModExpr($1, $3);
$$ = new ModExpr({AdoptRef{}, $1}, {AdoptRef{}, $3});
}
| expr '&' expr
{
set_location(@1, @3);
$$ = new BitExpr(EXPR_AND, $1, $3);
$$ = new BitExpr(EXPR_AND, {AdoptRef{}, $1}, {AdoptRef{}, $3});
}
| expr '|' expr
{
set_location(@1, @3);
$$ = new BitExpr(EXPR_OR, $1, $3);
$$ = new BitExpr(EXPR_OR, {AdoptRef{}, $1}, {AdoptRef{}, $3});
}
| expr '^' expr
{
set_location(@1, @3);
$$ = new BitExpr(EXPR_XOR, $1, $3);
$$ = new BitExpr(EXPR_XOR, {AdoptRef{}, $1}, {AdoptRef{}, $3});
}
| expr TOK_AND_AND expr
{
set_location(@1, @3);
$$ = new BoolExpr(EXPR_AND_AND, $1, $3);
$$ = new BoolExpr(EXPR_AND_AND, {AdoptRef{}, $1}, {AdoptRef{}, $3});
}
| expr TOK_OR_OR expr
{
set_location(@1, @3);
$$ = new BoolExpr(EXPR_OR_OR, $1, $3);
$$ = new BoolExpr(EXPR_OR_OR, {AdoptRef{}, $1}, {AdoptRef{}, $3});
}
| expr TOK_EQ expr
{
set_location(@1, @3);
$$ = new EqExpr(EXPR_EQ, $1, $3);
$$ = new EqExpr(EXPR_EQ, {AdoptRef{}, $1}, {AdoptRef{}, $3});
}
| expr TOK_NE expr
{
set_location(@1, @3);
$$ = new EqExpr(EXPR_NE, $1, $3);
$$ = new EqExpr(EXPR_NE, {AdoptRef{}, $1}, {AdoptRef{}, $3});
}
| expr '<' expr
{
set_location(@1, @3);
$$ = new RelExpr(EXPR_LT, $1, $3);
$$ = new RelExpr(EXPR_LT, {AdoptRef{}, $1}, {AdoptRef{}, $3});
}
| expr TOK_LE expr
{
set_location(@1, @3);
$$ = new RelExpr(EXPR_LE, $1, $3);
$$ = new RelExpr(EXPR_LE, {AdoptRef{}, $1}, {AdoptRef{}, $3});
}
| expr '>' expr
{
set_location(@1, @3);
$$ = new RelExpr(EXPR_GT, $1, $3);
$$ = new RelExpr(EXPR_GT, {AdoptRef{}, $1}, {AdoptRef{}, $3});
}
| expr TOK_GE expr
{
set_location(@1, @3);
$$ = new RelExpr(EXPR_GE, $1, $3);
$$ = new RelExpr(EXPR_GE, {AdoptRef{}, $1}, {AdoptRef{}, $3});
}
| expr '?' expr ':' expr
{
set_location(@1, @5);
$$ = new CondExpr($1, $3, $5);
$$ = new CondExpr({AdoptRef{}, $1}, {AdoptRef{}, $3}, {AdoptRef{}, $5});
}
| expr '=' expr
@ -474,7 +474,7 @@ expr:
" in arbitrary expression contexts, only"
" as a statement");
$$ = get_assign_expr($1, $3, in_init);
$$ = get_assign_expr({AdoptRef{}, $1}, {AdoptRef{}, $3}, in_init).release();
}
| TOK_LOCAL local_id '=' expr
@ -486,7 +486,7 @@ expr:
| expr '[' expr_list ']'
{
set_location(@1, @4);
$$ = new IndexExpr($1, $3);
$$ = new IndexExpr({AdoptRef{}, $1}, {AdoptRef{}, $3});
}
| index_slice
@ -494,13 +494,13 @@ expr:
| expr '$' TOK_ID
{
set_location(@1, @3);
$$ = new FieldExpr($1, $3);
$$ = new FieldExpr({AdoptRef{}, $1}, $3);
}
| '$' TOK_ID '=' expr
{
set_location(@1, @4);
$$ = new FieldAssignExpr($2, $4);
$$ = new FieldAssignExpr($2, {AdoptRef{}, $4});
}
| '$' TOK_ID func_params '='
@ -516,20 +516,20 @@ expr:
}
func_body
{
$$ = new FieldAssignExpr($2, new ConstExpr(func_id->ID_Val()->Ref()));
$$ = new FieldAssignExpr($2, make_intrusive<ConstExpr>(IntrusivePtr<Val>{NewRef{}, func_id->ID_Val()}));
Unref(func_id);
}
| expr TOK_IN expr
{
set_location(@1, @3);
$$ = new InExpr($1, $3);
$$ = new InExpr({AdoptRef{}, $1}, {AdoptRef{}, $3});
}
| expr TOK_NOT_IN expr
{
set_location(@1, @3);
$$ = new NotExpr(new InExpr($1, $3));
$$ = new NotExpr(make_intrusive<InExpr>(IntrusivePtr<Expr>{AdoptRef{}, $1}, IntrusivePtr<Expr>{AdoptRef{}, $3}));
}
| '[' expr_list ']'
@ -552,7 +552,7 @@ expr:
}
if ( is_record_ctor )
$$ = new RecordConstructorExpr($2);
$$ = new RecordConstructorExpr({AdoptRef{}, $2});
else
$$ = $2;
}
@ -560,33 +560,33 @@ expr:
| '[' ']'
{
// We interpret this as an empty record constructor.
$$ = new RecordConstructorExpr(new ListExpr);
$$ = new RecordConstructorExpr(make_intrusive<ListExpr>());
}
| TOK_RECORD '(' expr_list ')'
{
set_location(@1, @4);
$$ = new RecordConstructorExpr($3);
$$ = new RecordConstructorExpr({AdoptRef{}, $3});
}
| TOK_TABLE '(' { ++in_init; } opt_expr_list ')' { --in_init; }
opt_attr
{ // the ++in_init fixes up the parsing of "[x] = y"
set_location(@1, @5);
$$ = new TableConstructorExpr($4, $7);
$$ = new TableConstructorExpr({AdoptRef{}, $4}, $7);
}
| TOK_SET '(' opt_expr_list ')' opt_attr
{
set_location(@1, @4);
$$ = new SetConstructorExpr($3, $5);
$$ = new SetConstructorExpr({AdoptRef{}, $3}, $5);
}
| TOK_VECTOR '(' opt_expr_list ')'
{
set_location(@1, @4);
$$ = new VectorConstructorExpr($3);
$$ = new VectorConstructorExpr({AdoptRef{}, $3});
}
| expr '('
@ -612,20 +612,20 @@ expr:
{
switch ( ctor_type->Tag() ) {
case TYPE_RECORD:
$$ = new RecordCoerceExpr(new RecordConstructorExpr($4),
ctor_type->AsRecordType());
$$ = new RecordCoerceExpr(make_intrusive<RecordConstructorExpr>(IntrusivePtr<ListExpr>{AdoptRef{}, $4}),
{NewRef{}, ctor_type->AsRecordType()});
break;
case TYPE_TABLE:
if ( ctor_type->IsTable() )
$$ = new TableConstructorExpr($4, 0, ctor_type);
$$ = new TableConstructorExpr({AdoptRef{}, $4}, 0, {NewRef{}, ctor_type});
else
$$ = new SetConstructorExpr($4, 0, ctor_type);
$$ = new SetConstructorExpr({AdoptRef{}, $4}, 0, {NewRef{}, ctor_type});
break;
case TYPE_VECTOR:
$$ = new VectorConstructorExpr($4, ctor_type);
$$ = new VectorConstructorExpr({AdoptRef{}, $4}, {NewRef{}, ctor_type});
break;
default:
@ -635,7 +635,7 @@ expr:
}
else
$$ = new CallExpr($1, $4, in_hook > 0);
$$ = new CallExpr({AdoptRef{}, $1}, {AdoptRef{}, $4}, in_hook > 0);
}
| TOK_HOOK { ++in_hook; } expr
@ -650,7 +650,7 @@ expr:
| expr TOK_HAS_FIELD TOK_ID
{
set_location(@1, @3);
$$ = new HasFieldExpr($1, $3);
$$ = new HasFieldExpr({AdoptRef{}, $1}, $3);
}
| anonymous_function
@ -659,7 +659,7 @@ expr:
| TOK_SCHEDULE expr '{' event '}'
{
set_location(@1, @5);
$$ = new ScheduleExpr($2, $4);
$$ = new ScheduleExpr({AdoptRef{}, $2}, {AdoptRef{}, $4});
}
| TOK_ID
@ -694,7 +694,7 @@ expr:
{
id->Error("undeclared variable");
id->SetType(error_type());
$$ = new NameExpr(id.release());
$$ = new NameExpr(std::move(id));
}
else if ( id->IsEnumConst() )
@ -704,11 +704,11 @@ expr:
id->Name());
if ( intval < 0 )
reporter->InternalError("enum value not found for %s", id->Name());
$$ = new ConstExpr(t->GetVal(intval));
$$ = new ConstExpr({AdoptRef{}, t->GetVal(intval)});
}
else
{
$$ = new NameExpr(id.release());
$$ = new NameExpr(std::move(id));
}
}
}
@ -716,7 +716,7 @@ expr:
| TOK_CONSTANT
{
set_location(@1);
$$ = new ConstExpr($1);
$$ = new ConstExpr({AdoptRef{}, $1});
}
| '/' { begin_RE(); } TOK_PATTERN_TEXT TOK_PATTERN_END
@ -730,30 +730,30 @@ expr:
re->MakeCaseInsensitive();
re->Compile();
$$ = new ConstExpr(new PatternVal(re));
$$ = new ConstExpr(make_intrusive<PatternVal>(re));
}
| '|' expr '|' %prec '('
{
set_location(@1, @3);
auto e = $2;
IntrusivePtr<Expr> e{AdoptRef{}, $2};
if ( IsIntegral(e->Type()->Tag()) )
e = new ArithCoerceExpr(e, TYPE_INT);
e = make_intrusive<ArithCoerceExpr>(std::move(e), TYPE_INT);
$$ = new SizeExpr(e);
$$ = new SizeExpr(std::move(e));
}
| expr TOK_AS type
{
set_location(@1, @3);
$$ = new CastExpr($1, $3);
$$ = new CastExpr({AdoptRef{}, $1}, {AdoptRef{}, $3});
}
| expr TOK_IS type
{
set_location(@1, @3);
$$ = new IsExpr($1, $3);
$$ = new IsExpr({AdoptRef{}, $1}, {AdoptRef{}, $3});
}
;
@ -761,13 +761,13 @@ expr_list:
expr_list ',' expr
{
set_location(@1, @3);
$1->Append($3);
$1->Append({AdoptRef{}, $3});
}
| expr
{
set_location(@1);
$$ = new ListExpr($1);
$$ = new ListExpr({AdoptRef{}, $1});
}
;
@ -1301,15 +1301,15 @@ index_slice:
expr '[' opt_expr ':' opt_expr ']'
{
set_location(@1, @6);
Expr* low = $3 ? $3 : new ConstExpr(val_mgr->GetCount(0));
Expr* high = $5 ? $5 : new SizeExpr($1->Ref());
auto low = $3 ? IntrusivePtr<Expr>{AdoptRef{}, $3} : make_intrusive<ConstExpr>(IntrusivePtr<Val>{AdoptRef{}, val_mgr->GetCount(0)});
auto high = $5 ? IntrusivePtr<Expr>{AdoptRef{}, $5} : make_intrusive<SizeExpr>(IntrusivePtr<Expr>{NewRef{}, $1});
if ( ! IsIntegral(low->Type()->Tag()) || ! IsIntegral(high->Type()->Tag()) )
reporter->Error("slice notation must have integral values as indexes");
ListExpr* le = new ListExpr(low);
le->Append(high);
$$ = new IndexExpr($1, le, true);
auto le = make_intrusive<ListExpr>(std::move(low));
le->Append(std::move(high));
$$ = new IndexExpr({AdoptRef{}, $1}, std::move(le), true);
}
opt_attr:
@ -1364,7 +1364,7 @@ attr:
| TOK_ATTR_DEPRECATED '=' TOK_CONSTANT
{
if ( IsString($3->Type()->Tag()) )
$$ = new Attr(ATTR_DEPRECATED, new ConstExpr($3));
$$ = new Attr(ATTR_DEPRECATED, new ConstExpr({AdoptRef{}, $3}));
else
{
ODesc d;
@ -1534,7 +1534,7 @@ stmt:
| index_slice '=' expr ';' opt_no_test
{
set_location(@1, @4);
$$ = new ExprStmt(get_assign_expr($1, $3, in_init));
$$ = new ExprStmt(get_assign_expr({AdoptRef{}, $1}, {AdoptRef{}, $3}, in_init).release());
if ( ! $5 )
brofiler.AddStmt($$);
@ -1586,7 +1586,7 @@ event:
reporter->Warning("%s", id->GetDeprecationWarning().c_str());
}
$$ = new EventExpr($1, $3);
$$ = new EventExpr($1, {AdoptRef{}, $3});
}
;
@ -1839,19 +1839,19 @@ opt_no_test_block:
opt_deprecated:
TOK_ATTR_DEPRECATED
{ $$ = new ConstExpr(new StringVal("")); }
{ $$ = new ConstExpr(make_intrusive<StringVal>("")); }
|
TOK_ATTR_DEPRECATED '=' TOK_CONSTANT
{
if ( IsString($3->Type()->Tag()) )
$$ = new ConstExpr($3);
$$ = new ConstExpr({AdoptRef{}, $3});
else
{
ODesc d;
$3->Describe(&d);
reporter->Error("'&deprecated=%s' must use a string literal",
d.Description());
$$ = new ConstExpr(new StringVal(""));
$$ = new ConstExpr(make_intrusive<StringVal>(""));
}
}
|

View file

@ -20,6 +20,7 @@
#include "Expr.h"
#include "Func.h"
#include "Stmt.h"
#include "IntrusivePtr.h"
#include "Val.h"
#include "Var.h"
#include "Debug.h"
@ -746,7 +747,7 @@ void do_atif(Expr* expr)
LocalNameFinder cb;
expr->Traverse(&cb);
Val* val = 0;
IntrusivePtr<Val> val;
if ( cb.local_names.empty() )
val = expr->Eval(0);
@ -767,8 +768,6 @@ void do_atif(Expr* expr)
if_stack.push_back(current_depth);
BEGIN(IGNORE);
}
Unref(val);
}
void do_atifdef(const char* id)