mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
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:
parent
7be3641f1d
commit
c3ea246237
17 changed files with 885 additions and 1206 deletions
|
@ -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 )
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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 )
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
1391
src/Expr.cc
1391
src/Expr.cc
File diff suppressed because it is too large
Load diff
339
src/Expr.h
339
src/Expr.h
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
13
src/ID.cc
13
src/ID.cc
|
@ -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
|
||||||
|
|
21
src/Stmt.cc
21
src/Stmt.cc
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 )
|
||||||
|
|
53
src/Type.cc
53
src/Type.cc
|
@ -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)
|
||||||
|
|
41
src/Val.cc
41
src/Val.cc
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
31
src/Var.cc
31
src/Var.cc
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
140
src/parse.y
140
src/parse.y
|
@ -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>(""));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue