diff --git a/src/Attr.cc b/src/Attr.cc index 09b17e1e6a..6c5fdfc31f 100644 --- a/src/Attr.cc +++ b/src/Attr.cc @@ -6,6 +6,7 @@ #include "Expr.h" #include "Desc.h" #include "Val.h" +#include "IntrusivePtr.h" #include "threading/SerialTypes.h" const char* attr_name(attr_tag t) @@ -109,10 +110,8 @@ void Attr::DescribeReST(ODesc* d, bool shorten) const else { - Val* v = expr->Eval(0); ODesc dd; - v->Describe(&dd); - Unref(v); + expr->Eval(0)->Describe(&dd); string s = dd.Description(); for ( size_t i = 0; i < s.size(); ++i ) diff --git a/src/DbgBreakpoint.cc b/src/DbgBreakpoint.cc index e26a8bb050..11033c789c 100644 --- a/src/DbgBreakpoint.cc +++ b/src/DbgBreakpoint.cc @@ -13,6 +13,7 @@ #include "Scope.h" #include "Frame.h" #include "Func.h" +#include "IntrusivePtr.h" #include "Val.h" #include "Stmt.h" #include "Timer.h" @@ -246,7 +247,7 @@ BreakCode DbgBreakpoint::HasHit() if ( condition.size() ) { // TODO: ### evaluate using debugger frame too - Val* yes = dbg_eval_expr(condition.c_str()); + auto yes = dbg_eval_expr(condition.c_str()); if ( ! yes ) { @@ -260,7 +261,6 @@ BreakCode DbgBreakpoint::HasHit() if ( ! IsIntegral(yes->Type()->Tag()) && ! IsBool(yes->Type()->Tag()) ) { - Unref(yes); PrintHitMsg(); debug_msg("Breakpoint condition should return an integral type"); return bcHitAndDelete; @@ -269,11 +269,8 @@ BreakCode DbgBreakpoint::HasHit() yes->CoerceToInt(); if ( yes->IsZero() ) { - Unref(yes); return bcNoHit; } - - Unref(yes); } int repcount = GetRepeatCount(); diff --git a/src/Debug.cc b/src/Debug.cc index d592e69b73..ddfab0a5e4 100644 --- a/src/Debug.cc +++ b/src/Debug.cc @@ -16,6 +16,7 @@ using namespace std; #include "DebugCmds.h" #include "DbgBreakpoint.h" #include "ID.h" +#include "IntrusivePtr.h" #include "Expr.h" #include "Stmt.h" #include "Frame.h" @@ -946,7 +947,7 @@ extern YYLTYPE yylloc; // holds start line and column of token extern int line_number; extern const char* filename; -Val* dbg_eval_expr(const char* expr) +IntrusivePtr dbg_eval_expr(const char* expr) { // Push the current frame's associated scope. // Note: g_debugger_state.curr_frame_idx is the user-visible number, @@ -981,7 +982,7 @@ Val* dbg_eval_expr(const char* expr) yylloc.first_line = yylloc.last_line = line_number = 1; // Parse the thing into an expr. - Val* result = 0; + IntrusivePtr result; if ( yyparse() ) { if ( g_curr_debug_error ) diff --git a/src/Debug.h b/src/Debug.h index 45bb8ed470..676c587635 100644 --- a/src/Debug.h +++ b/src/Debug.h @@ -10,6 +10,7 @@ #include #include +template class IntrusivePtr; class Val; class Stmt; @@ -159,7 +160,7 @@ int dbg_handle_debug_input(); // read a line and then have it executed int dbg_execute_command(const char* cmd); // Interactive expression evaluation. -Val* dbg_eval_expr(const char* expr); +IntrusivePtr dbg_eval_expr(const char* expr); // Extra debugging facilities. // TODO: current connections, memory allocated, other internal data structures. diff --git a/src/DebugCmds.cc b/src/DebugCmds.cc index cc7d37bcb2..e9a6720dcd 100644 --- a/src/DebugCmds.cc +++ b/src/DebugCmds.cc @@ -15,6 +15,7 @@ #include "Desc.h" #include "DbgBreakpoint.h" #include "ID.h" +#include "IntrusivePtr.h" #include "Frame.h" #include "Func.h" #include "Stmt.h" @@ -564,13 +565,12 @@ int dbg_cmd_print(DebugCmd cmd, const vector& args) expr += " "; } - Val* val = dbg_eval_expr(expr.c_str()); + auto val = dbg_eval_expr(expr.c_str()); if ( val ) { ODesc d; val->Describe(&d); - Unref(val); debug_msg("%s\n", d.Description()); } else diff --git a/src/Expr.cc b/src/Expr.cc index 4821330e16..7b33a141d8 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -18,7 +18,6 @@ #include "digest.h" #include "module_util.h" #include "DebugLogger.h" -#include "IntrusivePtr.h" #include "broker/Data.h" @@ -64,11 +63,6 @@ Expr::Expr(BroExprTag arg_tag) SetLocationInfo(&start_location, &end_location); } -Expr::~Expr() - { - Unref(type); - } - int Expr::CanAdd() const { return 0; @@ -89,11 +83,11 @@ void Expr::Delete(Frame* /* f */) Internal("Expr::Delete called"); } -Expr* Expr::MakeLvalue() +IntrusivePtr Expr::MakeLvalue() { if ( ! IsError() ) ExprError("can't be assigned to"); - return this; + return {NewRef{}, this}; } void Expr::EvalIntoAggregate(const BroType* /* t */, Val* /* aggr */, @@ -102,15 +96,14 @@ void Expr::EvalIntoAggregate(const BroType* /* t */, Val* /* aggr */, Internal("Expr::EvalIntoAggregate called"); } -void Expr::Assign(Frame* /* f */, Val* v) +void Expr::Assign(Frame* /* f */, IntrusivePtr /* v */) { - Unref(v); Internal("Expr::Assign called"); } -BroType* Expr::InitType() const +IntrusivePtr Expr::InitType() const { - return type->Ref(); + return type; } int Expr::IsRecordElement(TypeDecl* /* td */) const @@ -123,7 +116,7 @@ int Expr::IsPure() const return 1; } -Val* Expr::InitVal(const BroType* t, Val* aggr) const +IntrusivePtr Expr::InitVal(const BroType* t, IntrusivePtr aggr) const { if ( aggr ) { @@ -134,7 +127,7 @@ Val* Expr::InitVal(const BroType* t, Val* aggr) const if ( IsError() ) return 0; - return check_and_promote(Eval(0), t, 1); + return {AdoptRef{}, check_and_promote(Eval(0).release(), t, 1)}; } int Expr::IsError() const @@ -144,7 +137,7 @@ int Expr::IsError() const void Expr::SetError() { - SetType(error_type()); + SetType({AdoptRef{}, error_type()}); } void Expr::SetError(const char* msg) @@ -189,15 +182,10 @@ void Expr::Canonicize() { } -void Expr::SetType(BroType* t) +void Expr::SetType(IntrusivePtr t) { if ( ! type || type->Tag() != TYPE_ERROR ) - { - Unref(type); - type = t; - } - else - Unref(t); + type = std::move(t); } void Expr::ExprError(const char msg[]) @@ -227,45 +215,39 @@ void Expr::RuntimeErrorWithCallStack(const std::string& msg) const } } -NameExpr::NameExpr(ID* arg_id, bool const_init) : Expr(EXPR_NAME) +NameExpr::NameExpr(IntrusivePtr arg_id, bool const_init) : Expr(EXPR_NAME), id(std::move(arg_id)) { - id = arg_id; in_const_init = const_init; if ( id->AsType() ) - SetType(new TypeType(id->AsType())); + SetType(make_intrusive(id->AsType())); else - SetType(id->Type()->Ref()); + SetType({NewRef{}, id->Type()}); EventHandler* h = event_registry->Lookup(id->Name()); if ( h ) h->SetUsed(); } -NameExpr::~NameExpr() +IntrusivePtr NameExpr::Eval(Frame* f) const { - Unref(id); - } - -Val* NameExpr::Eval(Frame* f) const - { - Val* v; + IntrusivePtr v; if ( id->AsType() ) - return new Val(id->AsType(), true); + return make_intrusive(id->AsType(), true); if ( id->IsGlobal() ) - v = id->ID_Val(); + v = {NewRef{}, id->ID_Val()}; else if ( f ) - v = f->GetElement(id); + v = {NewRef{}, f->GetElement(id.get())}; else // No frame - evaluating for Simplify() purposes return 0; if ( v ) - return v->Ref(); + return v; else { RuntimeError("value used but not set"); @@ -273,7 +255,7 @@ Val* NameExpr::Eval(Frame* f) const } } -Expr* NameExpr::MakeLvalue() +IntrusivePtr NameExpr::MakeLvalue() { if ( id->AsType() ) ExprError("Type name is not an lvalue"); @@ -284,15 +266,15 @@ Expr* NameExpr::MakeLvalue() if ( id->IsOption() && ! in_const_init ) ExprError("option is not a modifiable lvalue"); - return new RefExpr(this); + return make_intrusive(IntrusivePtr{NewRef{}, this}); } -void NameExpr::Assign(Frame* f, Val* v) +void NameExpr::Assign(Frame* f, IntrusivePtr v) { if ( id->IsGlobal() ) - id->SetVal(v); + id->SetVal(v.release()); else - f->SetElement(id, v); + f->SetElement(id.get(), v.release()); } int NameExpr::IsPure() const @@ -326,23 +308,14 @@ void NameExpr::ExprDescribe(ODesc* d) const } } -ConstExpr::ConstExpr(Val* arg_val) : Expr(EXPR_CONST) +ConstExpr::ConstExpr(IntrusivePtr arg_val) : Expr(EXPR_CONST), val(std::move(arg_val)) { - val = arg_val; - if ( val->Type()->Tag() == TYPE_LIST && val->AsListVal()->Length() == 1 ) { - val = val->AsListVal()->Index(0); - val->Ref(); - Unref(arg_val); + val = {NewRef{}, val->AsListVal()->Index(0)}; } - SetType(val->Type()->Ref()); - } - -ConstExpr::~ConstExpr() - { - Unref(val); + SetType({NewRef{}, val->Type()}); } void ConstExpr::ExprDescribe(ODesc* d) const @@ -350,9 +323,9 @@ void ConstExpr::ExprDescribe(ODesc* d) const val->Describe(d); } -Val* ConstExpr::Eval(Frame* /* f */) const +IntrusivePtr ConstExpr::Eval(Frame* /* f */) const { - return Value()->Ref(); + return {NewRef{}, Value()}; } TraversalCode ConstExpr::Traverse(TraversalCallback* cb) const @@ -364,29 +337,24 @@ TraversalCode ConstExpr::Traverse(TraversalCallback* cb) const HANDLE_TC_EXPR_POST(tc); } -UnaryExpr::UnaryExpr(BroExprTag arg_tag, Expr* arg_op) : Expr(arg_tag) +UnaryExpr::UnaryExpr(BroExprTag arg_tag, IntrusivePtr arg_op) : Expr(std::move(arg_tag)) { op = arg_op; if ( op->IsError() ) SetError(); } -UnaryExpr::~UnaryExpr() - { - Unref(op); - } - -Val* UnaryExpr::Eval(Frame* f) const +IntrusivePtr UnaryExpr::Eval(Frame* f) const { if ( IsError() ) return 0; - Val* v = op->Eval(f); + auto v = op->Eval(f); if ( ! v ) return 0; - if ( is_vector(v) && Tag() != EXPR_IS && Tag() != EXPR_CAST ) + if ( is_vector(v.get()) && Tag() != EXPR_IS && Tag() != EXPR_CAST ) { VectorVal* v_op = v->AsVectorVal(); VectorType* out_t; @@ -395,22 +363,19 @@ Val* UnaryExpr::Eval(Frame* f) const else out_t = Type()->AsVectorType(); - VectorVal* result = new VectorVal(out_t); + auto result = make_intrusive(out_t); for ( unsigned int i = 0; i < v_op->Size(); ++i ) { Val* v_i = v_op->Lookup(i); - result->Assign(i, v_i ? Fold(v_i) : 0); + result->Assign(i, v_i ? Fold(v_i).release() : 0); } - Unref(v); return result; } else { - Val* result = Fold(v); - Unref(v); - return result; + return Fold(v.get()); } } @@ -431,9 +396,9 @@ TraversalCode UnaryExpr::Traverse(TraversalCallback* cb) const HANDLE_TC_EXPR_POST(tc); } -Val* UnaryExpr::Fold(Val* v) const +IntrusivePtr UnaryExpr::Fold(Val* v) const { - return v->Ref(); + return {NewRef{}, v}; } void UnaryExpr::ExprDescribe(ODesc* d) const @@ -462,32 +427,21 @@ void UnaryExpr::ExprDescribe(ODesc* d) const } } -BinaryExpr::~BinaryExpr() - { - Unref(op1); - Unref(op2); - } - -Val* BinaryExpr::Eval(Frame* f) const +IntrusivePtr BinaryExpr::Eval(Frame* f) const { if ( IsError() ) return 0; - Val* v1 = op1->Eval(f); + auto v1 = op1->Eval(f); if ( ! v1 ) return 0; - Val* v2 = op2->Eval(f); + auto v2 = op2->Eval(f); if ( ! v2 ) - { - Unref(v1); return 0; - } - Val* result = 0; - - int is_vec1 = is_vector(v1); - int is_vec2 = is_vector(v2); + int is_vec1 = is_vector(v1.get()); + int is_vec2 = is_vector(v2.get()); if ( is_vec1 && is_vec2 ) { // fold pairs of elements @@ -496,34 +450,30 @@ Val* BinaryExpr::Eval(Frame* f) const if ( v_op1->Size() != v_op2->Size() ) { - Unref(v1); - Unref(v2); RuntimeError("vector operands are of different sizes"); return 0; } - VectorVal* v_result = new VectorVal(Type()->AsVectorType()); + auto v_result = make_intrusive(Type()->AsVectorType()); for ( unsigned int i = 0; i < v_op1->Size(); ++i ) { if ( v_op1->Lookup(i) && v_op2->Lookup(i) ) v_result->Assign(i, Fold(v_op1->Lookup(i), - v_op2->Lookup(i))); + v_op2->Lookup(i)).release()); else v_result->Assign(i, 0); // SetError("undefined element in vector operation"); } - Unref(v1); - Unref(v2); return v_result; } if ( IsVector(Type()->Tag()) && (is_vec1 || is_vec2) ) { // fold vector against scalar VectorVal* vv = (is_vec1 ? v1 : v2)->AsVectorVal(); - VectorVal* v_result = new VectorVal(Type()->AsVectorType()); + auto v_result = make_intrusive(Type()->AsVectorType()); for ( unsigned int i = 0; i < vv->Size(); ++i ) { @@ -531,24 +481,18 @@ Val* BinaryExpr::Eval(Frame* f) const if ( vv_i ) v_result->Assign(i, is_vec1 ? - Fold(vv_i, v2) : Fold(v1, vv_i)); + Fold(vv_i, v2.get()).release() : Fold(v1.get(), vv_i).release()); else v_result->Assign(i, 0); // SetError("Undefined element in vector operation"); } - Unref(v1); - Unref(v2); return v_result; } // scalar op scalar - result = Fold(v1, v2); - - Unref(v1); - Unref(v2); - return result; + return Fold(v1.get(), v2.get()); } int BinaryExpr::IsPure() const @@ -582,7 +526,7 @@ void BinaryExpr::ExprDescribe(ODesc* d) const op2->Describe(d); } -Val* BinaryExpr::Fold(Val* v1, Val* v2) const +IntrusivePtr BinaryExpr::Fold(Val* v1, Val* v2) const { InternalTypeTag it = v1->Type()->InternalType(); @@ -733,23 +677,23 @@ Val* BinaryExpr::Fold(Val* v1, Val* v2) const BadTag("BinaryExpr::Fold", expr_name(tag)); } - BroType* ret_type = type; + BroType* ret_type = Type(); if ( IsVector(ret_type->Tag()) ) ret_type = ret_type->YieldType(); if ( ret_type->Tag() == TYPE_INTERVAL ) - return new IntervalVal(d3, 1.0); + return make_intrusive(d3, 1.0); else if ( ret_type->InternalType() == TYPE_INTERNAL_DOUBLE ) - return new Val(d3, ret_type->Tag()); + return make_intrusive(d3, ret_type->Tag()); else if ( ret_type->InternalType() == TYPE_INTERNAL_UNSIGNED ) - return val_mgr->GetCount(u3); + return {AdoptRef{}, val_mgr->GetCount(u3)}; else if ( ret_type->Tag() == TYPE_BOOL ) - return val_mgr->GetBool(i3); + return {AdoptRef{}, val_mgr->GetBool(i3)}; else - return val_mgr->GetInt(i3); + return {AdoptRef{}, val_mgr->GetInt(i3)}; } -Val* BinaryExpr::StringFold(Val* v1, Val* v2) const +IntrusivePtr BinaryExpr::StringFold(Val* v1, Val* v2) const { const BroString* s1 = v1->AsString(); const BroString* s2 = v2->AsString(); @@ -773,18 +717,18 @@ Val* BinaryExpr::StringFold(Val* v1, Val* v2) const strings.push_back(s1); strings.push_back(s2); - return new StringVal(concatenate(strings)); + return make_intrusive(concatenate(strings)); } default: BadTag("BinaryExpr::StringFold", expr_name(tag)); } - return val_mgr->GetBool(result); + return {AdoptRef{}, val_mgr->GetBool(result)}; } -Val* BinaryExpr::PatternFold(Val* v1, Val* v2) const +IntrusivePtr BinaryExpr::PatternFold(Val* v1, Val* v2) const { const RE_Matcher* re1 = v1->AsPattern(); const RE_Matcher* re2 = v2->AsPattern(); @@ -796,10 +740,10 @@ Val* BinaryExpr::PatternFold(Val* v1, Val* v2) const RE_Matcher_conjunction(re1, re2) : RE_Matcher_disjunction(re1, re2); - return new PatternVal(res); + return make_intrusive(res); } -Val* BinaryExpr::SetFold(Val* v1, Val* v2) const +IntrusivePtr BinaryExpr::SetFold(Val* v1, Val* v2) const { TableVal* tv1 = v1->AsTableVal(); TableVal* tv2 = v2->AsTableVal(); @@ -808,21 +752,21 @@ Val* BinaryExpr::SetFold(Val* v1, Val* v2) const switch ( tag ) { case EXPR_AND: - return tv1->Intersect(tv2); + return {AdoptRef{}, tv1->Intersect(tv2)}; case EXPR_OR: result = v1->Clone()->AsTableVal(); if ( ! tv2->AddTo(result, false, false) ) reporter->InternalError("set union failed to type check"); - return result; + return {AdoptRef{}, result}; case EXPR_SUB: result = v1->Clone()->AsTableVal(); if ( ! tv2->RemoveFrom(result) ) reporter->InternalError("set difference failed to type check"); - return result; + return {AdoptRef{}, result}; case EXPR_EQ: res = tv1->EqualTo(tv2); @@ -851,10 +795,10 @@ Val* BinaryExpr::SetFold(Val* v1, Val* v2) const return 0; } - return val_mgr->GetBool(res); + return {AdoptRef{}, val_mgr->GetBool(res)}; } -Val* BinaryExpr::AddrFold(Val* v1, Val* v2) const +IntrusivePtr BinaryExpr::AddrFold(Val* v1, Val* v2) const { IPAddr a1 = v1->AsAddr(); IPAddr a2 = v2->AsAddr(); @@ -885,10 +829,10 @@ Val* BinaryExpr::AddrFold(Val* v1, Val* v2) const BadTag("BinaryExpr::AddrFold", expr_name(tag)); } - return val_mgr->GetBool(result); + return {AdoptRef{}, val_mgr->GetBool(result)}; } -Val* BinaryExpr::SubNetFold(Val* v1, Val* v2) const +IntrusivePtr BinaryExpr::SubNetFold(Val* v1, Val* v2) const { const IPPrefix& n1 = v1->AsSubNet(); const IPPrefix& n2 = v2->AsSubNet(); @@ -898,15 +842,14 @@ Val* BinaryExpr::SubNetFold(Val* v1, Val* v2) const if ( tag == EXPR_NE ) result = ! result; - return val_mgr->GetBool(result); + return {AdoptRef{}, val_mgr->GetBool(result)}; } void BinaryExpr::SwapOps() { // We could check here whether the operator is commutative. - Expr* t = op1; - op1 = op2; - op2 = t; + using std::swap; + swap(op1, op2); } void BinaryExpr::PromoteOps(TypeTag t) @@ -926,48 +869,45 @@ void BinaryExpr::PromoteOps(TypeTag t) reporter->Warning("mixing vector and scalar operands is deprecated"); if ( bt1 != t ) - op1 = new ArithCoerceExpr(op1, t); + op1 = make_intrusive(op1, t); if ( bt2 != t ) - op2 = new ArithCoerceExpr(op2, t); + op2 = make_intrusive(op2, t); } void BinaryExpr::PromoteType(TypeTag t, bool is_vector) { PromoteOps(t); - SetType(is_vector ? new VectorType(base_type(t)) : base_type(t)); + SetType(is_vector ? make_intrusive(base_type(t)) : IntrusivePtr{NewRef{}, base_type(t)}); } -CloneExpr::CloneExpr(Expr* arg_op) : UnaryExpr(EXPR_CLONE, arg_op) +CloneExpr::CloneExpr(IntrusivePtr arg_op) : UnaryExpr(EXPR_CLONE, std::move(arg_op)) { if ( IsError() ) return; BroType* t = op->Type(); - SetType(t->Ref()); + SetType({NewRef{}, t}); } -Val* CloneExpr::Eval(Frame* f) const +IntrusivePtr CloneExpr::Eval(Frame* f) const { if ( IsError() ) return 0; - Val* v = op->Eval(f); + auto v = op->Eval(f); if ( ! v ) return 0; - Val* result = Fold(v); - Unref(v); - - return result; + return Fold(v.get()); } -Val* CloneExpr::Fold(Val* v) const +IntrusivePtr CloneExpr::Fold(Val* v) const { - return v->Clone(); + return {AdoptRef{}, v->Clone()}; } -IncrExpr::IncrExpr(BroExprTag arg_tag, Expr* arg_op) +IncrExpr::IncrExpr(BroExprTag arg_tag, IntrusivePtr arg_op) : UnaryExpr(arg_tag, arg_op->MakeLvalue()) { if ( IsError() ) @@ -982,7 +922,7 @@ IncrExpr::IncrExpr(BroExprTag arg_tag, Expr* arg_op) else { reporter->Warning("increment/decrement operations for vectors deprecated"); - SetType(t->Ref()); + SetType({NewRef{}, t}); } } else @@ -990,11 +930,11 @@ IncrExpr::IncrExpr(BroExprTag arg_tag, Expr* arg_op) if ( ! IsIntegral(t->Tag()) ) ExprError("requires an integral operand"); else - SetType(t->Ref()); + SetType({NewRef{}, t}); } } -Val* IncrExpr::DoSingleEval(Frame* f, Val* v) const +IntrusivePtr IncrExpr::DoSingleEval(Frame* f, Val* v) const { bro_int_t k = v->CoerceToInt(); @@ -1014,41 +954,39 @@ Val* IncrExpr::DoSingleEval(Frame* f, Val* v) const ret_type = Type()->YieldType(); if ( ret_type->Tag() == TYPE_INT ) - return val_mgr->GetInt(k); + return {AdoptRef{}, val_mgr->GetInt(k)}; else - return val_mgr->GetCount(k); + return {AdoptRef{}, val_mgr->GetCount(k)}; } -Val* IncrExpr::Eval(Frame* f) const +IntrusivePtr IncrExpr::Eval(Frame* f) const { - Val* v = op->Eval(f); + auto v = op->Eval(f); if ( ! v ) return 0; - if ( is_vector(v) ) + if ( is_vector(v.get()) ) { - VectorVal* v_vec = v->AsVectorVal(); + IntrusivePtr v_vec{NewRef{}, v->AsVectorVal()}; for ( unsigned int i = 0; i < v_vec->Size(); ++i ) { Val* elt = v_vec->Lookup(i); if ( elt ) { - Val* new_elt = DoSingleEval(f, elt); - v_vec->Assign(i, new_elt); + v_vec->Assign(i, DoSingleEval(f, elt).release()); } else v_vec->Assign(i, 0); } - op->Assign(f, v_vec->Ref()); + op->Assign(f, std::move(v_vec)); return v; } else { - auto new_v = DoSingleEval(f, v); - Unref(v); - op->Assign(f, new_v->Ref()); + auto new_v = DoSingleEval(f, v.get()); + op->Assign(f, new_v); return new_v; } } @@ -1058,7 +996,7 @@ int IncrExpr::IsPure() const return 0; } -ComplementExpr::ComplementExpr(Expr* arg_op) : UnaryExpr(EXPR_COMPLEMENT, arg_op) +ComplementExpr::ComplementExpr(IntrusivePtr arg_op) : UnaryExpr(EXPR_COMPLEMENT, std::move(arg_op)) { if ( IsError() ) return; @@ -1069,15 +1007,15 @@ ComplementExpr::ComplementExpr(Expr* arg_op) : UnaryExpr(EXPR_COMPLEMENT, arg_op if ( bt != TYPE_COUNT ) ExprError("requires \"count\" operand"); else - SetType(base_type(TYPE_COUNT)); + SetType({AdoptRef{}, base_type(TYPE_COUNT)}); } -Val* ComplementExpr::Fold(Val* v) const +IntrusivePtr ComplementExpr::Fold(Val* v) const { - return val_mgr->GetCount(~ v->InternalUnsigned()); + return {AdoptRef{}, val_mgr->GetCount(~ v->InternalUnsigned())}; } -NotExpr::NotExpr(Expr* arg_op) : UnaryExpr(EXPR_NOT, arg_op) +NotExpr::NotExpr(IntrusivePtr arg_op) : UnaryExpr(EXPR_NOT, std::move(arg_op)) { if ( IsError() ) return; @@ -1088,15 +1026,15 @@ NotExpr::NotExpr(Expr* arg_op) : UnaryExpr(EXPR_NOT, arg_op) if ( ! IsIntegral(bt) && bt != TYPE_BOOL ) ExprError("requires an integral or boolean operand"); else - SetType(base_type(TYPE_BOOL)); + SetType({AdoptRef{}, base_type(TYPE_BOOL)}); } -Val* NotExpr::Fold(Val* v) const +IntrusivePtr NotExpr::Fold(Val* v) const { - return val_mgr->GetBool(! v->InternalInt()); + return {AdoptRef{}, val_mgr->GetBool(! v->InternalInt())}; } -PosExpr::PosExpr(Expr* arg_op) : UnaryExpr(EXPR_POSITIVE, arg_op) +PosExpr::PosExpr(IntrusivePtr arg_op) : UnaryExpr(EXPR_POSITIVE, std::move(arg_op)) { if ( IsError() ) return; @@ -1116,23 +1054,23 @@ PosExpr::PosExpr(Expr* arg_op) : UnaryExpr(EXPR_POSITIVE, arg_op) else ExprError("requires an integral or double operand"); - if ( is_vector(op) ) - SetType(new VectorType(base_result_type)); + if ( is_vector(op.get()) ) + SetType(make_intrusive(base_result_type)); else - SetType(base_result_type); + SetType({AdoptRef{}, base_result_type}); } -Val* PosExpr::Fold(Val* v) const +IntrusivePtr PosExpr::Fold(Val* v) const { TypeTag t = v->Type()->Tag(); if ( t == TYPE_DOUBLE || t == TYPE_INTERVAL || t == TYPE_INT ) - return v->Ref(); + return {NewRef{}, v}; else - return val_mgr->GetInt(v->CoerceToInt()); + return {AdoptRef{}, val_mgr->GetInt(v->CoerceToInt())}; } -NegExpr::NegExpr(Expr* arg_op) : UnaryExpr(EXPR_NEGATE, arg_op) +NegExpr::NegExpr(IntrusivePtr arg_op) : UnaryExpr(EXPR_NEGATE, std::move(arg_op)) { if ( IsError() ) return; @@ -1152,51 +1090,49 @@ NegExpr::NegExpr(Expr* arg_op) : UnaryExpr(EXPR_NEGATE, arg_op) else ExprError("requires an integral or double operand"); - if ( is_vector(op) ) - SetType(new VectorType(base_result_type)); + if ( is_vector(op.get()) ) + SetType(make_intrusive(base_result_type)); else - SetType(base_result_type); + SetType({AdoptRef{}, base_result_type}); } -Val* NegExpr::Fold(Val* v) const +IntrusivePtr NegExpr::Fold(Val* v) const { if ( v->Type()->Tag() == TYPE_DOUBLE ) - return new Val(- v->InternalDouble(), v->Type()->Tag()); + return make_intrusive(- v->InternalDouble(), v->Type()->Tag()); else if ( v->Type()->Tag() == TYPE_INTERVAL ) - return new IntervalVal(- v->InternalDouble(), 1.0); + return make_intrusive(- v->InternalDouble(), 1.0); else - return val_mgr->GetInt(- v->CoerceToInt()); + return {AdoptRef{}, val_mgr->GetInt(- v->CoerceToInt())}; } -SizeExpr::SizeExpr(Expr* arg_op) : UnaryExpr(EXPR_SIZE, arg_op) +SizeExpr::SizeExpr(IntrusivePtr arg_op) : UnaryExpr(EXPR_SIZE, std::move(arg_op)) { if ( IsError() ) return; if ( op->Type()->InternalType() == TYPE_INTERNAL_DOUBLE ) - SetType(base_type(TYPE_DOUBLE)); + SetType({AdoptRef{}, base_type(TYPE_DOUBLE)}); else - SetType(base_type(TYPE_COUNT)); + SetType({AdoptRef{}, base_type(TYPE_COUNT)}); } -Val* SizeExpr::Eval(Frame* f) const +IntrusivePtr SizeExpr::Eval(Frame* f) const { - Val* v = op->Eval(f); + auto v = op->Eval(f); if ( ! v ) return 0; - Val* result = Fold(v); - Unref(v); - return result; + return Fold(v.get()); } -Val* SizeExpr::Fold(Val* v) const +IntrusivePtr SizeExpr::Fold(Val* v) const { - return v->SizeVal(); + return {AdoptRef{}, v->SizeVal()}; } -AddExpr::AddExpr(Expr* arg_op1, Expr* arg_op2) -: BinaryExpr(EXPR_ADD, arg_op1, arg_op2) +AddExpr::AddExpr(IntrusivePtr arg_op1, IntrusivePtr arg_op2) + : BinaryExpr(EXPR_ADD, std::move(arg_op1), std::move(arg_op2)) { if ( IsError() ) return; @@ -1218,7 +1154,7 @@ AddExpr::AddExpr(Expr* arg_op1, Expr* arg_op2) else if ( bt1 == TYPE_INTERVAL && bt2 == TYPE_INTERVAL ) base_result_type = base_type(bt1); else if ( BothArithmetic(bt1, bt2) ) - PromoteType(max_type(bt1, bt2), is_vector(op1) || is_vector(op2)); + PromoteType(max_type(bt1, bt2), is_vector(op1.get()) || is_vector(op2.get())); else if ( BothString(bt1, bt2) ) base_result_type = base_type(bt1); else @@ -1226,25 +1162,25 @@ AddExpr::AddExpr(Expr* arg_op1, Expr* arg_op2) if ( base_result_type ) { - if ( is_vector(op1) || is_vector(op2) ) - SetType(new VectorType(base_result_type)); + if ( is_vector(op1.get()) || is_vector(op2.get()) ) + SetType(make_intrusive(base_result_type)); else - SetType(base_result_type); + SetType({AdoptRef{}, base_result_type}); } } void AddExpr::Canonicize() { - if ( expr_greater(op2, op1) || + if ( expr_greater(op2.get(), op1.get()) || (op1->Type()->Tag() == TYPE_INTERVAL && op2->Type()->Tag() == TYPE_TIME) || (op2->IsConst() && ! is_vector(op2->ExprVal()) && ! op1->IsConst())) SwapOps(); } -AddToExpr::AddToExpr(Expr* arg_op1, Expr* arg_op2) +AddToExpr::AddToExpr(IntrusivePtr arg_op1, IntrusivePtr arg_op2) : BinaryExpr(EXPR_ADD_TO, - is_vector(arg_op1) ? arg_op1 : arg_op1->MakeLvalue(), arg_op2) + is_vector(arg_op1.get()) ? std::move(arg_op1) : arg_op1->MakeLvalue(), std::move(arg_op2)) { if ( IsError() ) return; @@ -1253,11 +1189,11 @@ AddToExpr::AddToExpr(Expr* arg_op1, Expr* arg_op2) TypeTag bt2 = op2->Type()->Tag(); if ( BothArithmetic(bt1, bt2) ) - PromoteType(max_type(bt1, bt2), is_vector(op1) || is_vector(op2)); + PromoteType(max_type(bt1, bt2), is_vector(op1.get()) || is_vector(op2.get())); else if ( BothString(bt1, bt2) ) - SetType(base_type(bt1)); + SetType({AdoptRef{}, base_type(bt1)}); else if ( BothInterval(bt1, bt2) ) - SetType(base_type(bt1)); + SetType({AdoptRef{}, base_type(bt1)}); else if ( IsVector(bt1) ) { @@ -1268,9 +1204,9 @@ AddToExpr::AddToExpr(Expr* arg_op1, Expr* arg_op2) if ( IsArithmetic(bt2) ) { if ( bt2 != bt1 ) - op2 = new ArithCoerceExpr(op2, bt1); + op2 = make_intrusive(std::move(op2), bt1); - SetType(op1->Type()->Ref()); + SetType({NewRef{}, op1->Type()}); } else @@ -1282,49 +1218,44 @@ AddToExpr::AddToExpr(Expr* arg_op1, Expr* arg_op2) type_name(bt1), type_name(bt2))); else - SetType(op1->Type()->Ref()); + SetType({NewRef{}, op1->Type()}); } else ExprError("requires two arithmetic or two string operands"); } -Val* AddToExpr::Eval(Frame* f) const +IntrusivePtr AddToExpr::Eval(Frame* f) const { - Val* v1 = op1->Eval(f); + auto v1 = op1->Eval(f); if ( ! v1 ) return 0; - Val* v2 = op2->Eval(f); + auto v2 = op2->Eval(f); if ( ! v2 ) - { - Unref(v1); return 0; - } - if ( is_vector(v1) ) + if ( is_vector(v1.get()) ) { VectorVal* vv = v1->AsVectorVal(); - if ( ! vv->Assign(vv->Size(), v2) ) + if ( ! vv->Assign(vv->Size(), v2.release()) ) RuntimeError("type-checking failed in vector append"); return v1; } - Val* result = Fold(v1, v2); - Unref(v1); - Unref(v2); + auto result = Fold(v1.get(), v2.get()); if ( result ) { - op1->Assign(f, result->Ref()); + op1->Assign(f, result); return result; } else return 0; } -SubExpr::SubExpr(Expr* arg_op1, Expr* arg_op2) -: BinaryExpr(EXPR_SUB, arg_op1, arg_op2) +SubExpr::SubExpr(IntrusivePtr arg_op1, IntrusivePtr arg_op2) +: BinaryExpr(EXPR_SUB, std::move(arg_op1), std::move(arg_op2)) { if ( IsError() ) return; @@ -1346,7 +1277,7 @@ SubExpr::SubExpr(Expr* arg_op1, Expr* arg_op2) base_result_type = base_type(bt1); else if ( bt1 == TYPE_TIME && bt2 == TYPE_TIME ) - SetType(base_type(TYPE_INTERVAL)); + SetType({AdoptRef{}, base_type(TYPE_INTERVAL)}); else if ( bt1 == TYPE_INTERVAL && bt2 == TYPE_INTERVAL ) base_result_type = base_type(bt1); @@ -1354,28 +1285,28 @@ SubExpr::SubExpr(Expr* arg_op1, Expr* arg_op2) else if ( t1->IsSet() && t2->IsSet() ) { if ( same_type(t1, t2) ) - SetType(op1->Type()->Ref()); + SetType({NewRef{}, op1->Type()}); else ExprError("incompatible \"set\" operands"); } else if ( BothArithmetic(bt1, bt2) ) - PromoteType(max_type(bt1, bt2), is_vector(op1) || is_vector(op2)); + PromoteType(max_type(bt1, bt2), is_vector(op1.get()) || is_vector(op2.get())); else ExprError("requires arithmetic operands"); if ( base_result_type ) { - if ( is_vector(op1) || is_vector(op2) ) - SetType(new VectorType(base_result_type)); + if ( is_vector(op1.get()) || is_vector(op2.get()) ) + SetType(make_intrusive(base_result_type)); else - SetType(base_result_type); + SetType({AdoptRef{}, base_result_type}); } } -RemoveFromExpr::RemoveFromExpr(Expr* arg_op1, Expr* arg_op2) -: BinaryExpr(EXPR_REMOVE_FROM, arg_op1->MakeLvalue(), arg_op2) +RemoveFromExpr::RemoveFromExpr(IntrusivePtr arg_op1, IntrusivePtr arg_op2) +: BinaryExpr(EXPR_REMOVE_FROM, arg_op1->MakeLvalue(), std::move(arg_op2)) { if ( IsError() ) return; @@ -1384,42 +1315,36 @@ RemoveFromExpr::RemoveFromExpr(Expr* arg_op1, Expr* arg_op2) TypeTag bt2 = op2->Type()->Tag(); if ( BothArithmetic(bt1, bt2) ) - PromoteType(max_type(bt1, bt2), is_vector(op1) || is_vector(op2)); + PromoteType(max_type(bt1, bt2), is_vector(op1.get()) || is_vector(op2.get())); else if ( BothInterval(bt1, bt2) ) - SetType(base_type(bt1)); + SetType({AdoptRef{}, base_type(bt1)}); else ExprError("requires two arithmetic operands"); } -Val* RemoveFromExpr::Eval(Frame* f) const +IntrusivePtr RemoveFromExpr::Eval(Frame* f) const { - Val* v1 = op1->Eval(f); + auto v1 = op1->Eval(f); if ( ! v1 ) return 0; - Val* v2 = op2->Eval(f); + auto v2 = op2->Eval(f); if ( ! v2 ) - { - Unref(v1); return 0; - } - Val* result = Fold(v1, v2); - - Unref(v1); - Unref(v2); + auto result = Fold(v1.get(), v2.get()); if ( result ) { - op1->Assign(f, result->Ref()); + op1->Assign(f, result); return result; } else return 0; } -TimesExpr::TimesExpr(Expr* arg_op1, Expr* arg_op2) -: BinaryExpr(EXPR_TIMES, arg_op1, arg_op2) +TimesExpr::TimesExpr(IntrusivePtr arg_op1, IntrusivePtr arg_op2) +: BinaryExpr(EXPR_TIMES, std::move(arg_op1), std::move(arg_op2)) { if ( IsError() ) return; @@ -1437,25 +1362,25 @@ TimesExpr::TimesExpr(Expr* arg_op1, Expr* arg_op2) if ( bt1 == TYPE_INTERVAL || bt2 == TYPE_INTERVAL ) { if ( IsArithmetic(bt1) || IsArithmetic(bt2) ) - PromoteType(TYPE_INTERVAL, is_vector(op1) || is_vector(op2) ); + PromoteType(TYPE_INTERVAL, is_vector(op1.get()) || is_vector(op2.get()) ); else ExprError("multiplication with interval requires arithmetic operand"); } else if ( BothArithmetic(bt1, bt2) ) - PromoteType(max_type(bt1, bt2), is_vector(op1) || is_vector(op2)); + PromoteType(max_type(bt1, bt2), is_vector(op1.get()) || is_vector(op2.get())); else ExprError("requires arithmetic operands"); } void TimesExpr::Canonicize() { - if ( expr_greater(op2, op1) || op2->Type()->Tag() == TYPE_INTERVAL || + if ( expr_greater(op2.get(), op1.get()) || op2->Type()->Tag() == TYPE_INTERVAL || (op2->IsConst() && ! is_vector(op2->ExprVal()) && ! op1->IsConst()) ) SwapOps(); } -DivideExpr::DivideExpr(Expr* arg_op1, Expr* arg_op2) -: BinaryExpr(EXPR_DIVIDE, arg_op1, arg_op2) +DivideExpr::DivideExpr(IntrusivePtr arg_op1, IntrusivePtr arg_op2) +: BinaryExpr(EXPR_DIVIDE, std::move(arg_op1), std::move(arg_op2)) { if ( IsError() ) return; @@ -1471,30 +1396,30 @@ DivideExpr::DivideExpr(Expr* arg_op1, Expr* arg_op2) if ( bt1 == TYPE_INTERVAL || bt2 == TYPE_INTERVAL ) { if ( IsArithmetic(bt1) || IsArithmetic(bt2) ) - PromoteType(TYPE_INTERVAL, is_vector(op1) || is_vector(op2)); + PromoteType(TYPE_INTERVAL, is_vector(op1.get()) || is_vector(op2.get())); else if ( bt1 == TYPE_INTERVAL && bt2 == TYPE_INTERVAL ) { - if ( is_vector(op1) || is_vector(op2) ) - SetType(new VectorType(base_type(TYPE_DOUBLE))); + if ( is_vector(op1.get()) || is_vector(op2.get()) ) + SetType(make_intrusive(base_type(TYPE_DOUBLE))); else - SetType(base_type(TYPE_DOUBLE)); + SetType({AdoptRef{}, base_type(TYPE_DOUBLE)}); } else ExprError("division of interval requires arithmetic operand"); } else if ( BothArithmetic(bt1, bt2) ) - PromoteType(max_type(bt1, bt2), is_vector(op1) || is_vector(op2)); + PromoteType(max_type(bt1, bt2), is_vector(op1.get()) || is_vector(op2.get())); - else if ( bt1 == TYPE_ADDR && ! is_vector(op2) && + else if ( bt1 == TYPE_ADDR && ! is_vector(op2.get()) && (bt2 == TYPE_COUNT || bt2 == TYPE_INT) ) - SetType(base_type(TYPE_SUBNET)); + SetType({AdoptRef{}, base_type(TYPE_SUBNET)}); else ExprError("requires arithmetic operands"); } -Val* DivideExpr::AddrFold(Val* v1, Val* v2) const +IntrusivePtr DivideExpr::AddrFold(Val* v1, Val* v2) const { uint32_t mask; if ( v2->Type()->Tag() == TYPE_COUNT ) @@ -1515,11 +1440,11 @@ Val* DivideExpr::AddrFold(Val* v1, Val* v2) const RuntimeError(fmt("bad IPv6 subnet prefix length: %" PRIu32, mask)); } - return new SubNetVal(a, mask); + return make_intrusive(a, mask); } -ModExpr::ModExpr(Expr* arg_op1, Expr* arg_op2) -: BinaryExpr(EXPR_MOD, arg_op1, arg_op2) +ModExpr::ModExpr(IntrusivePtr arg_op1, IntrusivePtr arg_op2) +: BinaryExpr(EXPR_MOD, std::move(arg_op1), std::move(arg_op2)) { if ( IsError() ) return; @@ -1533,13 +1458,13 @@ ModExpr::ModExpr(Expr* arg_op1, Expr* arg_op2) bt2 = op2->Type()->AsVectorType()->YieldType()->Tag(); if ( BothIntegral(bt1, bt2) ) - PromoteType(max_type(bt1, bt2), is_vector(op1) || is_vector(op2)); + PromoteType(max_type(bt1, bt2), is_vector(op1.get()) || is_vector(op2.get())); else ExprError("requires integral operands"); } -BoolExpr::BoolExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2) -: BinaryExpr(arg_tag, arg_op1, arg_op2) +BoolExpr::BoolExpr(BroExprTag arg_tag, IntrusivePtr arg_op1, IntrusivePtr arg_op2) +: BinaryExpr(arg_tag, std::move(arg_op1), std::move(arg_op2)) { if ( IsError() ) return; @@ -1554,20 +1479,20 @@ BoolExpr::BoolExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2) if ( BothBool(bt1, bt2) ) { - if ( is_vector(op1) || is_vector(op2) ) + if ( is_vector(op1.get()) || is_vector(op2.get()) ) { - if ( ! (is_vector(op1) && is_vector(op2)) ) + if ( ! (is_vector(op1.get()) && is_vector(op2.get())) ) reporter->Warning("mixing vector and scalar operands is deprecated"); - SetType(new VectorType(base_type(TYPE_BOOL))); + SetType(make_intrusive(base_type(TYPE_BOOL))); } else - SetType(base_type(TYPE_BOOL)); + SetType({AdoptRef{}, base_type(TYPE_BOOL)}); } else ExprError("requires boolean operands"); } -Val* BoolExpr::DoSingleEval(Frame* f, Val* v1, Expr* op2) const +IntrusivePtr BoolExpr::DoSingleEval(Frame* f, IntrusivePtr v1, Expr* op2) const { if ( ! v1 ) return 0; @@ -1577,107 +1502,90 @@ Val* BoolExpr::DoSingleEval(Frame* f, Val* v1, Expr* op2) const if ( v1->IsZero() ) return v1; else - { - Unref(v1); return op2->Eval(f); - } } else { if ( v1->IsZero() ) - { - Unref(v1); return op2->Eval(f); - } else return v1; } } -Val* BoolExpr::Eval(Frame* f) const +IntrusivePtr BoolExpr::Eval(Frame* f) const { if ( IsError() ) return 0; - Val* v1 = op1->Eval(f); + auto v1 = op1->Eval(f); if ( ! v1 ) return 0; - int is_vec1 = is_vector(op1); - int is_vec2 = is_vector(op2); + int is_vec1 = is_vector(op1.get()); + int is_vec2 = is_vector(op2.get()); // Handle scalar op scalar if ( ! is_vec1 && ! is_vec2 ) - return DoSingleEval(f, v1, op2); + return DoSingleEval(f, std::move(v1), op2.get()); // Handle scalar op vector or vector op scalar // We can't short-circuit everything since we need to eval // a vector in order to find out its length. if ( ! (is_vec1 && is_vec2) ) { // Only one is a vector. - Val* scalar_v = 0; - VectorVal* vector_v = 0; + IntrusivePtr scalar_v; + IntrusivePtr vector_v; if ( is_vec1 ) { scalar_v = op2->Eval(f); - vector_v = v1->AsVectorVal(); + vector_v = {AdoptRef{}, v1.release()->AsVectorVal()}; } else { - scalar_v = v1; - vector_v = op2->Eval(f)->AsVectorVal(); + scalar_v = std::move(v1); + vector_v = {AdoptRef{}, op2->Eval(f).release()->AsVectorVal()}; } if ( ! scalar_v || ! vector_v ) - { - Unref(v1); return 0; - } - VectorVal* result = 0; + IntrusivePtr result; // It's either an EXPR_AND_AND or an EXPR_OR_OR. bool is_and = (tag == EXPR_AND_AND); if ( scalar_v->IsZero() == is_and ) { - result = new VectorVal(Type()->AsVectorType()); + result = make_intrusive(Type()->AsVectorType()); result->Resize(vector_v->Size()); result->AssignRepeat(0, result->Size(), - scalar_v); + scalar_v.get()); } else - result = vector_v->Ref()->AsVectorVal(); - - Unref(scalar_v); - Unref(vector_v); + result = std::move(vector_v); return result; } // Only case remaining: both are vectors. - Val* v2 = op2->Eval(f); + auto v2 = op2->Eval(f); if ( ! v2 ) - { - Unref(v1); return 0; - } VectorVal* vec_v1 = v1->AsVectorVal(); VectorVal* vec_v2 = v2->AsVectorVal(); if ( vec_v1->Size() != vec_v2->Size() ) { - Unref(v1); - Unref(v2); RuntimeError("vector operands have different sizes"); return 0; } - VectorVal* result = new VectorVal(Type()->AsVectorType()); + auto result = make_intrusive(Type()->AsVectorType()); result->Resize(vec_v1->Size()); for ( unsigned int i = 0; i < vec_v1->Size(); ++i ) @@ -1696,14 +1604,11 @@ Val* BoolExpr::Eval(Frame* f) const result->Assign(i, 0); } - Unref(v1); - Unref(v2); - return result; } -BitExpr::BitExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2) -: BinaryExpr(arg_tag, arg_op1, arg_op2) +BitExpr::BitExpr(BroExprTag arg_tag, IntrusivePtr arg_op1, IntrusivePtr arg_op2) +: BinaryExpr(arg_tag, std::move(arg_op1), std::move(arg_op2)) { if ( IsError() ) return; @@ -1724,10 +1629,10 @@ BitExpr::BitExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2) { if ( bt1 == TYPE_COUNTER && bt2 == TYPE_COUNTER ) ExprError("cannot apply a bitwise operator to two \"counter\" operands"); - else if ( is_vector(op1) || is_vector(op2) ) - SetType(new VectorType(base_type(TYPE_COUNT))); + else if ( is_vector(op1.get()) || is_vector(op2.get()) ) + SetType(make_intrusive(base_type(TYPE_COUNT))); else - SetType(base_type(TYPE_COUNT)); + SetType({AdoptRef{}, base_type(TYPE_COUNT)}); } else if ( bt1 == TYPE_PATTERN ) @@ -1737,13 +1642,13 @@ BitExpr::BitExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2) else if ( tag == EXPR_XOR ) ExprError("'^' operator does not apply to patterns"); else - SetType(base_type(TYPE_PATTERN)); + SetType({AdoptRef{}, base_type(TYPE_PATTERN)}); } else if ( t1->IsSet() && t2->IsSet() ) { if ( same_type(t1, t2) ) - SetType(op1->Type()->Ref()); + SetType({NewRef{}, op1->Type()}); else ExprError("incompatible \"set\" operands"); } @@ -1752,8 +1657,8 @@ BitExpr::BitExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2) ExprError("requires \"count\" or compatible \"set\" operands"); } -EqExpr::EqExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2) -: BinaryExpr(arg_tag, arg_op1, arg_op2) +EqExpr::EqExpr(BroExprTag arg_tag, IntrusivePtr arg_op1, IntrusivePtr arg_op2) +: BinaryExpr(arg_tag, std::move(arg_op1), std::move(arg_op2)) { if ( IsError() ) return; @@ -1771,10 +1676,10 @@ EqExpr::EqExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2) if ( IsVector(bt2) ) bt2 = t2->AsVectorType()->YieldType()->Tag(); - if ( is_vector(op1) || is_vector(op2) ) - SetType(new VectorType(base_type(TYPE_BOOL))); + if ( is_vector(op1.get()) || is_vector(op2.get()) ) + SetType(make_intrusive(base_type(TYPE_BOOL))); else - SetType(base_type(TYPE_BOOL)); + SetType({AdoptRef{}, base_type(TYPE_BOOL)}); if ( BothArithmetic(bt1, bt2) ) PromoteOps(max_type(bt1, bt2)); @@ -1833,28 +1738,28 @@ void EqExpr::Canonicize() else if ( op1->Type()->Tag() == TYPE_PATTERN ) ; - else if ( expr_greater(op2, op1) ) + else if ( expr_greater(op2.get(), op1.get()) ) SwapOps(); } -Val* EqExpr::Fold(Val* v1, Val* v2) const +IntrusivePtr EqExpr::Fold(Val* v1, Val* v2) const { if ( op1->Type()->Tag() == TYPE_PATTERN ) { RE_Matcher* re = v1->AsPattern(); const BroString* s = v2->AsString(); if ( tag == EXPR_EQ ) - return val_mgr->GetBool(re->MatchExactly(s)); + return {AdoptRef{}, val_mgr->GetBool(re->MatchExactly(s))}; else - return val_mgr->GetBool(! re->MatchExactly(s)); + return {AdoptRef{}, val_mgr->GetBool(! re->MatchExactly(s))}; } else return BinaryExpr::Fold(v1, v2); } -RelExpr::RelExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2) -: BinaryExpr(arg_tag, arg_op1, arg_op2) +RelExpr::RelExpr(BroExprTag arg_tag, IntrusivePtr arg_op1, IntrusivePtr arg_op2) +: BinaryExpr(arg_tag, std::move(arg_op1), std::move(arg_op2)) { if ( IsError() ) return; @@ -1872,10 +1777,10 @@ RelExpr::RelExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2) if ( IsVector(bt2) ) bt2 = t2->AsVectorType()->YieldType()->Tag(); - if ( is_vector(op1) || is_vector(op2) ) - SetType(new VectorType(base_type(TYPE_BOOL))); + if ( is_vector(op1.get()) || is_vector(op2.get()) ) + SetType(make_intrusive(base_type(TYPE_BOOL))); else - SetType(base_type(TYPE_BOOL)); + SetType({AdoptRef{}, base_type(TYPE_BOOL)}); if ( BothArithmetic(bt1, bt2) ) PromoteOps(max_type(bt1, bt2)); @@ -1910,13 +1815,9 @@ void RelExpr::Canonicize() } } -CondExpr::CondExpr(Expr* arg_op1, Expr* arg_op2, Expr* arg_op3) -: Expr(EXPR_COND) +CondExpr::CondExpr(IntrusivePtr arg_op1, IntrusivePtr arg_op2, IntrusivePtr arg_op3) + : Expr(EXPR_COND), op1(std::move(arg_op1)), op2(std::move(arg_op2)), op3(std::move(arg_op3)) { - op1 = arg_op1; - op2 = arg_op2; - op3 = arg_op3; - TypeTag bt1 = op1->Type()->Tag(); if ( IsVector(bt1) ) bt1 = op1->Type()->AsVectorType()->YieldType()->Tag(); @@ -1930,14 +1831,14 @@ CondExpr::CondExpr(Expr* arg_op1, Expr* arg_op2, Expr* arg_op3) else { TypeTag bt2 = op2->Type()->Tag(); - if ( is_vector(op2) ) + if ( is_vector(op2.get()) ) bt2 = op2->Type()->AsVectorType()->YieldType()->Tag(); TypeTag bt3 = op3->Type()->Tag(); if ( IsVector(bt3) ) bt3 = op3->Type()->AsVectorType()->YieldType()->Tag(); - if ( is_vector(op1) && ! (is_vector(op2) && is_vector(op3)) ) + if ( is_vector(op1.get()) && ! (is_vector(op2.get()) && is_vector(op3.get())) ) { ExprError("vector conditional requires vector alternatives"); return; @@ -1947,14 +1848,14 @@ CondExpr::CondExpr(Expr* arg_op1, Expr* arg_op2, Expr* arg_op3) { TypeTag t = max_type(bt2, bt3); if ( bt2 != t ) - op2 = new ArithCoerceExpr(op2, t); + op2 = make_intrusive(std::move(op2), t); if ( bt3 != t ) - op3 = new ArithCoerceExpr(op3, t); + op3 = make_intrusive(std::move(op3), t); - if ( is_vector(op2) ) - SetType(new VectorType(base_type(t))); + if ( is_vector(op2.get()) ) + SetType(make_intrusive(base_type(t))); else - SetType(base_type(t)); + SetType({AdoptRef{}, base_type(t)}); } else if ( bt2 != bt3 ) @@ -1966,48 +1867,32 @@ CondExpr::CondExpr(Expr* arg_op1, Expr* arg_op2, Expr* arg_op3) ! same_type(op2->Type(), op3->Type()) ) ExprError("operands must be of the same type"); else - SetType(op2->Type()->Ref()); + SetType({NewRef{}, op2->Type()}); } } } -CondExpr::~CondExpr() +IntrusivePtr CondExpr::Eval(Frame* f) const { - Unref(op1); - Unref(op2); - Unref(op3); - } - -Val* CondExpr::Eval(Frame* f) const - { - if ( ! is_vector(op1) ) + if ( ! is_vector(op1.get()) ) { // scalar is easy - Val* v = op1->Eval(f); - int false_eval = v->IsZero(); - Unref(v); + int false_eval = op1->Eval(f)->IsZero(); return (false_eval ? op3 : op2)->Eval(f); } // Vector case: no mixed scalar/vector cases allowed - Val* v1 = op1->Eval(f); + auto v1 = op1->Eval(f); if ( ! v1 ) return 0; - Val* v2 = op2->Eval(f); + auto v2 = op2->Eval(f); if ( ! v2 ) - { - Unref(v1); return 0; - } - Val* v3 = op3->Eval(f); + auto v3 = op3->Eval(f); if ( ! v3 ) - { - Unref(v1); - Unref(v2); return 0; - } VectorVal* cond = v1->AsVectorVal(); VectorVal* a = v2->AsVectorVal(); @@ -2015,14 +1900,11 @@ Val* CondExpr::Eval(Frame* f) const if ( cond->Size() != a->Size() || a->Size() != b->Size() ) { - Unref(v1); - Unref(v2); - Unref(v3); RuntimeError("vectors in conditional expression have different sizes"); return 0; } - VectorVal* result = new VectorVal(Type()->AsVectorType()); + auto result = make_intrusive(Type()->AsVectorType()); result->Resize(cond->Size()); for ( unsigned int i = 0; i < cond->Size(); ++i ) @@ -2037,10 +1919,6 @@ Val* CondExpr::Eval(Frame* f) const result->Assign(i, 0); } - Unref(v1); - Unref(v2); - Unref(v3); - return result; } @@ -2076,7 +1954,7 @@ void CondExpr::ExprDescribe(ODesc* d) const op3->Describe(d); } -RefExpr::RefExpr(Expr* arg_op) : UnaryExpr(EXPR_REF, arg_op) +RefExpr::RefExpr(IntrusivePtr arg_op) : UnaryExpr(EXPR_REF, std::move(arg_op)) { if ( IsError() ) return; @@ -2084,23 +1962,23 @@ RefExpr::RefExpr(Expr* arg_op) : UnaryExpr(EXPR_REF, arg_op) if ( ! ::is_assignable(op->Type()) ) ExprError("illegal assignment target"); else - SetType(op->Type()->Ref()); + SetType({NewRef{}, op->Type()}); } -Expr* RefExpr::MakeLvalue() +IntrusivePtr RefExpr::MakeLvalue() { - return this; + return {NewRef{}, this}; } -void RefExpr::Assign(Frame* f, Val* v) +void RefExpr::Assign(Frame* f, IntrusivePtr v) { - op->Assign(f, v); + op->Assign(f, std::move(v)); } -AssignExpr::AssignExpr(Expr* arg_op1, Expr* arg_op2, int arg_is_init, - Val* arg_val, attr_list* arg_attrs) +AssignExpr::AssignExpr(IntrusivePtr arg_op1, IntrusivePtr arg_op2, int arg_is_init, + IntrusivePtr arg_val, attr_list* arg_attrs) : BinaryExpr(EXPR_ASSIGN, - arg_is_init ? arg_op1 : arg_op1->MakeLvalue(), arg_op2) + arg_is_init ? std::move(arg_op1) : arg_op1->MakeLvalue(), std::move(arg_op2)) { val = 0; is_init = arg_is_init; @@ -2108,12 +1986,12 @@ AssignExpr::AssignExpr(Expr* arg_op1, Expr* arg_op2, int arg_is_init, if ( IsError() ) return; - SetType(arg_val ? arg_val->Type()->Ref() : op1->Type()->Ref()); + SetType({NewRef{}, arg_val ? arg_val->Type() : op1->Type()}); if ( is_init ) { - SetLocationInfo(arg_op1->GetLocationInfo(), - arg_op2->GetLocationInfo()); + SetLocationInfo(op1->GetLocationInfo(), + op2->GetLocationInfo()); return; } @@ -2121,14 +1999,9 @@ AssignExpr::AssignExpr(Expr* arg_op1, Expr* arg_op2, int arg_is_init, // generated error messages. (void) TypeCheck(arg_attrs); - val = arg_val ? arg_val->Ref() : 0; + val = std::move(arg_val); - SetLocationInfo(arg_op1->GetLocationInfo(), arg_op2->GetLocationInfo()); - } - -AssignExpr::~AssignExpr() - { - Unref(val); + SetLocationInfo(op1->GetLocationInfo(), op2->GetLocationInfo()); } bool AssignExpr::TypeCheck(attr_list* attrs) @@ -2152,14 +2025,14 @@ bool AssignExpr::TypeCheck(attr_list* attrs) if ( bt1 == TYPE_TIME && IsArithmetic(bt2) && op2->IsZero() ) { // Allow assignments to zero as a special case. - op2 = new ArithCoerceExpr(op2, bt1); + op2 = make_intrusive(std::move(op2), bt1); return true; } if ( bt1 == TYPE_TABLE && bt2 == bt1 && op2->Type()->AsTableType()->IsUnspecifiedTable() ) { - op2 = new TableCoerceExpr(op2, op1->Type()->AsTableType()); + op2 = make_intrusive(std::move(op2), IntrusivePtr{NewRef{}, op1->Type()->AsTableType()}); return true; } @@ -2175,9 +2048,9 @@ bool AssignExpr::TypeCheck(attr_list* attrs) bool empty_list_assignment = (op2->AsListExpr()->Exprs().length() == 0); if ( op1->Type()->IsSet() ) - op2 = new SetConstructorExpr(op2->AsListExpr(), attr_copy); + op2 = make_intrusive(IntrusivePtr{NewRef{}, op2->AsListExpr()}, attr_copy); else - op2 = new TableConstructorExpr(op2->AsListExpr(), attr_copy); + op2 = make_intrusive(IntrusivePtr{NewRef{}, op2->AsListExpr()}, attr_copy); if ( ! empty_list_assignment && ! same_type(op1->Type(), op2->Type()) ) { @@ -2196,13 +2069,13 @@ bool AssignExpr::TypeCheck(attr_list* attrs) { if ( bt2 == bt1 && op2->Type()->AsVectorType()->IsUnspecifiedVector() ) { - op2 = new VectorCoerceExpr(op2, op1->Type()->AsVectorType()); + op2 = make_intrusive(std::move(op2), IntrusivePtr{NewRef{}, op1->Type()->AsVectorType()}); return true; } if ( op2->Tag() == EXPR_LIST ) { - op2 = new VectorConstructorExpr(op2->AsListExpr(), op1->Type()); + op2 = make_intrusive(IntrusivePtr{AdoptRef{}, op2.release()->AsListExpr()}, IntrusivePtr{NewRef{}, op1->Type()}); return true; } } @@ -2228,7 +2101,7 @@ bool AssignExpr::TypeCheck(attr_list* attrs) } // Need to coerce. - op2 = new RecordCoerceExpr(op2, op1->Type()->AsRecordType()); + op2 = make_intrusive(std::move(op2), IntrusivePtr{NewRef{}, op1->Type()->AsRecordType()}); return true; } @@ -2241,7 +2114,7 @@ bool AssignExpr::TypeCheck(attr_list* attrs) // Some elements in constructor list must not match, see if // we can create a new constructor now that the expected type // of LHS is known and let it do coercions where possible. - SetConstructorExpr* sce = dynamic_cast(op2); + SetConstructorExpr* sce = dynamic_cast(op2.get()); if ( ! sce ) { ExprError("Failed typecast to SetConstructorExpr"); @@ -2265,7 +2138,7 @@ bool AssignExpr::TypeCheck(attr_list* attrs) } int errors_before = reporter->Errors(); - op2 = new SetConstructorExpr(ctor_list, attr_copy, op1->Type()); + op2 = make_intrusive(IntrusivePtr{NewRef{}, ctor_list}, attr_copy, IntrusivePtr{NewRef{}, op1->Type()}); int errors_after = reporter->Errors(); if ( errors_after > errors_before ) @@ -2306,7 +2179,7 @@ bool AssignExpr::TypeCheckArithmetics(TypeTag bt1, TypeTag bt2) if ( bt2 == TYPE_DOUBLE ) { Warn("dangerous assignment of double to integral"); - op2 = new ArithCoerceExpr(op2, bt1); + op2 = make_intrusive(std::move(op2), bt1); bt2 = op2->Type()->Tag(); } @@ -2317,7 +2190,7 @@ bool AssignExpr::TypeCheckArithmetics(TypeTag bt1, TypeTag bt2) if ( bt2 == TYPE_INT ) { Warn("dangerous assignment of integer to count"); - op2 = new ArithCoerceExpr(op2, bt1); + op2 = make_intrusive(std::move(op2), bt1); bt2 = op2->Type()->Tag(); } @@ -2330,7 +2203,7 @@ bool AssignExpr::TypeCheckArithmetics(TypeTag bt1, TypeTag bt2) } -Val* AssignExpr::Eval(Frame* f) const +IntrusivePtr AssignExpr::Eval(Frame* f) const { if ( is_init ) { @@ -2338,17 +2211,14 @@ Val* AssignExpr::Eval(Frame* f) const return 0; } - Val* v = op2->Eval(f); + auto v = op2->Eval(f); if ( v ) { - op1->Assign(f, v->Ref()); + op1->Assign(f, v); if ( val ) - { - Unref(v); - return val->Ref(); - } + return val; return v; } @@ -2356,7 +2226,7 @@ Val* AssignExpr::Eval(Frame* f) const return 0; } -BroType* AssignExpr::InitType() const +IntrusivePtr AssignExpr::InitType() const { if ( op1->Tag() != EXPR_LIST ) { @@ -2368,7 +2238,7 @@ BroType* AssignExpr::InitType() const if ( tl->Tag() != TYPE_LIST ) Internal("inconsistent list expr in AssignExpr::InitType"); - return new TableType(tl->Ref()->AsTypeList(), op2->Type()->Ref()); + return make_intrusive(tl->Ref()->AsTypeList(), op2->Type()->Ref()); } void AssignExpr::EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f) const @@ -2396,9 +2266,9 @@ void AssignExpr::EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f) const RecordVal* aggr_r = aggr->AsRecordVal(); - Val* v = op2->Eval(f); + auto v = op2->Eval(f); if ( v ) - aggr_r->Assign(field, v); + aggr_r->Assign(field, v.release()); return; } @@ -2408,22 +2278,16 @@ void AssignExpr::EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f) const TableVal* tv = aggr->AsTableVal(); - Val* index = op1->Eval(f); - Val* v = check_and_promote(op2->Eval(f), t->YieldType(), 1); + auto index = op1->Eval(f); + IntrusivePtr v{AdoptRef{}, check_and_promote(op2->Eval(f).release(), t->YieldType(), 1)}; if ( ! index || ! v ) - { - Unref(index); - Unref(v); return; - } - if ( ! tv->Assign(index, v) ) + if ( ! tv->Assign(index.get(), v.release()) ) RuntimeError("type clash in table assignment"); - - Unref(index); } -Val* AssignExpr::InitVal(const BroType* t, Val* aggr) const +IntrusivePtr AssignExpr::InitVal(const BroType* t, IntrusivePtr aggr) const { if ( ! aggr ) { @@ -2455,7 +2319,7 @@ Val* AssignExpr::InitVal(const BroType* t, Val* aggr) const Internal("bad aggregate in AssignExpr::InitVal"); RecordVal* aggr_r = aggr->AsRecordVal(); - Val* v = op2->InitVal(rt->FieldType(td.id), 0); + auto v = op2->InitVal(rt->FieldType(td.id), 0); if ( ! v ) return 0; @@ -2474,20 +2338,17 @@ Val* AssignExpr::InitVal(const BroType* t, Val* aggr) const if ( aggr->Type()->Tag() != TYPE_TABLE ) Internal("bad aggregate in AssignExpr::InitVal"); - TableVal* tv = aggr->AsTableVal(); + IntrusivePtr tv{NewRef{}, aggr->AsTableVal()}; // TODO: implement safer IntrusivePtr casts const TableType* tt = tv->Type()->AsTableType(); const BroType* yt = tv->Type()->YieldType(); - IntrusivePtr index{AdoptRef{}, op1->InitVal(tt->Indices(), 0)}; - IntrusivePtr v{AdoptRef{}, op2->InitVal(yt, 0)}; + auto index = op1->InitVal(tt->Indices(), 0); + auto v = op2->InitVal(yt, 0); if ( ! index || ! v ) return 0; if ( ! tv->ExpandAndInit(std::move(index), std::move(v)) ) - { - Unref(tv); return 0; - } return tv; } @@ -2505,7 +2366,7 @@ int AssignExpr::IsRecordElement(TypeDecl* td) const { if ( td ) { - const NameExpr* n = (const NameExpr*) op1; + const NameExpr* n = (const NameExpr*) op1.get(); td->type = op2->Type()->Ref(); td->id = copy_string(n->Id()->Name()); } @@ -2521,12 +2382,12 @@ int AssignExpr::IsPure() const return 0; } -IndexSliceAssignExpr::IndexSliceAssignExpr(Expr* op1, Expr* op2, int is_init) - : AssignExpr(op1, op2, is_init) +IndexSliceAssignExpr::IndexSliceAssignExpr(IntrusivePtr op1, IntrusivePtr op2, int is_init) + : AssignExpr(std::move(op1), std::move(op2), is_init) { } -Val* IndexSliceAssignExpr::Eval(Frame* f) const +IntrusivePtr IndexSliceAssignExpr::Eval(Frame* f) const { if ( is_init ) { @@ -2534,16 +2395,16 @@ Val* IndexSliceAssignExpr::Eval(Frame* f) const return 0; } - Val* v = op2->Eval(f); + auto v = op2->Eval(f); if ( v ) - op1->Assign(f, v); + op1->Assign(f, std::move(v)); return 0; } -IndexExpr::IndexExpr(Expr* arg_op1, ListExpr* arg_op2, bool arg_is_slice) -: BinaryExpr(EXPR_INDEX, arg_op1, arg_op2), is_slice(arg_is_slice) +IndexExpr::IndexExpr(IntrusivePtr arg_op1, IntrusivePtr arg_op2, bool arg_is_slice) +: BinaryExpr(EXPR_INDEX, std::move(arg_op1), std::move(arg_op2)), is_slice(arg_is_slice) { if ( IsError() ) return; @@ -2556,14 +2417,14 @@ IndexExpr::IndexExpr(Expr* arg_op1, ListExpr* arg_op2, bool arg_is_slice) else if ( IsString(op1->Type()->Tag()) ) { - if ( arg_op2->Exprs().length() != 1 ) + if ( op2->AsListExpr()->Exprs().length() != 1 ) ExprError("invalid string index expression"); } if ( IsError() ) return; - int match_type = op1->Type()->MatchesIndex(arg_op2); + int match_type = op1->Type()->MatchesIndex(op2->AsListExpr()); if ( match_type == DOES_NOT_MATCH_INDEX ) { std::string error_msg = @@ -2575,20 +2436,20 @@ IndexExpr::IndexExpr(Expr* arg_op1, ListExpr* arg_op2, bool arg_is_slice) else if ( ! op1->Type()->YieldType() ) { if ( IsString(op1->Type()->Tag()) && match_type == MATCHES_INDEX_SCALAR ) - SetType(base_type(TYPE_STRING)); + SetType({AdoptRef{}, base_type(TYPE_STRING)}); else // It's a set - so indexing it yields void. We don't // directly generate an error message, though, since this // expression might be part of an add/delete statement, // rather than yielding a value. - SetType(base_type(TYPE_VOID)); + SetType({AdoptRef{}, base_type(TYPE_VOID)}); } else if ( match_type == MATCHES_INDEX_SCALAR ) - SetType(op1->Type()->YieldType()->Ref()); + SetType({NewRef{}, op1->Type()->YieldType()}); else if ( match_type == MATCHES_INDEX_VECTOR ) - SetType(new VectorType(op1->Type()->YieldType()->Ref())); + SetType(make_intrusive(op1->Type()->YieldType()->Ref())); else ExprError("Unknown MatchesIndex() return value"); @@ -2617,21 +2478,15 @@ void IndexExpr::Add(Frame* f) if ( IsError() ) return; - Val* v1 = op1->Eval(f); + auto v1 = op1->Eval(f); if ( ! v1 ) return; - Val* v2 = op2->Eval(f); + auto v2 = op2->Eval(f); if ( ! v2 ) - { - Unref(v1); return; - } - v1->AsTableVal()->Assign(v2, 0); - - Unref(v1); - Unref(v2); + v1->AsTableVal()->Assign(v2.get(), 0); } void IndexExpr::Delete(Frame* f) @@ -2639,53 +2494,41 @@ void IndexExpr::Delete(Frame* f) if ( IsError() ) return; - Val* v1 = op1->Eval(f); + auto v1 = op1->Eval(f); if ( ! v1 ) return; - Val* v2 = op2->Eval(f); + auto v2 = op2->Eval(f); if ( ! v2 ) - { - Unref(v1); return; - } - Unref(v1->AsTableVal()->Delete(v2)); - - Unref(v1); - Unref(v2); + Unref(v1->AsTableVal()->Delete(v2.get())); } -Expr* IndexExpr::MakeLvalue() +IntrusivePtr IndexExpr::MakeLvalue() { if ( IsString(op1->Type()->Tag()) ) ExprError("cannot assign to string index expression"); - return new RefExpr(this); + return make_intrusive(IntrusivePtr{NewRef{}, this}); } -Val* IndexExpr::Eval(Frame* f) const +IntrusivePtr IndexExpr::Eval(Frame* f) const { - Val* v1 = op1->Eval(f); + auto v1 = op1->Eval(f); if ( ! v1 ) return 0; - Val* v2 = op2->Eval(f); + auto v2 = op2->Eval(f); if ( ! v2 ) - { - Unref(v1); return 0; - } - - Val* result; Val* indv = v2->AsListVal()->Index(0); if ( is_vector(indv) ) { VectorVal* v_v1 = v1->AsVectorVal(); VectorVal* v_v2 = indv->AsVectorVal(); - VectorVal* v_result = new VectorVal(Type()->AsVectorType()); - result = v_result; + auto v_result = make_intrusive(Type()->AsVectorType()); // Booleans select each element (or not). if ( IsBool(v_v2->Type()->YieldType()->Tag()) ) @@ -2693,7 +2536,6 @@ Val* IndexExpr::Eval(Frame* f) const if ( v_v1->Size() != v_v2->Size() ) { RuntimeError("size mismatch, boolean index and vector"); - Unref(v_result); return 0; } @@ -2718,13 +2560,11 @@ Val* IndexExpr::Eval(Frame* f) const v_result->Assign(i, a ? a->Ref() : nullptr); } } + + return v_result; } else - result = Fold(v1, v2); - - Unref(v1); - Unref(v2); - return result; + return Fold(v1.get(), v2.get()); } static int get_slice_index(int idx, int len) @@ -2737,12 +2577,12 @@ static int get_slice_index(int idx, int len) return idx; } -Val* IndexExpr::Fold(Val* v1, Val* v2) const +IntrusivePtr IndexExpr::Fold(Val* v1, Val* v2) const { if ( IsError() ) return 0; - Val* v = 0; + IntrusivePtr v; switch ( v1->Type()->Tag() ) { case TYPE_VECTOR: @@ -2751,11 +2591,11 @@ Val* IndexExpr::Fold(Val* v1, Val* v2) const const ListVal* lv = v2->AsListVal(); if ( lv->Length() == 1 ) - v = vect->Lookup(v2); + v = {NewRef{}, vect->Lookup(v2)}; else { int len = vect->Size(); - VectorVal* result = new VectorVal(vect->Type()->AsVectorType()); + auto result = make_intrusive(vect->Type()->AsVectorType()); bro_int_t first = get_slice_index(lv->Index(0)->CoerceToInt(), len); bro_int_t last = get_slice_index(lv->Index(1)->CoerceToInt(), len); @@ -2778,7 +2618,7 @@ Val* IndexExpr::Fold(Val* v1, Val* v2) const break; case TYPE_TABLE: - v = v1->AsTableVal()->Lookup(v2); // Then, we jump into the TableVal here. + v = {NewRef{}, v1->AsTableVal()->Lookup(v2)}; // Then, we jump into the TableVal here. break; case TYPE_STRING: @@ -2810,7 +2650,7 @@ Val* IndexExpr::Fold(Val* v1, Val* v2) const substring = s->GetSubstring(first, substring_len); } - return new StringVal(substring ? substring : new BroString("")); + return make_intrusive(substring ? substring : new BroString("")); } default: @@ -2818,37 +2658,31 @@ Val* IndexExpr::Fold(Val* v1, Val* v2) const break; } - if ( v ) - return v->Ref(); + if (v) + return v; RuntimeError("no such index"); return 0; } -void IndexExpr::Assign(Frame* f, Val* arg_v) +void IndexExpr::Assign(Frame* f, IntrusivePtr v) { - IntrusivePtr v{AdoptRef{}, arg_v}; - if ( IsError() ) return; - Val* v1 = op1->Eval(f); + auto v1 = op1->Eval(f); if ( ! v1 ) return; - Val* v2 = op2->Eval(f); + auto v2 = op2->Eval(f); if ( ! v1 || ! v2 ) - { - Unref(v1); - Unref(v2); return; - } // Hold an extra reference to 'arg_v' in case the ownership transfer to // the table/vector goes wrong and we still want to obtain diagnostic info // from the original value after the assignment already unref'd. - IntrusivePtr v_extra{NewRef{}, arg_v}; + const auto v_extra = v; switch ( v1->Type()->Tag() ) { case TYPE_VECTOR: @@ -2872,9 +2706,9 @@ void IndexExpr::Assign(Frame* f, Val* arg_v) for ( auto idx = 0u; idx < v_vect->Size(); idx++, first++ ) v1_vect->Insert(first, v_vect->Lookup(idx)->Ref()); } - else if ( ! v1_vect->Assign(v2, v.release()) ) + else if ( ! v1_vect->Assign(v2.get(), v.release()) ) { - v = v_extra; + v = std::move(v_extra); if ( v ) { @@ -2894,9 +2728,9 @@ void IndexExpr::Assign(Frame* f, Val* arg_v) } case TYPE_TABLE: - if ( ! v1->AsTableVal()->Assign(v2, v.release()) ) + if ( ! v1->AsTableVal()->Assign(v2.get(), v.release()) ) { - v = v_extra; + v = std::move(v_extra); if ( v ) { @@ -2922,9 +2756,6 @@ void IndexExpr::Assign(Frame* f, Val* arg_v) RuntimeErrorWithCallStack("bad index expression type in assignment"); break; } - - Unref(v1); - Unref(v2); } void IndexExpr::ExprDescribe(ODesc* d) const @@ -2953,8 +2784,8 @@ TraversalCode IndexExpr::Traverse(TraversalCallback* cb) const HANDLE_TC_EXPR_POST(tc); } -FieldExpr::FieldExpr(Expr* arg_op, const char* arg_field_name) -: UnaryExpr(EXPR_FIELD, arg_op) +FieldExpr::FieldExpr(IntrusivePtr arg_op, const char* arg_field_name) +: UnaryExpr(EXPR_FIELD, std::move(arg_op)) { field_name = copy_string(arg_field_name); td = 0; @@ -2974,7 +2805,7 @@ FieldExpr::FieldExpr(Expr* arg_op, const char* arg_field_name) ExprError("no such field in record"); else { - SetType(rt->FieldType(field)->Ref()); + SetType({NewRef{}, rt->FieldType(field)}); td = rt->FieldDecl(field); if ( rt->IsFieldDeprecated(field) ) @@ -2988,9 +2819,9 @@ FieldExpr::~FieldExpr() delete [] field_name; } -Expr* FieldExpr::MakeLvalue() +IntrusivePtr FieldExpr::MakeLvalue() { - return new RefExpr(this); + return make_intrusive(IntrusivePtr{NewRef{}, this}); } int FieldExpr::CanDel() const @@ -2998,23 +2829,17 @@ int FieldExpr::CanDel() const return td->FindAttr(ATTR_DEFAULT) || td->FindAttr(ATTR_OPTIONAL); } -void FieldExpr::Assign(Frame* f, Val* v) +void FieldExpr::Assign(Frame* f, IntrusivePtr v) { if ( IsError() ) - { - Unref(v); return; - } - Val* op_v = op->Eval(f); + auto op_v = op->Eval(f); if ( op_v ) { RecordVal* r = op_v->AsRecordVal(); - r->Assign(field, v); - Unref(r); + r->Assign(field, v.release()); } - else - Unref(v); } void FieldExpr::Delete(Frame* f) @@ -3022,11 +2847,11 @@ void FieldExpr::Delete(Frame* f) Assign(f, 0); } -Val* FieldExpr::Fold(Val* v) const +IntrusivePtr FieldExpr::Fold(Val* v) const { Val* result = v->AsRecordVal()->Lookup(field); if ( result ) - return result->Ref(); + return {NewRef{}, result}; // Check for &default. const Attr* def_attr = td ? td->FindAttr(ATTR_DEFAULT) : 0; @@ -3054,8 +2879,8 @@ void FieldExpr::ExprDescribe(ODesc* d) const d->Add(field); } -HasFieldExpr::HasFieldExpr(Expr* arg_op, const char* arg_field_name) -: UnaryExpr(EXPR_HAS_FIELD, arg_op) +HasFieldExpr::HasFieldExpr(IntrusivePtr arg_op, const char* arg_field_name) +: UnaryExpr(EXPR_HAS_FIELD, std::move(arg_op)) { field_name = arg_field_name; field = 0; @@ -3075,7 +2900,7 @@ HasFieldExpr::HasFieldExpr(Expr* arg_op, const char* arg_field_name) else if ( rt->IsFieldDeprecated(field) ) reporter->Warning("%s", rt->GetFieldDeprecationWarning(field, true).c_str()); - SetType(base_type(TYPE_BOOL)); + SetType({AdoptRef{}, base_type(TYPE_BOOL)}); } } @@ -3084,20 +2909,17 @@ HasFieldExpr::~HasFieldExpr() delete field_name; } -Val* HasFieldExpr::Fold(Val* v) const +IntrusivePtr HasFieldExpr::Fold(Val* v) const { RecordVal* rec_to_look_at; rec_to_look_at = v->AsRecordVal(); if ( ! rec_to_look_at ) - return val_mgr->GetBool(0); + return {AdoptRef{}, val_mgr->GetBool(0)}; - RecordVal* r = rec_to_look_at->Ref()->AsRecordVal(); - Val* ret = val_mgr->GetBool(r->Lookup(field) != 0); - Unref(r); - - return ret; + IntrusivePtr r{NewRef{}, rec_to_look_at->AsRecordVal()}; + return {AdoptRef{}, val_mgr->GetBool(r->Lookup(field) != 0)}; } void HasFieldExpr::ExprDescribe(ODesc* d) const @@ -3115,8 +2937,8 @@ void HasFieldExpr::ExprDescribe(ODesc* d) const d->Add(field); } -RecordConstructorExpr::RecordConstructorExpr(ListExpr* constructor_list) -: UnaryExpr(EXPR_RECORD_CONSTRUCTOR, constructor_list) +RecordConstructorExpr::RecordConstructorExpr(IntrusivePtr constructor_list) +: UnaryExpr(EXPR_RECORD_CONSTRUCTOR, std::move(constructor_list)) { if ( IsError() ) return; @@ -3124,7 +2946,7 @@ RecordConstructorExpr::RecordConstructorExpr(ListExpr* constructor_list) // Spin through the list, which should be comprised only of // record-field-assign expressions, and build up a // record type to associate with this constructor. - const expr_list& exprs = constructor_list->Exprs(); + const expr_list& exprs = op->AsListExpr()->Exprs(); type_decl_list* record_types = new type_decl_list(exprs.length()); for ( const auto& e : exprs ) @@ -3142,22 +2964,21 @@ RecordConstructorExpr::RecordConstructorExpr(ListExpr* constructor_list) record_types->push_back(new TypeDecl(field_type, field_name)); } - SetType(new RecordType(record_types)); + SetType(make_intrusive(record_types)); } RecordConstructorExpr::~RecordConstructorExpr() { } -Val* RecordConstructorExpr::InitVal(const BroType* t, Val* aggr) const +IntrusivePtr RecordConstructorExpr::InitVal(const BroType* t, IntrusivePtr aggr) const { - Val* v = Eval(0); + auto v = Eval(0); if ( v ) { RecordVal* rv = v->AsRecordVal(); - RecordVal* ar = rv->CoerceTo(t->AsRecordType(), aggr); - Unref(rv); + IntrusivePtr ar = {AdoptRef{}, rv->CoerceTo(t->AsRecordType(), aggr.get())}; if ( ar ) return ar; @@ -3167,7 +2988,7 @@ Val* RecordConstructorExpr::InitVal(const BroType* t, Val* aggr) const return 0; } -Val* RecordConstructorExpr::Fold(Val* v) const +IntrusivePtr RecordConstructorExpr::Fold(Val* v) const { ListVal* lv = v->AsListVal(); RecordType* rt = type->AsRecordType(); @@ -3175,7 +2996,7 @@ Val* RecordConstructorExpr::Fold(Val* v) const if ( lv->Length() != rt->NumFields() ) RuntimeErrorWithCallStack("inconsistency evaluating record constructor"); - RecordVal* rv = new RecordVal(rt); + auto rv = make_intrusive(rt); for ( int i = 0; i < lv->Length(); ++i ) rv->Assign(i, lv->Index(i)->Ref()); @@ -3190,9 +3011,9 @@ void RecordConstructorExpr::ExprDescribe(ODesc* d) const d->Add("]"); } -TableConstructorExpr::TableConstructorExpr(ListExpr* constructor_list, - attr_list* arg_attrs, BroType* arg_type) -: UnaryExpr(EXPR_TABLE_CONSTRUCTOR, constructor_list) +TableConstructorExpr::TableConstructorExpr(IntrusivePtr constructor_list, + attr_list* arg_attrs, IntrusivePtr arg_type) +: UnaryExpr(EXPR_TABLE_CONSTRUCTOR, std::move(constructor_list)) { attrs = 0; @@ -3203,20 +3024,20 @@ TableConstructorExpr::TableConstructorExpr(ListExpr* constructor_list, { if ( ! arg_type->IsTable() ) { - Error("bad table constructor type", arg_type); + Error("bad table constructor type", arg_type.get()); SetError(); return; } - SetType(arg_type->Ref()); + SetType(std::move(arg_type)); } else { - if ( constructor_list->Exprs().length() == 0 ) - SetType(new TableType(new TypeList(base_type(TYPE_ANY)), 0)); + if ( op->AsListExpr()->Exprs().length() == 0 ) + SetType(make_intrusive(new TypeList(base_type(TYPE_ANY)), nullptr)); else { - SetType(init_type(constructor_list)); + SetType({AdoptRef{}, init_type(op.get())}); if ( ! type ) SetError(); @@ -3227,10 +3048,10 @@ TableConstructorExpr::TableConstructorExpr(ListExpr* constructor_list, } } - attrs = arg_attrs ? new Attributes(arg_attrs, type, false, false) : 0; + attrs = arg_attrs ? new Attributes(arg_attrs, type.get(), false, false) : 0; type_list* indices = type->AsTableType()->Indices()->Types(); - const expr_list& cle = constructor_list->Exprs(); + const expr_list& cle = op->AsListExpr()->Exprs(); // check and promote all index expressions in ctor list for ( const auto& expr : cle ) @@ -3264,33 +3085,33 @@ TableConstructorExpr::TableConstructorExpr(ListExpr* constructor_list, } } -Val* TableConstructorExpr::Eval(Frame* f) const +IntrusivePtr TableConstructorExpr::Eval(Frame* f) const { if ( IsError() ) return 0; - Val* aggr = new TableVal(Type()->AsTableType(), attrs); + auto aggr = make_intrusive(Type()->AsTableType(), attrs); const expr_list& exprs = op->AsListExpr()->Exprs(); for ( const auto& expr : exprs ) - expr->EvalIntoAggregate(type, aggr, f); + expr->EvalIntoAggregate(type.get(), aggr.get(), f); - aggr->AsTableVal()->InitDefaultFunc(f); + aggr->InitDefaultFunc(f); return aggr; } -Val* TableConstructorExpr::InitVal(const BroType* t, Val* aggr) const +IntrusivePtr TableConstructorExpr::InitVal(const BroType* t, IntrusivePtr aggr) const { if ( IsError() ) return 0; TableType* tt = Type()->AsTableType(); - TableVal* tval = aggr ? aggr->AsTableVal() : new TableVal(tt, attrs); + auto tval = aggr ? IntrusivePtr{AdoptRef{}, aggr.release()->AsTableVal()} : make_intrusive(tt, attrs); const expr_list& exprs = op->AsListExpr()->Exprs(); for ( const auto& expr : exprs ) - expr->EvalIntoAggregate(t, tval, 0); + expr->EvalIntoAggregate(t, tval.get(), 0); return tval; } @@ -3302,9 +3123,9 @@ void TableConstructorExpr::ExprDescribe(ODesc* d) const d->Add(")"); } -SetConstructorExpr::SetConstructorExpr(ListExpr* constructor_list, - attr_list* arg_attrs, BroType* arg_type) -: UnaryExpr(EXPR_SET_CONSTRUCTOR, constructor_list) +SetConstructorExpr::SetConstructorExpr(IntrusivePtr constructor_list, + attr_list* arg_attrs, IntrusivePtr arg_type) +: UnaryExpr(EXPR_SET_CONSTRUCTOR, std::move(constructor_list)) { attrs = 0; @@ -3315,19 +3136,19 @@ SetConstructorExpr::SetConstructorExpr(ListExpr* constructor_list, { if ( ! arg_type->IsSet() ) { - Error("bad set constructor type", arg_type); + Error("bad set constructor type", arg_type.get()); SetError(); return; } - SetType(arg_type->Ref()); + SetType(std::move(arg_type)); } else { - if ( constructor_list->Exprs().length() == 0 ) - SetType(new ::SetType(new TypeList(base_type(TYPE_ANY)), 0)); + if ( op->AsListExpr()->Exprs().length() == 0 ) + SetType(make_intrusive<::SetType>(new TypeList(base_type(TYPE_ANY)), nullptr)); else - SetType(init_type(constructor_list)); + SetType({AdoptRef{}, init_type(op.get())}); } if ( ! type ) @@ -3336,14 +3157,14 @@ SetConstructorExpr::SetConstructorExpr(ListExpr* constructor_list, else if ( type->Tag() != TYPE_TABLE || ! type->AsTableType()->IsSet() ) SetError("values in set(...) constructor do not specify a set"); - attrs = arg_attrs ? new Attributes(arg_attrs, type, false, false) : 0; + attrs = arg_attrs ? new Attributes(arg_attrs, type.get(), false, false) : 0; type_list* indices = type->AsTableType()->Indices()->Types(); - expr_list& cle = constructor_list->Exprs(); + expr_list& cle = op->AsListExpr()->Exprs(); if ( indices->length() == 1 ) { - if ( ! check_and_promote_exprs_to_type(constructor_list, + if ( ! check_and_promote_exprs_to_type(op->AsListExpr(), (*indices)[0]) ) ExprError("inconsistent type in set constructor"); } @@ -3370,45 +3191,42 @@ SetConstructorExpr::SetConstructorExpr(ListExpr* constructor_list, } } -Val* SetConstructorExpr::Eval(Frame* f) const +IntrusivePtr SetConstructorExpr::Eval(Frame* f) const { if ( IsError() ) return 0; - TableVal* aggr = new TableVal(type->AsTableType(), attrs); + auto aggr = make_intrusive(type->AsTableType(), attrs); const expr_list& exprs = op->AsListExpr()->Exprs(); for ( const auto& expr : exprs ) { - Val* element = expr->Eval(f); - aggr->Assign(element, 0); - Unref(element); + auto element = expr->Eval(f); + aggr->Assign(element.get(), 0); } return aggr; } -Val* SetConstructorExpr::InitVal(const BroType* t, Val* aggr) const +IntrusivePtr SetConstructorExpr::InitVal(const BroType* t, IntrusivePtr aggr) const { if ( IsError() ) return 0; const BroType* index_type = t->AsTableType()->Indices(); TableType* tt = Type()->AsTableType(); - TableVal* tval = aggr ? aggr->AsTableVal() : new TableVal(tt, attrs); + auto tval = aggr ? IntrusivePtr{AdoptRef{}, aggr.release()->AsTableVal()} : make_intrusive(tt, attrs); const expr_list& exprs = op->AsListExpr()->Exprs(); for ( const auto& e : exprs ) { - Val* element = check_and_promote(e->Eval(0), index_type, 1); + IntrusivePtr element = {AdoptRef{}, check_and_promote(e->Eval(0).release(), index_type, 1)}; - if ( ! element || ! tval->Assign(element, 0) ) + if ( ! element || ! tval->Assign(element.get(), 0) ) { Error(fmt("initialization type mismatch in set"), e); return 0; } - - Unref(element); } return tval; @@ -3421,9 +3239,9 @@ void SetConstructorExpr::ExprDescribe(ODesc* d) const d->Add(")"); } -VectorConstructorExpr::VectorConstructorExpr(ListExpr* constructor_list, - BroType* arg_type) -: UnaryExpr(EXPR_VECTOR_CONSTRUCTOR, constructor_list) +VectorConstructorExpr::VectorConstructorExpr(IntrusivePtr constructor_list, + IntrusivePtr arg_type) +: UnaryExpr(EXPR_VECTOR_CONSTRUCTOR, std::move(constructor_list)) { if ( IsError() ) return; @@ -3432,29 +3250,29 @@ VectorConstructorExpr::VectorConstructorExpr(ListExpr* constructor_list, { if ( arg_type->Tag() != TYPE_VECTOR ) { - Error("bad vector constructor type", arg_type); + Error("bad vector constructor type", arg_type.get()); SetError(); return; } - SetType(arg_type->Ref()); + SetType(std::move(arg_type)); } else { - if ( constructor_list->Exprs().length() == 0 ) + if ( op->AsListExpr()->Exprs().length() == 0 ) { // vector(). // By default, assign VOID type here. A vector with // void type set is seen as an unspecified vector. - SetType(new ::VectorType(base_type(TYPE_VOID))); + SetType(make_intrusive<::VectorType>(base_type(TYPE_VOID))); return; } - BroType* t = merge_type_list(constructor_list); + BroType* t = merge_type_list(op->AsListExpr()); if ( t ) { - SetType(new VectorType(t->Ref())); + SetType(make_intrusive(t->Ref())); Unref(t); } else @@ -3464,24 +3282,24 @@ VectorConstructorExpr::VectorConstructorExpr(ListExpr* constructor_list, } } - if ( ! check_and_promote_exprs_to_type(constructor_list, + if ( ! check_and_promote_exprs_to_type(op->AsListExpr(), type->AsVectorType()->YieldType()) ) ExprError("inconsistent types in vector constructor"); } -Val* VectorConstructorExpr::Eval(Frame* f) const +IntrusivePtr VectorConstructorExpr::Eval(Frame* f) const { if ( IsError() ) return 0; - VectorVal* vec = new VectorVal(Type()->AsVectorType()); + auto vec = make_intrusive(Type()->AsVectorType()); const expr_list& exprs = op->AsListExpr()->Exprs(); loop_over_list(exprs, i) { Expr* e = exprs[i]; - Val* v = e->Eval(f); - if ( ! vec->Assign(i, v) ) + auto v = e->Eval(f); + if ( ! vec->Assign(i, v.release()) ) { RuntimeError(fmt("type mismatch at index %d", i)); return 0; @@ -3491,25 +3309,23 @@ Val* VectorConstructorExpr::Eval(Frame* f) const return vec; } -Val* VectorConstructorExpr::InitVal(const BroType* t, Val* aggr) const +IntrusivePtr VectorConstructorExpr::InitVal(const BroType* t, IntrusivePtr aggr) const { if ( IsError() ) return 0; VectorType* vt = Type()->AsVectorType(); - VectorVal* vec = aggr ? aggr->AsVectorVal() : new VectorVal(vt); + auto vec = aggr ? IntrusivePtr{AdoptRef{}, aggr.release()->AsVectorVal()} : make_intrusive(vt); const expr_list& exprs = op->AsListExpr()->Exprs(); loop_over_list(exprs, i) { Expr* e = exprs[i]; - Val* v = check_and_promote(e->Eval(0), t->YieldType(), 1); + IntrusivePtr v{AdoptRef{}, check_and_promote(e->Eval(0).release(), t->YieldType(), 1)}; - if ( ! v || ! vec->Assign(i, v) ) + if ( ! v || ! vec->Assign(i, v.release()) ) { Error(fmt("initialization type mismatch at index %d", i), e); - if ( ! aggr ) - Unref(vec); return 0; } } @@ -3524,11 +3340,10 @@ void VectorConstructorExpr::ExprDescribe(ODesc* d) const d->Add(")"); } -FieldAssignExpr::FieldAssignExpr(const char* arg_field_name, Expr* value) -: UnaryExpr(EXPR_FIELD_ASSIGN, value), field_name(arg_field_name) +FieldAssignExpr::FieldAssignExpr(const char* arg_field_name, IntrusivePtr value) +: UnaryExpr(EXPR_FIELD_ASSIGN, std::move(value)), field_name(arg_field_name) { - op->Ref(); - SetType(value->Type()->Ref()); + SetType({NewRef{}, op->Type()}); } void FieldAssignExpr::EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f) @@ -3539,7 +3354,7 @@ void FieldAssignExpr::EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f) RecordVal* rec = aggr->AsRecordVal(); const RecordType* rt = t->AsRecordType(); - Val* v = op->Eval(f); + auto v = op->Eval(f); if ( v ) { @@ -3549,7 +3364,7 @@ void FieldAssignExpr::EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f) reporter->InternalError("Missing record field: %s", field_name.c_str()); - rec->Assign(idx, v); + rec->Assign(idx, v.release()); } } @@ -3572,8 +3387,8 @@ void FieldAssignExpr::ExprDescribe(ODesc* d) const op->Describe(d); } -ArithCoerceExpr::ArithCoerceExpr(Expr* arg_op, TypeTag t) -: UnaryExpr(EXPR_ARITH_COERCE, arg_op) +ArithCoerceExpr::ArithCoerceExpr(IntrusivePtr arg_op, TypeTag t) +: UnaryExpr(EXPR_ARITH_COERCE, std::move(arg_op)) { if ( IsError() ) return; @@ -3583,11 +3398,11 @@ ArithCoerceExpr::ArithCoerceExpr(Expr* arg_op, TypeTag t) if ( IsVector(bt) ) { - SetType(new VectorType(base_type(t))); + SetType(make_intrusive(base_type(t))); vbt = op->Type()->AsVectorType()->YieldType()->Tag(); } else - SetType(base_type(t)); + SetType({AdoptRef{}, base_type(t)}); if ( (bt == TYPE_ENUM) != (t == TYPE_ENUM) ) ExprError("can't convert to/from enumerated type"); @@ -3601,17 +3416,17 @@ ArithCoerceExpr::ArithCoerceExpr(Expr* arg_op, TypeTag t) ExprError("bad coercion value"); } -Val* ArithCoerceExpr::FoldSingleVal(Val* v, InternalTypeTag t) const +IntrusivePtr ArithCoerceExpr::FoldSingleVal(Val* v, InternalTypeTag t) const { switch ( t ) { case TYPE_INTERNAL_DOUBLE: - return new Val(v->CoerceToDouble(), TYPE_DOUBLE); + return make_intrusive(v->CoerceToDouble(), TYPE_DOUBLE); case TYPE_INTERNAL_INT: - return val_mgr->GetInt(v->CoerceToInt()); + return {AdoptRef{}, val_mgr->GetInt(v->CoerceToInt())}; case TYPE_INTERNAL_UNSIGNED: - return val_mgr->GetCount(v->CoerceToUnsigned()); + return {AdoptRef{}, val_mgr->GetCount(v->CoerceToUnsigned())}; default: RuntimeErrorWithCallStack("bad type in CoerceExpr::Fold"); @@ -3619,7 +3434,7 @@ Val* ArithCoerceExpr::FoldSingleVal(Val* v, InternalTypeTag t) const } } -Val* ArithCoerceExpr::Fold(Val* v) const +IntrusivePtr ArithCoerceExpr::Fold(Val* v) const { InternalTypeTag t = type->InternalType(); @@ -3636,12 +3451,12 @@ Val* ArithCoerceExpr::Fold(Val* v) const t = Type()->AsVectorType()->YieldType()->InternalType(); VectorVal* vv = v->AsVectorVal(); - VectorVal* result = new VectorVal(Type()->AsVectorType()); + auto result = make_intrusive(Type()->AsVectorType()); for ( unsigned int i = 0; i < vv->Size(); ++i ) { Val* elt = vv->Lookup(i); if ( elt ) - result->Assign(i, FoldSingleVal(elt, t)); + result->Assign(i, FoldSingleVal(elt, t).release()); else result->Assign(i, 0); } @@ -3649,8 +3464,8 @@ Val* ArithCoerceExpr::Fold(Val* v) const return result; } -RecordCoerceExpr::RecordCoerceExpr(Expr* op, RecordType* r) -: UnaryExpr(EXPR_RECORD_COERCE, op) +RecordCoerceExpr::RecordCoerceExpr(IntrusivePtr arg_op, IntrusivePtr r) +: UnaryExpr(EXPR_RECORD_COERCE, std::move(arg_op)) { map_size = 0; map = 0; @@ -3658,7 +3473,7 @@ RecordCoerceExpr::RecordCoerceExpr(Expr* op, RecordType* r) if ( IsError() ) return; - SetType(r->Ref()); + SetType(std::move(r)); if ( Type()->Tag() != TYPE_RECORD ) ExprError("coercion to non-record"); @@ -3763,15 +3578,14 @@ RecordCoerceExpr::~RecordCoerceExpr() delete [] map; } -Val* RecordCoerceExpr::InitVal(const BroType* t, Val* aggr) const +IntrusivePtr RecordCoerceExpr::InitVal(const BroType* t, IntrusivePtr aggr) const { - Val* v = Eval(0); + auto v = Eval(0); if ( v ) { RecordVal* rv = v->AsRecordVal(); - RecordVal* ar = rv->CoerceTo(t->AsRecordType(), aggr); - Unref(rv); + IntrusivePtr ar{AdoptRef{}, rv->CoerceTo(t->AsRecordType(), aggr.release())}; if ( ar ) return ar; @@ -3781,16 +3595,16 @@ Val* RecordCoerceExpr::InitVal(const BroType* t, Val* aggr) const return 0; } -Val* RecordCoerceExpr::Fold(Val* v) const +IntrusivePtr RecordCoerceExpr::Fold(Val* v) const { - RecordVal* val = new RecordVal(Type()->AsRecordType()); + auto val = make_intrusive(Type()->AsRecordType()); RecordVal* rv = v->AsRecordVal(); for ( int i = 0; i < map_size; ++i ) { if ( map[i] >= 0 ) { - Val* rhs = rv->Lookup(map[i]); + IntrusivePtr rhs{NewRef{}, rv->Lookup(map[i])}; if ( ! rhs ) { const Attr* def = rv->Type()->AsRecordType()->FieldDecl( @@ -3799,8 +3613,6 @@ Val* RecordCoerceExpr::Fold(Val* v) const if ( def ) rhs = def->AttrExpr()->Eval(0); } - else - rhs = rhs->Ref(); assert(rhs || Type()->AsRecordType()->FieldDecl(i)->FindAttr(ATTR_OPTIONAL)); @@ -3819,30 +3631,26 @@ Val* RecordCoerceExpr::Fold(Val* v) const field_type->Tag() == TYPE_RECORD && ! same_type(rhs_type, field_type) ) { - Val* new_val = rhs->AsRecordVal()->CoerceTo( - field_type->AsRecordType()); + IntrusivePtr new_val{AdoptRef{}, rhs->AsRecordVal()->CoerceTo(field_type->AsRecordType())}; if ( new_val ) { - Unref(rhs); - rhs = new_val; + rhs = std::move(new_val); } } else if ( BothArithmetic(rhs_type->Tag(), field_type->Tag()) && ! same_type(rhs_type, field_type) ) { - if ( Val* new_val = check_and_promote(rhs, field_type, false, op->GetLocationInfo()) ) + if ( Val* new_val = check_and_promote(rhs.release(), field_type, false, op->GetLocationInfo()) ) { - // Don't call unref here on rhs because check_and_promote already called it. - rhs = new_val; + rhs = {AdoptRef{}, new_val}; } else { - Unref(val); RuntimeError("Failed type conversion"); } } - val->Assign(i, rhs); + val->Assign(i, rhs.release()); } else { @@ -3851,7 +3659,7 @@ Val* RecordCoerceExpr::Fold(Val* v) const if ( def ) { - Val* def_val = def->AttrExpr()->Eval(0); + auto def_val = def->AttrExpr()->Eval(0); BroType* def_type = def_val->Type(); BroType* field_type = Type()->AsRecordType()->FieldType(i); @@ -3864,12 +3672,11 @@ Val* RecordCoerceExpr::Fold(Val* v) const if ( tmp ) { - Unref(def_val); - def_val = tmp; + def_val = {AdoptRef{}, tmp}; } } - val->Assign(i, def_val); + val->Assign(i, def_val.release()); } else val->Assign(i, 0); @@ -3879,13 +3686,13 @@ Val* RecordCoerceExpr::Fold(Val* v) const return val; } -TableCoerceExpr::TableCoerceExpr(Expr* op, TableType* r) -: UnaryExpr(EXPR_TABLE_COERCE, op) +TableCoerceExpr::TableCoerceExpr(IntrusivePtr arg_op, IntrusivePtr r) +: UnaryExpr(EXPR_TABLE_COERCE, std::move(arg_op)) { if ( IsError() ) return; - SetType(r->Ref()); + SetType(std::move(r)); if ( Type()->Tag() != TYPE_TABLE ) ExprError("coercion to non-table"); @@ -3899,23 +3706,23 @@ TableCoerceExpr::~TableCoerceExpr() { } -Val* TableCoerceExpr::Fold(Val* v) const +IntrusivePtr TableCoerceExpr::Fold(Val* v) const { TableVal* tv = v->AsTableVal(); if ( tv->Size() > 0 ) RuntimeErrorWithCallStack("coercion of non-empty table/set"); - return new TableVal(Type()->AsTableType(), tv->Attrs()); + return make_intrusive(Type()->AsTableType(), tv->Attrs()); } -VectorCoerceExpr::VectorCoerceExpr(Expr* op, VectorType* v) -: UnaryExpr(EXPR_VECTOR_COERCE, op) +VectorCoerceExpr::VectorCoerceExpr(IntrusivePtr arg_op, IntrusivePtr v) +: UnaryExpr(EXPR_VECTOR_COERCE, std::move(arg_op)) { if ( IsError() ) return; - SetType(v->Ref()); + SetType(std::move(v)); if ( Type()->Tag() != TYPE_VECTOR ) ExprError("coercion to non-vector"); @@ -3929,18 +3736,18 @@ VectorCoerceExpr::~VectorCoerceExpr() { } -Val* VectorCoerceExpr::Fold(Val* v) const +IntrusivePtr VectorCoerceExpr::Fold(Val* v) const { VectorVal* vv = v->AsVectorVal(); if ( vv->Size() > 0 ) RuntimeErrorWithCallStack("coercion of non-empty vector"); - return new VectorVal(Type()->Ref()->AsVectorType()); + return make_intrusive(Type()->Ref()->AsVectorType()); } -FlattenExpr::FlattenExpr(Expr* arg_op) -: UnaryExpr(EXPR_FLATTEN, arg_op) +FlattenExpr::FlattenExpr(IntrusivePtr arg_op) +: UnaryExpr(EXPR_FLATTEN, std::move(arg_op)) { if ( IsError() ) return; @@ -3952,18 +3759,18 @@ FlattenExpr::FlattenExpr(Expr* arg_op) RecordType* rt = t->AsRecordType(); num_fields = rt->NumFields(); - TypeList* tl = new TypeList(); + auto tl = make_intrusive(); for ( int i = 0; i < num_fields; ++i ) tl->Append(rt->FieldType(i)->Ref()); Unref(rt); - SetType(tl); + SetType(std::move(tl)); } -Val* FlattenExpr::Fold(Val* v) const +IntrusivePtr FlattenExpr::Fold(Val* v) const { RecordVal* rv = v->AsRecordVal(); - ListVal* l = new ListVal(TYPE_ANY); + auto l = make_intrusive(TYPE_ANY); for ( int i = 0; i < num_fields; ++i ) { @@ -3978,7 +3785,7 @@ Val* FlattenExpr::Fold(Val* v) const const RecordType* rv_t = rv->Type()->AsRecordType(); const Attr* fa = rv_t->FieldDecl(i)->FindAttr(ATTR_DEFAULT); if ( fa ) - l->Append(fa->AttrExpr()->Eval(0)); + l->Append(fa->AttrExpr()->Eval(0).release()); else RuntimeError("missing field value"); @@ -4006,12 +3813,9 @@ void ScheduleTimer::Dispatch(double /* t */, int /* is_expire */) mgr.QueueEvent(event, std::move(args), SOURCE_LOCAL, 0, tmgr); } -ScheduleExpr::ScheduleExpr(Expr* arg_when, EventExpr* arg_event) -: Expr(EXPR_SCHEDULE) +ScheduleExpr::ScheduleExpr(IntrusivePtr arg_when, IntrusivePtr arg_event) +: Expr(EXPR_SCHEDULE), when(std::move(arg_when)), event(std::move(arg_event)) { - when = arg_when; - event = arg_event; - if ( IsError() || when->IsError() || event->IsError() ) return; @@ -4019,13 +3823,7 @@ ScheduleExpr::ScheduleExpr(Expr* arg_when, EventExpr* arg_event) if ( bt != TYPE_TIME && bt != TYPE_INTERVAL ) ExprError("schedule expression requires a time or time interval"); else - SetType(base_type(TYPE_TIMER)); - } - -ScheduleExpr::~ScheduleExpr() - { - Unref(when); - Unref(event); + SetType({AdoptRef{}, base_type(TYPE_TIMER)}); } int ScheduleExpr::IsPure() const @@ -4033,12 +3831,12 @@ int ScheduleExpr::IsPure() const return 0; } -Val* ScheduleExpr::Eval(Frame* f) const +IntrusivePtr ScheduleExpr::Eval(Frame* f) const { if ( terminating ) return 0; - Val* when_val = when->Eval(f); + auto when_val = when->Eval(f); if ( ! when_val ) return 0; @@ -4058,8 +3856,6 @@ Val* ScheduleExpr::Eval(Frame* f) const tmgr->Add(new ScheduleTimer(event->Handler(), args, dt, tmgr)); } - Unref(when_val); - return 0; } @@ -4098,8 +3894,8 @@ void ScheduleExpr::ExprDescribe(ODesc* d) const event->Describe(d); } -InExpr::InExpr(Expr* arg_op1, Expr* arg_op2) -: BinaryExpr(EXPR_IN, arg_op1, arg_op2) +InExpr::InExpr(IntrusivePtr arg_op1, IntrusivePtr arg_op2) +: BinaryExpr(EXPR_IN, std::move(arg_op1), std::move(arg_op2)) { if ( IsError() ) return; @@ -4108,11 +3904,11 @@ InExpr::InExpr(Expr* arg_op1, Expr* arg_op2) { if ( op2->Type()->Tag() != TYPE_STRING ) { - op2->Type()->Error("pattern requires string index", op1); + op2->Type()->Error("pattern requires string index", op1.get()); SetError(); } else - SetType(base_type(TYPE_BOOL)); + SetType({AdoptRef{}, base_type(TYPE_BOOL)}); } else if ( op1->Type()->Tag() == TYPE_RECORD ) @@ -4135,13 +3931,13 @@ InExpr::InExpr(Expr* arg_op1, Expr* arg_op2) SetError(); } else - SetType(base_type(TYPE_BOOL)); + SetType({AdoptRef{}, base_type(TYPE_BOOL)}); } } else if ( op1->Type()->Tag() == TYPE_STRING && op2->Type()->Tag() == TYPE_STRING ) - SetType(base_type(TYPE_BOOL)); + SetType({AdoptRef{}, base_type(TYPE_BOOL)}); else { @@ -4152,40 +3948,37 @@ InExpr::InExpr(Expr* arg_op1, Expr* arg_op2) { if ( op2->Type()->Tag() == TYPE_SUBNET ) { - SetType(base_type(TYPE_BOOL)); + SetType({AdoptRef{}, base_type(TYPE_BOOL)}); return; } if ( op2->Type()->Tag() == TYPE_TABLE && op2->Type()->AsTableType()->IsSubNetIndex() ) { - SetType(base_type(TYPE_BOOL)); + SetType({AdoptRef{}, base_type(TYPE_BOOL)}); return; } } if ( op1->Tag() != EXPR_LIST ) - op1 = new ListExpr(op1); + op1 = make_intrusive(std::move(op1)); ListExpr* lop1 = op1->AsListExpr(); if ( ! op2->Type()->MatchesIndex(lop1) ) SetError("not an index type"); else - { - op1 = lop1; - SetType(base_type(TYPE_BOOL)); - } + SetType({AdoptRef{}, base_type(TYPE_BOOL)}); } } -Val* InExpr::Fold(Val* v1, Val* v2) const +IntrusivePtr InExpr::Fold(Val* v1, Val* v2) const { if ( v1->Type()->Tag() == TYPE_PATTERN ) { RE_Matcher* re = v1->AsPattern(); const BroString* s = v2->AsString(); - return val_mgr->GetBool(re->MatchAnywhere(s) != 0); + return {AdoptRef{}, val_mgr->GetBool(re->MatchAnywhere(s) != 0)}; } if ( v2->Type()->Tag() == TYPE_STRING ) @@ -4194,12 +3987,12 @@ Val* InExpr::Fold(Val* v1, Val* v2) const const BroString* s2 = v2->AsString(); // Could do better here e.g. Boyer-Moore if done repeatedly. - return val_mgr->GetBool(strstr_n(s2->Len(), s2->Bytes(), s1->Len(), reinterpret_cast(s1->CheckString())) != -1); + return {AdoptRef{}, val_mgr->GetBool(strstr_n(s2->Len(), s2->Bytes(), s1->Len(), reinterpret_cast(s1->CheckString())) != -1)}; } if ( v1->Type()->Tag() == TYPE_ADDR && v2->Type()->Tag() == TYPE_SUBNET ) - return val_mgr->GetBool(v2->AsSubNetVal()->Contains(v1->AsAddr())); + return {AdoptRef{}, val_mgr->GetBool(v2->AsSubNetVal()->Contains(v1->AsAddr()))}; Val* res; @@ -4209,17 +4002,14 @@ Val* InExpr::Fold(Val* v1, Val* v2) const res = v2->AsTableVal()->Lookup(v1, false); if ( res ) - return val_mgr->GetBool(1); + return {AdoptRef{}, val_mgr->GetBool(1)}; else - return val_mgr->GetBool(0); + return {AdoptRef{}, val_mgr->GetBool(0)}; } -CallExpr::CallExpr(Expr* arg_func, ListExpr* arg_args, bool in_hook) -: Expr(EXPR_CALL) +CallExpr::CallExpr(IntrusivePtr arg_func, IntrusivePtr arg_args, bool in_hook) +: Expr(EXPR_CALL), func(std::move(arg_func)), args(std::move(arg_args)) { - func = arg_func; - args = arg_args; - if ( func->IsError() || args->IsError() ) { SetError(); @@ -4241,7 +4031,7 @@ CallExpr::CallExpr(Expr* arg_func, ListExpr* arg_args, bool in_hook) return; } - if ( ! func_type->MatchesIndex(args) ) + if ( ! func_type->MatchesIndex(args.get()) ) SetError("argument type mismatch in function call"); else { @@ -4273,18 +4063,18 @@ CallExpr::CallExpr(Expr* arg_func, ListExpr* arg_args, bool in_hook) } } else - SetType(yield->Ref()); + SetType({NewRef{}, yield}); // Check for call to built-ins that can be statically // analyzed. - Val* func_val; + IntrusivePtr func_val; if ( func->Tag() == EXPR_NAME && // This is cheating, but without it processing gets // quite confused regarding "value used but not set" // run-time errors when we apply this analysis during // parsing. Really we should instead do it after we've // parsed the entire set of scripts. - streq(((NameExpr*) func)->Id()->Name(), "fmt") && + streq(((NameExpr*) func.get())->Id()->Name(), "fmt") && // The following is needed because fmt might not yet // be bound as a name. did_builtin_init && @@ -4298,12 +4088,6 @@ CallExpr::CallExpr(Expr* arg_func, ListExpr* arg_args, bool in_hook) } } -CallExpr::~CallExpr() - { - Unref(func); - Unref(args); - } - int CallExpr::IsPure() const { if ( IsError() ) @@ -4312,7 +4096,7 @@ int CallExpr::IsPure() const if ( ! func->IsPure() ) return 0; - Val* func_val = func->Eval(0); + auto func_val = func->Eval(0); if ( ! func_val ) return 0; @@ -4325,12 +4109,11 @@ int CallExpr::IsPure() const int pure = 0; if ( f->GetKind() == Func::BUILTIN_FUNC ) pure = f->IsPure() && args->IsPure(); - Unref(func_val); return pure; } -Val* CallExpr::Eval(Frame* f) const +IntrusivePtr CallExpr::Eval(Frame* f) const { if ( IsError() ) return 0; @@ -4350,14 +4133,14 @@ Val* CallExpr::Eval(Frame* f) const DBG_LOG(DBG_NOTIFIERS, "%s: provides cached function result", trigger->Name()); - return v->Ref(); + return {NewRef{}, v}; } } } - Val* ret = 0; - Val* func_val = func->Eval(f); - val_list* v = eval_list(f, args); + IntrusivePtr ret; + auto func_val = func->Eval(f); + val_list* v = eval_list(f, args.get()); if ( func_val && v ) { @@ -4367,7 +4150,7 @@ Val* CallExpr::Eval(Frame* f) const if ( f ) f->SetCall(this); - ret = func->Call(v, f); + ret = {AdoptRef{}, func->Call(v, f)}; if ( f ) f->SetCall(current_call); @@ -4378,8 +4161,6 @@ Val* CallExpr::Eval(Frame* f) const else delete_vals(v); - Unref(func_val); - return ret; } @@ -4417,7 +4198,7 @@ LambdaExpr::LambdaExpr(std::unique_ptr arg_ing, ingredients = std::move(arg_ing); outer_ids = std::move(arg_outer_ids); - SetType(ingredients->id->Type()->Ref()); + SetType({NewRef{}, ingredients->id->Type()}); // Install a dummy version of the function globally for use only // when broker provides a closure. @@ -4467,10 +4248,10 @@ LambdaExpr::LambdaExpr(std::unique_ptr arg_ing, id->SetConst(); } -Val* LambdaExpr::Eval(Frame* f) const +IntrusivePtr LambdaExpr::Eval(Frame* f) const { ::Ref(ingredients->body); - BroFunc* lamb = new BroFunc( + auto lamb = make_intrusive( ingredients->id, ingredients->body, ingredients->inits, @@ -4483,9 +4264,7 @@ Val* LambdaExpr::Eval(Frame* f) const // Allows for lookups by the receiver. lamb->SetName(my_name.c_str()); - auto rval = new Val(lamb); - Unref(lamb); - return rval; + return make_intrusive(lamb.get()); } void LambdaExpr::ExprDescribe(ODesc* d) const @@ -4506,11 +4285,10 @@ TraversalCode LambdaExpr::Traverse(TraversalCallback* cb) const HANDLE_TC_EXPR_POST(tc); } -EventExpr::EventExpr(const char* arg_name, ListExpr* arg_args) -: Expr(EXPR_EVENT) +EventExpr::EventExpr(const char* arg_name, IntrusivePtr arg_args) +: Expr(EXPR_EVENT), args(std::move(arg_args)) { name = arg_name; - args = arg_args; EventHandler* h = event_registry->Lookup(name); if ( ! h ) @@ -4537,7 +4315,7 @@ EventExpr::EventExpr(const char* arg_name, ListExpr* arg_args) return; } - if ( ! func_type->MatchesIndex(args) ) + if ( ! func_type->MatchesIndex(args.get()) ) SetError("argument type mismatch in event invocation"); else { @@ -4549,17 +4327,12 @@ EventExpr::EventExpr(const char* arg_name, ListExpr* arg_args) } } -EventExpr::~EventExpr() - { - Unref(args); - } - -Val* EventExpr::Eval(Frame* f) const +IntrusivePtr EventExpr::Eval(Frame* f) const { if ( IsError() ) return 0; - val_list* v = eval_list(f, args); + val_list* v = eval_list(f, args.get()); mgr.QueueEvent(handler, std::move(*v)); delete v; @@ -4593,13 +4366,13 @@ void EventExpr::ExprDescribe(ODesc* d) const ListExpr::ListExpr() : Expr(EXPR_LIST) { - SetType(new TypeList()); + SetType(make_intrusive()); } -ListExpr::ListExpr(Expr* e) : Expr(EXPR_LIST) +ListExpr::ListExpr(IntrusivePtr e) : Expr(EXPR_LIST) { - SetType(new TypeList()); - Append(e); + SetType(make_intrusive()); + Append(std::move(e)); } ListExpr::~ListExpr() @@ -4608,10 +4381,10 @@ ListExpr::~ListExpr() Unref(expr); } -void ListExpr::Append(Expr* e) +void ListExpr::Append(IntrusivePtr e) { - exprs.push_back(e); - ((TypeList*) type)->Append(e->Type()->Ref()); + exprs.push_back(e.release()); + ((TypeList*) type.get())->Append(exprs.back()->Type()->Ref()); } int ListExpr::IsPure() const @@ -4632,27 +4405,26 @@ int ListExpr::AllConst() const return 1; } -Val* ListExpr::Eval(Frame* f) const +IntrusivePtr ListExpr::Eval(Frame* f) const { - ListVal* v = new ListVal(TYPE_ANY); + auto v = make_intrusive(TYPE_ANY); for ( const auto& expr : exprs ) { - Val* ev = expr->Eval(f); + auto ev = expr->Eval(f); if ( ! ev ) { RuntimeError("uninitialized list value"); - Unref(v); return 0; } - v->Append(ev); + v->Append(ev.release()); } return v; } -BroType* ListExpr::InitType() const +IntrusivePtr ListExpr::InitType() const { if ( exprs.length() == 0 ) { @@ -4678,12 +4450,12 @@ BroType* ListExpr::InitType() const } - return new RecordType(types); + return make_intrusive(types); } else { - TypeList* tl = new TypeList(); + auto tl = make_intrusive(); for ( const auto& e : exprs ) { BroType* ti = e->Type(); @@ -4709,7 +4481,7 @@ BroType* ListExpr::InitType() const } } -Val* ListExpr::InitVal(const BroType* t, Val* aggr) const +IntrusivePtr ListExpr::InitVal(const BroType* t, IntrusivePtr aggr) const { // While fairly similar to the EvalIntoAggregate() code, // we keep this separate since it also deals with initialization @@ -4722,26 +4494,22 @@ Val* ListExpr::InitVal(const BroType* t, Val* aggr) const // in which case we should expand as a ListVal. if ( ! aggr && type->AsTypeList()->AllMatch(t, 1) ) { - ListVal* v = new ListVal(TYPE_ANY); + auto v = make_intrusive(TYPE_ANY); const type_list* tl = type->AsTypeList()->Types(); if ( exprs.length() != tl->length() ) { Error("index mismatch", t); - Unref(v); return 0; } loop_over_list(exprs, i) { - Val* vi = exprs[i]->InitVal((*tl)[i], 0); + auto vi = exprs[i]->InitVal((*tl)[i], 0); if ( ! vi ) - { - Unref(v); return 0; - } - v->Append(vi); + v->Append(vi.release()); } return v; } @@ -4761,16 +4529,13 @@ Val* ListExpr::InitVal(const BroType* t, Val* aggr) const return 0; } - ListVal* v = new ListVal(TYPE_ANY); + auto v = make_intrusive(TYPE_ANY); loop_over_list(exprs, i) { - Val* vi = exprs[i]->InitVal((*tl)[i], 0); + auto vi = exprs[i]->InitVal((*tl)[i], 0); if ( ! vi ) - { - Unref(v); return 0; - } - v->Append(vi); + v->Append(vi.release()); } return v; } @@ -4792,7 +4557,7 @@ Val* ListExpr::InitVal(const BroType* t, Val* aggr) const Internal("missing aggregate in ListExpr::InitVal"); if ( t->IsSet() ) - return AddSetInit(t, aggr); + return AddSetInit(t, std::move(aggr)); if ( t->Tag() == TYPE_VECTOR ) { @@ -4803,15 +4568,15 @@ Val* ListExpr::InitVal(const BroType* t, Val* aggr) const { Expr* e = exprs[i]; check_and_promote_expr(e, vec->Type()->AsVectorType()->YieldType()); - Val* v = e->Eval(0); - if ( ! vec->Assign(i, v) ) + auto v = e->Eval(0); + if ( ! vec->Assign(i, v.release()) ) { e->Error(fmt("type mismatch at index %d", i)); return 0; } } - return aggr; + return std::move(aggr); } // If we got this far, then it's either a table or record @@ -4834,7 +4599,7 @@ Val* ListExpr::InitVal(const BroType* t, Val* aggr) const return 0; } - Val* v = e->Eval(0); + auto v = e->Eval(0); if ( ! same_type(v->Type(), t) ) { v->Type()->Error("type clash in table initializer", t); @@ -4849,7 +4614,7 @@ Val* ListExpr::InitVal(const BroType* t, Val* aggr) const return aggr; } -Val* ListExpr::AddSetInit(const BroType* t, Val* aggr) const +IntrusivePtr ListExpr::AddSetInit(const BroType* t, IntrusivePtr aggr) const { if ( aggr->Type()->Tag() != TYPE_TABLE ) Internal("bad aggregate in ListExpr::InitVal"); @@ -4860,7 +4625,7 @@ Val* ListExpr::AddSetInit(const BroType* t, Val* aggr) const for ( const auto& expr : exprs ) { - Val* element; + IntrusivePtr element; if ( expr->Type()->IsSet() ) // A set to flatten. @@ -4888,22 +4653,19 @@ Val* ListExpr::AddSetInit(const BroType* t, Val* aggr) const } if ( expr->Type()->Tag() == TYPE_LIST ) - element = check_and_promote(element, it, 1); + element = {AdoptRef{}, check_and_promote(element.release(), it, 1)}; else - element = check_and_promote(element, (*it->Types())[0], 1); + element = {AdoptRef{}, check_and_promote(element.release(), (*it->Types())[0], 1)}; if ( ! element ) return 0; - if ( ! tv->ExpandAndInit({AdoptRef{}, element}, 0) ) - { - Unref(tv); + if ( ! tv->ExpandAndInit(std::move(element), 0) ) return 0; - } } - return tv; + return std::move(aggr); } void ListExpr::ExprDescribe(ODesc* d) const @@ -4919,16 +4681,16 @@ void ListExpr::ExprDescribe(ODesc* d) const } } -Expr* ListExpr::MakeLvalue() +IntrusivePtr ListExpr::MakeLvalue() { for ( const auto & expr : exprs ) if ( expr->Tag() != EXPR_NAME ) ExprError("can only assign to list of identifiers"); - return new RefExpr(this); + return make_intrusive(IntrusivePtr{NewRef{}, this}); } -void ListExpr::Assign(Frame* f, Val* v) +void ListExpr::Assign(Frame* f, IntrusivePtr v) { ListVal* lv = v->AsListVal(); @@ -4936,9 +4698,7 @@ void ListExpr::Assign(Frame* f, Val* v) RuntimeError("mismatch in list lengths"); loop_over_list(exprs, i) - exprs[i]->Assign(f, (*lv->Vals())[i]->Ref()); - - Unref(v); + exprs[i]->Assign(f, {NewRef{}, (*lv->Vals())[i]}); } TraversalCode ListExpr::Traverse(TraversalCallback* cb) const @@ -4956,7 +4716,7 @@ TraversalCode ListExpr::Traverse(TraversalCallback* cb) const HANDLE_TC_EXPR_POST(tc); } -RecordAssignExpr::RecordAssignExpr(Expr* record, Expr* init_list, int is_init) +RecordAssignExpr::RecordAssignExpr(IntrusivePtr record, IntrusivePtr init_list, int is_init) { const expr_list& inits = init_list->AsListExpr()->Exprs(); @@ -4981,9 +4741,9 @@ RecordAssignExpr::RecordAssignExpr(Expr* record, Expr* init_list, int is_init) if ( field >= 0 && same_type(lhs->FieldType(field), t->FieldType(j)) ) { - FieldExpr* fe_lhs = new FieldExpr(record, field_name); - FieldExpr* fe_rhs = new FieldExpr(init, field_name); - Append(get_assign_expr(fe_lhs->Ref(), fe_rhs->Ref(), is_init)); + auto fe_lhs = make_intrusive(record, field_name); + auto fe_rhs = make_intrusive(IntrusivePtr{NewRef{}, init}, field_name); + Append(get_assign_expr(std::move(fe_lhs), std::move(fe_rhs), is_init)); } } } @@ -4996,9 +4756,9 @@ RecordAssignExpr::RecordAssignExpr(Expr* record, Expr* init_list, int is_init) const char* field_name = ""; // rf->FieldName(); if ( lhs->HasField(field_name) ) { - FieldExpr* fe_lhs = new FieldExpr(record, field_name); - Expr* fe_rhs = rf->Op(); - Append(get_assign_expr(fe_lhs->Ref(), fe_rhs, is_init)); + auto fe_lhs = make_intrusive(record, field_name); + IntrusivePtr fe_rhs = {NewRef{}, rf->Op()}; + Append(get_assign_expr(std::move(fe_lhs), std::move(fe_rhs), is_init)); } else { @@ -5017,34 +4777,30 @@ RecordAssignExpr::RecordAssignExpr(Expr* record, Expr* init_list, int is_init) } } -CastExpr::CastExpr(Expr* arg_op, BroType* t) : UnaryExpr(EXPR_CAST, arg_op) +CastExpr::CastExpr(IntrusivePtr arg_op, IntrusivePtr t) : UnaryExpr(EXPR_CAST, std::move(arg_op)) { auto stype = Op()->Type(); - ::Ref(t); - SetType(t); + SetType(std::move(t)); - if ( ! can_cast_value_to_type(stype, t) ) + if ( ! can_cast_value_to_type(stype, Type()) ) ExprError("cast not supported"); } -Val* CastExpr::Eval(Frame* f) const +IntrusivePtr CastExpr::Eval(Frame* f) const { if ( IsError() ) return 0; - Val* v = op->Eval(f); + auto v = op->Eval(f); if ( ! v ) return 0; - Val* nv = cast_value_to_type(v, Type()); + IntrusivePtr nv{AdoptRef{}, cast_value_to_type(v.get(), Type())}; if ( nv ) - { - Unref(v); return nv; - } ODesc d; d.Add("invalid cast of value with type '"); @@ -5057,7 +4813,6 @@ Val* CastExpr::Eval(Frame* f) const ! v->AsRecordVal()->Lookup(0) ) d.Add(" (nil $data field)"); - Unref(v); RuntimeError(d.Description()); return 0; // not reached. } @@ -5069,28 +4824,20 @@ void CastExpr::ExprDescribe(ODesc* d) const Type()->Describe(d); } -IsExpr::IsExpr(Expr* arg_op, BroType* arg_t) : UnaryExpr(EXPR_IS, arg_op) +IsExpr::IsExpr(IntrusivePtr arg_op, IntrusivePtr arg_t) : UnaryExpr(EXPR_IS, std::move(arg_op)), t(std::move(arg_t)) { - t = arg_t; - ::Ref(t); - - SetType(base_type(TYPE_BOOL)); + SetType({AdoptRef{}, base_type(TYPE_BOOL)}); } -IsExpr::~IsExpr() - { - Unref(t); - } - -Val* IsExpr::Fold(Val* v) const +IntrusivePtr IsExpr::Fold(Val* v) const { if ( IsError() ) return 0; - if ( can_cast_value_to_type(v, t) ) - return val_mgr->GetBool(1); + if ( can_cast_value_to_type(v, t.get()) ) + return {AdoptRef{}, val_mgr->GetBool(1)}; else - return val_mgr->GetBool(0); + return {AdoptRef{}, val_mgr->GetBool(0)}; } void IsExpr::ExprDescribe(ODesc* d) const @@ -5100,15 +4847,15 @@ void IsExpr::ExprDescribe(ODesc* d) const t->Describe(d); } -Expr* get_assign_expr(Expr* op1, Expr* op2, int is_init) +IntrusivePtr get_assign_expr(IntrusivePtr op1, IntrusivePtr op2, int is_init) { if ( op1->Type()->Tag() == TYPE_RECORD && op2->Type()->Tag() == TYPE_LIST ) - return new RecordAssignExpr(op1, op2, is_init); + return make_intrusive(std::move(op1), std::move(op2), is_init); else if ( op1->Tag() == EXPR_INDEX && op1->AsIndexExpr()->IsSlice() ) - return new IndexSliceAssignExpr(op1, op2, is_init); + return make_intrusive(std::move(op1), std::move(op2), is_init); else - return new AssignExpr(op1, op2, is_init); + return make_intrusive(std::move(op1), std::move(op2), is_init); } int check_and_promote_expr(Expr*& e, BroType* t) @@ -5138,7 +4885,7 @@ int check_and_promote_expr(Expr*& e, BroType* t) return 0; } - e = new ArithCoerceExpr(e, t_tag); + e = new ArithCoerceExpr({AdoptRef{}, e}, t_tag); return 1; } @@ -5163,7 +4910,7 @@ int check_and_promote_expr(Expr*& e, BroType* t) if ( record_promotion_compatible(t_r, et_r) ) { - e = new RecordCoerceExpr(e, t_r); + e = new RecordCoerceExpr({AdoptRef{}, e}, {NewRef{}, t_r}); return 1; } @@ -5177,14 +4924,14 @@ int check_and_promote_expr(Expr*& e, BroType* t) if ( t->Tag() == TYPE_TABLE && et->Tag() == TYPE_TABLE && et->AsTableType()->IsUnspecifiedTable() ) { - e = new TableCoerceExpr(e, t->AsTableType()); + e = new TableCoerceExpr({AdoptRef{}, e}, {NewRef{}, t->AsTableType()}); return 1; } if ( t->Tag() == TYPE_VECTOR && et->Tag() == TYPE_VECTOR && et->AsVectorType()->IsUnspecifiedVector() ) { - e = new VectorCoerceExpr(e, t->AsVectorType()); + e = new VectorCoerceExpr({AdoptRef{}, e}, {NewRef{}, t->AsVectorType()}); return 1; } @@ -5300,13 +5047,13 @@ val_list* eval_list(Frame* f, const ListExpr* l) bool success = true; for ( const auto& expr : e ) { - Val* ev = expr->Eval(f); + auto ev = expr->Eval(f); if ( ! ev ) { success = false; break; } - v->push_back(ev); + v->push_back(ev.release()); } if ( ! success ) diff --git a/src/Expr.h b/src/Expr.h index 771f4782e5..c2bcebae79 100644 --- a/src/Expr.h +++ b/src/Expr.h @@ -5,6 +5,7 @@ // BRO expressions. #include "BroList.h" +#include "IntrusivePtr.h" #include "Timer.h" #include "Type.h" #include "EventHandler.h" @@ -58,6 +59,7 @@ typedef enum { extern const char* expr_name(BroExprTag t); +template class IntrusivePtr; class Stmt; class Frame; class ListExpr; @@ -72,16 +74,14 @@ struct function_ingredients; class Expr : public BroObj { public: - BroType* Type() const { return type; } + BroType* Type() const { return type.get(); } BroExprTag Tag() const { return tag; } - ~Expr() override; - Expr* Ref() { ::Ref(this); return this; } // Evaluates the expression and returns a corresponding Val*, // or nil if the expression's value isn't fixed. - virtual Val* Eval(Frame* f) const = 0; + virtual IntrusivePtr Eval(Frame* f) const = 0; // Same, but the context is that we are adding an element // into the given aggregate of the given type. Note that @@ -91,12 +91,11 @@ public: const; // Assign to the given value, if appropriate. - virtual void Assign(Frame* f, Val* v); + virtual void Assign(Frame* f, IntrusivePtr v); // Returns the type corresponding to this expression interpreted - // as an initialization. The type should be Unref()'d when done - // using it. Returns nil if the initialization is illegal. - virtual BroType* InitType() const; + // as an initialization. Returns nil if the initialization is illegal. + virtual IntrusivePtr InitType() const; // Returns true if this expression, interpreted as an initialization, // constitutes a record element, false otherwise. If the TypeDecl* @@ -109,7 +108,7 @@ public: // with the given type. If "aggr" is non-nil, then this expression // is an element of the given aggregate, and it is added to it // accordingly. - virtual Val* InitVal(const BroType* t, Val* aggr) const; + virtual IntrusivePtr InitVal(const BroType* t, IntrusivePtr aggr) const; // True if the expression has no side effects, false otherwise. virtual int IsPure() const; @@ -145,7 +144,7 @@ public: // Return the expression converted to L-value form. If expr // cannot be used as an L-value, reports an error and returns // the current value of expr (this is the default method). - virtual Expr* MakeLvalue(); + virtual IntrusivePtr MakeLvalue(); // Marks the expression as one requiring (or at least appearing // with) parentheses. Used for pretty-printing. @@ -214,7 +213,7 @@ protected: // Puts the expression in canonical form. virtual void Canonicize(); - void SetType(BroType* t); + void SetType(IntrusivePtr t); // Reports the given error and sets the expression's type to // TYPE_ERROR. @@ -225,21 +224,20 @@ protected: void RuntimeErrorWithCallStack(const std::string& msg) const; BroExprTag tag; - BroType* type; + IntrusivePtr type; int paren; }; class NameExpr : public Expr { public: - explicit NameExpr(ID* id, bool const_init = false); - ~NameExpr() override; + explicit NameExpr(IntrusivePtr id, bool const_init = false); - ID* Id() const { return id; } + ID* Id() const { return id.get(); } - Val* Eval(Frame* f) const override; - void Assign(Frame* f, Val* v) override; - Expr* MakeLvalue() override; + IntrusivePtr Eval(Frame* f) const override; + void Assign(Frame* f, IntrusivePtr v) override; + IntrusivePtr MakeLvalue() override; int IsPure() const override; TraversalCode Traverse(TraversalCallback* cb) const override; @@ -247,91 +245,88 @@ public: protected: void ExprDescribe(ODesc* d) const override; - ID* id; + IntrusivePtr id; bool in_const_init; }; class ConstExpr : public Expr { public: - explicit ConstExpr(Val* val); - ~ConstExpr() override; + explicit ConstExpr(IntrusivePtr val); - Val* Value() const { return val; } + Val* Value() const { return val.get(); } - Val* Eval(Frame* f) const override; + IntrusivePtr Eval(Frame* f) const override; TraversalCode Traverse(TraversalCallback* cb) const override; protected: void ExprDescribe(ODesc* d) const override; - Val* val; + IntrusivePtr val; }; class UnaryExpr : public Expr { public: - Expr* Op() const { return op; } + Expr* Op() const { return op.get(); } // UnaryExpr::Eval correctly handles vector types. Any child // class that overrides Eval() should be modified to handle // vectors correctly as necessary. - Val* Eval(Frame* f) const override; + IntrusivePtr Eval(Frame* f) const override; int IsPure() const override; TraversalCode Traverse(TraversalCallback* cb) const override; protected: - UnaryExpr(BroExprTag arg_tag, Expr* arg_op); - ~UnaryExpr() override; + UnaryExpr(BroExprTag arg_tag, IntrusivePtr arg_op); void ExprDescribe(ODesc* d) const override; // Returns the expression folded using the given constant. - virtual Val* Fold(Val* v) const; + virtual IntrusivePtr Fold(Val* v) const; - Expr* op; + IntrusivePtr op; }; class BinaryExpr : public Expr { public: - Expr* Op1() const { return op1; } - Expr* Op2() const { return op2; } + Expr* Op1() const { return op1.get(); } + Expr* Op2() const { return op2.get(); } int IsPure() const override; // BinaryExpr::Eval correctly handles vector types. Any child // class that overrides Eval() should be modified to handle // vectors correctly as necessary. - Val* Eval(Frame* f) const override; + IntrusivePtr Eval(Frame* f) const override; TraversalCode Traverse(TraversalCallback* cb) const override; protected: - BinaryExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2) - : Expr(arg_tag), op1(arg_op1), op2(arg_op2) + BinaryExpr(BroExprTag arg_tag, IntrusivePtr arg_op1, IntrusivePtr arg_op2) + : Expr(arg_tag), op1(std::move(arg_op1)), op2(std::move(arg_op2)) { - if ( ! (arg_op1 && arg_op2) ) + if ( ! (op1 && op2) ) return; if ( op1->IsError() || op2->IsError() ) SetError(); } - ~BinaryExpr() override; // Returns the expression folded using the given constants. - virtual Val* Fold(Val* v1, Val* v2) const; + virtual IntrusivePtr Fold(Val* v1, Val* v2) const; // Same for when the constants are strings. - virtual Val* StringFold(Val* v1, Val* v2) const; + virtual IntrusivePtr StringFold(Val* v1, Val* v2) const; // Same for when the constants are patterns. - virtual Val* PatternFold(Val* v1, Val* v2) const; + virtual IntrusivePtr PatternFold(Val* v1, Val* v2) const; // Same for when the constants are sets. - virtual Val* SetFold(Val* v1, Val* v2) const; + virtual IntrusivePtr SetFold(Val* v1, Val* v2) const; // Same for when the constants are addresses or subnets. - virtual Val* AddrFold(Val* v1, Val* v2) const; - virtual Val* SubNetFold(Val* v1, Val* v2) const; + virtual IntrusivePtr AddrFold(Val* v1, Val* v2) const; + virtual IntrusivePtr SubNetFold(Val* v1, Val* v2) const; int BothConst() const { return op1->IsConst() && op2->IsConst(); } @@ -347,149 +342,148 @@ protected: void ExprDescribe(ODesc* d) const override; - Expr* op1; - Expr* op2; + IntrusivePtr op1; + IntrusivePtr op2; }; class CloneExpr : public UnaryExpr { public: - explicit CloneExpr(Expr* op); - Val* Eval(Frame* f) const override; + explicit CloneExpr(IntrusivePtr op); + IntrusivePtr Eval(Frame* f) const override; protected: - Val* Fold(Val* v) const override; + IntrusivePtr Fold(Val* v) const override; }; class IncrExpr : public UnaryExpr { public: - IncrExpr(BroExprTag tag, Expr* op); + IncrExpr(BroExprTag tag, IntrusivePtr op); - Val* Eval(Frame* f) const override; - Val* DoSingleEval(Frame* f, Val* v) const; + IntrusivePtr Eval(Frame* f) const override; + IntrusivePtr DoSingleEval(Frame* f, Val* v) const; int IsPure() const override; }; class ComplementExpr : public UnaryExpr { public: - explicit ComplementExpr(Expr* op); + explicit ComplementExpr(IntrusivePtr op); protected: - Val* Fold(Val* v) const override; + IntrusivePtr Fold(Val* v) const override; }; class NotExpr : public UnaryExpr { public: - explicit NotExpr(Expr* op); + explicit NotExpr(IntrusivePtr op); protected: - Val* Fold(Val* v) const override; + IntrusivePtr Fold(Val* v) const override; }; class PosExpr : public UnaryExpr { public: - explicit PosExpr(Expr* op); + explicit PosExpr(IntrusivePtr op); protected: - Val* Fold(Val* v) const override; + IntrusivePtr Fold(Val* v) const override; }; class NegExpr : public UnaryExpr { public: - explicit NegExpr(Expr* op); + explicit NegExpr(IntrusivePtr op); protected: - Val* Fold(Val* v) const override; + IntrusivePtr Fold(Val* v) const override; }; class SizeExpr : public UnaryExpr { public: - explicit SizeExpr(Expr* op); - Val* Eval(Frame* f) const override; + explicit SizeExpr(IntrusivePtr op); + IntrusivePtr Eval(Frame* f) const override; protected: - Val* Fold(Val* v) const override; + IntrusivePtr Fold(Val* v) const override; }; class AddExpr : public BinaryExpr { public: - AddExpr(Expr* op1, Expr* op2); + AddExpr(IntrusivePtr op1, IntrusivePtr op2); void Canonicize() override; }; class AddToExpr : public BinaryExpr { public: - AddToExpr(Expr* op1, Expr* op2); - Val* Eval(Frame* f) const override; + AddToExpr(IntrusivePtr op1, IntrusivePtr op2); + IntrusivePtr Eval(Frame* f) const override; }; class RemoveFromExpr : public BinaryExpr { public: - RemoveFromExpr(Expr* op1, Expr* op2); - Val* Eval(Frame* f) const override; + RemoveFromExpr(IntrusivePtr op1, IntrusivePtr op2); + IntrusivePtr Eval(Frame* f) const override; }; class SubExpr : public BinaryExpr { public: - SubExpr(Expr* op1, Expr* op2); + SubExpr(IntrusivePtr op1, IntrusivePtr op2); }; class TimesExpr : public BinaryExpr { public: - TimesExpr(Expr* op1, Expr* op2); + TimesExpr(IntrusivePtr op1, IntrusivePtr op2); void Canonicize() override; }; class DivideExpr : public BinaryExpr { public: - DivideExpr(Expr* op1, Expr* op2); + DivideExpr(IntrusivePtr op1, IntrusivePtr op2); protected: - Val* AddrFold(Val* v1, Val* v2) const override; + IntrusivePtr AddrFold(Val* v1, Val* v2) const override; }; class ModExpr : public BinaryExpr { public: - ModExpr(Expr* op1, Expr* op2); + ModExpr(IntrusivePtr op1, IntrusivePtr op2); }; class BoolExpr : public BinaryExpr { public: - BoolExpr(BroExprTag tag, Expr* op1, Expr* op2); + BoolExpr(BroExprTag tag, IntrusivePtr op1, IntrusivePtr op2); - Val* Eval(Frame* f) const override; - Val* DoSingleEval(Frame* f, Val* v1, Expr* op2) const; + IntrusivePtr Eval(Frame* f) const override; + IntrusivePtr DoSingleEval(Frame* f, IntrusivePtr v1, Expr* op2) const; }; class BitExpr : public BinaryExpr { public: - BitExpr(BroExprTag tag, Expr* op1, Expr* op2); + BitExpr(BroExprTag tag, IntrusivePtr op1, IntrusivePtr op2); }; class EqExpr : public BinaryExpr { public: - EqExpr(BroExprTag tag, Expr* op1, Expr* op2); + EqExpr(BroExprTag tag, IntrusivePtr op1, IntrusivePtr op2); void Canonicize() override; protected: - Val* Fold(Val* v1, Val* v2) const override; + IntrusivePtr Fold(Val* v1, Val* v2) const override; }; class RelExpr : public BinaryExpr { public: - RelExpr(BroExprTag tag, Expr* op1, Expr* op2); + RelExpr(BroExprTag tag, IntrusivePtr op1, IntrusivePtr op2); void Canonicize() override; }; class CondExpr : public Expr { public: - CondExpr(Expr* op1, Expr* op2, Expr* op3); - ~CondExpr() override; + CondExpr(IntrusivePtr op1, IntrusivePtr op2, IntrusivePtr op3); - const Expr* Op1() const { return op1; } - const Expr* Op2() const { return op2; } - const Expr* Op3() const { return op3; } + const Expr* Op1() const { return op1.get(); } + const Expr* Op2() const { return op2.get(); } + const Expr* Op3() const { return op3.get(); } - Val* Eval(Frame* f) const override; + IntrusivePtr Eval(Frame* f) const override; int IsPure() const override; TraversalCode Traverse(TraversalCallback* cb) const override; @@ -497,31 +491,30 @@ public: protected: void ExprDescribe(ODesc* d) const override; - Expr* op1; - Expr* op2; - Expr* op3; + IntrusivePtr op1; + IntrusivePtr op2; + IntrusivePtr op3; }; class RefExpr : public UnaryExpr { public: - explicit RefExpr(Expr* op); + explicit RefExpr(IntrusivePtr op); - void Assign(Frame* f, Val* v) override; - Expr* MakeLvalue() override; + void Assign(Frame* f, IntrusivePtr v) override; + IntrusivePtr MakeLvalue() override; }; class AssignExpr : public BinaryExpr { public: // If val is given, evaluating this expression will always yield the val // yet still perform the assignment. Used for triggers. - AssignExpr(Expr* op1, Expr* op2, int is_init, Val* val = 0, attr_list* attrs = 0); - ~AssignExpr() override; + AssignExpr(IntrusivePtr op1, IntrusivePtr op2, int is_init, IntrusivePtr val = nullptr, attr_list* attrs = nullptr); - Val* Eval(Frame* f) const override; + IntrusivePtr Eval(Frame* f) const override; void EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f) const override; - BroType* InitType() const override; + IntrusivePtr InitType() const override; int IsRecordElement(TypeDecl* td) const override; - Val* InitVal(const BroType* t, Val* aggr) const override; + IntrusivePtr InitVal(const BroType* t, IntrusivePtr aggr) const override; int IsPure() const override; protected: @@ -529,18 +522,18 @@ protected: bool TypeCheckArithmetics(TypeTag bt1, TypeTag bt2); int is_init; - Val* val; // optional + IntrusivePtr val; // optional }; class IndexSliceAssignExpr : public AssignExpr { public: - IndexSliceAssignExpr(Expr* op1, Expr* op2, int is_init); - Val* Eval(Frame* f) const override; + IndexSliceAssignExpr(IntrusivePtr op1, IntrusivePtr op2, int is_init); + IntrusivePtr Eval(Frame* f) const override; }; class IndexExpr : public BinaryExpr { public: - IndexExpr(Expr* op1, ListExpr* op2, bool is_slice = false); + IndexExpr(IntrusivePtr op1, IntrusivePtr op2, bool is_slice = false); int CanAdd() const override; int CanDel() const override; @@ -548,19 +541,19 @@ public: void Add(Frame* f) override; void Delete(Frame* f) override; - void Assign(Frame* f, Val* v) override; - Expr* MakeLvalue() override; + void Assign(Frame* f, IntrusivePtr v) override; + IntrusivePtr MakeLvalue() override; // Need to override Eval since it can take a vector arg but does // not necessarily return a vector. - Val* Eval(Frame* f) const override; + IntrusivePtr Eval(Frame* f) const override; TraversalCode Traverse(TraversalCallback* cb) const override; bool IsSlice() const { return is_slice; } protected: - Val* Fold(Val* v1, Val* v2) const override; + IntrusivePtr Fold(Val* v1, Val* v2) const override; void ExprDescribe(ODesc* d) const override; @@ -569,7 +562,7 @@ protected: class FieldExpr : public UnaryExpr { public: - FieldExpr(Expr* op, const char* field_name); + FieldExpr(IntrusivePtr op, const char* field_name); ~FieldExpr() override; int Field() const { return field; } @@ -577,13 +570,13 @@ public: int CanDel() const override; - void Assign(Frame* f, Val* v) override; + void Assign(Frame* f, IntrusivePtr v) override; void Delete(Frame* f) override; - Expr* MakeLvalue() override; + IntrusivePtr MakeLvalue() override; protected: - Val* Fold(Val* v) const override; + IntrusivePtr Fold(Val* v) const override; void ExprDescribe(ODesc* d) const override; @@ -596,13 +589,13 @@ protected: // "rec?$$attrname" is true if the attribute attrname is not nil. class HasFieldExpr : public UnaryExpr { public: - HasFieldExpr(Expr* op, const char* field_name); + HasFieldExpr(IntrusivePtr op, const char* field_name); ~HasFieldExpr() override; const char* FieldName() const { return field_name; } protected: - Val* Fold(Val* v) const override; + IntrusivePtr Fold(Val* v) const override; void ExprDescribe(ODesc* d) const override; @@ -612,28 +605,28 @@ protected: class RecordConstructorExpr : public UnaryExpr { public: - explicit RecordConstructorExpr(ListExpr* constructor_list); + explicit RecordConstructorExpr(IntrusivePtr constructor_list); ~RecordConstructorExpr() override; protected: - Val* InitVal(const BroType* t, Val* aggr) const override; - Val* Fold(Val* v) const override; + IntrusivePtr InitVal(const BroType* t, IntrusivePtr aggr) const override; + IntrusivePtr Fold(Val* v) const override; void ExprDescribe(ODesc* d) const override; }; class TableConstructorExpr : public UnaryExpr { public: - TableConstructorExpr(ListExpr* constructor_list, attr_list* attrs, - BroType* arg_type = 0); + TableConstructorExpr(IntrusivePtr constructor_list, attr_list* attrs, + IntrusivePtr arg_type = nullptr); ~TableConstructorExpr() override { Unref(attrs); } Attributes* Attrs() { return attrs; } - Val* Eval(Frame* f) const override; + IntrusivePtr Eval(Frame* f) const override; protected: - Val* InitVal(const BroType* t, Val* aggr) const override; + IntrusivePtr InitVal(const BroType* t, IntrusivePtr aggr) const override; void ExprDescribe(ODesc* d) const override; @@ -642,16 +635,16 @@ protected: class SetConstructorExpr : public UnaryExpr { public: - SetConstructorExpr(ListExpr* constructor_list, attr_list* attrs, - BroType* arg_type = 0); + SetConstructorExpr(IntrusivePtr constructor_list, attr_list* attrs, + IntrusivePtr arg_type = nullptr); ~SetConstructorExpr() override { Unref(attrs); } Attributes* Attrs() { return attrs; } - Val* Eval(Frame* f) const override; + IntrusivePtr Eval(Frame* f) const override; protected: - Val* InitVal(const BroType* t, Val* aggr) const override; + IntrusivePtr InitVal(const BroType* t, IntrusivePtr aggr) const override; void ExprDescribe(ODesc* d) const override; @@ -660,19 +653,19 @@ protected: class VectorConstructorExpr : public UnaryExpr { public: - explicit VectorConstructorExpr(ListExpr* constructor_list, BroType* arg_type = 0); + explicit VectorConstructorExpr(IntrusivePtr constructor_list, IntrusivePtr arg_type = nullptr); - Val* Eval(Frame* f) const override; + IntrusivePtr Eval(Frame* f) const override; protected: - Val* InitVal(const BroType* t, Val* aggr) const override; + IntrusivePtr InitVal(const BroType* t, IntrusivePtr aggr) const override; void ExprDescribe(ODesc* d) const override; }; class FieldAssignExpr : public UnaryExpr { public: - FieldAssignExpr(const char* field_name, Expr* value); + FieldAssignExpr(const char* field_name, IntrusivePtr value); const char* FieldName() const { return field_name.c_str(); } @@ -687,21 +680,21 @@ protected: class ArithCoerceExpr : public UnaryExpr { public: - ArithCoerceExpr(Expr* op, TypeTag t); + ArithCoerceExpr(IntrusivePtr op, TypeTag t); protected: - Val* FoldSingleVal(Val* v, InternalTypeTag t) const; - Val* Fold(Val* v) const override; + IntrusivePtr FoldSingleVal(Val* v, InternalTypeTag t) const; + IntrusivePtr Fold(Val* v) const override; }; class RecordCoerceExpr : public UnaryExpr { public: - RecordCoerceExpr(Expr* op, RecordType* r); + RecordCoerceExpr(IntrusivePtr op, IntrusivePtr r); ~RecordCoerceExpr() override; protected: - Val* InitVal(const BroType* t, Val* aggr) const override; - Val* Fold(Val* v) const override; + IntrusivePtr InitVal(const BroType* t, IntrusivePtr aggr) const override; + IntrusivePtr Fold(Val* v) const override; // For each super-record slot, gives subrecord slot with which to // fill it. @@ -711,30 +704,30 @@ protected: class TableCoerceExpr : public UnaryExpr { public: - TableCoerceExpr(Expr* op, TableType* r); + TableCoerceExpr(IntrusivePtr op, IntrusivePtr r); ~TableCoerceExpr() override; protected: - Val* Fold(Val* v) const override; + IntrusivePtr Fold(Val* v) const override; }; class VectorCoerceExpr : public UnaryExpr { public: - VectorCoerceExpr(Expr* op, VectorType* v); + VectorCoerceExpr(IntrusivePtr op, IntrusivePtr v); ~VectorCoerceExpr() override; protected: - Val* Fold(Val* v) const override; + IntrusivePtr Fold(Val* v) const override; }; // An internal operator for flattening array indices that are records // into a list of individual values. class FlattenExpr : public UnaryExpr { public: - explicit FlattenExpr(Expr* op); + explicit FlattenExpr(IntrusivePtr op); protected: - Val* Fold(Val* v) const override; + IntrusivePtr Fold(Val* v) const override; int num_fields; }; @@ -755,53 +748,51 @@ protected: class ScheduleExpr : public Expr { public: - ScheduleExpr(Expr* when, EventExpr* event); - ~ScheduleExpr() override; + ScheduleExpr(IntrusivePtr when, IntrusivePtr event); int IsPure() const override; - Val* Eval(Frame* f) const override; + IntrusivePtr Eval(Frame* f) const override; - Expr* When() const { return when; } - EventExpr* Event() const { return event; } + Expr* When() const { return when.get(); } + EventExpr* Event() const { return event.get(); } TraversalCode Traverse(TraversalCallback* cb) const override; protected: void ExprDescribe(ODesc* d) const override; - Expr* when; - EventExpr* event; + IntrusivePtr when; + IntrusivePtr event; }; class InExpr : public BinaryExpr { public: - InExpr(Expr* op1, Expr* op2); + InExpr(IntrusivePtr op1, IntrusivePtr op2); protected: - Val* Fold(Val* v1, Val* v2) const override; + IntrusivePtr Fold(Val* v1, Val* v2) const override; }; class CallExpr : public Expr { public: - CallExpr(Expr* func, ListExpr* args, bool in_hook = false); - ~CallExpr() override; + CallExpr(IntrusivePtr func, IntrusivePtr args, bool in_hook = false); - Expr* Func() const { return func; } - ListExpr* Args() const { return args; } + Expr* Func() const { return func.get(); } + ListExpr* Args() const { return args.get(); } int IsPure() const override; - Val* Eval(Frame* f) const override; + IntrusivePtr Eval(Frame* f) const override; TraversalCode Traverse(TraversalCallback* cb) const override; protected: void ExprDescribe(ODesc* d) const override; - Expr* func; - ListExpr* args; + IntrusivePtr func; + IntrusivePtr args; }; @@ -815,7 +806,7 @@ public: LambdaExpr(std::unique_ptr ingredients, id_list outer_ids); - Val* Eval(Frame* f) const override; + IntrusivePtr Eval(Frame* f) const override; TraversalCode Traverse(TraversalCallback* cb) const override; protected: @@ -830,14 +821,13 @@ private: class EventExpr : public Expr { public: - EventExpr(const char* name, ListExpr* args); - ~EventExpr() override; + EventExpr(const char* name, IntrusivePtr args); const char* Name() const { return name.c_str(); } - ListExpr* Args() const { return args; } + ListExpr* Args() const { return args.get(); } EventHandlerPtr Handler() const { return handler; } - Val* Eval(Frame* f) const override; + IntrusivePtr Eval(Frame* f) const override; TraversalCode Traverse(TraversalCallback* cb) const override; @@ -846,16 +836,16 @@ protected: string name; EventHandlerPtr handler; - ListExpr* args; + IntrusivePtr args; }; class ListExpr : public Expr { public: ListExpr(); - explicit ListExpr(Expr* e); + explicit ListExpr(IntrusivePtr e); ~ListExpr() override; - void Append(Expr* e); + void Append(IntrusivePtr e); const expr_list& Exprs() const { return exprs; } expr_list& Exprs() { return exprs; } @@ -866,17 +856,17 @@ public: // True if the entire list represents constant values. int AllConst() const; - Val* Eval(Frame* f) const override; + IntrusivePtr Eval(Frame* f) const override; - BroType* InitType() const override; - Val* InitVal(const BroType* t, Val* aggr) const override; - Expr* MakeLvalue() override; - void Assign(Frame* f, Val* v) override; + IntrusivePtr InitType() const override; + IntrusivePtr InitVal(const BroType* t, IntrusivePtr aggr) const override; + IntrusivePtr MakeLvalue() override; + void Assign(Frame* f, IntrusivePtr v) override; TraversalCode Traverse(TraversalCallback* cb) const override; protected: - Val* AddSetInit(const BroType* t, Val* aggr) const; + IntrusivePtr AddSetInit(const BroType* t, IntrusivePtr aggr) const; void ExprDescribe(ODesc* d) const override; @@ -886,29 +876,28 @@ protected: class RecordAssignExpr : public ListExpr { public: - RecordAssignExpr(Expr* record, Expr* init_list, int is_init); + RecordAssignExpr(IntrusivePtr record, IntrusivePtr init_list, int is_init); }; class CastExpr : public UnaryExpr { public: - CastExpr(Expr* op, BroType* t); + CastExpr(IntrusivePtr op, IntrusivePtr t); protected: - Val* Eval(Frame* f) const override; + IntrusivePtr Eval(Frame* f) const override; void ExprDescribe(ODesc* d) const override; }; class IsExpr : public UnaryExpr { public: - IsExpr(Expr* op, BroType* t); - virtual ~IsExpr(); + IsExpr(IntrusivePtr op, IntrusivePtr t); protected: - Val* Fold(Val* v) const override; + IntrusivePtr Fold(Val* v) const override; void ExprDescribe(ODesc* d) const override; private: - BroType* t; + IntrusivePtr t; }; inline Val* Expr::ExprVal() const @@ -919,7 +908,7 @@ inline Val* Expr::ExprVal() const } // Decides whether to return an AssignExpr or a RecordAssignExpr. -Expr* get_assign_expr(Expr* op1, Expr* op2, int is_init); +IntrusivePtr get_assign_expr(IntrusivePtr op1, IntrusivePtr op2, int is_init); // Type-check the given expression(s) against the given type(s). Complain // if the expression cannot match the given type, returning 0. If it can diff --git a/src/Func.cc b/src/Func.cc index 47993ba03b..5583032f79 100644 --- a/src/Func.cc +++ b/src/Func.cc @@ -815,7 +815,7 @@ bool check_built_in_call(BuiltinFunc* f, CallExpr* call) return false; } - Val* fmt_str_val = fmt_str_arg->Eval(0); + auto fmt_str_val = fmt_str_arg->Eval(0); if ( fmt_str_val ) { @@ -829,7 +829,6 @@ bool check_built_in_call(BuiltinFunc* f, CallExpr* call) if ( ! *fmt_str ) { - Unref(fmt_str_val); call->Error("format string ends with bare '%'"); return false; } @@ -841,13 +840,11 @@ bool check_built_in_call(BuiltinFunc* f, CallExpr* call) if ( args.length() != num_fmt + 1 ) { - Unref(fmt_str_val); call->Error("mismatch between format string to fmt() and number of arguments passed"); return false; } } - Unref(fmt_str_val); return true; } @@ -868,7 +865,7 @@ static int get_func_priority(const attr_list& attrs) continue; } - Val* v = a->AttrExpr()->Eval(0); + auto v = a->AttrExpr()->Eval(0); if ( ! v ) { a->Error("cannot evaluate attribute expression"); @@ -877,13 +874,11 @@ static int get_func_priority(const attr_list& attrs) if ( ! IsIntegral(v->Type()->Tag()) ) { - Unref(v); a->Error("expression is not of integral type"); continue; } priority = v->InternalInt(); - Unref(v); } return priority; diff --git a/src/ID.cc b/src/ID.cc index d6b949fc59..2eea08acfa 100644 --- a/src/ID.cc +++ b/src/ID.cc @@ -278,15 +278,14 @@ void ID::SetOption() void ID::EvalFunc(Expr* ef, Expr* ev) { - Expr* arg1 = new ConstExpr(val->Ref()); - ListExpr* args = new ListExpr(); - args->Append(arg1); - args->Append(ev->Ref()); + auto arg1 = make_intrusive(IntrusivePtr{NewRef{}, val}); + auto args = make_intrusive(); + args->Append(std::move(arg1)); + args->Append({NewRef{}, ev}); - CallExpr* ce = new CallExpr(ef->Ref(), args); + auto ce = make_intrusive(IntrusivePtr{NewRef{}, ef}, std::move(args)); - SetVal(ce->Eval(0)); - Unref(ce); + SetVal(ce->Eval(0).release()); } #if 0 diff --git a/src/Stmt.cc b/src/Stmt.cc index e9a54917f9..495a3ed432 100644 --- a/src/Stmt.cc +++ b/src/Stmt.cc @@ -321,14 +321,10 @@ Val* ExprStmt::Exec(Frame* f, stmt_flow_type& flow) const RegisterAccess(); flow = FLOW_NEXT; - Val* v = e->Eval(f); + auto v = e->Eval(f); if ( v ) - { - Val* ret_val = DoExec(f, v, flow); - Unref(v); - return ret_val; - } + return DoExec(f, v.get(), flow); else return 0; } @@ -670,10 +666,10 @@ SwitchStmt::SwitchStmt(Expr* index, case_list* arg_cases) : if ( ne->Id()->IsConst() ) { - Val* v = ne->Eval(0); + auto v = ne->Eval(0); if ( v ) - Unref(exprs.replace(j, new ConstExpr(v))); + Unref(exprs.replace(j, new ConstExpr(std::move(v)))); } } break; @@ -1068,15 +1064,12 @@ Val* WhileStmt::Exec(Frame* f, stmt_flow_type& flow) const for ( ; ; ) { - Val* cond = loop_condition->Eval(f); + auto cond = loop_condition->Eval(f); if ( ! cond ) break; - bool cont = cond->AsBool(); - Unref(cond); - - if ( ! cont ) + if ( ! cond->AsBool() ) break; flow = FLOW_NEXT; @@ -1481,7 +1474,7 @@ Val* ReturnStmt::Exec(Frame* f, stmt_flow_type& flow) const flow = FLOW_RETURN; if ( e ) - return e->Eval(f); + return e->Eval(f).release(); else return 0; } diff --git a/src/Trigger.cc b/src/Trigger.cc index 5a600074a6..9d71ce5700 100644 --- a/src/Trigger.cc +++ b/src/Trigger.cc @@ -63,13 +63,10 @@ TraversalCode TriggerTraversalCallback::PreExpr(const Expr* expr) try { - Val* v = e->Eval(trigger->frame); + auto v = e->Eval(trigger->frame); if ( v ) - { - trigger->Register(v); - Unref(v); - } + trigger->Register(v.get()); } catch ( InterpreterException& ) { /* Already reported */ } @@ -157,7 +154,7 @@ Trigger::Trigger(Expr* arg_cond, Stmt* arg_body, Stmt* arg_timeout_stmts, arg_frame->SetDelayed(); } - Val* timeout_val = nullptr; + IntrusivePtr timeout_val; if ( arg_timeout ) { @@ -172,7 +169,6 @@ Trigger::Trigger(Expr* arg_cond, Stmt* arg_body, Stmt* arg_timeout_stmts, if ( timeout_val ) { timeout_value = timeout_val->AsInterval(); - Unref(timeout_val); } // Make sure we don't get deleted if somebody calls a method like @@ -271,7 +267,7 @@ bool Trigger::Eval() f->SetTrigger(this); - Val* v = nullptr; + IntrusivePtr v; try { @@ -294,7 +290,6 @@ bool Trigger::Eval() { // Not true. Perhaps next time... DBG_LOG(DBG_NOTIFIERS, "%s: trigger condition is false", Name()); - Unref(v); Unref(f); Init(); return false; @@ -303,13 +298,12 @@ bool Trigger::Eval() DBG_LOG(DBG_NOTIFIERS, "%s: trigger condition is true, executing", Name()); - Unref(v); - v = 0; + v = nullptr; stmt_flow_type flow; try { - v = body->Exec(f, flow); + v = {AdoptRef{}, body->Exec(f, flow)}; } catch ( InterpreterException& e ) { /* Already reported. */ } @@ -327,12 +321,11 @@ bool Trigger::Eval() delete [] pname; #endif - trigger->Cache(frame->GetCall(), v); + trigger->Cache(frame->GetCall(), v.get()); trigger->Release(); frame->ClearTrigger(); } - Unref(v); Unref(f); if ( timer ) diff --git a/src/Type.cc b/src/Type.cc index 31ee469b64..8ab11ce312 100644 --- a/src/Type.cc +++ b/src/Type.cc @@ -705,7 +705,7 @@ Val* RecordType::FieldDefault(int field) const const Attr* def_attr = td->attrs->FindAttr(ATTR_DEFAULT); - return def_attr ? def_attr->AttrExpr()->Eval(0) : 0; + return def_attr ? def_attr->AttrExpr()->Eval(0).release() : 0; } int RecordType::FieldOffset(const char* field) const @@ -2065,7 +2065,7 @@ BroType* init_type(Expr* init) { if ( init->Tag() != EXPR_LIST ) { - BroType* t = init->InitType(); + auto t = init->InitType(); if ( ! t ) return 0; @@ -2073,11 +2073,10 @@ BroType* init_type(Expr* init) t->AsTypeList()->Types()->length() != 1 ) { init->Error("list used in scalar initialization"); - Unref(t); return 0; } - return t; + return t.release(); } ListExpr* init_list = init->AsListExpr(); @@ -2094,47 +2093,25 @@ BroType* init_type(Expr* init) if ( e0->IsRecordElement(0) ) // ListExpr's know how to build a record from their // components. - return init_list->InitType(); + return init_list->InitType().release(); - BroType* t = e0->InitType(); + auto t = e0->InitType(); if ( t ) - { - BroType* old_t = t; - t = reduce_type(t); - - if ( t ) - // reduce_type() does not return a referenced pointer, but we want - // to own a reference, so create one here - Ref(t); - - // reduce_type() does not adopt our reference passed as parameter, so - // we need to release it (after the Ref() call above) - Unref(old_t); - } - + t = {NewRef{}, reduce_type(t.get())}; if ( ! t ) return 0; for ( int i = 1; t && i < el.length(); ++i ) { - BroType* el_t = el[i]->InitType(); - BroType* ti = el_t ? reduce_type(el_t) : 0; + auto el_t = el[i]->InitType(); + BroType* ti = el_t ? reduce_type(el_t.get()) : 0; if ( ! ti ) - { - Unref(t); return 0; - } - if ( same_type(t, ti) ) - { - Unref(ti); + if ( same_type(t.get(), ti) ) continue; - } - BroType* t_merge = merge_types(t, ti); - Unref(t); - Unref(ti); - t = t_merge; + t = IntrusivePtr{AdoptRef{}, merge_types(t.get(), ti)}; } if ( ! t ) @@ -2145,18 +2122,18 @@ BroType* init_type(Expr* init) if ( t->Tag() == TYPE_TABLE && ! t->AsTableType()->IsSet() ) // A list of table elements. - return t; + return t.release(); // A set. If the index type isn't yet a type list, make // it one, as that's what's required for creating a set type. if ( t->Tag() != TYPE_LIST ) { - TypeList* tl = new TypeList(t); - tl->Append(t); - t = tl; + auto tl = make_intrusive(t.get()->Ref()); + tl->Append(t.release()); + t = std::move(tl); } - return new SetType(t->AsTypeList(), 0); + return new SetType(t.release()->AsTypeList(), 0); } bool is_atomic_type(const BroType* t) diff --git a/src/Val.cc b/src/Val.cc index 5bfa228e4b..72cca0017f 100644 --- a/src/Val.cc +++ b/src/Val.cc @@ -1745,14 +1745,14 @@ Val* TableVal::Default(Val* index) record_promotion_compatible(dtype->AsRecordType(), ytype->AsRecordType()) ) { - Expr* coerce = new RecordCoerceExpr(def_attr->AttrExpr()->Ref(), - ytype->AsRecordType()); - def_val = coerce->Eval(0); + Expr* coerce = new RecordCoerceExpr({NewRef{}, def_attr->AttrExpr()}, + {NewRef{}, ytype->AsRecordType()}); + def_val = coerce->Eval(0).release(); Unref(coerce); } else - def_val = def_attr->AttrExpr()->Eval(0); + def_val = def_attr->AttrExpr()->Eval(0).release(); } if ( ! def_val ) @@ -1958,7 +1958,7 @@ void TableVal::CallChangeFunc(const Val* index, Val* old_value, OnChangeType tpe try { - IntrusivePtr thefunc{AdoptRef{}, change_func->Eval(nullptr)}; + auto thefunc = change_func->Eval(nullptr); if ( ! thefunc ) { @@ -2250,7 +2250,7 @@ void TableVal::InitDefaultFunc(Frame* f) ytype->AsRecordType()) ) return; // TableVal::Default will handle this. - def_val = def_attr->AttrExpr()->Eval(f); + def_val = def_attr->AttrExpr()->Eval(f).release(); } void TableVal::InitTimer(double delay) @@ -2375,9 +2375,8 @@ double TableVal::GetExpireTime() try { - Val* timeout = expire_time->Eval(0); + auto timeout = expire_time->Eval(0); interval = (timeout ? timeout->AsInterval() : -1); - Unref(timeout); } catch ( InterpreterException& e ) { @@ -2407,7 +2406,7 @@ double TableVal::CallExpireFunc(Val* idx) try { - Val* vf = expire_func->Eval(0); + auto vf = expire_func->Eval(0); if ( ! vf ) { @@ -2419,7 +2418,6 @@ double TableVal::CallExpireFunc(Val* idx) if ( vf->Type()->Tag() != TYPE_FUNC ) { vf->Error("not a function"); - Unref(vf); Unref(idx); return 0; } @@ -2467,8 +2465,6 @@ double TableVal::CallExpireFunc(Val* idx) secs = result->AsInterval(); Unref(result); } - - Unref(vf); } catch ( InterpreterException& e ) @@ -2575,7 +2571,7 @@ RecordVal::RecordVal(RecordType* t, bool init_fields) : Val(t) { Attributes* a = t->FieldDecl(i)->attrs; Attr* def_attr = a ? a->FindAttr(ATTR_DEFAULT) : 0; - Val* def = def_attr ? def_attr->AttrExpr()->Eval(0) : 0; + auto def = def_attr ? def_attr->AttrExpr()->Eval(0) : 0; BroType* type = t->FieldDecl(i)->type; if ( def && type->Tag() == TYPE_RECORD && @@ -2585,8 +2581,7 @@ RecordVal::RecordVal(RecordType* t, bool init_fields) : Val(t) Val* tmp = def->AsRecordVal()->CoerceTo(type->AsRecordType()); if ( tmp ) { - Unref(def); - def = tmp; + def = {AdoptRef{}, tmp}; } } @@ -2595,18 +2590,16 @@ RecordVal::RecordVal(RecordType* t, bool init_fields) : Val(t) TypeTag tag = type->Tag(); if ( tag == TYPE_RECORD ) - def = new RecordVal(type->AsRecordType()); + def = make_intrusive(type->AsRecordType()); else if ( tag == TYPE_TABLE ) - def = new TableVal(type->AsTableType(), a); + def = make_intrusive(type->AsTableType(), a); else if ( tag == TYPE_VECTOR ) - def = new VectorVal(type->AsVectorType()); + def = make_intrusive(type->AsVectorType()); } - vl->push_back(def ? def->Ref() : 0); - - Unref(def); + vl->push_back(def.release()); } } @@ -2710,9 +2703,9 @@ RecordVal* RecordVal::CoerceTo(const RecordType* t, Val* aggr, bool allow_orphan if ( ar_t->FieldType(t_i)->Tag() == TYPE_RECORD && ! same_type(ar_t->FieldType(t_i), v->Type()) ) { - Expr* rhs = new ConstExpr(v->Ref()); - Expr* e = new RecordCoerceExpr(rhs, ar_t->FieldType(t_i)->AsRecordType()); - ar->Assign(t_i, e->Eval(0)); + auto rhs = make_intrusive(IntrusivePtr{NewRef{}, v}); + auto e = make_intrusive(std::move(rhs), IntrusivePtr{NewRef{}, ar_t->FieldType(t_i)->AsRecordType()}); + ar->Assign(t_i, e->Eval(0).release()); continue; } diff --git a/src/Var.cc b/src/Var.cc index 05bdfbfc7e..0399af05cb 100644 --- a/src/Var.cc +++ b/src/Var.cc @@ -16,11 +16,11 @@ #include "Traverse.h" #include "module_util.h" -static Val* init_val(Expr* init, const BroType* t, Val* aggr) +static IntrusivePtr init_val(Expr* init, const BroType* t, IntrusivePtr aggr) { try { - return init->InitVal(t, aggr); + return init->InitVal(t, std::move(aggr)); } catch ( InterpreterException& e ) { @@ -159,26 +159,23 @@ static void make_var(ID* id, IntrusivePtr t, init_class c, IntrusivePtr else if ( dt != VAR_REDEF || init || ! attr ) { - Val* aggr; + IntrusivePtr aggr; if ( t->Tag() == TYPE_RECORD ) { - aggr = new RecordVal(t->AsRecordType()); + aggr = make_intrusive(t->AsRecordType()); if ( init && t ) // Have an initialization and type is not deduced. - init = make_intrusive(init.release(), t->AsRecordType()); + init = make_intrusive(std::move(init), IntrusivePtr{NewRef{}, t->AsRecordType()}); } else if ( t->Tag() == TYPE_TABLE ) - aggr = new TableVal(t->AsTableType(), id->Attrs()); + aggr = make_intrusive(t->AsTableType(), id->Attrs()); else if ( t->Tag() == TYPE_VECTOR ) - aggr = new VectorVal(t->AsVectorType()); + aggr = make_intrusive(t->AsVectorType()); - else - aggr = 0; - - Val* v = 0; + IntrusivePtr v; if ( init ) { v = init_val(init.get(), t.get(), aggr); @@ -187,9 +184,9 @@ static void make_var(ID* id, IntrusivePtr t, init_class c, IntrusivePtr } if ( aggr ) - id->SetVal(aggr, c); + id->SetVal(aggr.release(), c); else if ( v ) - id->SetVal(v, c); + id->SetVal(v.release(), c); } } @@ -244,9 +241,9 @@ IntrusivePtr add_local(IntrusivePtr id, IntrusivePtr t, init_ // may free "init" const Location location = init->GetLocationInfo() != nullptr ? *init->GetLocationInfo() : no_location; - Expr* name_expr = new NameExpr(IntrusivePtr{id}.release(), dt == VAR_CONST); + auto name_expr = make_intrusive(id, dt == VAR_CONST); auto stmt = - make_intrusive(new AssignExpr(name_expr, init.release(), 0, 0, + make_intrusive(new AssignExpr(std::move(name_expr), std::move(init), 0, 0, id->Attrs() ? id->Attrs()->Attrs() : 0 )); stmt->SetLocationInfo(&location); @@ -262,8 +259,8 @@ IntrusivePtr add_local(IntrusivePtr id, IntrusivePtr t, init_ extern IntrusivePtr add_and_assign_local(IntrusivePtr id, IntrusivePtr init, IntrusivePtr val) { - make_var(id.get(), 0, INIT_FULL, IntrusivePtr{init}, 0, VAR_REGULAR, 0); - return make_intrusive(new NameExpr(id.release()), init.release(), 0, val.release()); + make_var(id.get(), 0, INIT_FULL, init, 0, VAR_REGULAR, 0); + return make_intrusive(make_intrusive(std::move(id)), std::move(init), 0, std::move(val)); } void add_type(ID* id, IntrusivePtr t, attr_list* attr) diff --git a/src/input/Manager.cc b/src/input/Manager.cc index fcd574647f..c85bc82575 100644 --- a/src/input/Manager.cc +++ b/src/input/Manager.cc @@ -973,7 +973,7 @@ bool Manager::UnrollRecordType(vector *fields, const RecordType *rec, { string name = nameprepend + rec->FieldName(i); const char* secondary = 0; - Val* c = nullptr; + IntrusivePtr c; TypeTag ty = rec->FieldType(i)->Tag(); TypeTag st = TYPE_VOID; bool optional = false; @@ -1001,7 +1001,6 @@ bool Manager::UnrollRecordType(vector *fields, const RecordType *rec, optional = true; Field* field = new Field(name.c_str(), secondary, ty, st, optional); - Unref(c); fields->push_back(field); } } diff --git a/src/parse.y b/src/parse.y index a7c5b1e980..3f9c51e973 100644 --- a/src/parse.y +++ b/src/parse.y @@ -312,157 +312,157 @@ expr: | TOK_COPY '(' expr ')' { set_location(@1, @4); - $$ = new CloneExpr($3); + $$ = new CloneExpr({AdoptRef{}, $3}); } | TOK_INCR expr { set_location(@1, @2); - $$ = new IncrExpr(EXPR_INCR, $2); + $$ = new IncrExpr(EXPR_INCR, {AdoptRef{}, $2}); } | TOK_DECR expr { set_location(@1, @2); - $$ = new IncrExpr(EXPR_DECR, $2); + $$ = new IncrExpr(EXPR_DECR, {AdoptRef{}, $2}); } | '!' expr { set_location(@1, @2); - $$ = new NotExpr($2); + $$ = new NotExpr({AdoptRef{}, $2}); } | '~' expr { set_location(@1, @2); - $$ = new ComplementExpr($2); + $$ = new ComplementExpr({AdoptRef{}, $2}); } | '-' expr %prec '!' { set_location(@1, @2); - $$ = new NegExpr($2); + $$ = new NegExpr({AdoptRef{}, $2}); } | '+' expr %prec '!' { set_location(@1, @2); - $$ = new PosExpr($2); + $$ = new PosExpr({AdoptRef{}, $2}); } | expr '+' expr { set_location(@1, @3); - $$ = new AddExpr($1, $3); + $$ = new AddExpr({AdoptRef{}, $1}, {AdoptRef{}, $3}); } | expr TOK_ADD_TO expr { set_location(@1, @3); - $$ = new AddToExpr($1, $3); + $$ = new AddToExpr({AdoptRef{}, $1}, {AdoptRef{}, $3}); } | expr '-' expr { set_location(@1, @3); - $$ = new SubExpr($1, $3); + $$ = new SubExpr({AdoptRef{}, $1}, {AdoptRef{}, $3}); } | expr TOK_REMOVE_FROM expr { set_location(@1, @3); - $$ = new RemoveFromExpr($1, $3); + $$ = new RemoveFromExpr({AdoptRef{}, $1}, {AdoptRef{}, $3}); } | expr '*' expr { set_location(@1, @3); - $$ = new TimesExpr($1, $3); + $$ = new TimesExpr({AdoptRef{}, $1}, {AdoptRef{}, $3}); } | expr '/' expr { set_location(@1, @3); - $$ = new DivideExpr($1, $3); + $$ = new DivideExpr({AdoptRef{}, $1}, {AdoptRef{}, $3}); } | expr '%' expr { set_location(@1, @3); - $$ = new ModExpr($1, $3); + $$ = new ModExpr({AdoptRef{}, $1}, {AdoptRef{}, $3}); } | expr '&' expr { set_location(@1, @3); - $$ = new BitExpr(EXPR_AND, $1, $3); + $$ = new BitExpr(EXPR_AND, {AdoptRef{}, $1}, {AdoptRef{}, $3}); } | expr '|' expr { set_location(@1, @3); - $$ = new BitExpr(EXPR_OR, $1, $3); + $$ = new BitExpr(EXPR_OR, {AdoptRef{}, $1}, {AdoptRef{}, $3}); } | expr '^' expr { set_location(@1, @3); - $$ = new BitExpr(EXPR_XOR, $1, $3); + $$ = new BitExpr(EXPR_XOR, {AdoptRef{}, $1}, {AdoptRef{}, $3}); } | expr TOK_AND_AND expr { set_location(@1, @3); - $$ = new BoolExpr(EXPR_AND_AND, $1, $3); + $$ = new BoolExpr(EXPR_AND_AND, {AdoptRef{}, $1}, {AdoptRef{}, $3}); } | expr TOK_OR_OR expr { set_location(@1, @3); - $$ = new BoolExpr(EXPR_OR_OR, $1, $3); + $$ = new BoolExpr(EXPR_OR_OR, {AdoptRef{}, $1}, {AdoptRef{}, $3}); } | expr TOK_EQ expr { set_location(@1, @3); - $$ = new EqExpr(EXPR_EQ, $1, $3); + $$ = new EqExpr(EXPR_EQ, {AdoptRef{}, $1}, {AdoptRef{}, $3}); } | expr TOK_NE expr { set_location(@1, @3); - $$ = new EqExpr(EXPR_NE, $1, $3); + $$ = new EqExpr(EXPR_NE, {AdoptRef{}, $1}, {AdoptRef{}, $3}); } | expr '<' expr { set_location(@1, @3); - $$ = new RelExpr(EXPR_LT, $1, $3); + $$ = new RelExpr(EXPR_LT, {AdoptRef{}, $1}, {AdoptRef{}, $3}); } | expr TOK_LE expr { set_location(@1, @3); - $$ = new RelExpr(EXPR_LE, $1, $3); + $$ = new RelExpr(EXPR_LE, {AdoptRef{}, $1}, {AdoptRef{}, $3}); } | expr '>' expr { set_location(@1, @3); - $$ = new RelExpr(EXPR_GT, $1, $3); + $$ = new RelExpr(EXPR_GT, {AdoptRef{}, $1}, {AdoptRef{}, $3}); } | expr TOK_GE expr { set_location(@1, @3); - $$ = new RelExpr(EXPR_GE, $1, $3); + $$ = new RelExpr(EXPR_GE, {AdoptRef{}, $1}, {AdoptRef{}, $3}); } | expr '?' expr ':' expr { set_location(@1, @5); - $$ = new CondExpr($1, $3, $5); + $$ = new CondExpr({AdoptRef{}, $1}, {AdoptRef{}, $3}, {AdoptRef{}, $5}); } | expr '=' expr @@ -474,7 +474,7 @@ expr: " in arbitrary expression contexts, only" " as a statement"); - $$ = get_assign_expr($1, $3, in_init); + $$ = get_assign_expr({AdoptRef{}, $1}, {AdoptRef{}, $3}, in_init).release(); } | TOK_LOCAL local_id '=' expr @@ -486,7 +486,7 @@ expr: | expr '[' expr_list ']' { set_location(@1, @4); - $$ = new IndexExpr($1, $3); + $$ = new IndexExpr({AdoptRef{}, $1}, {AdoptRef{}, $3}); } | index_slice @@ -494,13 +494,13 @@ expr: | expr '$' TOK_ID { set_location(@1, @3); - $$ = new FieldExpr($1, $3); + $$ = new FieldExpr({AdoptRef{}, $1}, $3); } | '$' TOK_ID '=' expr { set_location(@1, @4); - $$ = new FieldAssignExpr($2, $4); + $$ = new FieldAssignExpr($2, {AdoptRef{}, $4}); } | '$' TOK_ID func_params '=' @@ -516,20 +516,20 @@ expr: } func_body { - $$ = new FieldAssignExpr($2, new ConstExpr(func_id->ID_Val()->Ref())); + $$ = new FieldAssignExpr($2, make_intrusive(IntrusivePtr{NewRef{}, func_id->ID_Val()})); Unref(func_id); } | expr TOK_IN expr { set_location(@1, @3); - $$ = new InExpr($1, $3); + $$ = new InExpr({AdoptRef{}, $1}, {AdoptRef{}, $3}); } | expr TOK_NOT_IN expr { set_location(@1, @3); - $$ = new NotExpr(new InExpr($1, $3)); + $$ = new NotExpr(make_intrusive(IntrusivePtr{AdoptRef{}, $1}, IntrusivePtr{AdoptRef{}, $3})); } | '[' expr_list ']' @@ -552,7 +552,7 @@ expr: } if ( is_record_ctor ) - $$ = new RecordConstructorExpr($2); + $$ = new RecordConstructorExpr({AdoptRef{}, $2}); else $$ = $2; } @@ -560,33 +560,33 @@ expr: | '[' ']' { // We interpret this as an empty record constructor. - $$ = new RecordConstructorExpr(new ListExpr); + $$ = new RecordConstructorExpr(make_intrusive()); } | TOK_RECORD '(' expr_list ')' { set_location(@1, @4); - $$ = new RecordConstructorExpr($3); + $$ = new RecordConstructorExpr({AdoptRef{}, $3}); } | TOK_TABLE '(' { ++in_init; } opt_expr_list ')' { --in_init; } opt_attr { // the ++in_init fixes up the parsing of "[x] = y" set_location(@1, @5); - $$ = new TableConstructorExpr($4, $7); + $$ = new TableConstructorExpr({AdoptRef{}, $4}, $7); } | TOK_SET '(' opt_expr_list ')' opt_attr { set_location(@1, @4); - $$ = new SetConstructorExpr($3, $5); + $$ = new SetConstructorExpr({AdoptRef{}, $3}, $5); } | TOK_VECTOR '(' opt_expr_list ')' { set_location(@1, @4); - $$ = new VectorConstructorExpr($3); + $$ = new VectorConstructorExpr({AdoptRef{}, $3}); } | expr '(' @@ -612,20 +612,20 @@ expr: { switch ( ctor_type->Tag() ) { case TYPE_RECORD: - $$ = new RecordCoerceExpr(new RecordConstructorExpr($4), - ctor_type->AsRecordType()); + $$ = new RecordCoerceExpr(make_intrusive(IntrusivePtr{AdoptRef{}, $4}), + {NewRef{}, ctor_type->AsRecordType()}); break; case TYPE_TABLE: if ( ctor_type->IsTable() ) - $$ = new TableConstructorExpr($4, 0, ctor_type); + $$ = new TableConstructorExpr({AdoptRef{}, $4}, 0, {NewRef{}, ctor_type}); else - $$ = new SetConstructorExpr($4, 0, ctor_type); + $$ = new SetConstructorExpr({AdoptRef{}, $4}, 0, {NewRef{}, ctor_type}); break; case TYPE_VECTOR: - $$ = new VectorConstructorExpr($4, ctor_type); + $$ = new VectorConstructorExpr({AdoptRef{}, $4}, {NewRef{}, ctor_type}); break; default: @@ -635,7 +635,7 @@ expr: } else - $$ = new CallExpr($1, $4, in_hook > 0); + $$ = new CallExpr({AdoptRef{}, $1}, {AdoptRef{}, $4}, in_hook > 0); } | TOK_HOOK { ++in_hook; } expr @@ -650,7 +650,7 @@ expr: | expr TOK_HAS_FIELD TOK_ID { set_location(@1, @3); - $$ = new HasFieldExpr($1, $3); + $$ = new HasFieldExpr({AdoptRef{}, $1}, $3); } | anonymous_function @@ -659,7 +659,7 @@ expr: | TOK_SCHEDULE expr '{' event '}' { set_location(@1, @5); - $$ = new ScheduleExpr($2, $4); + $$ = new ScheduleExpr({AdoptRef{}, $2}, {AdoptRef{}, $4}); } | TOK_ID @@ -694,7 +694,7 @@ expr: { id->Error("undeclared variable"); id->SetType(error_type()); - $$ = new NameExpr(id.release()); + $$ = new NameExpr(std::move(id)); } else if ( id->IsEnumConst() ) @@ -704,11 +704,11 @@ expr: id->Name()); if ( intval < 0 ) reporter->InternalError("enum value not found for %s", id->Name()); - $$ = new ConstExpr(t->GetVal(intval)); + $$ = new ConstExpr({AdoptRef{}, t->GetVal(intval)}); } else { - $$ = new NameExpr(id.release()); + $$ = new NameExpr(std::move(id)); } } } @@ -716,7 +716,7 @@ expr: | TOK_CONSTANT { set_location(@1); - $$ = new ConstExpr($1); + $$ = new ConstExpr({AdoptRef{}, $1}); } | '/' { begin_RE(); } TOK_PATTERN_TEXT TOK_PATTERN_END @@ -730,30 +730,30 @@ expr: re->MakeCaseInsensitive(); re->Compile(); - $$ = new ConstExpr(new PatternVal(re)); + $$ = new ConstExpr(make_intrusive(re)); } | '|' expr '|' %prec '(' { set_location(@1, @3); - auto e = $2; + IntrusivePtr e{AdoptRef{}, $2}; if ( IsIntegral(e->Type()->Tag()) ) - e = new ArithCoerceExpr(e, TYPE_INT); + e = make_intrusive(std::move(e), TYPE_INT); - $$ = new SizeExpr(e); + $$ = new SizeExpr(std::move(e)); } | expr TOK_AS type { set_location(@1, @3); - $$ = new CastExpr($1, $3); + $$ = new CastExpr({AdoptRef{}, $1}, {AdoptRef{}, $3}); } | expr TOK_IS type { set_location(@1, @3); - $$ = new IsExpr($1, $3); + $$ = new IsExpr({AdoptRef{}, $1}, {AdoptRef{}, $3}); } ; @@ -761,13 +761,13 @@ expr_list: expr_list ',' expr { set_location(@1, @3); - $1->Append($3); + $1->Append({AdoptRef{}, $3}); } | expr { set_location(@1); - $$ = new ListExpr($1); + $$ = new ListExpr({AdoptRef{}, $1}); } ; @@ -1301,15 +1301,15 @@ index_slice: expr '[' opt_expr ':' opt_expr ']' { set_location(@1, @6); - Expr* low = $3 ? $3 : new ConstExpr(val_mgr->GetCount(0)); - Expr* high = $5 ? $5 : new SizeExpr($1->Ref()); + auto low = $3 ? IntrusivePtr{AdoptRef{}, $3} : make_intrusive(IntrusivePtr{AdoptRef{}, val_mgr->GetCount(0)}); + auto high = $5 ? IntrusivePtr{AdoptRef{}, $5} : make_intrusive(IntrusivePtr{NewRef{}, $1}); if ( ! IsIntegral(low->Type()->Tag()) || ! IsIntegral(high->Type()->Tag()) ) reporter->Error("slice notation must have integral values as indexes"); - ListExpr* le = new ListExpr(low); - le->Append(high); - $$ = new IndexExpr($1, le, true); + auto le = make_intrusive(std::move(low)); + le->Append(std::move(high)); + $$ = new IndexExpr({AdoptRef{}, $1}, std::move(le), true); } opt_attr: @@ -1364,7 +1364,7 @@ attr: | TOK_ATTR_DEPRECATED '=' TOK_CONSTANT { if ( IsString($3->Type()->Tag()) ) - $$ = new Attr(ATTR_DEPRECATED, new ConstExpr($3)); + $$ = new Attr(ATTR_DEPRECATED, new ConstExpr({AdoptRef{}, $3})); else { ODesc d; @@ -1534,7 +1534,7 @@ stmt: | index_slice '=' expr ';' opt_no_test { set_location(@1, @4); - $$ = new ExprStmt(get_assign_expr($1, $3, in_init)); + $$ = new ExprStmt(get_assign_expr({AdoptRef{}, $1}, {AdoptRef{}, $3}, in_init).release()); if ( ! $5 ) brofiler.AddStmt($$); @@ -1586,7 +1586,7 @@ event: reporter->Warning("%s", id->GetDeprecationWarning().c_str()); } - $$ = new EventExpr($1, $3); + $$ = new EventExpr($1, {AdoptRef{}, $3}); } ; @@ -1839,19 +1839,19 @@ opt_no_test_block: opt_deprecated: TOK_ATTR_DEPRECATED - { $$ = new ConstExpr(new StringVal("")); } + { $$ = new ConstExpr(make_intrusive("")); } | TOK_ATTR_DEPRECATED '=' TOK_CONSTANT { if ( IsString($3->Type()->Tag()) ) - $$ = new ConstExpr($3); + $$ = new ConstExpr({AdoptRef{}, $3}); else { ODesc d; $3->Describe(&d); reporter->Error("'&deprecated=%s' must use a string literal", d.Description()); - $$ = new ConstExpr(new StringVal("")); + $$ = new ConstExpr(make_intrusive("")); } } | diff --git a/src/scan.l b/src/scan.l index ca197501d6..641a0d6fb3 100644 --- a/src/scan.l +++ b/src/scan.l @@ -20,6 +20,7 @@ #include "Expr.h" #include "Func.h" #include "Stmt.h" +#include "IntrusivePtr.h" #include "Val.h" #include "Var.h" #include "Debug.h" @@ -746,7 +747,7 @@ void do_atif(Expr* expr) LocalNameFinder cb; expr->Traverse(&cb); - Val* val = 0; + IntrusivePtr val; if ( cb.local_names.empty() ) val = expr->Eval(0); @@ -767,8 +768,6 @@ void do_atif(Expr* expr) if_stack.push_back(current_depth); BEGIN(IGNORE); } - - Unref(val); } void do_atifdef(const char* id)