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

View file

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

View file

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

View file

@ -10,6 +10,7 @@
#include <map> #include <map>
#include <string> #include <string>
template <class T> class IntrusivePtr;
class Val; class Val;
class Stmt; 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); int dbg_execute_command(const char* cmd);
// Interactive expression evaluation. // Interactive expression evaluation.
Val* dbg_eval_expr(const char* expr); IntrusivePtr<Val> dbg_eval_expr(const char* expr);
// Extra debugging facilities. // Extra debugging facilities.
// TODO: current connections, memory allocated, other internal data structures. // TODO: current connections, memory allocated, other internal data structures.

View file

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

File diff suppressed because it is too large Load diff

View file

@ -5,6 +5,7 @@
// BRO expressions. // BRO expressions.
#include "BroList.h" #include "BroList.h"
#include "IntrusivePtr.h"
#include "Timer.h" #include "Timer.h"
#include "Type.h" #include "Type.h"
#include "EventHandler.h" #include "EventHandler.h"
@ -58,6 +59,7 @@ typedef enum {
extern const char* expr_name(BroExprTag t); extern const char* expr_name(BroExprTag t);
template <class T> class IntrusivePtr;
class Stmt; class Stmt;
class Frame; class Frame;
class ListExpr; class ListExpr;
@ -72,16 +74,14 @@ struct function_ingredients;
class Expr : public BroObj { class Expr : public BroObj {
public: public:
BroType* Type() const { return type; } BroType* Type() const { return type.get(); }
BroExprTag Tag() const { return tag; } BroExprTag Tag() const { return tag; }
~Expr() override;
Expr* Ref() { ::Ref(this); return this; } Expr* Ref() { ::Ref(this); return this; }
// Evaluates the expression and returns a corresponding Val*, // Evaluates the expression and returns a corresponding Val*,
// or nil if the expression's value isn't fixed. // 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 // Same, but the context is that we are adding an element
// into the given aggregate of the given type. Note that // into the given aggregate of the given type. Note that
@ -91,12 +91,11 @@ public:
const; const;
// Assign to the given value, if appropriate. // 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 // Returns the type corresponding to this expression interpreted
// as an initialization. The type should be Unref()'d when done // as an initialization. Returns nil if the initialization is illegal.
// using it. Returns nil if the initialization is illegal. virtual IntrusivePtr<BroType> InitType() const;
virtual BroType* InitType() const;
// Returns true if this expression, interpreted as an initialization, // Returns true if this expression, interpreted as an initialization,
// constitutes a record element, false otherwise. If the TypeDecl* // 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 // 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 // is an element of the given aggregate, and it is added to it
// accordingly. // 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. // True if the expression has no side effects, false otherwise.
virtual int IsPure() const; virtual int IsPure() const;
@ -145,7 +144,7 @@ public:
// Return the expression converted to L-value form. If expr // Return the expression converted to L-value form. If expr
// cannot be used as an L-value, reports an error and returns // cannot be used as an L-value, reports an error and returns
// the current value of expr (this is the default method). // 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 // Marks the expression as one requiring (or at least appearing
// with) parentheses. Used for pretty-printing. // with) parentheses. Used for pretty-printing.
@ -214,7 +213,7 @@ protected:
// Puts the expression in canonical form. // Puts the expression in canonical form.
virtual void Canonicize(); virtual void Canonicize();
void SetType(BroType* t); void SetType(IntrusivePtr<BroType> t);
// Reports the given error and sets the expression's type to // Reports the given error and sets the expression's type to
// TYPE_ERROR. // TYPE_ERROR.
@ -225,21 +224,20 @@ protected:
void RuntimeErrorWithCallStack(const std::string& msg) const; void RuntimeErrorWithCallStack(const std::string& msg) const;
BroExprTag tag; BroExprTag tag;
BroType* type; IntrusivePtr<BroType> type;
int paren; int paren;
}; };
class NameExpr : public Expr { class NameExpr : public Expr {
public: public:
explicit NameExpr(ID* id, bool const_init = false); explicit NameExpr(IntrusivePtr<ID> id, bool const_init = false);
~NameExpr() override;
ID* Id() const { return id; } ID* Id() const { return id.get(); }
Val* Eval(Frame* f) const override; IntrusivePtr<Val> Eval(Frame* f) const override;
void Assign(Frame* f, Val* v) override; void Assign(Frame* f, IntrusivePtr<Val> v) override;
Expr* MakeLvalue() override; IntrusivePtr<Expr> MakeLvalue() override;
int IsPure() const override; int IsPure() const override;
TraversalCode Traverse(TraversalCallback* cb) const override; TraversalCode Traverse(TraversalCallback* cb) const override;
@ -247,91 +245,88 @@ public:
protected: protected:
void ExprDescribe(ODesc* d) const override; void ExprDescribe(ODesc* d) const override;
ID* id; IntrusivePtr<ID> id;
bool in_const_init; bool in_const_init;
}; };
class ConstExpr : public Expr { class ConstExpr : public Expr {
public: public:
explicit ConstExpr(Val* val); explicit ConstExpr(IntrusivePtr<Val> val);
~ConstExpr() override;
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; TraversalCode Traverse(TraversalCallback* cb) const override;
protected: protected:
void ExprDescribe(ODesc* d) const override; void ExprDescribe(ODesc* d) const override;
Val* val; IntrusivePtr<Val> val;
}; };
class UnaryExpr : public Expr { class UnaryExpr : public Expr {
public: public:
Expr* Op() const { return op; } Expr* Op() const { return op.get(); }
// UnaryExpr::Eval correctly handles vector types. Any child // UnaryExpr::Eval correctly handles vector types. Any child
// class that overrides Eval() should be modified to handle // class that overrides Eval() should be modified to handle
// vectors correctly as necessary. // vectors correctly as necessary.
Val* Eval(Frame* f) const override; IntrusivePtr<Val> Eval(Frame* f) const override;
int IsPure() const override; int IsPure() const override;
TraversalCode Traverse(TraversalCallback* cb) const override; TraversalCode Traverse(TraversalCallback* cb) const override;
protected: protected:
UnaryExpr(BroExprTag arg_tag, Expr* arg_op); UnaryExpr(BroExprTag arg_tag, IntrusivePtr<Expr> arg_op);
~UnaryExpr() override;
void ExprDescribe(ODesc* d) const override; void ExprDescribe(ODesc* d) const override;
// Returns the expression folded using the given constant. // 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 { class BinaryExpr : public Expr {
public: public:
Expr* Op1() const { return op1; } Expr* Op1() const { return op1.get(); }
Expr* Op2() const { return op2; } Expr* Op2() const { return op2.get(); }
int IsPure() const override; int IsPure() const override;
// BinaryExpr::Eval correctly handles vector types. Any child // BinaryExpr::Eval correctly handles vector types. Any child
// class that overrides Eval() should be modified to handle // class that overrides Eval() should be modified to handle
// vectors correctly as necessary. // vectors correctly as necessary.
Val* Eval(Frame* f) const override; IntrusivePtr<Val> Eval(Frame* f) const override;
TraversalCode Traverse(TraversalCallback* cb) const override; TraversalCode Traverse(TraversalCallback* cb) const override;
protected: protected:
BinaryExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2) BinaryExpr(BroExprTag arg_tag, IntrusivePtr<Expr> arg_op1, IntrusivePtr<Expr> arg_op2)
: Expr(arg_tag), op1(arg_op1), op2(arg_op2) : Expr(arg_tag), op1(std::move(arg_op1)), op2(std::move(arg_op2))
{ {
if ( ! (arg_op1 && arg_op2) ) if ( ! (op1 && op2) )
return; return;
if ( op1->IsError() || op2->IsError() ) if ( op1->IsError() || op2->IsError() )
SetError(); SetError();
} }
~BinaryExpr() override;
// Returns the expression folded using the given constants. // 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. // 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. // 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. // 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. // Same for when the constants are addresses or subnets.
virtual Val* AddrFold(Val* v1, Val* v2) const; virtual IntrusivePtr<Val> AddrFold(Val* v1, Val* v2) const;
virtual Val* SubNetFold(Val* v1, Val* v2) const; virtual IntrusivePtr<Val> SubNetFold(Val* v1, Val* v2) const;
int BothConst() const { return op1->IsConst() && op2->IsConst(); } int BothConst() const { return op1->IsConst() && op2->IsConst(); }
@ -347,149 +342,148 @@ protected:
void ExprDescribe(ODesc* d) const override; void ExprDescribe(ODesc* d) const override;
Expr* op1; IntrusivePtr<Expr> op1;
Expr* op2; IntrusivePtr<Expr> op2;
}; };
class CloneExpr : public UnaryExpr { class CloneExpr : public UnaryExpr {
public: public:
explicit CloneExpr(Expr* op); explicit CloneExpr(IntrusivePtr<Expr> op);
Val* Eval(Frame* f) const override; IntrusivePtr<Val> Eval(Frame* f) const override;
protected: protected:
Val* Fold(Val* v) const override; IntrusivePtr<Val> Fold(Val* v) const override;
}; };
class IncrExpr : public UnaryExpr { class IncrExpr : public UnaryExpr {
public: public:
IncrExpr(BroExprTag tag, Expr* op); IncrExpr(BroExprTag tag, IntrusivePtr<Expr> op);
Val* Eval(Frame* f) const override; IntrusivePtr<Val> Eval(Frame* f) const override;
Val* DoSingleEval(Frame* f, Val* v) const; IntrusivePtr<Val> DoSingleEval(Frame* f, Val* v) const;
int IsPure() const override; int IsPure() const override;
}; };
class ComplementExpr : public UnaryExpr { class ComplementExpr : public UnaryExpr {
public: public:
explicit ComplementExpr(Expr* op); explicit ComplementExpr(IntrusivePtr<Expr> op);
protected: protected:
Val* Fold(Val* v) const override; IntrusivePtr<Val> Fold(Val* v) const override;
}; };
class NotExpr : public UnaryExpr { class NotExpr : public UnaryExpr {
public: public:
explicit NotExpr(Expr* op); explicit NotExpr(IntrusivePtr<Expr> op);
protected: protected:
Val* Fold(Val* v) const override; IntrusivePtr<Val> Fold(Val* v) const override;
}; };
class PosExpr : public UnaryExpr { class PosExpr : public UnaryExpr {
public: public:
explicit PosExpr(Expr* op); explicit PosExpr(IntrusivePtr<Expr> op);
protected: protected:
Val* Fold(Val* v) const override; IntrusivePtr<Val> Fold(Val* v) const override;
}; };
class NegExpr : public UnaryExpr { class NegExpr : public UnaryExpr {
public: public:
explicit NegExpr(Expr* op); explicit NegExpr(IntrusivePtr<Expr> op);
protected: protected:
Val* Fold(Val* v) const override; IntrusivePtr<Val> Fold(Val* v) const override;
}; };
class SizeExpr : public UnaryExpr { class SizeExpr : public UnaryExpr {
public: public:
explicit SizeExpr(Expr* op); explicit SizeExpr(IntrusivePtr<Expr> op);
Val* Eval(Frame* f) const override; IntrusivePtr<Val> Eval(Frame* f) const override;
protected: protected:
Val* Fold(Val* v) const override; IntrusivePtr<Val> Fold(Val* v) const override;
}; };
class AddExpr : public BinaryExpr { class AddExpr : public BinaryExpr {
public: public:
AddExpr(Expr* op1, Expr* op2); AddExpr(IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2);
void Canonicize() override; void Canonicize() override;
}; };
class AddToExpr : public BinaryExpr { class AddToExpr : public BinaryExpr {
public: public:
AddToExpr(Expr* op1, Expr* op2); AddToExpr(IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2);
Val* Eval(Frame* f) const override; IntrusivePtr<Val> Eval(Frame* f) const override;
}; };
class RemoveFromExpr : public BinaryExpr { class RemoveFromExpr : public BinaryExpr {
public: public:
RemoveFromExpr(Expr* op1, Expr* op2); RemoveFromExpr(IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2);
Val* Eval(Frame* f) const override; IntrusivePtr<Val> Eval(Frame* f) const override;
}; };
class SubExpr : public BinaryExpr { class SubExpr : public BinaryExpr {
public: public:
SubExpr(Expr* op1, Expr* op2); SubExpr(IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2);
}; };
class TimesExpr : public BinaryExpr { class TimesExpr : public BinaryExpr {
public: public:
TimesExpr(Expr* op1, Expr* op2); TimesExpr(IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2);
void Canonicize() override; void Canonicize() override;
}; };
class DivideExpr : public BinaryExpr { class DivideExpr : public BinaryExpr {
public: public:
DivideExpr(Expr* op1, Expr* op2); DivideExpr(IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2);
protected: protected:
Val* AddrFold(Val* v1, Val* v2) const override; IntrusivePtr<Val> AddrFold(Val* v1, Val* v2) const override;
}; };
class ModExpr : public BinaryExpr { class ModExpr : public BinaryExpr {
public: public:
ModExpr(Expr* op1, Expr* op2); ModExpr(IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2);
}; };
class BoolExpr : public BinaryExpr { class BoolExpr : public BinaryExpr {
public: public:
BoolExpr(BroExprTag tag, Expr* op1, Expr* op2); BoolExpr(BroExprTag tag, IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2);
Val* Eval(Frame* f) const override; IntrusivePtr<Val> Eval(Frame* f) const override;
Val* DoSingleEval(Frame* f, Val* v1, Expr* op2) const; IntrusivePtr<Val> DoSingleEval(Frame* f, IntrusivePtr<Val> v1, Expr* op2) const;
}; };
class BitExpr : public BinaryExpr { class BitExpr : public BinaryExpr {
public: public:
BitExpr(BroExprTag tag, Expr* op1, Expr* op2); BitExpr(BroExprTag tag, IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2);
}; };
class EqExpr : public BinaryExpr { class EqExpr : public BinaryExpr {
public: public:
EqExpr(BroExprTag tag, Expr* op1, Expr* op2); EqExpr(BroExprTag tag, IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2);
void Canonicize() override; void Canonicize() override;
protected: protected:
Val* Fold(Val* v1, Val* v2) const override; IntrusivePtr<Val> Fold(Val* v1, Val* v2) const override;
}; };
class RelExpr : public BinaryExpr { class RelExpr : public BinaryExpr {
public: public:
RelExpr(BroExprTag tag, Expr* op1, Expr* op2); RelExpr(BroExprTag tag, IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2);
void Canonicize() override; void Canonicize() override;
}; };
class CondExpr : public Expr { class CondExpr : public Expr {
public: public:
CondExpr(Expr* op1, Expr* op2, Expr* op3); CondExpr(IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2, IntrusivePtr<Expr> op3);
~CondExpr() override;
const Expr* Op1() const { return op1; } const Expr* Op1() const { return op1.get(); }
const Expr* Op2() const { return op2; } const Expr* Op2() const { return op2.get(); }
const Expr* Op3() const { return op3; } const Expr* Op3() const { return op3.get(); }
Val* Eval(Frame* f) const override; IntrusivePtr<Val> Eval(Frame* f) const override;
int IsPure() const override; int IsPure() const override;
TraversalCode Traverse(TraversalCallback* cb) const override; TraversalCode Traverse(TraversalCallback* cb) const override;
@ -497,31 +491,30 @@ public:
protected: protected:
void ExprDescribe(ODesc* d) const override; void ExprDescribe(ODesc* d) const override;
Expr* op1; IntrusivePtr<Expr> op1;
Expr* op2; IntrusivePtr<Expr> op2;
Expr* op3; IntrusivePtr<Expr> op3;
}; };
class RefExpr : public UnaryExpr { class RefExpr : public UnaryExpr {
public: public:
explicit RefExpr(Expr* op); explicit RefExpr(IntrusivePtr<Expr> op);
void Assign(Frame* f, Val* v) override; void Assign(Frame* f, IntrusivePtr<Val> v) override;
Expr* MakeLvalue() override; IntrusivePtr<Expr> MakeLvalue() override;
}; };
class AssignExpr : public BinaryExpr { class AssignExpr : public BinaryExpr {
public: public:
// If val is given, evaluating this expression will always yield the val // If val is given, evaluating this expression will always yield the val
// yet still perform the assignment. Used for triggers. // yet still perform the assignment. Used for triggers.
AssignExpr(Expr* op1, Expr* op2, int is_init, Val* val = 0, attr_list* attrs = 0); AssignExpr(IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2, int is_init, IntrusivePtr<Val> val = nullptr, attr_list* attrs = nullptr);
~AssignExpr() override;
Val* Eval(Frame* f) const override; IntrusivePtr<Val> Eval(Frame* f) const override;
void EvalIntoAggregate(const BroType* t, Val* aggr, 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; 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; int IsPure() const override;
protected: protected:
@ -529,18 +522,18 @@ protected:
bool TypeCheckArithmetics(TypeTag bt1, TypeTag bt2); bool TypeCheckArithmetics(TypeTag bt1, TypeTag bt2);
int is_init; int is_init;
Val* val; // optional IntrusivePtr<Val> val; // optional
}; };
class IndexSliceAssignExpr : public AssignExpr { class IndexSliceAssignExpr : public AssignExpr {
public: public:
IndexSliceAssignExpr(Expr* op1, Expr* op2, int is_init); IndexSliceAssignExpr(IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2, int is_init);
Val* Eval(Frame* f) const override; IntrusivePtr<Val> Eval(Frame* f) const override;
}; };
class IndexExpr : public BinaryExpr { class IndexExpr : public BinaryExpr {
public: 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 CanAdd() const override;
int CanDel() const override; int CanDel() const override;
@ -548,19 +541,19 @@ public:
void Add(Frame* f) override; void Add(Frame* f) override;
void Delete(Frame* f) override; void Delete(Frame* f) override;
void Assign(Frame* f, Val* v) override; void Assign(Frame* f, IntrusivePtr<Val> v) override;
Expr* MakeLvalue() override; IntrusivePtr<Expr> MakeLvalue() override;
// Need to override Eval since it can take a vector arg but does // Need to override Eval since it can take a vector arg but does
// not necessarily return a vector. // not necessarily return a vector.
Val* Eval(Frame* f) const override; IntrusivePtr<Val> Eval(Frame* f) const override;
TraversalCode Traverse(TraversalCallback* cb) const override; TraversalCode Traverse(TraversalCallback* cb) const override;
bool IsSlice() const { return is_slice; } bool IsSlice() const { return is_slice; }
protected: protected:
Val* Fold(Val* v1, Val* v2) const override; IntrusivePtr<Val> Fold(Val* v1, Val* v2) const override;
void ExprDescribe(ODesc* d) const override; void ExprDescribe(ODesc* d) const override;
@ -569,7 +562,7 @@ protected:
class FieldExpr : public UnaryExpr { class FieldExpr : public UnaryExpr {
public: public:
FieldExpr(Expr* op, const char* field_name); FieldExpr(IntrusivePtr<Expr> op, const char* field_name);
~FieldExpr() override; ~FieldExpr() override;
int Field() const { return field; } int Field() const { return field; }
@ -577,13 +570,13 @@ public:
int CanDel() const override; int CanDel() const override;
void Assign(Frame* f, Val* v) override; void Assign(Frame* f, IntrusivePtr<Val> v) override;
void Delete(Frame* f) override; void Delete(Frame* f) override;
Expr* MakeLvalue() override; IntrusivePtr<Expr> MakeLvalue() override;
protected: protected:
Val* Fold(Val* v) const override; IntrusivePtr<Val> Fold(Val* v) const override;
void ExprDescribe(ODesc* d) const override; void ExprDescribe(ODesc* d) const override;
@ -596,13 +589,13 @@ protected:
// "rec?$$attrname" is true if the attribute attrname is not nil. // "rec?$$attrname" is true if the attribute attrname is not nil.
class HasFieldExpr : public UnaryExpr { class HasFieldExpr : public UnaryExpr {
public: public:
HasFieldExpr(Expr* op, const char* field_name); HasFieldExpr(IntrusivePtr<Expr> op, const char* field_name);
~HasFieldExpr() override; ~HasFieldExpr() override;
const char* FieldName() const { return field_name; } const char* FieldName() const { return field_name; }
protected: protected:
Val* Fold(Val* v) const override; IntrusivePtr<Val> Fold(Val* v) const override;
void ExprDescribe(ODesc* d) const override; void ExprDescribe(ODesc* d) const override;
@ -612,28 +605,28 @@ protected:
class RecordConstructorExpr : public UnaryExpr { class RecordConstructorExpr : public UnaryExpr {
public: public:
explicit RecordConstructorExpr(ListExpr* constructor_list); explicit RecordConstructorExpr(IntrusivePtr<ListExpr> constructor_list);
~RecordConstructorExpr() override; ~RecordConstructorExpr() override;
protected: protected:
Val* InitVal(const BroType* t, Val* aggr) const override; IntrusivePtr<Val> InitVal(const BroType* t, IntrusivePtr<Val> aggr) const override;
Val* Fold(Val* v) const override; IntrusivePtr<Val> Fold(Val* v) const override;
void ExprDescribe(ODesc* d) const override; void ExprDescribe(ODesc* d) const override;
}; };
class TableConstructorExpr : public UnaryExpr { class TableConstructorExpr : public UnaryExpr {
public: public:
TableConstructorExpr(ListExpr* constructor_list, attr_list* attrs, TableConstructorExpr(IntrusivePtr<ListExpr> constructor_list, attr_list* attrs,
BroType* arg_type = 0); IntrusivePtr<BroType> arg_type = nullptr);
~TableConstructorExpr() override { Unref(attrs); } ~TableConstructorExpr() override { Unref(attrs); }
Attributes* Attrs() { return attrs; } Attributes* Attrs() { return attrs; }
Val* Eval(Frame* f) const override; IntrusivePtr<Val> Eval(Frame* f) const override;
protected: 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; void ExprDescribe(ODesc* d) const override;
@ -642,16 +635,16 @@ protected:
class SetConstructorExpr : public UnaryExpr { class SetConstructorExpr : public UnaryExpr {
public: public:
SetConstructorExpr(ListExpr* constructor_list, attr_list* attrs, SetConstructorExpr(IntrusivePtr<ListExpr> constructor_list, attr_list* attrs,
BroType* arg_type = 0); IntrusivePtr<BroType> arg_type = nullptr);
~SetConstructorExpr() override { Unref(attrs); } ~SetConstructorExpr() override { Unref(attrs); }
Attributes* Attrs() { return attrs; } Attributes* Attrs() { return attrs; }
Val* Eval(Frame* f) const override; IntrusivePtr<Val> Eval(Frame* f) const override;
protected: 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; void ExprDescribe(ODesc* d) const override;
@ -660,19 +653,19 @@ protected:
class VectorConstructorExpr : public UnaryExpr { class VectorConstructorExpr : public UnaryExpr {
public: 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: 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; void ExprDescribe(ODesc* d) const override;
}; };
class FieldAssignExpr : public UnaryExpr { class FieldAssignExpr : public UnaryExpr {
public: 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(); } const char* FieldName() const { return field_name.c_str(); }
@ -687,21 +680,21 @@ protected:
class ArithCoerceExpr : public UnaryExpr { class ArithCoerceExpr : public UnaryExpr {
public: public:
ArithCoerceExpr(Expr* op, TypeTag t); ArithCoerceExpr(IntrusivePtr<Expr> op, TypeTag t);
protected: protected:
Val* FoldSingleVal(Val* v, InternalTypeTag t) const; IntrusivePtr<Val> FoldSingleVal(Val* v, InternalTypeTag t) const;
Val* Fold(Val* v) const override; IntrusivePtr<Val> Fold(Val* v) const override;
}; };
class RecordCoerceExpr : public UnaryExpr { class RecordCoerceExpr : public UnaryExpr {
public: public:
RecordCoerceExpr(Expr* op, RecordType* r); RecordCoerceExpr(IntrusivePtr<Expr> op, IntrusivePtr<RecordType> r);
~RecordCoerceExpr() override; ~RecordCoerceExpr() override;
protected: protected:
Val* InitVal(const BroType* t, Val* aggr) const override; IntrusivePtr<Val> InitVal(const BroType* t, IntrusivePtr<Val> aggr) const override;
Val* Fold(Val* v) const override; IntrusivePtr<Val> Fold(Val* v) const override;
// For each super-record slot, gives subrecord slot with which to // For each super-record slot, gives subrecord slot with which to
// fill it. // fill it.
@ -711,30 +704,30 @@ protected:
class TableCoerceExpr : public UnaryExpr { class TableCoerceExpr : public UnaryExpr {
public: public:
TableCoerceExpr(Expr* op, TableType* r); TableCoerceExpr(IntrusivePtr<Expr> op, IntrusivePtr<TableType> r);
~TableCoerceExpr() override; ~TableCoerceExpr() override;
protected: protected:
Val* Fold(Val* v) const override; IntrusivePtr<Val> Fold(Val* v) const override;
}; };
class VectorCoerceExpr : public UnaryExpr { class VectorCoerceExpr : public UnaryExpr {
public: public:
VectorCoerceExpr(Expr* op, VectorType* v); VectorCoerceExpr(IntrusivePtr<Expr> op, IntrusivePtr<VectorType> v);
~VectorCoerceExpr() override; ~VectorCoerceExpr() override;
protected: protected:
Val* Fold(Val* v) const override; IntrusivePtr<Val> Fold(Val* v) const override;
}; };
// An internal operator for flattening array indices that are records // An internal operator for flattening array indices that are records
// into a list of individual values. // into a list of individual values.
class FlattenExpr : public UnaryExpr { class FlattenExpr : public UnaryExpr {
public: public:
explicit FlattenExpr(Expr* op); explicit FlattenExpr(IntrusivePtr<Expr> op);
protected: protected:
Val* Fold(Val* v) const override; IntrusivePtr<Val> Fold(Val* v) const override;
int num_fields; int num_fields;
}; };
@ -755,53 +748,51 @@ protected:
class ScheduleExpr : public Expr { class ScheduleExpr : public Expr {
public: public:
ScheduleExpr(Expr* when, EventExpr* event); ScheduleExpr(IntrusivePtr<Expr> when, IntrusivePtr<EventExpr> event);
~ScheduleExpr() override;
int IsPure() const override; int IsPure() const override;
Val* Eval(Frame* f) const override; IntrusivePtr<Val> Eval(Frame* f) const override;
Expr* When() const { return when; } Expr* When() const { return when.get(); }
EventExpr* Event() const { return event; } EventExpr* Event() const { return event.get(); }
TraversalCode Traverse(TraversalCallback* cb) const override; TraversalCode Traverse(TraversalCallback* cb) const override;
protected: protected:
void ExprDescribe(ODesc* d) const override; void ExprDescribe(ODesc* d) const override;
Expr* when; IntrusivePtr<Expr> when;
EventExpr* event; IntrusivePtr<EventExpr> event;
}; };
class InExpr : public BinaryExpr { class InExpr : public BinaryExpr {
public: public:
InExpr(Expr* op1, Expr* op2); InExpr(IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2);
protected: protected:
Val* Fold(Val* v1, Val* v2) const override; IntrusivePtr<Val> Fold(Val* v1, Val* v2) const override;
}; };
class CallExpr : public Expr { class CallExpr : public Expr {
public: public:
CallExpr(Expr* func, ListExpr* args, bool in_hook = false); CallExpr(IntrusivePtr<Expr> func, IntrusivePtr<ListExpr> args, bool in_hook = false);
~CallExpr() override;
Expr* Func() const { return func; } Expr* Func() const { return func.get(); }
ListExpr* Args() const { return args; } ListExpr* Args() const { return args.get(); }
int IsPure() const override; int IsPure() const override;
Val* Eval(Frame* f) const override; IntrusivePtr<Val> Eval(Frame* f) const override;
TraversalCode Traverse(TraversalCallback* cb) const override; TraversalCode Traverse(TraversalCallback* cb) const override;
protected: protected:
void ExprDescribe(ODesc* d) const override; void ExprDescribe(ODesc* d) const override;
Expr* func; IntrusivePtr<Expr> func;
ListExpr* args; IntrusivePtr<ListExpr> args;
}; };
@ -815,7 +806,7 @@ public:
LambdaExpr(std::unique_ptr<function_ingredients> ingredients, LambdaExpr(std::unique_ptr<function_ingredients> ingredients,
id_list outer_ids); id_list outer_ids);
Val* Eval(Frame* f) const override; IntrusivePtr<Val> Eval(Frame* f) const override;
TraversalCode Traverse(TraversalCallback* cb) const override; TraversalCode Traverse(TraversalCallback* cb) const override;
protected: protected:
@ -830,14 +821,13 @@ private:
class EventExpr : public Expr { class EventExpr : public Expr {
public: public:
EventExpr(const char* name, ListExpr* args); EventExpr(const char* name, IntrusivePtr<ListExpr> args);
~EventExpr() override;
const char* Name() const { return name.c_str(); } const char* Name() const { return name.c_str(); }
ListExpr* Args() const { return args; } ListExpr* Args() const { return args.get(); }
EventHandlerPtr Handler() const { return handler; } EventHandlerPtr Handler() const { return handler; }
Val* Eval(Frame* f) const override; IntrusivePtr<Val> Eval(Frame* f) const override;
TraversalCode Traverse(TraversalCallback* cb) const override; TraversalCode Traverse(TraversalCallback* cb) const override;
@ -846,16 +836,16 @@ protected:
string name; string name;
EventHandlerPtr handler; EventHandlerPtr handler;
ListExpr* args; IntrusivePtr<ListExpr> args;
}; };
class ListExpr : public Expr { class ListExpr : public Expr {
public: public:
ListExpr(); ListExpr();
explicit ListExpr(Expr* e); explicit ListExpr(IntrusivePtr<Expr> e);
~ListExpr() override; ~ListExpr() override;
void Append(Expr* e); void Append(IntrusivePtr<Expr> e);
const expr_list& Exprs() const { return exprs; } const expr_list& Exprs() const { return exprs; }
expr_list& Exprs() { return exprs; } expr_list& Exprs() { return exprs; }
@ -866,17 +856,17 @@ public:
// True if the entire list represents constant values. // True if the entire list represents constant values.
int AllConst() const; int AllConst() const;
Val* Eval(Frame* f) const override; IntrusivePtr<Val> Eval(Frame* f) const override;
BroType* InitType() const override; IntrusivePtr<BroType> InitType() const override;
Val* InitVal(const BroType* t, Val* aggr) const override; IntrusivePtr<Val> InitVal(const BroType* t, IntrusivePtr<Val> aggr) const override;
Expr* MakeLvalue() override; IntrusivePtr<Expr> MakeLvalue() override;
void Assign(Frame* f, Val* v) override; void Assign(Frame* f, IntrusivePtr<Val> v) override;
TraversalCode Traverse(TraversalCallback* cb) const override; TraversalCode Traverse(TraversalCallback* cb) const override;
protected: 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; void ExprDescribe(ODesc* d) const override;
@ -886,29 +876,28 @@ protected:
class RecordAssignExpr : public ListExpr { class RecordAssignExpr : public ListExpr {
public: 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 { class CastExpr : public UnaryExpr {
public: public:
CastExpr(Expr* op, BroType* t); CastExpr(IntrusivePtr<Expr> op, IntrusivePtr<BroType> t);
protected: protected:
Val* Eval(Frame* f) const override; IntrusivePtr<Val> Eval(Frame* f) const override;
void ExprDescribe(ODesc* d) const override; void ExprDescribe(ODesc* d) const override;
}; };
class IsExpr : public UnaryExpr { class IsExpr : public UnaryExpr {
public: public:
IsExpr(Expr* op, BroType* t); IsExpr(IntrusivePtr<Expr> op, IntrusivePtr<BroType> t);
virtual ~IsExpr();
protected: protected:
Val* Fold(Val* v) const override; IntrusivePtr<Val> Fold(Val* v) const override;
void ExprDescribe(ODesc* d) const override; void ExprDescribe(ODesc* d) const override;
private: private:
BroType* t; IntrusivePtr<BroType> t;
}; };
inline Val* Expr::ExprVal() const inline Val* Expr::ExprVal() const
@ -919,7 +908,7 @@ inline Val* Expr::ExprVal() const
} }
// Decides whether to return an AssignExpr or a RecordAssignExpr. // 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 // 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 // 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; return false;
} }
Val* fmt_str_val = fmt_str_arg->Eval(0); auto fmt_str_val = fmt_str_arg->Eval(0);
if ( fmt_str_val ) if ( fmt_str_val )
{ {
@ -829,7 +829,6 @@ bool check_built_in_call(BuiltinFunc* f, CallExpr* call)
if ( ! *fmt_str ) if ( ! *fmt_str )
{ {
Unref(fmt_str_val);
call->Error("format string ends with bare '%'"); call->Error("format string ends with bare '%'");
return false; return false;
} }
@ -841,13 +840,11 @@ bool check_built_in_call(BuiltinFunc* f, CallExpr* call)
if ( args.length() != num_fmt + 1 ) if ( args.length() != num_fmt + 1 )
{ {
Unref(fmt_str_val);
call->Error("mismatch between format string to fmt() and number of arguments passed"); call->Error("mismatch between format string to fmt() and number of arguments passed");
return false; return false;
} }
} }
Unref(fmt_str_val);
return true; return true;
} }
@ -868,7 +865,7 @@ static int get_func_priority(const attr_list& attrs)
continue; continue;
} }
Val* v = a->AttrExpr()->Eval(0); auto v = a->AttrExpr()->Eval(0);
if ( ! v ) if ( ! v )
{ {
a->Error("cannot evaluate attribute expression"); a->Error("cannot evaluate attribute expression");
@ -877,13 +874,11 @@ static int get_func_priority(const attr_list& attrs)
if ( ! IsIntegral(v->Type()->Tag()) ) if ( ! IsIntegral(v->Type()->Tag()) )
{ {
Unref(v);
a->Error("expression is not of integral type"); a->Error("expression is not of integral type");
continue; continue;
} }
priority = v->InternalInt(); priority = v->InternalInt();
Unref(v);
} }
return priority; return priority;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -16,11 +16,11 @@
#include "Traverse.h" #include "Traverse.h"
#include "module_util.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 try
{ {
return init->InitVal(t, aggr); return init->InitVal(t, std::move(aggr));
} }
catch ( InterpreterException& e ) 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 ) else if ( dt != VAR_REDEF || init || ! attr )
{ {
Val* aggr; IntrusivePtr<Val> aggr;
if ( t->Tag() == TYPE_RECORD ) if ( t->Tag() == TYPE_RECORD )
{ {
aggr = new RecordVal(t->AsRecordType()); aggr = make_intrusive<RecordVal>(t->AsRecordType());
if ( init && t ) if ( init && t )
// Have an initialization and type is not deduced. // 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 ) 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 ) else if ( t->Tag() == TYPE_VECTOR )
aggr = new VectorVal(t->AsVectorType()); aggr = make_intrusive<VectorVal>(t->AsVectorType());
else IntrusivePtr<Val> v;
aggr = 0;
Val* v = 0;
if ( init ) if ( init )
{ {
v = init_val(init.get(), t.get(), aggr); 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 ) if ( aggr )
id->SetVal(aggr, c); id->SetVal(aggr.release(), c);
else if ( v ) 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" // may free "init"
const Location location = init->GetLocationInfo() != nullptr ? *init->GetLocationInfo() : no_location; 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 = 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 )); id->Attrs() ? id->Attrs()->Attrs() : 0 ));
stmt->SetLocationInfo(&location); 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) 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); make_var(id.get(), 0, INIT_FULL, init, 0, VAR_REGULAR, 0);
return make_intrusive<AssignExpr>(new NameExpr(id.release()), init.release(), 0, val.release()); 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) 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); string name = nameprepend + rec->FieldName(i);
const char* secondary = 0; const char* secondary = 0;
Val* c = nullptr; IntrusivePtr<Val> c;
TypeTag ty = rec->FieldType(i)->Tag(); TypeTag ty = rec->FieldType(i)->Tag();
TypeTag st = TYPE_VOID; TypeTag st = TYPE_VOID;
bool optional = false; bool optional = false;
@ -1001,7 +1001,6 @@ bool Manager::UnrollRecordType(vector<Field*> *fields, const RecordType *rec,
optional = true; optional = true;
Field* field = new Field(name.c_str(), secondary, ty, st, optional); Field* field = new Field(name.c_str(), secondary, ty, st, optional);
Unref(c);
fields->push_back(field); fields->push_back(field);
} }
} }

View file

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

View file

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