diff --git a/src/Attr.cc b/src/Attr.cc index 5e8fb4bd7b..bbef7742ea 100644 --- a/src/Attr.cc +++ b/src/Attr.cc @@ -23,18 +23,20 @@ const char* attr_name(attr_tag t) return attr_names[int(t)]; } -Attr::Attr(attr_tag t, Expr* e) +Attr::Attr(attr_tag t, IntrusivePtr e) + : expr(std::move(e)) { tag = t; - expr = e; SetLocationInfo(&start_location, &end_location); } -Attr::~Attr() +Attr::Attr(attr_tag t) + : Attr(t, nullptr) { - Unref(expr); } +Attr::~Attr() = default; + void Attr::Describe(ODesc* d) const { AddTag(d); @@ -131,10 +133,10 @@ void Attr::AddTag(ODesc* d) const d->Add(attr_name(Tag())); } -Attributes::Attributes(attr_list* a, BroType* t, bool arg_in_record, bool is_global) +Attributes::Attributes(attr_list* a, IntrusivePtr t, bool arg_in_record, bool is_global) + : type(std::move(t)) { attrs = new attr_list(a->length()); - type = t->Ref(); in_record = arg_in_record; global_var = is_global; @@ -145,7 +147,7 @@ Attributes::Attributes(attr_list* a, BroType* t, bool arg_in_record, bool is_glo // the necessary checking gets done. for ( const auto& attr : *a ) - AddAttr(attr); + AddAttr({NewRef{}, attr}); delete a; } @@ -156,23 +158,20 @@ Attributes::~Attributes() Unref(attr); delete attrs; - - Unref(type); } -void Attributes::AddAttr(Attr* attr) +void Attributes::AddAttr(IntrusivePtr attr) { if ( ! attrs ) attrs = new attr_list(1); // We overwrite old attributes by deleting them first. RemoveAttr(attr->Tag()); - attrs->push_back(attr); - Ref(attr); + attrs->push_back(IntrusivePtr{attr}.release()); // We only check the attribute after we've added it, to facilitate // generating error messages via Attributes::Describe. - CheckAttr(attr); + CheckAttr(attr.get()); // For ADD_FUNC or DEL_FUNC, add in an implicit REDEF, since // those attributes only have meaning for a redefinable value. @@ -190,7 +189,7 @@ void Attributes::AddAttrs(Attributes* a) { attr_list* as = a->Attrs(); for ( const auto& attr : *as ) - AddAttr(attr); + AddAttr({NewRef{}, attr}); Unref(a); } @@ -274,7 +273,7 @@ void Attributes::CheckAttr(Attr* a) } FuncType* aft = at->AsFuncType(); - if ( ! same_type(aft->YieldType(), type) ) + if ( ! same_type(aft->YieldType(), type.get()) ) { a->AttrExpr()->Error( is_add ? @@ -299,7 +298,7 @@ void Attributes::CheckAttr(Attr* a) if ( type->Tag() != TYPE_TABLE || (type->IsSet() && ! in_record) ) { - if ( same_type(atype, type) ) + if ( same_type(atype, type.get()) ) // Ok. break; @@ -315,15 +314,16 @@ void Attributes::CheckAttr(Attr* a) // Ok. break; - Expr* e = a->AttrExpr(); - if ( check_and_promote_expr(e, type) ) + auto e = check_and_promote_expr(a->AttrExpr(), type.get()); + + if ( e ) { - a->SetAttrExpr(e); + a->SetAttrExpr(std::move(e)); // Ok. break; } - a->AttrExpr()->Error("&default value has inconsistent type", type); + a->AttrExpr()->Error("&default value has inconsistent type", type.get()); return; } @@ -354,10 +354,11 @@ void Attributes::CheckAttr(Attr* a) // Ok. break; - Expr* e = a->AttrExpr(); - if ( check_and_promote_expr(e, ytype) ) + auto e = check_and_promote_expr(a->AttrExpr(), ytype); + + if ( e ) { - a->SetAttrExpr(e); + a->SetAttrExpr(std::move(e)); // Ok. break; } @@ -373,17 +374,17 @@ void Attributes::CheckAttr(Attr* a) { // &default applies to record field. - if ( same_type(atype, type) ) + if ( same_type(atype, type.get()) ) // Ok. break; if ( (atype->Tag() == TYPE_TABLE && atype->AsTableType()->IsUnspecifiedTable()) ) { - Expr* e = a->AttrExpr(); + auto e = check_and_promote_expr(a->AttrExpr(), type.get()); - if ( check_and_promote_expr(e, type) ) + if ( e ) { - a->SetAttrExpr(e); + a->SetAttrExpr(std::move(e)); break; } } @@ -574,7 +575,7 @@ void Attributes::CheckAttr(Attr* a) break; case ATTR_LOG: - if ( ! threading::Value::IsCompatibleType(type) ) + if ( ! threading::Value::IsCompatibleType(type.get()) ) Error("&log applied to a type that cannot be logged"); break; diff --git a/src/Attr.h b/src/Attr.h index 1a13eab913..f09b3a7a6e 100644 --- a/src/Attr.h +++ b/src/Attr.h @@ -4,6 +4,7 @@ #include "Obj.h" #include "BroList.h" +#include "IntrusivePtr.h" class Expr; @@ -35,18 +36,15 @@ typedef enum { class Attr : public BroObj { public: - explicit Attr(attr_tag t, Expr* e = 0); + Attr(attr_tag t, IntrusivePtr e); + explicit Attr(attr_tag t); ~Attr() override; attr_tag Tag() const { return tag; } - Expr* AttrExpr() const { return expr; } + Expr* AttrExpr() const { return expr.get(); } - // Up to the caller to decide if previous expr can be unref'd since it may - // not always be safe; e.g. expressions (at time of writing) don't always - // keep careful track of referencing their operands, so doing something - // like SetAttrExpr(coerce(AttrExpr())) must not completely unref the - // previous expr as the new expr depends on it. - void SetAttrExpr(Expr* e) { expr = e; } + template + void SetAttrExpr(E&& e) { expr = std::forward(e); } void Describe(ODesc* d) const override; void DescribeReST(ODesc* d, bool shorten = false) const; @@ -69,16 +67,16 @@ protected: void AddTag(ODesc* d) const; attr_tag tag; - Expr* expr; + IntrusivePtr expr; }; // Manages a collection of attributes. class Attributes : public BroObj { public: - Attributes(attr_list* a, BroType* t, bool in_record, bool is_global); + Attributes(attr_list* a, IntrusivePtr t, bool in_record, bool is_global); ~Attributes() override; - void AddAttr(Attr* a); + void AddAttr(IntrusivePtr a); void AddAttrs(Attributes* a); // Unref's 'a' when done Attr* FindAttr(attr_tag t) const; @@ -93,10 +91,9 @@ public: bool operator==(const Attributes& other) const; protected: - Attributes() : type(), attrs(), in_record() { } void CheckAttr(Attr* attr); - BroType* type; + IntrusivePtr type; attr_list* attrs; bool in_record; bool global_var; diff --git a/src/CompHash.cc b/src/CompHash.cc index f617f253ec..7406410b7d 100644 --- a/src/CompHash.cc +++ b/src/CompHash.cc @@ -180,9 +180,9 @@ char* CompositeHash::SingleValHash(int type_check, char* kp0, for ( int i = 0; i < num_fields; ++i ) { - Val* rv_i = rv->Lookup(i); + auto rv_i = rv->Lookup(i); - Attributes* a = rt->FieldDecl(i)->attrs; + Attributes* a = rt->FieldDecl(i)->attrs.get(); bool optional = (a && a->FindAttr(ATTR_OPTIONAL)); if ( ! (rv_i || optional) ) @@ -249,9 +249,10 @@ char* CompositeHash::SingleValHash(int type_check, char* kp0, if ( ! v->Type()->IsSet() ) { - Val* val = tv->Lookup(key); + auto val = tv->Lookup(key); + if ( ! (kp1 = SingleValHash(type_check, kp1, val->Type(), - val, false)) ) + val.get(), false)) ) { Unref(lv); return 0; @@ -519,7 +520,7 @@ int CompositeHash::SingleTypeKeySize(BroType* bt, const Val* v, for ( int i = 0; i < num_fields; ++i ) { - Attributes* a = rt->FieldDecl(i)->attrs; + Attributes* a = rt->FieldDecl(i)->attrs.get(); bool optional = (a && a->FindAttr(ATTR_OPTIONAL)); sz = SingleTypeKeySize(rt->FieldType(i), @@ -554,8 +555,8 @@ int CompositeHash::SingleTypeKeySize(BroType* bt, const Val* v, if ( ! bt->IsSet() ) { - Val* val = tv->Lookup(key); - sz = SingleTypeKeySize(val->Type(), val, type_check, sz, + auto val = tv->Lookup(key); + sz = SingleTypeKeySize(val->Type(), val.get(), type_check, sz, false, calc_static_size); if ( ! sz ) { @@ -720,19 +721,19 @@ int CompositeHash::SizeAlign(int offset, unsigned int size) const return offset; } -ListVal* CompositeHash::RecoverVals(const HashKey* k) const +IntrusivePtr CompositeHash::RecoverVals(const HashKey* k) const { - ListVal* l = new ListVal(TYPE_ANY); + auto l = make_intrusive(TYPE_ANY); const type_list* tl = type->Types(); const char* kp = (const char*) k->Key(); const char* const k_end = kp + k->Size(); for ( const auto& type : *tl ) { - Val* v = nullptr; - kp = RecoverOneVal(k, kp, k_end, type, v, false); + IntrusivePtr v; + kp = RecoverOneVal(k, kp, k_end, type, &v, false); ASSERT(v); - l->Append(v); + l->Append(v.release()); } if ( kp != k_end ) @@ -743,7 +744,7 @@ ListVal* CompositeHash::RecoverVals(const HashKey* k) const const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0, const char* const k_end, BroType* t, - Val*& pval, bool optional) const + IntrusivePtr* pval, bool optional) const { // k->Size() == 0 for a single empty string. if ( kp0 >= k_end && k->Size() > 0 ) @@ -760,7 +761,7 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0, if ( ! *kp ) { - pval = 0; + *pval = nullptr; return kp0; } } @@ -772,15 +773,15 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0, kp1 = reinterpret_cast(kp+1); if ( tag == TYPE_ENUM ) - pval = t->AsEnumType()->GetVal(*kp); + *pval = t->AsEnumType()->GetVal(*kp); else if ( tag == TYPE_BOOL ) - pval = val_mgr->GetBool(*kp); + *pval = {AdoptRef{}, val_mgr->GetBool(*kp)}; else if ( tag == TYPE_INT ) - pval = val_mgr->GetInt(*kp); + *pval = {AdoptRef{}, val_mgr->GetInt(*kp)}; else { reporter->InternalError("bad internal unsigned int in CompositeHash::RecoverOneVal()"); - pval = 0; + *pval = nullptr; } } break; @@ -793,16 +794,16 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0, switch ( tag ) { case TYPE_COUNT: case TYPE_COUNTER: - pval = val_mgr->GetCount(*kp); + *pval = {AdoptRef{}, val_mgr->GetCount(*kp)}; break; case TYPE_PORT: - pval = val_mgr->GetPort(*kp); + *pval = {AdoptRef{}, val_mgr->GetPort(*kp)}; break; default: reporter->InternalError("bad internal unsigned int in CompositeHash::RecoverOneVal()"); - pval = 0; + *pval = nullptr; break; } } @@ -814,9 +815,9 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0, kp1 = reinterpret_cast(kp+1); if ( tag == TYPE_INTERVAL ) - pval = new IntervalVal(*kp, 1.0); + *pval = make_intrusive(*kp, 1.0); else - pval = new Val(*kp, tag); + *pval = make_intrusive(*kp, tag); } break; @@ -829,12 +830,12 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0, switch ( tag ) { case TYPE_ADDR: - pval = new AddrVal(addr); + *pval = make_intrusive(addr); break; default: reporter->InternalError("bad internal address in CompositeHash::RecoverOneVal()"); - pval = 0; + *pval = nullptr; break; } } @@ -844,7 +845,7 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0, { const uint32_t* const kp = AlignType(kp0); kp1 = reinterpret_cast(kp+5); - pval = new SubNetVal(kp, kp[4]); + *pval = make_intrusive(kp, kp[4]); } break; @@ -862,20 +863,19 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0, if ( ! f ) reporter->InternalError("failed to look up unique function id %" PRIu32 " in CompositeHash::RecoverOneVal()", *kp); - pval = new Val(f); + *pval = make_intrusive(f); + auto pvt = (*pval)->Type(); - if ( ! pval->Type() ) + if ( ! pvt ) reporter->InternalError("bad aggregate Val in CompositeHash::RecoverOneVal()"); - else if ( t->Tag() != TYPE_FUNC && - ! same_type(pval->Type(), t) ) + else if ( t->Tag() != TYPE_FUNC && ! same_type(pvt, t) ) // ### Maybe fix later, but may be fundamentally // un-checkable --US reporter->InternalError("inconsistent aggregate Val in CompositeHash::RecoverOneVal()"); // ### A crude approximation for now. - else if ( t->Tag() == TYPE_FUNC && - pval->Type()->Tag() != TYPE_FUNC ) + else if ( t->Tag() == TYPE_FUNC && pvt->Tag() != TYPE_FUNC ) reporter->InternalError("inconsistent aggregate Val in CompositeHash::RecoverOneVal()"); } break; @@ -898,7 +898,7 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0, re = new RE_Matcher(kp1, kp1 + len[0]); kp1 += len[0] + len[1]; } - pval = new PatternVal(re); + *pval = make_intrusive(re); } break; @@ -912,13 +912,13 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0, int i; for ( i = 0; i < num_fields; ++i ) { - Val* v; + IntrusivePtr v; - Attributes* a = rt->FieldDecl(i)->attrs; + Attributes* a = rt->FieldDecl(i)->attrs.get(); bool optional = (a && a->FindAttr(ATTR_OPTIONAL)); kp = RecoverOneVal(k, kp, k_end, - rt->FieldType(i), v, optional); + rt->FieldType(i), &v, optional); // An earlier call to reporter->InternalError would have called abort() and broken the // call tree that clang-tidy is relying on to get the error described. @@ -926,21 +926,21 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0, if ( ! (v || optional) ) { reporter->InternalError("didn't recover expected number of fields from HashKey"); - pval = 0; + pval = nullptr; break; } - values.push_back(v); + values.push_back(v.release()); } ASSERT(int(values.size()) == num_fields); - RecordVal* rv = new RecordVal(rt); + auto rv = make_intrusive(rt); for ( int i = 0; i < num_fields; ++i ) rv->Assign(i, values[i]); - pval = rv; + *pval = std::move(rv); kp1 = kp; } break; @@ -952,29 +952,25 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0, n = *kp; kp1 = reinterpret_cast(kp+1); TableType* tt = t->AsTableType(); - TableVal* tv = new TableVal(tt); - vector keys, values; + auto tv = make_intrusive(IntrusivePtr{NewRef{}, tt}); + for ( int i = 0; i < n; ++i ) { - Val* key; - kp1 = RecoverOneVal(k, kp1, k_end, tt->Indices(), key, false); - keys.push_back(key); - if ( ! t->IsSet() ) + IntrusivePtr key; + kp1 = RecoverOneVal(k, kp1, k_end, tt->Indices(), &key, false); + + if ( t->IsSet() ) + tv->Assign(key.get(), nullptr); + else { - Val* value; - kp1 = RecoverOneVal(k, kp1, k_end, tt->YieldType(), value, + IntrusivePtr value; + kp1 = RecoverOneVal(k, kp1, k_end, tt->YieldType(), &value, false); - values.push_back(value); + tv->Assign(key.get(), std::move(value)); } } - for ( int i = 0; i < n; ++i ) - { - tv->Assign(keys[i], t->IsSet() ? 0 : values[i]); - Unref(keys[i]); - } - - pval = tv; + *pval = std::move(tv); } break; @@ -985,7 +981,8 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0, n = *kp; kp1 = reinterpret_cast(kp+1); VectorType* vt = t->AsVectorType(); - VectorVal* vv = new VectorVal(vt); + auto vv = make_intrusive(vt); + for ( unsigned int i = 0; i < n; ++i ) { kp = AlignType(kp1); @@ -994,14 +991,16 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0, kp = AlignType(kp1); unsigned int have_val = *kp; kp1 = reinterpret_cast(kp+1); - Val* value = 0; + IntrusivePtr value; + if ( have_val ) - kp1 = RecoverOneVal(k, kp1, k_end, vt->YieldType(), value, + kp1 = RecoverOneVal(k, kp1, k_end, vt->YieldType(), &value, false); - vv->Assign(index, value); + + vv->Assign(index, std::move(value)); } - pval = vv; + *pval = std::move(vv); } break; @@ -1012,16 +1011,17 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0, n = *kp; kp1 = reinterpret_cast(kp+1); TypeList* tl = t->AsTypeList(); - ListVal* lv = new ListVal(TYPE_ANY); + auto lv = make_intrusive(TYPE_ANY); + for ( int i = 0; i < n; ++i ) { - Val* v; + IntrusivePtr v; BroType* it = (*tl->Types())[i]; - kp1 = RecoverOneVal(k, kp1, k_end, it, v, false); - lv->Append(v); + kp1 = RecoverOneVal(k, kp1, k_end, it, &v, false); + lv->Append(v.release()); } - pval = lv; + *pval = std::move(lv); } break; @@ -1051,7 +1051,7 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0, kp1 = reinterpret_cast(kp+1); } - pval = new StringVal(new BroString((const byte_vec) kp1, n, 1)); + *pval = make_intrusive(new BroString((const byte_vec) kp1, n, 1)); kp1 += n; } break; diff --git a/src/CompHash.h b/src/CompHash.h index 9aa3555200..c604576bd3 100644 --- a/src/CompHash.h +++ b/src/CompHash.h @@ -18,7 +18,7 @@ public: HashKey* ComputeHash(const Val* v, int type_check) const; // Given a hash key, recover the values used to create it. - ListVal* RecoverVals(const HashKey* k) const; + IntrusivePtr RecoverVals(const HashKey* k) const; unsigned int MemoryAllocation() const { return padded_sizeof(*this) + pad_size(size); } @@ -36,7 +36,7 @@ protected: // upon errors, so there is no return value for invalid input. const char* RecoverOneVal(const HashKey* k, const char* kp, const char* const k_end, - BroType* t, Val*& pval, bool optional) const; + BroType* t, IntrusivePtr* pval, bool optional) const; // Rounds the given pointer up to the nearest multiple of the // given size, if not already a multiple. diff --git a/src/Conn.cc b/src/Conn.cc index 67b7ad772c..99d1b22933 100644 --- a/src/Conn.cc +++ b/src/Conn.cc @@ -337,13 +337,13 @@ RecordVal* Connection::BuildConnVal() TransportProto prot_type = ConnTransport(); - RecordVal* id_val = new RecordVal(conn_id); - id_val->Assign(0, new AddrVal(orig_addr)); + auto id_val = make_intrusive(conn_id); + id_val->Assign(0, make_intrusive(orig_addr)); id_val->Assign(1, val_mgr->GetPort(ntohs(orig_port), prot_type)); - id_val->Assign(2, new AddrVal(resp_addr)); + id_val->Assign(2, make_intrusive(resp_addr)); id_val->Assign(3, val_mgr->GetPort(ntohs(resp_port), prot_type)); - RecordVal* orig_endp = new RecordVal(endpoint); + auto orig_endp = make_intrusive(endpoint); orig_endp->Assign(0, val_mgr->GetCount(0)); orig_endp->Assign(1, val_mgr->GetCount(0)); orig_endp->Assign(4, val_mgr->GetCount(orig_flow_label)); @@ -352,27 +352,27 @@ RecordVal* Connection::BuildConnVal() char null[l2_len]{}; if ( memcmp(&orig_l2_addr, &null, l2_len) != 0 ) - orig_endp->Assign(5, new StringVal(fmt_mac(orig_l2_addr, l2_len))); + orig_endp->Assign(5, make_intrusive(fmt_mac(orig_l2_addr, l2_len))); - RecordVal* resp_endp = new RecordVal(endpoint); + auto resp_endp = make_intrusive(endpoint); resp_endp->Assign(0, val_mgr->GetCount(0)); resp_endp->Assign(1, val_mgr->GetCount(0)); resp_endp->Assign(4, val_mgr->GetCount(resp_flow_label)); if ( memcmp(&resp_l2_addr, &null, l2_len) != 0 ) - resp_endp->Assign(5, new StringVal(fmt_mac(resp_l2_addr, l2_len))); + resp_endp->Assign(5, make_intrusive(fmt_mac(resp_l2_addr, l2_len))); - conn_val->Assign(0, id_val); - conn_val->Assign(1, orig_endp); - conn_val->Assign(2, resp_endp); + conn_val->Assign(0, std::move(id_val)); + conn_val->Assign(1, std::move(orig_endp)); + conn_val->Assign(2, std::move(resp_endp)); // 3 and 4 are set below. - conn_val->Assign(5, new TableVal(string_set)); // service + conn_val->Assign(5, make_intrusive(IntrusivePtr{NewRef{}, string_set})); // service conn_val->Assign(6, val_mgr->GetEmptyString()); // history if ( ! uid ) uid.Set(bits_per_uid); - conn_val->Assign(7, new StringVal(uid.Base62("C").c_str())); + conn_val->Assign(7, make_intrusive(uid.Base62("C").c_str())); if ( encapsulation && encapsulation->Depth() > 0 ) conn_val->Assign(8, encapsulation->GetVectorVal()); @@ -388,9 +388,9 @@ RecordVal* Connection::BuildConnVal() if ( root_analyzer ) root_analyzer->UpdateConnVal(conn_val); - conn_val->Assign(3, new Val(start_time, TYPE_TIME)); // ### - conn_val->Assign(4, new Val(last_time - start_time, TYPE_INTERVAL)); - conn_val->Assign(6, new StringVal(history.c_str())); + conn_val->Assign(3, make_intrusive(start_time, TYPE_TIME)); // ### + conn_val->Assign(4, make_intrusive(last_time - start_time, TYPE_INTERVAL)); + conn_val->Assign(6, make_intrusive(history.c_str())); conn_val->Assign(11, val_mgr->GetBool(is_successful)); conn_val->SetOrigin(this); @@ -422,7 +422,7 @@ void Connection::AppendAddl(const char* str) const char* old = conn_val->Lookup(6)->AsString()->CheckString(); const char* format = *old ? "%s %s" : "%s%s"; - conn_val->Assign(6, new StringVal(fmt(format, old, str))); + conn_val->Assign(6, make_intrusive(fmt(format, old, str))); } // Returns true if the character at s separates a version number. diff --git a/src/DNS_Mgr.cc b/src/DNS_Mgr.cc index f6be03077a..d7c76d8bd6 100644 --- a/src/DNS_Mgr.cc +++ b/src/DNS_Mgr.cc @@ -32,11 +32,13 @@ #include #include "BroString.h" +#include "Expr.h" #include "Event.h" #include "Net.h" #include "Val.h" #include "Var.h" #include "Reporter.h" +#include "IntrusivePtr.h" #include "iosource/Manager.h" #include "digest.h" @@ -118,9 +120,9 @@ public: return req_host ? req_host : req_addr.AsString(); } - ListVal* Addrs(); - TableVal* AddrsSet(); // addresses returned as a set - StringVal* Host(); + IntrusivePtr Addrs(); + IntrusivePtr AddrsSet(); // addresses returned as a set + IntrusivePtr Host(); double CreationTime() const { return creation_time; } @@ -154,11 +156,11 @@ protected: int num_names; char** names; - StringVal* host_val; + IntrusivePtr host_val; int num_addrs; IPAddr* addrs; - ListVal* addrs_val; + IntrusivePtr addrs_val; int failed; double creation_time; @@ -170,13 +172,13 @@ void DNS_Mgr_mapping_delete_func(void* v) delete (DNS_Mapping*) v; } -static TableVal* empty_addr_set() +static IntrusivePtr empty_addr_set() { - BroType* addr_t = base_type(TYPE_ADDR); - TypeList* set_index = new TypeList(addr_t); - set_index->Append(addr_t); - SetType* s = new SetType(set_index, 0); - return new TableVal(s); + auto addr_t = base_type(TYPE_ADDR); + auto set_index = make_intrusive(addr_t); + set_index->Append(std::move(addr_t)); + auto s = make_intrusive(std::move(set_index), nullptr); + return make_intrusive(std::move(s)); } DNS_Mapping::DNS_Mapping(const char* host, struct hostent* h, uint32_t ttl) @@ -268,48 +270,41 @@ DNS_Mapping::~DNS_Mapping() } delete [] addrs; - - Unref(host_val); - Unref(addrs_val); } -ListVal* DNS_Mapping::Addrs() +IntrusivePtr DNS_Mapping::Addrs() { if ( failed ) - return 0; + return nullptr; if ( ! addrs_val ) { - ListVal* hv = new ListVal(TYPE_ADDR); + auto addrs_val = make_intrusive(TYPE_ADDR); + for ( int i = 0; i < num_addrs; ++i ) - hv->Append(new AddrVal(addrs[i])); - addrs_val = hv; + addrs_val->Append(new AddrVal(addrs[i])); } - Ref(addrs_val); return addrs_val; } -TableVal* DNS_Mapping::AddrsSet() { - ListVal* l = Addrs(); +IntrusivePtr DNS_Mapping::AddrsSet() { + auto l = Addrs(); if ( ! l ) return empty_addr_set(); - auto rval = l->ConvertToSet(); - Unref(l); - return rval; + return {AdoptRef{}, l->ConvertToSet()}; } -StringVal* DNS_Mapping::Host() +IntrusivePtr DNS_Mapping::Host() { if ( failed || num_names == 0 || ! names[0] ) return 0; if ( ! host_val ) - host_val = new StringVal(names[0]); + host_val = make_intrusive(names[0]); - Ref(host_val); return host_val; } @@ -475,16 +470,14 @@ void DNS_Mgr::InitPostScript() LoadCache(fopen(cache_name, "r")); } -static TableVal* fake_name_lookup_result(const char* name) +static IntrusivePtr fake_name_lookup_result(const char* name) { uint32_t hash[4]; internal_md5(reinterpret_cast(name), strlen(name), reinterpret_cast(hash)); - ListVal* hv = new ListVal(TYPE_ADDR); + auto hv = make_intrusive(TYPE_ADDR); hv->Append(new AddrVal(hash)); - TableVal* tv = hv->ConvertToSet(); - Unref(hv); - return tv; + return {AdoptRef{}, hv->ConvertToSet()}; } static const char* fake_text_lookup_result(const char* name) @@ -502,7 +495,7 @@ static const char* fake_addr_lookup_result(const IPAddr& addr) return tmp; } -TableVal* DNS_Mgr::LookupHost(const char* name) +IntrusivePtr DNS_Mgr::LookupHost(const char* name) { if ( mode == DNS_FAKE ) return fake_name_lookup_result(name); @@ -528,10 +521,9 @@ TableVal* DNS_Mgr::LookupHost(const char* name) } else if ( d4 && d6 ) { - TableVal* tv4 = d4->AddrsSet(); - TableVal* tv6 = d6->AddrsSet(); - tv4->AddTo(tv6, false); - Unref(tv4); + auto tv4 = d4->AddrsSet(); + auto tv6 = d6->AddrsSet(); + tv4->AddTo(tv6.get(), false); return tv6; } } @@ -560,7 +552,7 @@ TableVal* DNS_Mgr::LookupHost(const char* name) } } -Val* DNS_Mgr::LookupAddr(const IPAddr& addr) +IntrusivePtr DNS_Mgr::LookupAddr(const IPAddr& addr) { InitSource(); @@ -577,7 +569,7 @@ Val* DNS_Mgr::LookupAddr(const IPAddr& addr) { string s(addr); reporter->Warning("can't resolve IP address: %s", s.c_str()); - return new StringVal(s.c_str()); + return make_intrusive(s.c_str()); } } } @@ -586,7 +578,7 @@ Val* DNS_Mgr::LookupAddr(const IPAddr& addr) switch ( mode ) { case DNS_PRIME: requests.push_back(new DNS_Mgr_Request(addr)); - return new StringVal(""); + return make_intrusive(""); case DNS_FORCE: reporter->FatalError("can't find DNS entry for %s in cache", @@ -712,19 +704,17 @@ void DNS_Mgr::Event(EventHandlerPtr e, DNS_Mapping* dm) if ( ! e ) return; - mgr.QueueEventFast(e, {BuildMappingVal(dm)}); + mgr.QueueEventFast(e, {BuildMappingVal(dm).release()}); } -void DNS_Mgr::Event(EventHandlerPtr e, DNS_Mapping* dm, ListVal* l1, ListVal* l2) +void DNS_Mgr::Event(EventHandlerPtr e, DNS_Mapping* dm, + IntrusivePtr l1, IntrusivePtr l2) { if ( ! e ) return; - Unref(l1); - Unref(l2); - mgr.QueueEventFast(e, { - BuildMappingVal(dm), + BuildMappingVal(dm).release(), l1->ConvertToSet(), l2->ConvertToSet(), }); @@ -736,22 +726,22 @@ void DNS_Mgr::Event(EventHandlerPtr e, DNS_Mapping* old_dm, DNS_Mapping* new_dm) return; mgr.QueueEventFast(e, { - BuildMappingVal(old_dm), - BuildMappingVal(new_dm), + BuildMappingVal(old_dm).release(), + BuildMappingVal(new_dm).release(), }); } -Val* DNS_Mgr::BuildMappingVal(DNS_Mapping* dm) +IntrusivePtr DNS_Mgr::BuildMappingVal(DNS_Mapping* dm) { - RecordVal* r = new RecordVal(dm_rec); + auto r = make_intrusive(dm_rec); - r->Assign(0, new Val(dm->CreationTime(), TYPE_TIME)); - r->Assign(1, new StringVal(dm->ReqHost() ? dm->ReqHost() : "")); - r->Assign(2, new AddrVal(dm->ReqAddr())); + r->Assign(0, make_intrusive(dm->CreationTime(), TYPE_TIME)); + r->Assign(1, make_intrusive(dm->ReqHost() ? dm->ReqHost() : "")); + r->Assign(2, make_intrusive(dm->ReqAddr())); r->Assign(3, val_mgr->GetBool(dm->Valid())); - Val* h = dm->Host(); - r->Assign(4, h ? h : new StringVal("")); + auto h = dm->Host(); + r->Assign(4, h ? h.release() : new StringVal("")); r->Assign(5, dm->AddrsSet()); return r; @@ -868,8 +858,8 @@ void DNS_Mgr::CompareMappings(DNS_Mapping* prev_dm, DNS_Mapping* new_dm) return; } - StringVal* prev_s = prev_dm->Host(); - StringVal* new_s = new_dm->Host(); + auto prev_s = prev_dm->Host(); + auto new_s = new_dm->Host(); if ( prev_s || new_s ) { @@ -879,13 +869,10 @@ void DNS_Mgr::CompareMappings(DNS_Mapping* prev_dm, DNS_Mapping* new_dm) Event(dns_mapping_lost_name, prev_dm); else if ( ! Bstr_eq(new_s->AsString(), prev_s->AsString()) ) Event(dns_mapping_name_changed, prev_dm, new_dm); - - Unref(prev_s); - Unref(new_s); } - ListVal* prev_a = prev_dm->Addrs(); - ListVal* new_a = new_dm->Addrs(); + auto prev_a = prev_dm->Addrs(); + auto new_a = new_dm->Addrs(); if ( ! prev_a || ! new_a ) { @@ -893,21 +880,16 @@ void DNS_Mgr::CompareMappings(DNS_Mapping* prev_dm, DNS_Mapping* new_dm) return; } - ListVal* prev_delta = AddrListDelta(prev_a, new_a); - ListVal* new_delta = AddrListDelta(new_a, prev_a); + auto prev_delta = AddrListDelta(prev_a.get(), new_a.get()); + auto new_delta = AddrListDelta(new_a.get(), prev_a.get()); if ( prev_delta->Length() > 0 || new_delta->Length() > 0 ) - Event(dns_mapping_altered, new_dm, prev_delta, new_delta); - else - { - Unref(prev_delta); - Unref(new_delta); - } + Event(dns_mapping_altered, new_dm, std::move(prev_delta), std::move(new_delta)); } -ListVal* DNS_Mgr::AddrListDelta(ListVal* al1, ListVal* al2) +IntrusivePtr DNS_Mgr::AddrListDelta(ListVal* al1, ListVal* al2) { - ListVal* delta = new ListVal(TYPE_ADDR); + auto delta = make_intrusive(TYPE_ADDR); for ( int i = 0; i < al1->Length(); ++i ) { @@ -1015,7 +997,7 @@ const char* DNS_Mgr::LookupAddrInCache(const IPAddr& addr) return d->names ? d->names[0] : "<\?\?\?>"; } -TableVal* DNS_Mgr::LookupNameInCache(const string& name) +IntrusivePtr DNS_Mgr::LookupNameInCache(const string& name) { HostMap::iterator it = host_mappings.find(name); if ( it == host_mappings.end() ) @@ -1038,10 +1020,9 @@ TableVal* DNS_Mgr::LookupNameInCache(const string& name) return 0; } - TableVal* tv4 = d4->AddrsSet(); - TableVal* tv6 = d6->AddrsSet(); - tv4->AddTo(tv6, false); - Unref(tv4); + auto tv4 = d4->AddrsSet(); + auto tv6 = d6->AddrsSet(); + tv4->AddTo(tv6.get(), false); return tv6; } @@ -1066,10 +1047,9 @@ const char* DNS_Mgr::LookupTextInCache(const string& name) } static void resolve_lookup_cb(DNS_Mgr::LookupCallback* callback, - TableVal* result) + IntrusivePtr result) { - callback->Resolved(result); - Unref(result); + callback->Resolved(result.get()); delete callback; } @@ -1129,10 +1109,10 @@ void DNS_Mgr::AsyncLookupName(const string& name, LookupCallback* callback) } // Do we already know the answer? - TableVal* addrs = LookupNameInCache(name); + auto addrs = LookupNameInCache(name); if ( addrs ) { - resolve_lookup_cb(callback, addrs); + resolve_lookup_cb(callback, std::move(addrs)); return; } @@ -1321,13 +1301,12 @@ void DNS_Mgr::CheckAsyncHostRequest(const char* host, bool timeout) if ( i != asyncs_names.end() ) { - TableVal* addrs = LookupNameInCache(host); + auto addrs = LookupNameInCache(host); if ( addrs ) { ++successful; - i->second->Resolved(addrs); - Unref(addrs); + i->second->Resolved(addrs.get()); } else if ( timeout ) diff --git a/src/DNS_Mgr.h b/src/DNS_Mgr.h index 3c816f1afb..248949b51b 100644 --- a/src/DNS_Mgr.h +++ b/src/DNS_Mgr.h @@ -12,6 +12,7 @@ #include "iosource/IOSource.h" #include "IPAddr.h" +template class IntrusivePtr; class Val; class ListVal; class TableVal; @@ -47,9 +48,9 @@ public: // Looks up the address or addresses of the given host, and returns // a set of addr. - TableVal* LookupHost(const char* host); + IntrusivePtr LookupHost(const char* host); - Val* LookupAddr(const IPAddr& addr); + IntrusivePtr LookupAddr(const IPAddr& addr); // Define the directory where to store the data. void SetDir(const char* arg_dir) { dir = copy_string(arg_dir); } @@ -59,7 +60,7 @@ public: int Save(); const char* LookupAddrInCache(const IPAddr& addr); - TableVal* LookupNameInCache(const string& name); + IntrusivePtr LookupNameInCache(const string& name); const char* LookupTextInCache(const string& name); // Support for async lookups. @@ -96,14 +97,15 @@ protected: friend class DNS_Mgr_Request; void Event(EventHandlerPtr e, DNS_Mapping* dm); - void Event(EventHandlerPtr e, DNS_Mapping* dm, ListVal* l1, ListVal* l2); + void Event(EventHandlerPtr e, DNS_Mapping* dm, + IntrusivePtr l1, IntrusivePtr l2); void Event(EventHandlerPtr e, DNS_Mapping* old_dm, DNS_Mapping* new_dm); - Val* BuildMappingVal(DNS_Mapping* dm); + IntrusivePtr BuildMappingVal(DNS_Mapping* dm); void AddResult(DNS_Mgr_Request* dr, struct nb_dns_result* r); void CompareMappings(DNS_Mapping* prev_dm, DNS_Mapping* new_dm); - ListVal* AddrListDelta(ListVal* al1, ListVal* al2); + IntrusivePtr AddrListDelta(ListVal* al1, ListVal* al2); void DumpAddrList(FILE* f, ListVal* al); typedef map > HostMap; diff --git a/src/Debug.cc b/src/Debug.cc index d42cb9f71e..39757277f6 100644 --- a/src/Debug.cc +++ b/src/Debug.cc @@ -234,7 +234,7 @@ static void parse_function_name(vector& result, Stmt* body = 0; // the particular body we care about; 0 = all if ( bodies.size() == 1 ) - body = bodies[0].stmts; + body = bodies[0].stmts.get(); else { while ( 1 ) @@ -245,8 +245,7 @@ static void parse_function_name(vector& result, { Stmt* first; Location stmt_loc; - get_first_statement(bodies[i].stmts, first, - stmt_loc); + get_first_statement(bodies[i].stmts.get(), first, stmt_loc); debug_msg("[%d] %s:%d\n", i+1, stmt_loc.filename, stmt_loc.first_line); } @@ -278,7 +277,7 @@ static void parse_function_name(vector& result, int option = atoi(input.c_str()); if ( option > 0 && option <= (int) bodies.size() ) { - body = bodies[option - 1].stmts; + body = bodies[option - 1].stmts.get(); break; } } @@ -308,7 +307,7 @@ static void parse_function_name(vector& result, for ( unsigned int i = 0; i < bodies.size(); ++i ) { - get_first_statement(bodies[i].stmts, first, stmt_loc); + get_first_statement(bodies[i].stmts.get(), first, stmt_loc); if ( ! first ) continue; diff --git a/src/DebugCmds.cc b/src/DebugCmds.cc index e9a6720dcd..f59651d65e 100644 --- a/src/DebugCmds.cc +++ b/src/DebugCmds.cc @@ -62,7 +62,7 @@ void lookup_global_symbols_regex(const string& orig_regex, vector& matches, ID* nextid; for ( const auto& sym : syms ) { - ID* nextid = sym.second; + ID* nextid = sym.second.get(); if ( ! func_only || nextid->Type()->Tag() == TYPE_FUNC ) if ( ! regexec (&re, nextid->Name(), 0, 0, 0) ) matches.push_back(nextid); diff --git a/src/EventHandler.cc b/src/EventHandler.cc index dc62971305..9a5cba56b1 100644 --- a/src/EventHandler.cc +++ b/src/EventHandler.cc @@ -114,7 +114,7 @@ void EventHandler::Call(val_list* vl, bool no_remote) if ( local ) // No try/catch here; we pass exceptions upstream. - Unref(local->Call(vl)); + local->Call(vl); else { for ( auto v : *vl ) @@ -138,21 +138,18 @@ void EventHandler::NewEvent(val_list* vl) { const char* fname = args->FieldName(i); BroType* ftype = args->FieldType(i); - Val* fdefault = args->FieldDefault(i); + auto fdefault = args->FieldDefault(i); - RecordVal* rec = new RecordVal(call_argument); - rec->Assign(0, new StringVal(fname)); + auto rec = make_intrusive(call_argument); + rec->Assign(0, make_intrusive(fname)); ODesc d; d.SetShort(); ftype->Describe(&d); - rec->Assign(1, new StringVal(d.Description())); + rec->Assign(1, make_intrusive(d.Description())); if ( fdefault ) - { - Ref(fdefault); - rec->Assign(2, fdefault); - } + rec->Assign(2, std::move(fdefault)); if ( i < vl->length() && (*vl)[i] ) { @@ -161,7 +158,7 @@ void EventHandler::NewEvent(val_list* vl) rec->Assign(3, val); } - vargs->Assign(i, rec); + vargs->Assign(i, std::move(rec)); } Event* ev = new Event(new_event, { diff --git a/src/Expr.cc b/src/Expr.cc index d419298ad8..ad6c18432c 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -134,7 +134,7 @@ bool Expr::IsError() const void Expr::SetError() { - SetType({AdoptRef{}, error_type()}); + SetType(error_type()); } void Expr::SetError(const char* msg) @@ -218,7 +218,7 @@ NameExpr::NameExpr(IntrusivePtr arg_id, bool const_init) in_const_init = const_init; if ( id->AsType() ) - SetType(make_intrusive(id->AsType())); + SetType(make_intrusive(IntrusivePtr{NewRef{}, id->AsType()})); else SetType({NewRef{}, id->Type()}); @@ -365,7 +365,7 @@ IntrusivePtr UnaryExpr::Eval(Frame* f) const 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).release() : 0); + result->Assign(i, v_i ? Fold(v_i) : nullptr); } return result; @@ -458,9 +458,7 @@ IntrusivePtr BinaryExpr::Eval(Frame* f) const 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)).release()); + v_result->Assign(i, Fold(v_op1->Lookup(i), v_op2->Lookup(i))); else v_result->Assign(i, nullptr); // SetError("undefined element in vector operation"); @@ -478,9 +476,8 @@ IntrusivePtr BinaryExpr::Eval(Frame* f) const { Val* vv_i = vv->Lookup(i); if ( vv_i ) - v_result->Assign(i, is_vec1 ? - Fold(vv_i, v2.get()).release() : - Fold(v1.get(), vv_i).release()); + v_result->Assign(i, is_vec1 ? Fold(vv_i, v2.get()) + : Fold(v1.get(), vv_i)); else v_result->Assign(i, nullptr); @@ -747,7 +744,6 @@ IntrusivePtr BinaryExpr::SetFold(Val* v1, Val* v2) const { TableVal* tv1 = v1->AsTableVal(); TableVal* tv2 = v2->AsTableVal(); - TableVal* result; bool res = false; switch ( tag ) { @@ -755,18 +751,24 @@ IntrusivePtr BinaryExpr::SetFold(Val* v1, Val* v2) const return {AdoptRef{}, tv1->Intersect(tv2)}; case EXPR_OR: - result = v1->Clone()->AsTableVal(); + { + auto rval = v1->Clone(); - if ( ! tv2->AddTo(result, false, false) ) + if ( ! tv2->AddTo(rval.get(), false, false) ) reporter->InternalError("set union failed to type check"); - return {AdoptRef{}, result}; + + return rval; + } case EXPR_SUB: - result = v1->Clone()->AsTableVal(); + { + auto rval = v1->Clone(); - if ( ! tv2->RemoveFrom(result) ) + if ( ! tv2->RemoveFrom(rval.get()) ) reporter->InternalError("set difference failed to type check"); - return {AdoptRef{}, result}; + + return rval; + } case EXPR_EQ: res = tv1->EqualTo(tv2); @@ -881,7 +883,7 @@ void BinaryExpr::PromoteType(TypeTag t, bool is_vector) if ( is_vector) SetType(make_intrusive(base_type(t))); else - SetType(IntrusivePtr{AdoptRef{}, base_type(t)}); + SetType(base_type(t)); } CloneExpr::CloneExpr(IntrusivePtr arg_op) @@ -909,7 +911,7 @@ IntrusivePtr CloneExpr::Eval(Frame* f) const IntrusivePtr CloneExpr::Fold(Val* v) const { - return {AdoptRef{}, v->Clone()}; + return v->Clone(); } IncrExpr::IncrExpr(BroExprTag arg_tag, IntrusivePtr arg_op) @@ -981,7 +983,7 @@ IntrusivePtr IncrExpr::Eval(Frame* f) const Val* elt = v_vec->Lookup(i); if ( elt ) - v_vec->Assign(i, DoSingleEval(f, elt).release()); + v_vec->Assign(i, DoSingleEval(f, elt)); else v_vec->Assign(i, nullptr); } @@ -1015,7 +1017,7 @@ ComplementExpr::ComplementExpr(IntrusivePtr arg_op) if ( bt != TYPE_COUNT ) ExprError("requires \"count\" operand"); else - SetType({AdoptRef{}, base_type(TYPE_COUNT)}); + SetType(base_type(TYPE_COUNT)); } IntrusivePtr ComplementExpr::Fold(Val* v) const @@ -1035,7 +1037,7 @@ NotExpr::NotExpr(IntrusivePtr arg_op) if ( ! IsIntegral(bt) && bt != TYPE_BOOL ) ExprError("requires an integral or boolean operand"); else - SetType({AdoptRef{}, base_type(TYPE_BOOL)}); + SetType(base_type(TYPE_BOOL)); } IntrusivePtr NotExpr::Fold(Val* v) const @@ -1055,20 +1057,20 @@ PosExpr::PosExpr(IntrusivePtr arg_op) t = t->AsVectorType()->YieldType(); TypeTag bt = t->Tag(); - BroType* base_result_type = 0; + IntrusivePtr base_result_type; if ( IsIntegral(bt) ) // Promote count and counter to int. base_result_type = base_type(TYPE_INT); else if ( bt == TYPE_INTERVAL || bt == TYPE_DOUBLE ) - base_result_type = t->Ref(); + base_result_type = {NewRef{}, t}; else ExprError("requires an integral or double operand"); if ( is_vector(op.get()) ) - SetType(make_intrusive(base_result_type)); + SetType(make_intrusive(std::move(base_result_type))); else - SetType({AdoptRef{}, base_result_type}); + SetType(std::move(base_result_type)); } IntrusivePtr PosExpr::Fold(Val* v) const @@ -1093,20 +1095,20 @@ NegExpr::NegExpr(IntrusivePtr arg_op) t = t->AsVectorType()->YieldType(); TypeTag bt = t->Tag(); - BroType* base_result_type = 0; + IntrusivePtr base_result_type; if ( IsIntegral(bt) ) // Promote count and counter to int. base_result_type = base_type(TYPE_INT); else if ( bt == TYPE_INTERVAL || bt == TYPE_DOUBLE ) - base_result_type = t->Ref(); + base_result_type = {NewRef{}, t}; else ExprError("requires an integral or double operand"); if ( is_vector(op.get()) ) - SetType(make_intrusive(base_result_type)); + SetType(make_intrusive(std::move(base_result_type))); else - SetType({AdoptRef{}, base_result_type}); + SetType(std::move(base_result_type)); } IntrusivePtr NegExpr::Fold(Val* v) const @@ -1126,9 +1128,9 @@ SizeExpr::SizeExpr(IntrusivePtr arg_op) return; if ( op->Type()->InternalType() == TYPE_INTERNAL_DOUBLE ) - SetType({AdoptRef{}, base_type(TYPE_DOUBLE)}); + SetType(base_type(TYPE_DOUBLE)); else - SetType({AdoptRef{}, base_type(TYPE_COUNT)}); + SetType(base_type(TYPE_COUNT)); } IntrusivePtr SizeExpr::Eval(Frame* f) const @@ -1143,7 +1145,7 @@ IntrusivePtr SizeExpr::Eval(Frame* f) const IntrusivePtr SizeExpr::Fold(Val* v) const { - return {AdoptRef{}, v->SizeVal()}; + return v->SizeVal(); } AddExpr::AddExpr(IntrusivePtr arg_op1, IntrusivePtr arg_op2) @@ -1162,7 +1164,7 @@ AddExpr::AddExpr(IntrusivePtr arg_op1, IntrusivePtr arg_op2) if ( IsVector(bt2) ) bt2 = op2->Type()->AsVectorType()->YieldType()->Tag(); - BroType* base_result_type = 0; + IntrusivePtr base_result_type; if ( bt1 == TYPE_TIME && bt2 == TYPE_INTERVAL ) base_result_type = base_type(bt1); @@ -1180,9 +1182,9 @@ AddExpr::AddExpr(IntrusivePtr arg_op1, IntrusivePtr arg_op2) if ( base_result_type ) { if ( is_vector(op1.get()) || is_vector(op2.get()) ) - SetType(make_intrusive(base_result_type)); + SetType(make_intrusive(std::move(base_result_type))); else - SetType({AdoptRef{}, base_result_type}); + SetType(std::move(base_result_type)); } } @@ -1209,9 +1211,9 @@ AddToExpr::AddToExpr(IntrusivePtr arg_op1, IntrusivePtr arg_op2) if ( BothArithmetic(bt1, bt2) ) PromoteType(max_type(bt1, bt2), is_vector(op1.get()) || is_vector(op2.get())); else if ( BothString(bt1, bt2) ) - SetType({AdoptRef{}, base_type(bt1)}); + SetType(base_type(bt1)); else if ( BothInterval(bt1, bt2) ) - SetType({AdoptRef{}, base_type(bt1)}); + SetType(base_type(bt1)); else if ( IsVector(bt1) ) { @@ -1259,7 +1261,7 @@ IntrusivePtr AddToExpr::Eval(Frame* f) const { VectorVal* vv = v1->AsVectorVal(); - if ( ! vv->Assign(vv->Size(), v2.release()) ) + if ( ! vv->Assign(vv->Size(), v2) ) RuntimeError("type-checking failed in vector append"); return v1; @@ -1293,13 +1295,13 @@ SubExpr::SubExpr(IntrusivePtr arg_op1, IntrusivePtr arg_op2) if ( IsVector(bt2) ) bt2 = t2->AsVectorType()->YieldType()->Tag(); - BroType* base_result_type = 0; + IntrusivePtr base_result_type; if ( bt1 == TYPE_TIME && bt2 == TYPE_INTERVAL ) base_result_type = base_type(bt1); else if ( bt1 == TYPE_TIME && bt2 == TYPE_TIME ) - SetType({AdoptRef{}, base_type(TYPE_INTERVAL)}); + SetType(base_type(TYPE_INTERVAL)); else if ( bt1 == TYPE_INTERVAL && bt2 == TYPE_INTERVAL ) base_result_type = base_type(bt1); @@ -1321,9 +1323,9 @@ SubExpr::SubExpr(IntrusivePtr arg_op1, IntrusivePtr arg_op2) if ( base_result_type ) { if ( is_vector(op1.get()) || is_vector(op2.get()) ) - SetType(make_intrusive(base_result_type)); + SetType(make_intrusive(std::move(base_result_type))); else - SetType({AdoptRef{}, base_result_type}); + SetType(std::move(base_result_type)); } } @@ -1340,7 +1342,7 @@ RemoveFromExpr::RemoveFromExpr(IntrusivePtr arg_op1, if ( BothArithmetic(bt1, bt2) ) PromoteType(max_type(bt1, bt2), is_vector(op1.get()) || is_vector(op2.get())); else if ( BothInterval(bt1, bt2) ) - SetType({AdoptRef{}, base_type(bt1)}); + SetType(base_type(bt1)); else ExprError("requires two arithmetic operands"); } @@ -1432,7 +1434,7 @@ DivideExpr::DivideExpr(IntrusivePtr arg_op1, if ( is_vector(op1.get()) || is_vector(op2.get()) ) SetType(make_intrusive(base_type(TYPE_DOUBLE))); else - SetType({AdoptRef{}, base_type(TYPE_DOUBLE)}); + SetType(base_type(TYPE_DOUBLE)); } else ExprError("division of interval requires arithmetic operand"); @@ -1443,7 +1445,7 @@ DivideExpr::DivideExpr(IntrusivePtr arg_op1, else if ( bt1 == TYPE_ADDR && ! is_vector(op2.get()) && (bt2 == TYPE_COUNT || bt2 == TYPE_INT) ) - SetType({AdoptRef{}, base_type(TYPE_SUBNET)}); + SetType(base_type(TYPE_SUBNET)); else ExprError("requires arithmetic operands"); @@ -1522,7 +1524,7 @@ BoolExpr::BoolExpr(BroExprTag arg_tag, SetType(make_intrusive(base_type(TYPE_BOOL))); } else - SetType({AdoptRef{}, base_type(TYPE_BOOL)}); + SetType(base_type(TYPE_BOOL)); } else ExprError("requires boolean operands"); @@ -1671,7 +1673,7 @@ BitExpr::BitExpr(BroExprTag arg_tag, else if ( is_vector(op1.get()) || is_vector(op2.get()) ) SetType(make_intrusive(base_type(TYPE_COUNT))); else - SetType({AdoptRef{}, base_type(TYPE_COUNT)}); + SetType(base_type(TYPE_COUNT)); } else if ( bt1 == TYPE_PATTERN ) @@ -1681,7 +1683,7 @@ BitExpr::BitExpr(BroExprTag arg_tag, else if ( tag == EXPR_XOR ) ExprError("'^' operator does not apply to patterns"); else - SetType({AdoptRef{}, base_type(TYPE_PATTERN)}); + SetType(base_type(TYPE_PATTERN)); } else if ( t1->IsSet() && t2->IsSet() ) @@ -1719,7 +1721,7 @@ EqExpr::EqExpr(BroExprTag arg_tag, if ( is_vector(op1.get()) || is_vector(op2.get()) ) SetType(make_intrusive(base_type(TYPE_BOOL))); else - SetType({AdoptRef{}, base_type(TYPE_BOOL)}); + SetType(base_type(TYPE_BOOL)); if ( BothArithmetic(bt1, bt2) ) PromoteOps(max_type(bt1, bt2)); @@ -1821,7 +1823,7 @@ RelExpr::RelExpr(BroExprTag arg_tag, if ( is_vector(op1.get()) || is_vector(op2.get()) ) SetType(make_intrusive(base_type(TYPE_BOOL))); else - SetType({AdoptRef{}, base_type(TYPE_BOOL)}); + SetType(base_type(TYPE_BOOL)); if ( BothArithmetic(bt1, bt2) ) PromoteOps(max_type(bt1, bt2)); @@ -1901,7 +1903,7 @@ CondExpr::CondExpr(IntrusivePtr arg_op1, IntrusivePtr arg_op2, if ( is_vector(op2.get()) ) SetType(make_intrusive(base_type(t))); else - SetType({AdoptRef{}, base_type(t)}); + SetType(base_type(t)); } else if ( bt2 != bt3 ) @@ -2154,7 +2156,7 @@ bool AssignExpr::TypeCheck(attr_list* attrs) const TypeDecl* td1 = rt1->FieldDecl(i); const TypeDecl* td2 = rt2->FieldDecl(i); - if ( same_attrs(td1->attrs, td2->attrs) ) + if ( same_attrs(td1->attrs.get(), td2->attrs.get()) ) // Everything matches. return true; } @@ -2300,7 +2302,8 @@ IntrusivePtr AssignExpr::InitType() const if ( tl->Tag() != TYPE_LIST ) Internal("inconsistent list expr in AssignExpr::InitType"); - return make_intrusive(tl->Ref()->AsTypeList(), op2->Type()->Ref()); + return make_intrusive(IntrusivePtr{NewRef{}, tl->AsTypeList()}, + IntrusivePtr{NewRef{}, op2->Type()}); } void AssignExpr::EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f) const @@ -2332,7 +2335,7 @@ void AssignExpr::EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f) const auto v = op2->Eval(f); if ( v ) - aggr_r->Assign(field, v.release()); + aggr_r->Assign(field, std::move(v)); return; } @@ -2348,7 +2351,7 @@ void AssignExpr::EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f) const if ( ! index || ! v ) return; - if ( ! tv->Assign(index.get(), v.release()) ) + if ( ! tv->Assign(index.get(), std::move(v)) ) RuntimeError("type clash in table assignment"); } @@ -2392,7 +2395,7 @@ IntrusivePtr AssignExpr::InitVal(const BroType* t, IntrusivePtr aggr) if ( ! v ) return nullptr; - aggr_r->Assign(field, v->Ref()); + aggr_r->Assign(field, v); return v; } @@ -2438,7 +2441,7 @@ bool AssignExpr::IsRecordElement(TypeDecl* td) const if ( td ) { const NameExpr* n = (const NameExpr*) op1.get(); - td->type = op2->Type()->Ref(); + td->type = {NewRef{}, op2->Type()}; td->id = copy_string(n->Id()->Name()); } @@ -2511,20 +2514,20 @@ IndexExpr::IndexExpr(IntrusivePtr arg_op1, else if ( ! op1->Type()->YieldType() ) { if ( IsString(op1->Type()->Tag()) && match_type == MATCHES_INDEX_SCALAR ) - SetType({AdoptRef{}, base_type(TYPE_STRING)}); + SetType(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({AdoptRef{}, base_type(TYPE_VOID)}); + SetType(base_type(TYPE_VOID)); } else if ( match_type == MATCHES_INDEX_SCALAR ) SetType({NewRef{}, op1->Type()->YieldType()}); else if ( match_type == MATCHES_INDEX_VECTOR ) - SetType(make_intrusive(op1->Type()->YieldType()->Ref())); + SetType(make_intrusive(IntrusivePtr{NewRef{}, op1->Type()->YieldType()})); else ExprError("Unknown MatchesIndex() return value"); @@ -2581,7 +2584,7 @@ void IndexExpr::Delete(Frame* f) if ( ! v2 ) return; - Unref(v1->AsTableVal()->Delete(v2.get())); + v1->AsTableVal()->Delete(v2.get()); } IntrusivePtr IndexExpr::MakeLvalue() @@ -2700,7 +2703,7 @@ IntrusivePtr IndexExpr::Fold(Val* v1, Val* v2) const break; case TYPE_TABLE: - v = {NewRef{}, v1->AsTableVal()->Lookup(v2)}; // Then, we jump into the TableVal here. + v = v1->AsTableVal()->Lookup(v2); // Then, we jump into the TableVal here. break; case TYPE_STRING: @@ -2789,7 +2792,7 @@ void IndexExpr::Assign(Frame* f, IntrusivePtr 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.get(), v.release()) ) + else if ( ! v1_vect->Assign(v2.get(), std::move(v)) ) { v = std::move(v_extra); @@ -2811,7 +2814,7 @@ void IndexExpr::Assign(Frame* f, IntrusivePtr v) } case TYPE_TABLE: - if ( ! v1->AsTableVal()->Assign(v2.get(), v.release()) ) + if ( ! v1->AsTableVal()->Assign(v2.get(), std::move(v)) ) { v = std::move(v_extra); @@ -2919,7 +2922,7 @@ void FieldExpr::Assign(Frame* f, IntrusivePtr v) if ( op_v ) { RecordVal* r = op_v->AsRecordVal(); - r->Assign(field, v.release()); + r->Assign(field, std::move(v)); } } @@ -2982,7 +2985,7 @@ HasFieldExpr::HasFieldExpr(IntrusivePtr arg_op, else if ( rt->IsFieldDeprecated(field) ) reporter->Warning("%s", rt->GetFieldDeprecationWarning(field, true).c_str()); - SetType({AdoptRef{}, base_type(TYPE_BOOL)}); + SetType(base_type(TYPE_BOOL)); } } @@ -3034,9 +3037,9 @@ RecordConstructorExpr::RecordConstructorExpr(IntrusivePtr constructor_ } FieldAssignExpr* field = (FieldAssignExpr*) e; - BroType* field_type = field->Type()->Ref(); + IntrusivePtr field_type{NewRef{}, field->Type()}; char* field_name = copy_string(field->FieldName()); - record_types->push_back(new TypeDecl(field_type, field_name)); + record_types->push_back(new TypeDecl(std::move(field_type), field_name)); } SetType(make_intrusive(record_types)); @@ -3053,8 +3056,7 @@ IntrusivePtr RecordConstructorExpr::InitVal(const BroType* t, IntrusivePtr< if ( v ) { RecordVal* rv = v->AsRecordVal(); - IntrusivePtr ar{AdoptRef{}, - rv->CoerceTo(t->AsRecordType(), aggr.get())}; + auto ar = rv->CoerceTo(t->AsRecordType(), aggr.release()); if ( ar ) return ar; @@ -3110,10 +3112,10 @@ TableConstructorExpr::TableConstructorExpr(IntrusivePtr constructor_li else { if ( op->AsListExpr()->Exprs().empty() ) - SetType(make_intrusive(new TypeList(base_type(TYPE_ANY)), nullptr)); + SetType(make_intrusive(make_intrusive(base_type(TYPE_ANY)), nullptr)); else { - SetType({AdoptRef{}, init_type(op.get())}); + SetType(init_type(op.get())); if ( ! type ) SetError(); @@ -3124,7 +3126,7 @@ TableConstructorExpr::TableConstructorExpr(IntrusivePtr constructor_li } } - attrs = arg_attrs ? new Attributes(arg_attrs, type.get(), false, false) : 0; + attrs = arg_attrs ? new Attributes(arg_attrs, type, false, false) : 0; type_list* indices = type->AsTableType()->Indices()->Types(); const expr_list& cle = op->AsListExpr()->Exprs(); @@ -3149,10 +3151,16 @@ TableConstructorExpr::TableConstructorExpr(IntrusivePtr constructor_li { Expr* idx = idx_exprs[j]; - if ( check_and_promote_expr(idx, (*indices)[j]) ) + auto promoted_idx = check_and_promote_expr(idx, (*indices)[j]); + + if ( promoted_idx ) { - if ( idx != idx_exprs[j] ) - idx_exprs.replace(j, idx); + if ( promoted_idx.get() != idx ) + { + Unref(idx); + idx_exprs.replace(j, promoted_idx.release()); + } + continue; } @@ -3166,7 +3174,8 @@ IntrusivePtr TableConstructorExpr::Eval(Frame* f) const if ( IsError() ) return nullptr; - auto aggr = make_intrusive(Type()->AsTableType(), attrs); + auto aggr = make_intrusive(IntrusivePtr{NewRef{}, Type()->AsTableType()}, + IntrusivePtr{NewRef{}, attrs}); const expr_list& exprs = op->AsListExpr()->Exprs(); for ( const auto& expr : exprs ) @@ -3185,7 +3194,7 @@ IntrusivePtr TableConstructorExpr::InitVal(const BroType* t, IntrusivePtrAsTableType(); auto tval = aggr ? IntrusivePtr{AdoptRef{}, aggr.release()->AsTableVal()} : - make_intrusive(tt, attrs); + make_intrusive(IntrusivePtr{NewRef{}, tt}, IntrusivePtr{NewRef{}, attrs}); const expr_list& exprs = op->AsListExpr()->Exprs(); for ( const auto& expr : exprs ) @@ -3224,9 +3233,9 @@ SetConstructorExpr::SetConstructorExpr(IntrusivePtr constructor_list, else { if ( op->AsListExpr()->Exprs().empty() ) - SetType(make_intrusive<::SetType>(new TypeList(base_type(TYPE_ANY)), nullptr)); + SetType(make_intrusive<::SetType>(make_intrusive(base_type(TYPE_ANY)), nullptr)); else - SetType({AdoptRef{}, init_type(op.get())}); + SetType(init_type(op.get())); } if ( ! type ) @@ -3235,7 +3244,7 @@ SetConstructorExpr::SetConstructorExpr(IntrusivePtr 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.get(), false, false) : 0; + attrs = arg_attrs ? new Attributes(arg_attrs, type, false, false) : 0; type_list* indices = type->AsTableType()->Indices()->Types(); expr_list& cle = op->AsListExpr()->Exprs(); @@ -3274,7 +3283,8 @@ IntrusivePtr SetConstructorExpr::Eval(Frame* f) const if ( IsError() ) return nullptr; - auto aggr = make_intrusive(type->AsTableType(), attrs); + auto aggr = make_intrusive(IntrusivePtr{NewRef{}, type->AsTableType()}, + IntrusivePtr{NewRef{}, attrs}); const expr_list& exprs = op->AsListExpr()->Exprs(); for ( const auto& expr : exprs ) @@ -3295,7 +3305,7 @@ IntrusivePtr SetConstructorExpr::InitVal(const BroType* t, IntrusivePtrAsTableType(); auto tval = aggr ? IntrusivePtr{AdoptRef{}, aggr.release()->AsTableVal()} : - make_intrusive(tt, attrs); + make_intrusive(IntrusivePtr{NewRef{}, tt}, IntrusivePtr{NewRef{}, attrs}); const expr_list& exprs = op->AsListExpr()->Exprs(); for ( const auto& e : exprs ) @@ -3348,13 +3358,10 @@ VectorConstructorExpr::VectorConstructorExpr(IntrusivePtr constructor_ return; } - BroType* t = merge_type_list(op->AsListExpr()); + auto t = merge_type_list(op->AsListExpr()); if ( t ) - { - SetType(make_intrusive(t->Ref())); - Unref(t); - } + SetType(make_intrusive(std::move(t))); else { SetError(); @@ -3378,9 +3385,8 @@ IntrusivePtr VectorConstructorExpr::Eval(Frame* f) const loop_over_list(exprs, i) { Expr* e = exprs[i]; - auto v = e->Eval(f); - if ( ! vec->Assign(i, v.release()) ) + if ( ! vec->Assign(i, e->Eval(f)) ) { RuntimeError(fmt("type mismatch at index %d", i)); return nullptr; @@ -3406,7 +3412,7 @@ IntrusivePtr VectorConstructorExpr::InitVal(const BroType* t, IntrusivePtr< Expr* e = exprs[i]; auto v = check_and_promote(e->Eval(nullptr), t->YieldType(), 1); - if ( ! v || ! vec->Assign(i, v.release()) ) + if ( ! v || ! vec->Assign(i, std::move(v)) ) { Error(fmt("initialization type mismatch at index %d", i), e); return nullptr; @@ -3448,7 +3454,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.release()); + rec->Assign(idx, std::move(v)); } } @@ -3456,7 +3462,7 @@ bool FieldAssignExpr::IsRecordElement(TypeDecl* td) const { if ( td ) { - td->type = op->Type()->Ref(); + td->type = {NewRef{}, op->Type()}; td->id = copy_string(field_name.c_str()); } @@ -3486,7 +3492,7 @@ ArithCoerceExpr::ArithCoerceExpr(IntrusivePtr arg_op, TypeTag t) vbt = op->Type()->AsVectorType()->YieldType()->Tag(); } else - SetType({AdoptRef{}, base_type(t)}); + SetType(base_type(t)); if ( (bt == TYPE_ENUM) != (t == TYPE_ENUM) ) ExprError("can't convert to/from enumerated type"); @@ -3542,7 +3548,7 @@ IntrusivePtr ArithCoerceExpr::Fold(Val* v) const { Val* elt = vv->Lookup(i); if ( elt ) - result->Assign(i, FoldSingleVal(elt, t).release()); + result->Assign(i, FoldSingleVal(elt, t)); else result->Assign(i, 0); } @@ -3670,8 +3676,7 @@ IntrusivePtr RecordCoerceExpr::InitVal(const BroType* t, IntrusivePtr if ( v ) { RecordVal* rv = v->AsRecordVal(); - IntrusivePtr ar{AdoptRef{}, - rv->CoerceTo(t->AsRecordType(), aggr.release())}; + auto ar = rv->CoerceTo(t->AsRecordType(), aggr.release()); if ( ar ) return ar; @@ -3706,7 +3711,7 @@ IntrusivePtr RecordCoerceExpr::Fold(Val* v) const if ( ! rhs ) { // Optional field is missing. - val->Assign(i, 0); + val->Assign(i, nullptr); continue; } @@ -3718,8 +3723,7 @@ IntrusivePtr RecordCoerceExpr::Fold(Val* v) const field_type->Tag() == TYPE_RECORD && ! same_type(rhs_type, field_type) ) { - IntrusivePtr new_val{AdoptRef{}, - rhs->AsRecordVal()->CoerceTo(field_type->AsRecordType())}; + auto new_val = rhs->AsRecordVal()->CoerceTo(field_type->AsRecordType()); if ( new_val ) rhs = std::move(new_val); @@ -3733,7 +3737,7 @@ IntrusivePtr RecordCoerceExpr::Fold(Val* v) const RuntimeError("Failed type conversion"); } - val->Assign(i, rhs.release()); + val->Assign(i, std::move(rhs)); } else { @@ -3750,17 +3754,17 @@ IntrusivePtr RecordCoerceExpr::Fold(Val* v) const field_type->Tag() == TYPE_RECORD && ! same_type(def_type, field_type) ) { - Val* tmp = def_val->AsRecordVal()->CoerceTo( + auto tmp = def_val->AsRecordVal()->CoerceTo( field_type->AsRecordType()); if ( tmp ) - def_val = {AdoptRef{}, tmp}; + def_val = std::move(tmp); } - val->Assign(i, def_val.release()); + val->Assign(i, std::move(def_val)); } else - val->Assign(i, 0); + val->Assign(i, nullptr); } } @@ -3795,7 +3799,8 @@ IntrusivePtr TableCoerceExpr::Fold(Val* v) const if ( tv->Size() > 0 ) RuntimeErrorWithCallStack("coercion of non-empty table/set"); - return make_intrusive(Type()->AsTableType(), tv->Attrs()); + return make_intrusive(IntrusivePtr{NewRef{}, Type()->AsTableType()}, + IntrusivePtr{NewRef{}, tv->Attrs()}); } VectorCoerceExpr::VectorCoerceExpr(IntrusivePtr arg_op, @@ -3846,7 +3851,7 @@ FlattenExpr::FlattenExpr(IntrusivePtr arg_op) auto tl = make_intrusive(); for ( int i = 0; i < num_fields; ++i ) - tl->Append(rt->FieldType(i)->Ref()); + tl->Append({NewRef{}, rt->FieldType(i)}); Unref(rt); SetType(std::move(tl)); @@ -3909,7 +3914,7 @@ ScheduleExpr::ScheduleExpr(IntrusivePtr arg_when, if ( bt != TYPE_TIME && bt != TYPE_INTERVAL ) ExprError("schedule expression requires a time or time interval"); else - SetType({AdoptRef{}, base_type(TYPE_TIMER)}); + SetType(base_type(TYPE_TIMER)); } bool ScheduleExpr::IsPure() const @@ -3996,7 +4001,7 @@ InExpr::InExpr(IntrusivePtr arg_op1, IntrusivePtr arg_op2) SetError(); } else - SetType({AdoptRef{}, base_type(TYPE_BOOL)}); + SetType(base_type(TYPE_BOOL)); } else if ( op1->Type()->Tag() == TYPE_RECORD ) @@ -4019,13 +4024,13 @@ InExpr::InExpr(IntrusivePtr arg_op1, IntrusivePtr arg_op2) SetError(); } else - SetType({AdoptRef{}, base_type(TYPE_BOOL)}); + SetType(base_type(TYPE_BOOL)); } } else if ( op1->Type()->Tag() == TYPE_STRING && op2->Type()->Tag() == TYPE_STRING ) - SetType({AdoptRef{}, base_type(TYPE_BOOL)}); + SetType(base_type(TYPE_BOOL)); else { @@ -4036,14 +4041,14 @@ InExpr::InExpr(IntrusivePtr arg_op1, IntrusivePtr arg_op2) { if ( op2->Type()->Tag() == TYPE_SUBNET ) { - SetType({AdoptRef{}, base_type(TYPE_BOOL)}); + SetType(base_type(TYPE_BOOL)); return; } if ( op2->Type()->Tag() == TYPE_TABLE && op2->Type()->AsTableType()->IsSubNetIndex() ) { - SetType({AdoptRef{}, base_type(TYPE_BOOL)}); + SetType(base_type(TYPE_BOOL)); return; } } @@ -4056,7 +4061,7 @@ InExpr::InExpr(IntrusivePtr arg_op1, IntrusivePtr arg_op2) if ( ! op2->Type()->MatchesIndex(lop1) ) SetError("not an index type"); else - SetType({AdoptRef{}, base_type(TYPE_BOOL)}); + SetType(base_type(TYPE_BOOL)); } } @@ -4084,12 +4089,12 @@ IntrusivePtr InExpr::Fold(Val* v1, Val* v2) const v2->Type()->Tag() == TYPE_SUBNET ) return {AdoptRef{}, val_mgr->GetBool(v2->AsSubNetVal()->Contains(v1->AsAddr()))}; - Val* res; + bool res; if ( is_vector(v2) ) - res = v2->AsVectorVal()->Lookup(v1); + res = (bool)v2->AsVectorVal()->Lookup(v1); else - res = v2->AsTableVal()->Lookup(v1, false); + res = (bool)v2->AsTableVal()->Lookup(v1, false); return {AdoptRef{}, val_mgr->GetBool(res)}; } @@ -4241,7 +4246,7 @@ IntrusivePtr CallExpr::Eval(Frame* f) const if ( f ) f->SetCall(this); - ret = {AdoptRef{}, func->Call(v, f)}; + ret = func->Call(v, f); if ( f ) f->SetCall(current_call); @@ -4283,6 +4288,29 @@ void CallExpr::ExprDescribe(ODesc* d) const args->Describe(d); } +static std::unique_ptr shallow_copy_func_inits(const IntrusivePtr& body, + const id_list* src) + { + if ( ! body ) + return nullptr; + + if ( ! src ) + return nullptr; + + if ( src->empty() ) + return nullptr; + + auto dest = std::make_unique(src->length()); + + for ( ID* i : *src ) + { + Ref(i); + dest->push_back(i); + } + + return dest; + } + LambdaExpr::LambdaExpr(std::unique_ptr arg_ing, id_list arg_outer_ids) : Expr(EXPR_LAMBDA) { @@ -4293,11 +4321,10 @@ LambdaExpr::LambdaExpr(std::unique_ptr arg_ing, // Install a dummy version of the function globally for use only // when broker provides a closure. - ::Ref(ingredients->body); BroFunc* dummy_func = new BroFunc( - ingredients->id, + ingredients->id.get(), ingredients->body, - ingredients->inits, + shallow_copy_func_inits(ingredients->body, ingredients->inits).release(), ingredients->frame_size, ingredients->priority); @@ -4341,11 +4368,10 @@ LambdaExpr::LambdaExpr(std::unique_ptr arg_ing, IntrusivePtr LambdaExpr::Eval(Frame* f) const { - ::Ref(ingredients->body); auto lamb = make_intrusive( - ingredients->id, + ingredients->id.get(), ingredients->body, - ingredients->inits, + shallow_copy_func_inits(ingredients->body, ingredients->inits).release(), ingredients->frame_size, ingredients->priority); @@ -4474,7 +4500,7 @@ ListExpr::~ListExpr() void ListExpr::Append(IntrusivePtr e) { exprs.push_back(e.release()); - ((TypeList*) type.get())->Append(exprs.back()->Type()->Ref()); + ((TypeList*) type.get())->Append({NewRef{}, exprs.back()->Type()}); } bool ListExpr::IsPure() const @@ -4561,12 +4587,12 @@ IntrusivePtr ListExpr::InitType() const if ( ! til->IsPure() || ! til->AllMatch(til->PureType(), 1) ) - tl->Append(til->Ref()); + tl->Append({NewRef{}, til}); else - tl->Append(til->PureType()->Ref()); + tl->Append({NewRef{}, til->PureType()}); } else - tl->Append(ti->Ref()); + tl->Append({NewRef{}, ti}); } return tl; @@ -4665,10 +4691,12 @@ IntrusivePtr ListExpr::InitVal(const BroType* t, IntrusivePtr aggr) co loop_over_list(exprs, i) { Expr* e = exprs[i]; - check_and_promote_expr(e, vec->Type()->AsVectorType()->YieldType()); - auto v = e->Eval(nullptr); + auto promoted_e = check_and_promote_expr(e, vec->Type()->AsVectorType()->YieldType()); - if ( ! vec->Assign(i, v.release()) ) + if ( promoted_e ) + e = promoted_e.get(); + + if ( ! vec->Assign(i, e->Eval(nullptr)) ) { e->Error(fmt("type mismatch at index %d", i)); return nullptr; @@ -4929,7 +4957,7 @@ void CastExpr::ExprDescribe(ODesc* d) const IsExpr::IsExpr(IntrusivePtr arg_op, IntrusivePtr arg_t) : UnaryExpr(EXPR_IS, std::move(arg_op)), t(std::move(arg_t)) { - SetType({AdoptRef{}, base_type(TYPE_BOOL)}); + SetType(base_type(TYPE_BOOL)); } IntrusivePtr IsExpr::Fold(Val* v) const @@ -4964,35 +4992,34 @@ IntrusivePtr get_assign_expr(IntrusivePtr op1, is_init); } -int check_and_promote_expr(Expr*& e, BroType* t) +IntrusivePtr check_and_promote_expr(Expr* const e, BroType* t) { BroType* et = e->Type(); TypeTag e_tag = et->Tag(); TypeTag t_tag = t->Tag(); if ( t->Tag() == TYPE_ANY ) - return 1; + return {NewRef{}, e}; if ( EitherArithmetic(t_tag, e_tag) ) { if ( e_tag == t_tag ) - return 1; + return {NewRef{}, e}; if ( ! BothArithmetic(t_tag, e_tag) ) { t->Error("arithmetic mixed with non-arithmetic", e); - return 0; + return nullptr; } TypeTag mt = max_type(t_tag, e_tag); if ( mt != t_tag ) { t->Error("over-promotion of arithmetic value", e); - return 0; + return nullptr; } - e = new ArithCoerceExpr({AdoptRef{}, e}, t_tag); - return 1; + return make_intrusive(IntrusivePtr{NewRef{}, e}, t_tag); } if ( t->Tag() == TYPE_RECORD && et->Tag() == TYPE_RECORD ) @@ -5008,20 +5035,18 @@ int check_and_promote_expr(Expr*& e, BroType* t) const TypeDecl* td1 = t_r->FieldDecl(i); const TypeDecl* td2 = et_r->FieldDecl(i); - if ( same_attrs(td1->attrs, td2->attrs) ) + if ( same_attrs(td1->attrs.get(), td2->attrs.get()) ) // Everything matches perfectly. - return 1; + return {NewRef{}, e}; } } if ( record_promotion_compatible(t_r, et_r) ) - { - e = new RecordCoerceExpr({AdoptRef{}, e}, {NewRef{}, t_r}); - return 1; - } + return make_intrusive(IntrusivePtr{NewRef{}, e}, + IntrusivePtr{NewRef{}, t_r}); t->Error("incompatible record types", e); - return 0; + return nullptr; } @@ -5029,23 +5054,19 @@ int check_and_promote_expr(Expr*& e, BroType* t) { if ( t->Tag() == TYPE_TABLE && et->Tag() == TYPE_TABLE && et->AsTableType()->IsUnspecifiedTable() ) - { - e = new TableCoerceExpr({AdoptRef{}, e}, {NewRef{}, t->AsTableType()}); - return 1; - } + return make_intrusive(IntrusivePtr{NewRef{}, e}, + IntrusivePtr{NewRef{}, t->AsTableType()}); if ( t->Tag() == TYPE_VECTOR && et->Tag() == TYPE_VECTOR && et->AsVectorType()->IsUnspecifiedVector() ) - { - e = new VectorCoerceExpr({AdoptRef{}, e}, {NewRef{}, t->AsVectorType()}); - return 1; - } + return make_intrusive(IntrusivePtr{NewRef{}, e}, + IntrusivePtr{NewRef{}, t->AsVectorType()}); t->Error("type clash", e); - return 0; + return nullptr; } - return 1; + return {NewRef{}, e}; } int check_and_promote_exprs(ListExpr* const elements, TypeList* types) @@ -5065,14 +5086,19 @@ int check_and_promote_exprs(ListExpr* const elements, TypeList* types) loop_over_list(el, i) { Expr* e = el[i]; - if ( ! check_and_promote_expr(e, (*tl)[i]) ) + auto promoted_e = check_and_promote_expr(e, (*tl)[i]); + + if ( ! promoted_e ) { e->Error("type mismatch", (*tl)[i]); return 0; } - if ( e != el[i] ) - el.replace(i, e); + if ( promoted_e.get() != e ) + { + Unref(e); + el.replace(i, promoted_e.release()); + } } return 1; @@ -5114,7 +5140,7 @@ int check_and_promote_args(ListExpr* const args, RecordType* types) TypeList* tl = new TypeList(); for ( int i = 0; i < types->NumFields(); ++i ) - tl->Append(types->FieldType(i)->Ref()); + tl->Append({NewRef{}, types->FieldType(i)}); int rval = check_and_promote_exprs(args, tl); Unref(tl); @@ -5132,14 +5158,19 @@ int check_and_promote_exprs_to_type(ListExpr* const elements, BroType* type) loop_over_list(el, i) { Expr* e = el[i]; - if ( ! check_and_promote_expr(e, type) ) + auto promoted_e = check_and_promote_expr(e, type); + + if ( ! promoted_e ) { e->Error("type mismatch", type); return 0; } - if ( e != el[i] ) - el.replace(i, e); + if ( promoted_e.get() != e ) + { + Unref(e); + el.replace(i, promoted_e.release()); + } } return 1; diff --git a/src/Expr.h b/src/Expr.h index 5874330306..95c1167abe 100644 --- a/src/Expr.h +++ b/src/Expr.h @@ -8,6 +8,7 @@ #include "Type.h" #include "EventHandler.h" #include "TraverseTypes.h" +#include "Val.h" #include #include @@ -924,7 +925,13 @@ IntrusivePtr get_assign_expr(IntrusivePtr op1, // types or a single type. // // Note, the type is not "const" because it can be ref'd. -extern int check_and_promote_expr(Expr*& e, BroType* t); + +/** + * Returns nullptr if the expression cannot match or a promoted + * expression. + */ +extern IntrusivePtr check_and_promote_expr(Expr* e, BroType* t); + extern int check_and_promote_exprs(ListExpr* elements, TypeList* types); extern int check_and_promote_args(ListExpr* args, RecordType* types); extern int check_and_promote_exprs_to_type(ListExpr* elements, BroType* type); diff --git a/src/File.cc b/src/File.cc index 14ced1d32c..27702f0658 100644 --- a/src/File.cc +++ b/src/File.cc @@ -71,13 +71,13 @@ BroFile::BroFile(FILE* arg_f, const char* arg_name, const char* arg_access) is_open = (f != 0); } -BroFile::BroFile(const char* arg_name, const char* arg_access, BroType* arg_t) +BroFile::BroFile(const char* arg_name, const char* arg_access) { Init(); f = 0; name = copy_string(arg_name); access = copy_string(arg_access); - t = arg_t ? arg_t : base_type(TYPE_STRING); + t = base_type(TYPE_STRING); if ( streq(name, "/dev/stdin") ) f = stdin; @@ -154,7 +154,6 @@ bool BroFile::Open(FILE* file, const char* mode) BroFile::~BroFile() { Close(); - Unref(t); Unref(attrs); delete [] name; @@ -171,7 +170,6 @@ void BroFile::Init() attrs = 0; buffered = true; raw_output = false; - t = 0; #ifdef USE_PERFTOOLS_DEBUG heap_checker->IgnoreObject(this); @@ -286,7 +284,7 @@ RecordVal* BroFile::Rotate() return 0; } - info->Assign(2, new Val(open_time, TYPE_TIME)); + info->Assign(2, make_intrusive(open_time, TYPE_TIME)); Unlink(); @@ -355,6 +353,6 @@ BroFile* BroFile::GetFile(const char* name) } } - return new BroFile(name, "w", 0); + return new BroFile(name, "w"); } diff --git a/src/File.h b/src/File.h index c5a358a23a..b1b15a6661 100644 --- a/src/File.h +++ b/src/File.h @@ -3,6 +3,7 @@ #pragma once #include "Obj.h" +#include "IntrusivePtr.h" #include #include @@ -22,7 +23,7 @@ class BroFile : public BroObj { public: explicit BroFile(FILE* arg_f); BroFile(FILE* arg_f, const char* filename, const char* access); - BroFile(const char* filename, const char* access, BroType* arg_t = 0); + BroFile(const char* filename, const char* access); ~BroFile() override; const char* Name() const; @@ -36,7 +37,7 @@ public: void SetBuf(bool buffered); // false=line buffered, true=fully buffered - BroType* FType() const { return t; } + BroType* FType() const { return t.get(); } // Whether the file is open in a general sense; it might // not be open as a Unix file due to our management of @@ -93,7 +94,7 @@ protected: void RaiseOpenEvent(); FILE* f; - BroType* t; + IntrusivePtr t; char* name; char* access; int is_open; // whether the file is open in a general sense diff --git a/src/Frame.cc b/src/Frame.cc index 8db8a1f7ff..88a60e3b1f 100644 --- a/src/Frame.cc +++ b/src/Frame.cc @@ -25,7 +25,6 @@ Frame::Frame(int arg_size, const BroFunc* func, const val_list* fn_args) break_before_next_stmt = false; break_on_return = false; - trigger = nullptr; call = nullptr; delayed = false; @@ -43,9 +42,6 @@ Frame::~Frame() Unref(func); } - // Deleting a Frame that is a view is a no-op. - Unref(trigger); - if ( ! weak_closure_ref ) Unref(closure); @@ -183,11 +179,9 @@ Frame* Frame::Clone() const other->call = call; other->trigger = trigger; - if ( trigger ) - Ref(trigger); for (int i = 0; i < size; i++) - other->frame[i] = frame[i] ? frame[i]->Clone() : nullptr; + other->frame[i] = frame[i] ? frame[i]->Clone().release() : nullptr; return other; } @@ -200,23 +194,22 @@ static bool val_is_func(Val* v, BroFunc* func) return v->AsFunc() == func; } -static Val* clone_if_not_func(Val** frame, int offset, BroFunc* func, +static void clone_if_not_func(Val** frame, int offset, BroFunc* func, Frame* other) { auto v = frame[offset]; if ( ! v ) - return nullptr; + return; if ( val_is_func(v, func) ) { other->SetElement(offset, v, true); - return v; + return; } auto rval = v->Clone(); - other->SetElement(offset, rval); - return rval; + other->SetElement(offset, rval.release()); } Frame* Frame::SelectiveClone(const id_list& selection, BroFunc* func) const @@ -359,14 +352,14 @@ broker::expected Frame::Serialize(const Frame* target, const id_li return {std::move(rval)}; } -std::pair Frame::Unserialize(const broker::vector& data) +std::pair> Frame::Unserialize(const broker::vector& data) { if ( data.size() == 0 ) return std::make_pair(true, nullptr); id_list outer_ids; std::unordered_map offset_map; - Frame* closure = nullptr; + IntrusivePtr closure; auto where = data.begin(); @@ -410,7 +403,7 @@ std::pair Frame::Unserialize(const broker::vector& data) return std::make_pair(false, nullptr); } - closure = closure_pair.second; + closure = std::move(closure_pair.second); } auto has_vec = broker::get_if(*where); @@ -448,11 +441,11 @@ std::pair Frame::Unserialize(const broker::vector& data) int frame_size = body.size(); // We'll associate this frame with a function later. - Frame* rf = new Frame(frame_size, nullptr, nullptr); + auto rf = make_intrusive(frame_size, nullptr, nullptr); rf->offset_map = std::move(offset_map); // Frame takes ownership of unref'ing elements in outer_ids rf->outer_ids = std::move(outer_ids); - rf->closure = closure; + rf->closure = closure.release(); rf->weak_closure_ref = false; for ( int i = 0; i < frame_size; ++i ) @@ -463,32 +456,23 @@ std::pair Frame::Unserialize(const broker::vector& data) broker::vector val_tuple = *has_vec; if ( val_tuple.size() != 2 ) - { - Unref(rf); return std::make_pair(false, nullptr); - } auto has_type = broker::get_if(val_tuple[1]); if ( ! has_type ) - { - Unref(rf); return std::make_pair(false, nullptr); - } broker::integer g = *has_type; BroType t( static_cast(g) ); auto val = bro_broker::data_to_val(std::move(val_tuple[0]), &t); if ( ! val ) - { - Unref(rf); return std::make_pair(false, nullptr); - } rf->frame[i] = val.release(); } - return std::make_pair(true, rf); + return std::make_pair(true, std::move(rf)); } void Frame::AddKnownOffsets(const id_list& ids) @@ -521,19 +505,13 @@ void Frame::CaptureClosure(Frame* c, id_list arg_outer_ids) // if (c) closure = c->SelectiveClone(outer_ids); } -void Frame::SetTrigger(trigger::Trigger* arg_trigger) +void Frame::SetTrigger(IntrusivePtr arg_trigger) { - ClearTrigger(); - - if ( arg_trigger ) - Ref(arg_trigger); - - trigger = arg_trigger; + trigger = std::move(arg_trigger); } void Frame::ClearTrigger() { - Unref(trigger); trigger = nullptr; } diff --git a/src/Frame.h b/src/Frame.h index 8a5c3b339a..d999b6f3ed 100644 --- a/src/Frame.h +++ b/src/Frame.h @@ -4,6 +4,7 @@ #include "BroList.h" // for typedef val_list #include "Obj.h" +#include "IntrusivePtr.h" #include #include @@ -189,7 +190,7 @@ public: * and the second is the unserialized frame with reference count +1, or * null if the serialization wasn't successful. */ - static std::pair Unserialize(const broker::vector& data); + static std::pair> Unserialize(const broker::vector& data); /** * Sets the IDs that the frame knows offsets for. These offsets will @@ -210,9 +211,9 @@ public: // If the frame is run in the context of a trigger condition evaluation, // the trigger needs to be registered. - void SetTrigger(trigger::Trigger* arg_trigger); + void SetTrigger(IntrusivePtr arg_trigger); void ClearTrigger(); - trigger::Trigger* GetTrigger() const { return trigger; } + trigger::Trigger* GetTrigger() const { return trigger.get(); } void SetCall(const CallExpr* arg_call) { call = arg_call; } void ClearCall() { call = 0; } @@ -290,7 +291,7 @@ private: bool break_before_next_stmt; bool break_on_return; - trigger::Trigger* trigger; + IntrusivePtr trigger; const CallExpr* call; bool delayed; diff --git a/src/Func.cc b/src/Func.cc index e6924a539f..e54a4c4ac4 100644 --- a/src/Func.cc +++ b/src/Func.cc @@ -111,35 +111,36 @@ std::string render_call_stack() return rval; } -Func::Func() : scope(0), type(0) +Func::Func() { unique_id = unique_ids.size(); unique_ids.push_back(this); } -Func::Func(Kind arg_kind) : scope(0), kind(arg_kind), type(0) +Func::Func(Kind arg_kind) : kind(arg_kind) { unique_id = unique_ids.size(); unique_ids.push_back(this); } -Func::~Func() - { - Unref(type); - } +Func::~Func() = default; -void Func::AddBody(Stmt* /* new_body */, id_list* /* new_inits */, +void Func::AddBody(IntrusivePtr /* new_body */, id_list* /* new_inits */, size_t /* new_frame_size */, int /* priority */) { Internal("Func::AddBody called"); } -Func* Func::DoClone() +void Func::SetScope(IntrusivePtr newscope) + { + scope = std::move(newscope); + } + +IntrusivePtr Func::DoClone() { // By default, ok just to return a reference. Func does not have any state // that is different across instances. - ::Ref(this); - return this; + return {NewRef{}, this}; } void Func::DescribeDebug(ODesc* d, const val_list* args) const @@ -180,7 +181,7 @@ TraversalCode Func::Traverse(TraversalCallback* cb) const { // FIXME: Make a fake scope for builtins? Scope* old_scope = cb->current_scope; - cb->current_scope = scope; + cb->current_scope = scope.get(); TraversalCode tc = cb->PreFunction(this); HANDLE_TC_STMT_PRE(tc); @@ -206,13 +207,10 @@ TraversalCode Func::Traverse(TraversalCallback* cb) const void Func::CopyStateInto(Func* other) const { - std::for_each(bodies.begin(), bodies.end(), [](const Body& b) { Ref(b.stmts); }); - other->bodies = bodies; other->scope = scope; other->kind = kind; - Ref(type); other->type = type; other->name = name; @@ -273,17 +271,18 @@ std::pair Func::HandlePluginResult(std::pair plugin_resu return plugin_result; } -BroFunc::BroFunc(ID* arg_id, Stmt* arg_body, id_list* aggr_inits, - size_t arg_frame_size, int priority) : Func(BRO_FUNC) +BroFunc::BroFunc(ID* arg_id, IntrusivePtr arg_body, id_list* aggr_inits, + size_t arg_frame_size, int priority) + : Func(BRO_FUNC) { name = arg_id->Name(); - type = arg_id->Type()->Ref(); + type = {NewRef{}, arg_id->Type()}; frame_size = arg_frame_size; if ( arg_body ) { Body b; - b.stmts = AddInits(arg_body, aggr_inits); + b.stmts = AddInits(std::move(arg_body), aggr_inits); b.priority = priority; bodies.push_back(b); } @@ -291,9 +290,6 @@ BroFunc::BroFunc(ID* arg_id, Stmt* arg_body, id_list* aggr_inits, BroFunc::~BroFunc() { - std::for_each(bodies.begin(), bodies.end(), - [](Body& b) { Unref(b.stmts); }); - if ( ! weak_closure_ref ) Unref(closure); } @@ -304,7 +300,7 @@ int BroFunc::IsPure() const [](const Body& b) { return b.stmts->IsPure(); }); } -Val* BroFunc::Call(val_list* args, Frame* parent) const +IntrusivePtr BroFunc::Call(val_list* args, Frame* parent) const { #ifdef PROFILE_BRO_FUNCTIONS DEBUG_MSG("Function: %s\n", Name()); @@ -319,10 +315,7 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const plugin_result = HandlePluginResult(plugin_result, args, Flavor()); if( plugin_result.first ) - { - Val *result = plugin_result.second; - return result; - } + return {AdoptRef{}, plugin_result.second}; if ( bodies.empty() ) { @@ -331,10 +324,10 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const for ( const auto& arg : *args ) Unref(arg); - return Flavor() == FUNC_FLAVOR_HOOK ? val_mgr->GetTrue() : 0; + return Flavor() == FUNC_FLAVOR_HOOK ? IntrusivePtr{AdoptRef{}, val_mgr->GetTrue()} : nullptr; } - Frame* f = new Frame(frame_size, this, args); + auto f = make_intrusive(frame_size, this, args); if ( closure ) f->CaptureClosure(closure, outer_ids); @@ -342,11 +335,11 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const // Hand down any trigger. if ( parent ) { - f->SetTrigger(parent->GetTrigger()); + f->SetTrigger({NewRef{}, parent->GetTrigger()}); f->SetCall(parent->GetCall()); } - g_frame_stack.push_back(f); // used for backtracing + g_frame_stack.push_back(f.get()); // used for backtracing const CallExpr* call_expr = parent ? parent->GetCall() : nullptr; call_stack.emplace_back(CallInfo{call_expr, this, args}); @@ -360,7 +353,7 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const } stmt_flow_type flow = FLOW_NEXT; - Val* result = 0; + IntrusivePtr result; for ( const auto& body : bodies ) { @@ -368,8 +361,6 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const sample_logger->LocationSeen( body.stmts->GetLocationInfo()); - Unref(result); - // Fill in the rest of the frame with the function's arguments. loop_over_list(*args, j) { @@ -387,7 +378,7 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const try { - result = body.stmts->Exec(f, flow).release(); + result = body.stmts->Exec(f.get(), flow); } catch ( InterpreterException& e ) @@ -397,7 +388,6 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const { g_frame_stack.pop_back(); call_stack.pop_back(); - Unref(f); // Result not set b/c exception was thrown throw; } @@ -418,13 +408,12 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const { // Ignore any return values of hook bodies, final return value // depends on whether a body returns as a result of break statement. - Unref(result); - result = 0; + result = nullptr; if ( flow == FLOW_BREAK ) { // Short-circuit execution of remaining hook handler bodies. - result = val_mgr->GetFalse(); + result = {AdoptRef{}, val_mgr->GetFalse()}; break; } } @@ -440,7 +429,7 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const if ( Flavor() == FUNC_FLAVOR_HOOK ) { if ( ! result ) - result = val_mgr->GetTrue(); + result = {AdoptRef{}, val_mgr->GetTrue()}; } // Warn if the function returns something, but we returned from @@ -462,25 +451,21 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const g_frame_stack.pop_back(); - Unref(f); - return result; } -void BroFunc::AddBody(Stmt* new_body, id_list* new_inits, - size_t new_frame_size, int priority) +void BroFunc::AddBody(IntrusivePtr new_body, id_list* new_inits, + size_t new_frame_size, int priority) { if ( new_frame_size > frame_size ) frame_size = new_frame_size; - new_body = AddInits(new_body, new_inits); + new_body = AddInits(std::move(new_body), new_inits); if ( Flavor() == FUNC_FLAVOR_FUNCTION ) { // For functions, we replace the old body with the new one. assert(bodies.size() <= 1); - for ( const auto& body : bodies ) - Unref(body.stmts); bodies.clear(); } @@ -535,10 +520,12 @@ void BroFunc::SetClosureFrame(Frame* f) bool BroFunc::UpdateClosure(const broker::vector& data) { auto result = Frame::Unserialize(data); + if ( ! result.first ) return false; - Frame* new_closure = result.second; + auto& new_closure = result.second; + if ( new_closure ) new_closure->SetFunction(this); @@ -546,19 +533,19 @@ bool BroFunc::UpdateClosure(const broker::vector& data) Unref(closure); weak_closure_ref = false; - closure = new_closure; + closure = new_closure.release(); return true; } -Func* BroFunc::DoClone() +IntrusivePtr BroFunc::DoClone() { // BroFunc could hold a closure. In this case a clone of it must // store a copy of this closure. - BroFunc* other = new BroFunc(); + auto other = IntrusivePtr{AdoptRef{}, new BroFunc()}; - CopyStateInto(other); + CopyStateInto(other.get()); other->frame_size = frame_size; other->closure = closure ? closure->SelectiveClone(outer_ids, this) : nullptr; @@ -586,14 +573,14 @@ void BroFunc::Describe(ODesc* d) const } } -Stmt* BroFunc::AddInits(Stmt* body, id_list* inits) +IntrusivePtr BroFunc::AddInits(IntrusivePtr body, id_list* inits) { if ( ! inits || inits->length() == 0 ) return body; - StmtList* stmt_series = new StmtList; + auto stmt_series = make_intrusive(); stmt_series->Stmts().push_back(new InitStmt(inits)); - stmt_series->Stmts().push_back(body); + stmt_series->Stmts().push_back(body.release()); return stmt_series; } @@ -612,7 +599,7 @@ BuiltinFunc::BuiltinFunc(built_in_func arg_func, const char* arg_name, if ( id->HasVal() ) reporter->InternalError("built-in function %s multiply defined", Name()); - type = id->Type()->Ref(); + type = {NewRef{}, id->Type()}; id->SetVal(make_intrusive(this)); } @@ -625,7 +612,7 @@ int BuiltinFunc::IsPure() const return is_pure; } -Val* BuiltinFunc::Call(val_list* args, Frame* parent) const +IntrusivePtr BuiltinFunc::Call(val_list* args, Frame* parent) const { #ifdef PROFILE_BRO_FUNCTIONS DEBUG_MSG("Function: %s\n", Name()); @@ -640,10 +627,7 @@ Val* BuiltinFunc::Call(val_list* args, Frame* parent) const plugin_result = HandlePluginResult(plugin_result, args, FUNC_FLAVOR_FUNCTION); if ( plugin_result.first ) - { - Val *result = plugin_result.second; - return result; - } + return {AdoptRef{}, plugin_result.second}; if ( g_trace_state.DoTrace() ) { @@ -655,7 +639,7 @@ Val* BuiltinFunc::Call(val_list* args, Frame* parent) const const CallExpr* call_expr = parent ? parent->GetCall() : nullptr; call_stack.emplace_back(CallInfo{call_expr, this, args}); - Val* result = func(parent, args); + IntrusivePtr result{AdoptRef{}, func(parent, args)}; call_stack.pop_back(); for ( const auto& arg : *args ) @@ -885,29 +869,22 @@ static int get_func_priority(const attr_list& attrs) return priority; } -function_ingredients::function_ingredients(Scope* scope, Stmt* body) +function_ingredients::function_ingredients(IntrusivePtr scope, IntrusivePtr body) { frame_size = scope->Length(); inits = scope->GetInits(); - this->scope = scope; - ::Ref(this->scope); - id = scope->ScopeID(); - ::Ref(id); + this->scope = std::move(scope); + id = {NewRef{}, this->scope->ScopeID()}; - auto attrs = scope->Attrs(); + auto attrs = this->scope->Attrs(); priority = (attrs ? get_func_priority(*attrs) : 0); - this->body = body; - ::Ref(this->body); + this->body = std::move(body); } function_ingredients::~function_ingredients() { - Unref(id); - Unref(body); - Unref(scope); - for ( const auto& i : *inits ) Unref(i); diff --git a/src/Func.h b/src/Func.h index e70980d1de..2bed2f2d94 100644 --- a/src/Func.h +++ b/src/Func.h @@ -4,6 +4,7 @@ #include "BroList.h" #include "Obj.h" +#include "IntrusivePtr.h" #include "Type.h" /* for function_flavor */ #include "TraverseTypes.h" @@ -40,7 +41,7 @@ public: function_flavor Flavor() const { return FType()->Flavor(); } struct Body { - Stmt* stmts; + IntrusivePtr stmts; int priority; bool operator<(const Body& other) const { return priority > other.priority; } // reverse sort @@ -49,15 +50,14 @@ public: const vector& GetBodies() const { return bodies; } bool HasBodies() const { return bodies.size(); } - // virtual Val* Call(ListExpr* args) const = 0; - virtual Val* Call(val_list* args, Frame* parent = 0) const = 0; + virtual IntrusivePtr Call(val_list* args, Frame* parent = 0) const = 0; // Add a new event handler to an existing function (event). - virtual void AddBody(Stmt* new_body, id_list* new_inits, - size_t new_frame_size, int priority = 0); + virtual void AddBody(IntrusivePtr new_body, id_list* new_inits, + size_t new_frame_size, int priority = 0); - virtual void SetScope(Scope* newscope) { scope = newscope; } - virtual Scope* GetScope() const { return scope; } + virtual void SetScope(IntrusivePtr newscope); + virtual Scope* GetScope() const { return scope.get(); } virtual FuncType* FType() const { return type->AsFuncType(); } @@ -69,7 +69,7 @@ public: void Describe(ODesc* d) const override = 0; virtual void DescribeDebug(ODesc* d, const val_list* args) const; - virtual Func* DoClone(); + virtual IntrusivePtr DoClone(); virtual TraversalCode Traverse(TraversalCallback* cb) const; @@ -87,9 +87,9 @@ protected: std::pair HandlePluginResult(std::pair plugin_result, val_list* args, function_flavor flavor) const; vector bodies; - Scope* scope; + IntrusivePtr scope; Kind kind; - BroType* type; + IntrusivePtr type; string name; uint32_t unique_id; static vector unique_ids; @@ -98,11 +98,11 @@ protected: class BroFunc : public Func { public: - BroFunc(ID* id, Stmt* body, id_list* inits, size_t frame_size, int priority); + BroFunc(ID* id, IntrusivePtr body, id_list* inits, size_t frame_size, int priority); ~BroFunc() override; int IsPure() const override; - Val* Call(val_list* args, Frame* parent) const override; + IntrusivePtr Call(val_list* args, Frame* parent) const override; /** * Adds adds a closure to the function. Closures are cloned and @@ -133,7 +133,7 @@ public: */ broker::expected SerializeClosure() const; - void AddBody(Stmt* new_body, id_list* new_inits, + void AddBody(IntrusivePtr new_body, id_list* new_inits, size_t new_frame_size, int priority) override; /** Sets this function's outer_id list. */ @@ -144,12 +144,12 @@ public: protected: BroFunc() : Func(BRO_FUNC) {} - Stmt* AddInits(Stmt* body, id_list* inits); + IntrusivePtr AddInits(IntrusivePtr body, id_list* inits); /** * Clones this function along with its closures. */ - Func* DoClone() override; + IntrusivePtr DoClone() override; /** * Performs a selective clone of *f* using the IDs that were @@ -177,7 +177,7 @@ public: ~BuiltinFunc() override; int IsPure() const override; - Val* Call(val_list* args, Frame* parent) const override; + IntrusivePtr Call(val_list* args, Frame* parent) const override; built_in_func TheFunc() const { return func; } void Describe(ODesc* d) const override; @@ -208,16 +208,16 @@ struct function_ingredients { // Gathers all of the information from a scope and a function body needed // to build a function. - function_ingredients(Scope* scope, Stmt* body); + function_ingredients(IntrusivePtr scope, IntrusivePtr body); ~function_ingredients(); - ID* id; - Stmt* body; + IntrusivePtr id; + IntrusivePtr body; id_list* inits; int frame_size; int priority; - Scope* scope; + IntrusivePtr scope; }; extern vector call_stack; diff --git a/src/ID.cc b/src/ID.cc index b506c99b46..f8d4c97bd1 100644 --- a/src/ID.cc +++ b/src/ID.cc @@ -163,7 +163,7 @@ void ID::UpdateValAttrs() return; if ( val && val->Type()->Tag() == TYPE_TABLE ) - val->AsTableVal()->SetAttrs(attrs.get()); + val->AsTableVal()->SetAttrs(attrs); if ( val && val->Type()->Tag() == TYPE_FILE ) val->AsFile()->SetAttrs(attrs.get()); @@ -188,9 +188,9 @@ void ID::UpdateValAttrs() TypeDecl* fd = rt->FieldDecl(i); if ( ! fd->attrs ) - fd->attrs = new Attributes(new attr_list, rt->FieldType(i), true, IsGlobal()); + fd->attrs = make_intrusive(new attr_list, IntrusivePtr{NewRef{}, rt->FieldType(i)}, true, IsGlobal()); - fd->attrs->AddAttr(new Attr(ATTR_LOG)); + fd->attrs->AddAttr(make_intrusive(ATTR_LOG)); } } } @@ -206,13 +206,13 @@ bool ID::IsDeprecated() const return FindAttr(ATTR_DEPRECATED) != 0; } -void ID::MakeDeprecated(Expr* deprecation) +void ID::MakeDeprecated(IntrusivePtr deprecation) { if ( IsDeprecated() ) return; - attr_list* attr = new attr_list{new Attr(ATTR_DEPRECATED, deprecation)}; - AddAttrs(make_intrusive(attr, Type(), false, IsGlobal())); + attr_list* attr = new attr_list{new Attr(ATTR_DEPRECATED, std::move(deprecation))}; + AddAttrs(make_intrusive(attr, IntrusivePtr{NewRef{}, Type()}, false, IsGlobal())); } string ID::GetDeprecationWarning() const @@ -262,7 +262,7 @@ void ID::SetOption() if ( ! IsRedefinable() ) { attr_list* attr = new attr_list{new Attr(ATTR_REDEF)}; - AddAttrs(make_intrusive(attr, Type(), false, IsGlobal())); + AddAttrs(make_intrusive(attr, IntrusivePtr{NewRef{}, Type()}, false, IsGlobal())); } } @@ -314,7 +314,7 @@ TraversalCode ID::Traverse(TraversalCallback* cb) const void ID::Error(const char* msg, const BroObj* o2) { BroObj::Error(msg, o2, 1); - SetType({AdoptRef{}, error_type()}); + SetType(error_type()); } void ID::Describe(ODesc* d) const diff --git a/src/ID.h b/src/ID.h index c3fba83235..ee96ea7845 100644 --- a/src/ID.h +++ b/src/ID.h @@ -86,7 +86,7 @@ public: bool IsDeprecated() const; - void MakeDeprecated(Expr* deprecation); + void MakeDeprecated(IntrusivePtr deprecation); std::string GetDeprecationWarning() const; diff --git a/src/IP.cc b/src/IP.cc index 56adbca6e7..9d3cdc297a 100644 --- a/src/IP.cc +++ b/src/IP.cc @@ -65,7 +65,7 @@ static VectorVal* BuildOptionsVal(const u_char* data, int len) // PadN or other option uint16_t off = 2 * sizeof(uint8_t); rv->Assign(1, val_mgr->GetCount(opt->ip6o_len)); - rv->Assign(2, new StringVal( + rv->Assign(2, make_intrusive( new BroString(data + off, opt->ip6o_len, 1))); data += opt->ip6o_len + off; len -= opt->ip6o_len + off; @@ -91,8 +91,8 @@ RecordVal* IPv6_Hdr::BuildRecordVal(VectorVal* chain) const rv->Assign(2, val_mgr->GetCount(ntohs(ip6->ip6_plen))); rv->Assign(3, val_mgr->GetCount(ip6->ip6_nxt)); rv->Assign(4, val_mgr->GetCount(ip6->ip6_hlim)); - rv->Assign(5, new AddrVal(IPAddr(ip6->ip6_src))); - rv->Assign(6, new AddrVal(IPAddr(ip6->ip6_dst))); + rv->Assign(5, make_intrusive(IPAddr(ip6->ip6_src))); + rv->Assign(6, make_intrusive(IPAddr(ip6->ip6_dst))); if ( ! chain ) chain = new VectorVal( internal_type("ip6_ext_hdr_chain")->AsVectorType()); @@ -132,7 +132,7 @@ RecordVal* IPv6_Hdr::BuildRecordVal(VectorVal* chain) const rv->Assign(2, val_mgr->GetCount(rt->ip6r_type)); rv->Assign(3, val_mgr->GetCount(rt->ip6r_segleft)); uint16_t off = 4 * sizeof(uint8_t); - rv->Assign(4, new StringVal(new BroString(data + off, Length() - off, 1))); + rv->Assign(4, make_intrusive(new BroString(data + off, Length() - off, 1))); } break; @@ -163,7 +163,7 @@ RecordVal* IPv6_Hdr::BuildRecordVal(VectorVal* chain) const // Payload Len was non-zero for this header. rv->Assign(4, val_mgr->GetCount(ntohl(((uint32_t*)data)[2]))); uint16_t off = 3 * sizeof(uint32_t); - rv->Assign(5, new StringVal(new BroString(data + off, Length() - off, 1))); + rv->Assign(5, make_intrusive(new BroString(data + off, Length() - off, 1))); } } break; @@ -284,7 +284,7 @@ RecordVal* IPv6_Hdr::BuildRecordVal(VectorVal* chain) const RecordVal* m = new RecordVal(hdrType(ip6_mob_brr_type, "ip6_mobility_be")); m->Assign(0, val_mgr->GetCount(*((uint8_t*)msg_data))); const in6_addr* hoa = (const in6_addr*)(msg_data + sizeof(uint16_t)); - m->Assign(1, new AddrVal(IPAddr(*hoa))); + m->Assign(1, make_intrusive(IPAddr(*hoa))); off += sizeof(uint16_t) + sizeof(in6_addr); m->Assign(2, BuildOptionsVal(data + off, Length() - off)); msg->Assign(8, m); @@ -341,8 +341,8 @@ RecordVal* IP_Hdr::BuildIPHdrVal() const rval->Assign(3, val_mgr->GetCount(ntohs(ip4->ip_id))); rval->Assign(4, val_mgr->GetCount(ip4->ip_ttl)); rval->Assign(5, val_mgr->GetCount(ip4->ip_p)); - rval->Assign(6, new AddrVal(ip4->ip_src.s_addr)); - rval->Assign(7, new AddrVal(ip4->ip_dst.s_addr)); + rval->Assign(6, make_intrusive(ip4->ip_src.s_addr)); + rval->Assign(7, make_intrusive(ip4->ip_dst.s_addr)); } else { diff --git a/src/OpaqueVal.cc b/src/OpaqueVal.cc index 1696111bfa..0d2d0a8887 100644 --- a/src/OpaqueVal.cc +++ b/src/OpaqueVal.cc @@ -89,9 +89,7 @@ IntrusivePtr OpaqueVal::Unserialize(const broker::data& data) return nullptr; if ( ! val->DoUnserialize((*v)[1]) ) - { return nullptr; - } return val; } @@ -143,17 +141,17 @@ BroType* OpaqueVal::UnserializeType(const broker::data& data) if ( ! tag ) return nullptr; - return base_type(static_cast(*tag)); + return base_type(static_cast(*tag)).release(); } -Val* OpaqueVal::DoClone(CloneState* state) +IntrusivePtr OpaqueVal::DoClone(CloneState* state) { auto d = OpaqueVal::Serialize(); if ( ! d ) return nullptr; auto rval = OpaqueVal::Unserialize(std::move(*d)); - return state->NewClone(this, rval.release()); + return state->NewClone(this, std::move(rval)); } bool HashVal::IsValid() const @@ -223,17 +221,19 @@ MD5Val::~MD5Val() EVP_MD_CTX_free(ctx); } -Val* MD5Val::DoClone(CloneState* state) +IntrusivePtr MD5Val::DoClone(CloneState* state) { - auto out = new MD5Val(); + auto out = make_intrusive(); + if ( IsValid() ) { if ( ! out->Init() ) return nullptr; + EVP_MD_CTX_copy_ex(out->ctx, ctx); } - return state->NewClone(this, out); + return state->NewClone(this, std::move(out)); } void MD5Val::digest(val_list& vlist, u_char result[MD5_DIGEST_LENGTH]) @@ -374,17 +374,19 @@ SHA1Val::~SHA1Val() EVP_MD_CTX_free(ctx); } -Val* SHA1Val::DoClone(CloneState* state) +IntrusivePtr SHA1Val::DoClone(CloneState* state) { - auto out = new SHA1Val(); + auto out = make_intrusive(); + if ( IsValid() ) { if ( ! out->Init() ) return nullptr; + EVP_MD_CTX_copy_ex(out->ctx, ctx); } - return state->NewClone(this, out); + return state->NewClone(this, std::move(out)); } void SHA1Val::digest(val_list& vlist, u_char result[SHA_DIGEST_LENGTH]) @@ -518,17 +520,19 @@ SHA256Val::~SHA256Val() EVP_MD_CTX_free(ctx); } -Val* SHA256Val::DoClone(CloneState* state) +IntrusivePtr SHA256Val::DoClone(CloneState* state) { - auto out = new SHA256Val(); + auto out = make_intrusive(); + if ( IsValid() ) { if ( ! out->Init() ) return nullptr; + EVP_MD_CTX_copy_ex(out->ctx, ctx); } - return state->NewClone(this, out); + return state->NewClone(this, std::move(out)); } void SHA256Val::digest(val_list& vlist, u_char result[SHA256_DIGEST_LENGTH]) @@ -773,16 +777,16 @@ BloomFilterVal::BloomFilterVal(probabilistic::BloomFilter* bf) bloom_filter = bf; } -Val* BloomFilterVal::DoClone(CloneState* state) +IntrusivePtr BloomFilterVal::DoClone(CloneState* state) { if ( bloom_filter ) { - auto bf = new BloomFilterVal(bloom_filter->Clone()); + auto bf = make_intrusive(bloom_filter->Clone()); bf->Typify(type); - return state->NewClone(this, bf); + return state->NewClone(this, std::move(bf)); } - return state->NewClone(this, new BloomFilterVal()); + return state->NewClone(this, make_intrusive()); } bool BloomFilterVal::Typify(BroType* arg_type) @@ -793,8 +797,8 @@ bool BloomFilterVal::Typify(BroType* arg_type) type = arg_type; type->Ref(); - auto tl = make_intrusive(type); - tl->Append(type->Ref()); + auto tl = make_intrusive(IntrusivePtr{NewRef{}, type}); + tl->Append({NewRef{}, type}); hash = new CompositeHash(std::move(tl)); return true; @@ -949,10 +953,10 @@ CardinalityVal::~CardinalityVal() delete hash; } -Val* CardinalityVal::DoClone(CloneState* state) +IntrusivePtr CardinalityVal::DoClone(CloneState* state) { return state->NewClone(this, - new CardinalityVal(new probabilistic::CardinalityCounter(*c))); + make_intrusive(new probabilistic::CardinalityCounter(*c))); } bool CardinalityVal::Typify(BroType* arg_type) @@ -963,8 +967,8 @@ bool CardinalityVal::Typify(BroType* arg_type) type = arg_type; type->Ref(); - auto tl = make_intrusive(type); - tl->Append(type->Ref()); + auto tl = make_intrusive(IntrusivePtr{NewRef{}, type}); + tl->Append({NewRef{}, type}); hash = new CompositeHash(std::move(tl)); return true; @@ -1043,7 +1047,7 @@ IntrusivePtr ParaglobVal::Get(StringVal* &pattern) std::vector matches = this->internal_paraglob->get(string_pattern); for (unsigned int i = 0; i < matches.size(); i++) - rval->Assign(i, new StringVal(matches.at(i))); + rval->Assign(i, make_intrusive(matches.at(i))); return rval; } @@ -1097,10 +1101,10 @@ bool ParaglobVal::DoUnserialize(const broker::data& data) return true; } -Val* ParaglobVal::DoClone(CloneState* state) +IntrusivePtr ParaglobVal::DoClone(CloneState* state) { try { - return new ParaglobVal + return make_intrusive (std::make_unique(this->internal_paraglob->serialize())); } catch (const paraglob::underflow_error& e) diff --git a/src/OpaqueVal.h b/src/OpaqueVal.h index d4b1f61307..ff90344954 100644 --- a/src/OpaqueVal.h +++ b/src/OpaqueVal.h @@ -140,7 +140,7 @@ protected: * may also override this with a more efficient custom clone * implementation of their own. */ - Val* DoClone(CloneState* state) override; + IntrusivePtr DoClone(CloneState* state) override; /** * Helper function for derived class that need to record a type @@ -191,7 +191,7 @@ public: MD5Val(); ~MD5Val(); - Val* DoClone(CloneState* state) override; + IntrusivePtr DoClone(CloneState* state) override; protected: friend class Val; @@ -212,7 +212,7 @@ public: SHA1Val(); ~SHA1Val(); - Val* DoClone(CloneState* state) override; + IntrusivePtr DoClone(CloneState* state) override; protected: friend class Val; @@ -233,7 +233,7 @@ public: SHA256Val(); ~SHA256Val(); - Val* DoClone(CloneState* state) override; + IntrusivePtr DoClone(CloneState* state) override; protected: friend class Val; @@ -268,7 +268,7 @@ public: explicit BloomFilterVal(probabilistic::BloomFilter* bf); ~BloomFilterVal() override; - Val* DoClone(CloneState* state) override; + IntrusivePtr DoClone(CloneState* state) override; BroType* Type() const; bool Typify(BroType* type); @@ -304,7 +304,7 @@ public: explicit CardinalityVal(probabilistic::CardinalityCounter*); ~CardinalityVal() override; - Val* DoClone(CloneState* state) override; + IntrusivePtr DoClone(CloneState* state) override; void Add(const Val* val); @@ -327,7 +327,7 @@ class ParaglobVal : public OpaqueVal { public: explicit ParaglobVal(std::unique_ptr p); IntrusivePtr Get(StringVal* &pattern); - Val* DoClone(CloneState* state) override; + IntrusivePtr DoClone(CloneState* state) override; bool operator==(const ParaglobVal& other) const; protected: diff --git a/src/RuleCondition.cc b/src/RuleCondition.cc index ff42b135b9..656d4d5cf7 100644 --- a/src/RuleCondition.cc +++ b/src/RuleCondition.cc @@ -145,7 +145,7 @@ RuleConditionEval::RuleConditionEval(const char* func) rules_error("eval function type must yield a 'bool'", func); TypeList tl; - tl.Append(internal_type("signature_state")->Ref()); + tl.Append({NewRef{}, internal_type("signature_state")}); tl.Append(base_type(TYPE_STRING)); if ( ! f->CheckArgs(tl.Types()) ) @@ -175,24 +175,16 @@ bool RuleConditionEval::DoMatch(Rule* rule, RuleEndpointState* state, else args.push_back(val_mgr->GetEmptyString()); - bool result = 0; + bool result = false; try { - Val* val = id->ID_Val()->AsFunc()->Call(&args); - - if ( val ) - { - result = val->AsBool(); - Unref(val); - } - else - result = false; + auto val = id->ID_Val()->AsFunc()->Call(&args); + result = val && val->AsBool(); } catch ( InterpreterException& e ) { - result = false; } return result; diff --git a/src/RuleMatcher.cc b/src/RuleMatcher.cc index 53e3dba055..e49503e276 100644 --- a/src/RuleMatcher.cc +++ b/src/RuleMatcher.cc @@ -78,7 +78,7 @@ Val* RuleMatcher::BuildRuleStateValue(const Rule* rule, const RuleEndpointState* state) const { RecordVal* val = new RecordVal(signature_state); - val->Assign(0, new StringVal(rule->ID())); + val->Assign(0, make_intrusive(rule->ID())); val->Assign(1, state->GetAnalyzer()->BuildConnVal()); val->Assign(2, val_mgr->GetBool(state->is_orig)); val->Assign(3, val_mgr->GetCount(state->payload_size)); diff --git a/src/Scope.cc b/src/Scope.cc index e72df4aa8d..c75dc64410 100644 --- a/src/Scope.cc +++ b/src/Scope.cc @@ -16,9 +16,9 @@ static scope_list scopes; static Scope* top_scope; -Scope::Scope(ID* id, attr_list* al) +Scope::Scope(IntrusivePtr id, attr_list* al) + : scope_id(std::move(id)) { - scope_id = id; attrs = al; return_type = 0; @@ -26,27 +26,20 @@ Scope::Scope(ID* id, attr_list* al) if ( id ) { - BroType* id_type = id->Type(); + BroType* id_type = scope_id->Type(); if ( id_type->Tag() == TYPE_ERROR ) return; else if ( id_type->Tag() != TYPE_FUNC ) reporter->InternalError("bad scope id"); - Ref(id); - FuncType* ft = id->Type()->AsFuncType(); - return_type = ft->YieldType(); - if ( return_type ) - Ref(return_type); + return_type = {NewRef{}, ft->YieldType()}; } } Scope::~Scope() { - for ( const auto& entry : local ) - Unref(entry.second); - if ( attrs ) { for ( const auto& attr : *attrs ) @@ -55,9 +48,6 @@ Scope::~Scope() delete attrs; } - Unref(scope_id); - Unref(return_type); - if ( inits ) { for ( const auto& i : *inits ) @@ -108,7 +98,7 @@ void Scope::Describe(ODesc* d) const for ( const auto& entry : local ) { - ID* id = entry.second; + ID* id = entry.second.get(); id->Describe(d); d->NL(); } @@ -118,7 +108,7 @@ TraversalCode Scope::Traverse(TraversalCallback* cb) const { for ( const auto& entry : local ) { - ID* id = entry.second; + ID* id = entry.second.get(); TraversalCode tc = id->Traverse(cb); HANDLE_TC_STMT_PRE(tc); } @@ -183,11 +173,11 @@ IntrusivePtr install_ID(const char* name, const char* module_name, auto id = make_intrusive(full_name.data(), scope, is_export); if ( SCOPE_FUNCTION != scope ) - global_scope()->Insert(std::move(full_name), IntrusivePtr{id}.release()); + global_scope()->Insert(std::move(full_name), id); else { id->SetOffset(top_scope->Length()); - top_scope->Insert(std::move(full_name), IntrusivePtr{id}.release()); + top_scope->Insert(std::move(full_name), id); } return id; @@ -198,9 +188,9 @@ void push_existing_scope(Scope* scope) scopes.push_back(scope); } -void push_scope(ID* id, attr_list* attrs) +void push_scope(IntrusivePtr id, attr_list* attrs) { - top_scope = new Scope(id, attrs); + top_scope = new Scope(std::move(id), attrs); scopes.push_back(top_scope); } diff --git a/src/Scope.h b/src/Scope.h index cc55c98fea..9fec692e8c 100644 --- a/src/Scope.h +++ b/src/Scope.h @@ -8,6 +8,7 @@ #include "Obj.h" #include "BroList.h" +#include "IntrusivePtr.h" #include "TraverseTypes.h" template class IntrusivePtr; @@ -17,7 +18,7 @@ class ListVal; class Scope : public BroObj { public: - explicit Scope(ID* id, attr_list* al); + explicit Scope(IntrusivePtr id, attr_list* al); ~Scope() override; template @@ -26,31 +27,22 @@ public: const auto& entry = local.find(std::forward(name)); if ( entry != local.end() ) - return entry->second; + return entry->second.get(); return nullptr; } - template - void Insert(N&& name, ID* id) - { - auto [it, inserted] = local.emplace(std::forward(name), id); - - if ( ! inserted ) - { - Unref(it->second); - it->second = id; - } - } + template + void Insert(N&& name, I&& id) { local[std::forward(name)] = std::forward(id); } template - ID* Remove(N&& name) + IntrusivePtr Remove(N&& name) { const auto& entry = local.find(std::forward(name)); if ( entry != local.end() ) { - ID* id = entry->second; + auto id = std::move(entry->second); local.erase(entry); return id; } @@ -58,12 +50,12 @@ public: return nullptr; } - ID* ScopeID() const { return scope_id; } + ID* ScopeID() const { return scope_id.get(); } attr_list* Attrs() const { return attrs; } - BroType* ReturnType() const { return return_type; } + BroType* ReturnType() const { return return_type.get(); } size_t Length() const { return local.size(); } - const std::map& Vars() { return local; } + const auto& Vars() { return local; } ID* GenerateTemporary(const char* name); @@ -72,17 +64,17 @@ public: id_list* GetInits(); // Adds a variable to the list. - void AddInit(ID* id) { inits->push_back(id); } + void AddInit(IntrusivePtr id) { inits->push_back(id.release()); } void Describe(ODesc* d) const override; TraversalCode Traverse(TraversalCallback* cb) const; protected: - ID* scope_id; + IntrusivePtr scope_id; attr_list* attrs; - BroType* return_type; - std::map local; + IntrusivePtr return_type; + std::map> local; id_list* inits; }; @@ -98,7 +90,7 @@ extern IntrusivePtr lookup_ID(const char* name, const char* module, extern IntrusivePtr install_ID(const char* name, const char* module_name, bool is_global, bool is_export); -extern void push_scope(ID* id, attr_list* attrs); +extern void push_scope(IntrusivePtr id, attr_list* attrs); extern void push_existing_scope(Scope* scope); // Returns the one popped off. diff --git a/src/SmithWaterman.cc b/src/SmithWaterman.cc index a71b15a27f..31611d1d4a 100644 --- a/src/SmithWaterman.cc +++ b/src/SmithWaterman.cc @@ -84,25 +84,25 @@ VectorVal* BroSubstring::VecToPolicy(Vec* vec) { BroSubstring* bst = (*vec)[i]; - RecordVal* st_val = new RecordVal(sw_substring_type); - st_val->Assign(0, new StringVal(new BroString(*bst))); + auto st_val = make_intrusive(sw_substring_type); + st_val->Assign(0, make_intrusive(new BroString(*bst))); - VectorVal* aligns = new VectorVal(sw_align_vec_type); + auto aligns = make_intrusive(sw_align_vec_type); for ( unsigned int j = 0; j < bst->GetNumAlignments(); ++j ) { const BSSAlign& align = (bst->GetAlignments())[j]; - RecordVal* align_val = new RecordVal(sw_align_type); - align_val->Assign(0, new StringVal(new BroString(*align.string))); + auto align_val = make_intrusive(sw_align_type); + align_val->Assign(0, make_intrusive(new BroString(*align.string))); align_val->Assign(1, val_mgr->GetCount(align.index)); - aligns->Assign(j+1, align_val); + aligns->Assign(j + 1, std::move(align_val)); } - st_val->Assign(1, aligns); + st_val->Assign(1, std::move(aligns)); st_val->Assign(2, val_mgr->GetBool(bst->IsNewAlignment())); - result->Assign(i+1, st_val); + result->Assign(i + 1, std::move(st_val)); } } diff --git a/src/Stats.cc b/src/Stats.cc index 5d76dc5e80..4ab911507e 100644 --- a/src/Stats.cc +++ b/src/Stats.cc @@ -252,7 +252,7 @@ void ProfileLogger::Log() for ( const auto& global : globals ) { - ID* id = global.second; + ID* id = global.second.get(); // We don't show/count internal globals as they are always // contained in some other global user-visible container. @@ -345,7 +345,7 @@ SampleLogger::SampleLogger() if ( ! load_sample_info ) load_sample_info = internal_type("load_sample_info")->AsTableType(); - load_samples = new TableVal(load_sample_info); + load_samples = new TableVal({NewRef{}, load_sample_info}); } SampleLogger::~SampleLogger() diff --git a/src/Stmt.cc b/src/Stmt.cc index a1df712eb7..4c6fc82520 100644 --- a/src/Stmt.cc +++ b/src/Stmt.cc @@ -202,9 +202,8 @@ static IntrusivePtr lookup_enum_val(const char* module_name, const char int index = et->Lookup(module_name, name); assert(index >= 0); - IntrusivePtr rval{AdoptRef{}, et->GetVal(index)}; - return rval; + return et->GetVal(index); } static void print_log(val_list* vals) @@ -217,11 +216,11 @@ static void print_log(val_list* vals) { ODesc d(DESC_READABLE); val->Describe(&d); - vec->Assign(vec->Size(), new StringVal(d.Description())); + vec->Assign(vec->Size(), make_intrusive(d.Description())); } - record->Assign(0, new Val(current_time(), TYPE_TIME)); - record->Assign(1, vec.release()); + record->Assign(0, make_intrusive(current_time(), TYPE_TIME)); + record->Assign(1, std::move(vec)); log_mgr->Write(plval.get(), record.get()); } @@ -588,7 +587,7 @@ static void int_del_func(void* v) void SwitchStmt::Init() { auto t = make_intrusive(); - t->Append(e->Type()->Ref()); + t->Append({NewRef{}, e->Type()}); comp_hash = new CompositeHash(std::move(t)); case_label_value_map.SetDeleteFunc(int_del_func); @@ -1115,7 +1114,7 @@ ForStmt::ForStmt(id_list* arg_loop_vars, IntrusivePtr loop_expr) BroType* t = (*loop_vars)[0]->Type(); if ( ! t ) - add_local({NewRef{}, (*loop_vars)[0]}, {AdoptRef{}, base_type(TYPE_COUNT)}, + add_local({NewRef{}, (*loop_vars)[0]}, base_type(TYPE_COUNT), INIT_NONE, 0, 0, VAR_REGULAR); else if ( ! IsIntegral(t->Tag()) ) @@ -1136,7 +1135,7 @@ ForStmt::ForStmt(id_list* arg_loop_vars, IntrusivePtr loop_expr) BroType* t = (*loop_vars)[0]->Type(); if ( ! t ) add_local({NewRef{}, (*loop_vars)[0]}, - {AdoptRef{}, base_type(TYPE_STRING)}, + base_type(TYPE_STRING), INIT_NONE, 0, 0, VAR_REGULAR); else if ( t->Tag() != TYPE_STRING ) @@ -1432,7 +1431,7 @@ ReturnStmt::ReturnStmt(IntrusivePtr arg_e) { if ( e ) { - ft->SetYieldType(e->Type()); + ft->SetYieldType({NewRef{}, e->Type()}); s->ScopeID()->SetInferReturnType(false); } } @@ -1451,9 +1450,10 @@ ReturnStmt::ReturnStmt(IntrusivePtr arg_e) else { - Expr* e_ = e.release(); - (void) check_and_promote_expr(e_, yt); - e = {AdoptRef{}, e_}; + auto promoted_e = check_and_promote_expr(e.get(), yt); + + if ( promoted_e ) + e = std::move(promoted_e); } } @@ -1667,7 +1667,7 @@ IntrusivePtr InitStmt::Exec(Frame* f, stmt_flow_type& flow) const v = new VectorVal(t->AsVectorType()); break; case TYPE_TABLE: - v = new TableVal(t->AsTableType(), aggr->Attrs()); + v = new TableVal({NewRef{}, t->AsTableType()}, {NewRef{}, aggr->Attrs()}); break; default: break; diff --git a/src/Tag.cc b/src/Tag.cc index b834bad9c9..f09b06c054 100644 --- a/src/Tag.cc +++ b/src/Tag.cc @@ -2,6 +2,7 @@ #include "Tag.h" #include "Val.h" +#include "IntrusivePtr.h" Tag::Tag(EnumType* etype, type_t arg_type, subtype_t arg_subtype) { @@ -11,7 +12,7 @@ Tag::Tag(EnumType* etype, type_t arg_type, subtype_t arg_subtype) subtype = arg_subtype; int64_t i = (int64_t)(type) | ((int64_t)subtype << 31); Ref(etype); - val = etype->GetVal(i); + val = etype->GetVal(i).release(); } Tag::Tag(EnumVal* arg_val) @@ -85,7 +86,7 @@ EnumVal* Tag::AsEnumVal(EnumType* etype) const { assert(type == 0 && subtype == 0); Ref(etype); - val = etype->GetVal(0); + val = etype->GetVal(0).release(); } return val; diff --git a/src/Trigger.cc b/src/Trigger.cc index 15d912fb2d..b962e449c1 100644 --- a/src/Trigger.cc +++ b/src/Trigger.cc @@ -265,7 +265,7 @@ bool Trigger::Eval() return false; } - f->SetTrigger(this); + f->SetTrigger({NewRef{}, this}); IntrusivePtr v; diff --git a/src/TunnelEncapsulation.cc b/src/TunnelEncapsulation.cc index 724a69cca9..ffb565b1fb 100644 --- a/src/TunnelEncapsulation.cc +++ b/src/TunnelEncapsulation.cc @@ -20,15 +20,15 @@ RecordVal* EncapsulatingConn::GetRecordVal() const { RecordVal *rv = new RecordVal(BifType::Record::Tunnel::EncapsulatingConn); - RecordVal* id_val = new RecordVal(conn_id); - id_val->Assign(0, new AddrVal(src_addr)); + auto id_val = make_intrusive(conn_id); + id_val->Assign(0, make_intrusive(src_addr)); id_val->Assign(1, val_mgr->GetPort(ntohs(src_port), proto)); - id_val->Assign(2, new AddrVal(dst_addr)); + id_val->Assign(2, make_intrusive(dst_addr)); id_val->Assign(3, val_mgr->GetPort(ntohs(dst_port), proto)); - rv->Assign(0, id_val); + rv->Assign(0, std::move(id_val)); rv->Assign(1, BifType::Enum::Tunnel::Type->GetVal(type)); - rv->Assign(2, new StringVal(uid.Base62("C").c_str())); + rv->Assign(2, make_intrusive(uid.Base62("C").c_str())); return rv; } diff --git a/src/Type.cc b/src/Type.cc index b855e0cbde..b1b83c4541 100644 --- a/src/Type.cc +++ b/src/Type.cc @@ -100,7 +100,7 @@ int BroType::MatchesIndex(ListExpr* const index) const if ( index->Exprs().length() != 1 && index->Exprs().length() != 2 ) return DOES_NOT_MATCH_INDEX; - if ( check_and_promote_exprs_to_type(index, ::base_type(TYPE_INT)) ) + if ( check_and_promote_exprs_to_type(index, ::base_type(TYPE_INT).get()) ) return MATCHES_INDEX_SCALAR; } @@ -109,7 +109,7 @@ int BroType::MatchesIndex(ListExpr* const index) const BroType* BroType::YieldType() { - return 0; + return nullptr; } int BroType::HasField(const char* /* field */) const @@ -119,7 +119,7 @@ int BroType::HasField(const char* /* field */) const BroType* BroType::FieldType(const char* /* field */) const { - return 0; + return nullptr; } void BroType::Describe(ODesc* d) const @@ -155,8 +155,6 @@ TypeList::~TypeList() { for ( const auto& type : types ) Unref(type); - - Unref(pure_type); } int TypeList::AllMatch(const BroType* t, int is_init) const @@ -167,23 +165,20 @@ int TypeList::AllMatch(const BroType* t, int is_init) const return 1; } -void TypeList::Append(BroType* t) +void TypeList::Append(IntrusivePtr t) { - if ( pure_type && ! same_type(t, pure_type) ) + if ( pure_type && ! same_type(t.get(), pure_type.get()) ) reporter->InternalError("pure type-list violation"); - types.push_back(t); + types.push_back(t.release()); } -void TypeList::AppendEvenIfNotPure(BroType* t) +void TypeList::AppendEvenIfNotPure(IntrusivePtr t) { - if ( pure_type && ! same_type(t, pure_type) ) - { - Unref(pure_type); - pure_type = 0; - } + if ( pure_type && ! same_type(t.get(), pure_type.get()) ) + pure_type = nullptr; - types.push_back(t); + types.push_back(t.release()); } void TypeList::Describe(ODesc* d) const @@ -220,11 +215,7 @@ unsigned int TypeList::MemoryAllocation() const + types.MemoryAllocation() - padded_sizeof(types); } -IndexType::~IndexType() - { - Unref(indices); - Unref(yield_type); - } +IndexType::~IndexType() = default; int IndexType::MatchesIndex(ListExpr* const index) const { @@ -242,12 +233,12 @@ int IndexType::MatchesIndex(ListExpr* const index) const BroType* IndexType::YieldType() { - return yield_type; + return yield_type.get(); } const BroType* IndexType::YieldType() const { - return yield_type; + return yield_type.get(); } void IndexType::Describe(ODesc* d) const @@ -326,8 +317,8 @@ bool IndexType::IsSubNetIndex() const return false; } -TableType::TableType(TypeList* ind, BroType* yield) -: IndexType(TYPE_TABLE, ind, yield) +TableType::TableType(IntrusivePtr ind, IntrusivePtr yield) + : IndexType(TYPE_TABLE, std::move(ind), std::move(yield)) { if ( ! indices ) return; @@ -355,11 +346,6 @@ TableType::TableType(TypeList* ind, BroType* yield) TableType* TableType::ShallowClone() { - if ( indices ) - indices->Ref(); - if ( yield_type ) - yield_type->Ref(); - return new TableType(indices, yield_type); } @@ -377,20 +363,20 @@ TypeList* TableType::ExpandRecordIndex(RecordType* rt) const for ( int i = 0; i < n; ++i ) { TypeDecl* td = rt->FieldDecl(i); - tl->Append(td->type->Ref()); + tl->Append(td->type); } return tl; } -SetType::SetType(TypeList* ind, ListExpr* arg_elements) : TableType(ind, 0) +SetType::SetType(IntrusivePtr ind, IntrusivePtr arg_elements) + : TableType(std::move(ind), nullptr), elements(std::move(arg_elements)) { - elements = arg_elements; if ( elements ) { if ( indices ) { // We already have a type. - if ( ! check_and_promote_exprs(elements, indices) ) + if ( ! check_and_promote_exprs(elements.get(), indices.get()) ) SetError(); } else @@ -406,21 +392,17 @@ SetType::SetType(TypeList* ind, ListExpr* arg_elements) : TableType(ind, 0) else if ( tl->length() == 1 ) { - BroType* t = flatten_type((*tl)[0]->Ref()); - indices = new TypeList(t); - indices->Append(t->Ref()); + IntrusivePtr ft{NewRef{}, flatten_type((*tl)[0])}; + indices = make_intrusive(ft); + indices->Append(std::move(ft)); } else { - BroType* t = merge_types((*tl)[0], (*tl)[1]); + auto t = merge_types((*tl)[0], (*tl)[1]); for ( int i = 2; t && i < tl->length(); ++i ) - { - BroType* t_new = merge_types(t, (*tl)[i]); - Unref(t); - t = t_new; - } + t = merge_types(t.get(), (*tl)[i]); if ( ! t ) { @@ -428,8 +410,8 @@ SetType::SetType(TypeList* ind, ListExpr* arg_elements) : TableType(ind, 0) return; } - indices = new TypeList(t); - indices->Append(t); + indices = make_intrusive(t); + indices->Append(std::move(t)); } } } @@ -437,29 +419,18 @@ SetType::SetType(TypeList* ind, ListExpr* arg_elements) : TableType(ind, 0) SetType* SetType::ShallowClone() { - if ( elements ) - elements->Ref(); - - if ( indices ) - indices->Ref(); - return new SetType(indices, elements); } -SetType::~SetType() - { - Unref(elements); - } +SetType::~SetType() = default; -FuncType::FuncType(RecordType* arg_args, BroType* arg_yield, function_flavor arg_flavor) -: BroType(TYPE_FUNC) +FuncType::FuncType(IntrusivePtr arg_args, + IntrusivePtr arg_yield, function_flavor arg_flavor) + : BroType(TYPE_FUNC), args(std::move(arg_args)), + arg_types(make_intrusive()), yield(std::move(arg_yield)) { - args = arg_args; - yield = arg_yield; flavor = arg_flavor; - arg_types = new TypeList(); - bool has_default_arg = false; for ( int i = 0; i < args->NumFields(); ++i ) @@ -476,16 +447,16 @@ FuncType::FuncType(RecordType* arg_args, BroType* arg_yield, function_flavor arg args->Error(err_str); } - arg_types->Append(args->FieldType(i)->Ref()); + arg_types->Append({NewRef{}, args->FieldType(i)}); } } FuncType* FuncType::ShallowClone() { auto f = new FuncType(); - f->args = args->Ref()->AsRecordType(); - f->arg_types = arg_types->Ref()->AsTypeList(); - f->yield = yield->Ref(); + f->args = {NewRef{}, args->AsRecordType()}; + f->arg_types = {NewRef{}, arg_types->AsTypeList()}; + f->yield = yield; f->flavor = flavor; return f; } @@ -509,26 +480,21 @@ string FuncType::FlavorString() const } } -FuncType::~FuncType() - { - Unref(args); - Unref(arg_types); - Unref(yield); - } +FuncType::~FuncType() = default; BroType* FuncType::YieldType() { - return yield; + return yield.get(); } const BroType* FuncType::YieldType() const { - return yield; + return yield.get(); } int FuncType::MatchesIndex(ListExpr* const index) const { - return check_and_promote_args(index, args) ? + return check_and_promote_args(index, args.get()) ? MATCHES_INDEX_SCALAR : DOES_NOT_MATCH_INDEX; } @@ -606,28 +572,23 @@ void FuncType::DescribeReST(ODesc* d, bool roles_only) const } } -TypeDecl::TypeDecl(BroType* t, const char* i, attr_list* arg_attrs, bool in_record) +TypeDecl::TypeDecl(IntrusivePtr t, const char* i, attr_list* arg_attrs, bool in_record) + : type(std::move(t)), + attrs(arg_attrs ? make_intrusive(arg_attrs, type, in_record, false) : nullptr), + id(i) { - type = t; - attrs = arg_attrs ? new Attributes(arg_attrs, t, in_record, false) : 0; - id = i; } TypeDecl::TypeDecl(const TypeDecl& other) { - type = other.type->Ref(); + type = other.type; attrs = other.attrs; - if ( attrs ) - ::Ref(attrs); - id = copy_string(other.id); } TypeDecl::~TypeDecl() { - Unref(type); - Unref(attrs); delete [] id; } @@ -692,19 +653,19 @@ BroType* RecordType::FieldType(const char* field) const BroType* RecordType::FieldType(int field) const { - return (*types)[field]->type; + return (*types)[field]->type.get(); } -Val* RecordType::FieldDefault(int field) const +IntrusivePtr RecordType::FieldDefault(int field) const { const TypeDecl* td = FieldDecl(field); if ( ! td->attrs ) - return 0; + return nullptr; const Attr* def_attr = td->attrs->FindAttr(ATTR_DEFAULT); - return def_attr ? def_attr->AttrExpr()->Eval(nullptr).release() : nullptr; + return def_attr ? def_attr->AttrExpr()->Eval(nullptr) : nullptr; } int RecordType::FieldOffset(const char* field) const @@ -806,9 +767,9 @@ static string container_type_name(const BroType* ft) return s; } -TableVal* RecordType::GetRecordFieldsVal(const RecordVal* rv) const +IntrusivePtr RecordType::GetRecordFieldsVal(const RecordVal* rv) const { - auto rval = new TableVal(internal_type("record_field_table")->AsTableType()); + auto rval = make_intrusive(IntrusivePtr{NewRef{}, internal_type("record_field_table")->AsTableType()}); for ( int i = 0; i < NumFields(); ++i ) { @@ -824,15 +785,15 @@ TableVal* RecordType::GetRecordFieldsVal(const RecordVal* rv) const bool logged = (fd->attrs && fd->FindAttr(ATTR_LOG) != 0); - RecordVal* nr = new RecordVal(internal_type("record_field")->AsRecordType()); + auto nr = make_intrusive(internal_type("record_field")->AsRecordType()); string s = container_type_name(ft); - nr->Assign(0, new StringVal(s)); + nr->Assign(0, make_intrusive(s)); nr->Assign(1, val_mgr->GetBool(logged)); nr->Assign(2, fv); nr->Assign(3, FieldDefault(i)); Val* field_name = new StringVal(FieldName(i)); - rval->Assign(field_name, nr); + rval->Assign(field_name, std::move(nr)); Unref(field_name); } @@ -863,9 +824,9 @@ const char* RecordType::AddFields(type_decl_list* others, attr_list* attr) if ( log ) { if ( ! td->attrs ) - td->attrs = new Attributes(new attr_list, td->type, true, false); + td->attrs = make_intrusive(new attr_list, td->type, true, false); - td->attrs->AddAttr(new Attr(ATTR_LOG)); + td->attrs->AddAttr(make_intrusive(ATTR_LOG)); } types->push_back(td); @@ -874,7 +835,7 @@ const char* RecordType::AddFields(type_decl_list* others, attr_list* attr) delete others; num_fields = types->length(); - return 0; + return nullptr; } void RecordType::DescribeFields(ODesc* d) const @@ -890,7 +851,7 @@ void RecordType::DescribeFields(ODesc* d) const d->Add(td->id); d->Add(":"); - if ( d->FindType(td->type) ) + if ( d->FindType(td->type.get()) ) d->Add(""); else td->type->Describe(d); @@ -936,7 +897,7 @@ void RecordType::DescribeFieldsReST(ODesc* d, bool func_args) const const TypeDecl* td = FieldDecl(i); - if ( d->FindType(td->type) ) + if ( d->FindType(td->type.get()) ) d->Add(""); else { @@ -1046,20 +1007,16 @@ void SubNetType::Describe(ODesc* d) const d->Add(int(Tag())); } -FileType::FileType(BroType* yield_type) -: BroType(TYPE_FILE) +FileType::FileType(IntrusivePtr yield_type) + : BroType(TYPE_FILE), yield(std::move(yield_type)) { - yield = yield_type; } -FileType::~FileType() - { - Unref(yield); - } +FileType::~FileType() = default; BroType* FileType::YieldType() { - return yield; + return yield.get(); } void FileType::Describe(ODesc* d) const @@ -1104,18 +1061,10 @@ EnumType::EnumType(const string& name) } EnumType::EnumType(const EnumType* e) - : BroType(TYPE_ENUM) + : BroType(TYPE_ENUM), names(e->names), vals(e->vals) { counter = e->counter; SetName(e->GetName()); - - for ( auto it = e->names.begin(); it != e->names.end(); ++it ) - names[it->first] = it->second; - - vals = e->vals; - - for ( auto& kv : vals ) - ::Ref(kv.second); } EnumType* EnumType::ShallowClone() @@ -1126,11 +1075,7 @@ EnumType* EnumType::ShallowClone() return new EnumType(this); } -EnumType::~EnumType() - { - for ( auto& kv : vals ) - Unref(kv.second); - } +EnumType::~EnumType() = default; // Note, we use reporter->Error() here (not Error()) to include the current script // location in the error message, rather than the one where the type was @@ -1180,7 +1125,7 @@ void EnumType::CheckAndAddName(const string& module_name, const char* name, id->SetEnumConst(); if ( deprecation ) - id->MakeDeprecated(deprecation); + id->MakeDeprecated({NewRef{}, deprecation}); zeekygen_mgr->Identifier(std::move(id)); } @@ -1203,7 +1148,7 @@ void EnumType::CheckAndAddName(const string& module_name, const char* name, AddNameInternal(module_name, name, val, is_export); if ( vals.find(val) == vals.end() ) - vals[val] = new EnumVal(this, val); + vals[val] = IntrusivePtr{AdoptRef{}, new EnumVal(this, val)}; set types = BroType::GetAliases(GetName()); set::const_iterator it; @@ -1239,7 +1184,7 @@ const char* EnumType::Lookup(bro_int_t value) const if ( iter->second == value ) return iter->first.c_str(); - return 0; + return nullptr; } EnumType::enum_name_list EnumType::Names() const @@ -1252,20 +1197,19 @@ EnumType::enum_name_list EnumType::Names() const return n; } -EnumVal* EnumType::GetVal(bro_int_t i) +IntrusivePtr EnumType::GetVal(bro_int_t i) { auto it = vals.find(i); - EnumVal* rval; + IntrusivePtr rval; if ( it == vals.end() ) { - rval = new EnumVal(this, i); + rval = IntrusivePtr{AdoptRef{}, new EnumVal(this, i)}; vals[i] = rval; } else rval = it->second; - ::Ref(rval); return rval; } @@ -1346,23 +1290,17 @@ void EnumType::DescribeReST(ODesc* d, bool roles_only) const } } -VectorType::VectorType(BroType* element_type) - : BroType(TYPE_VECTOR), yield_type(element_type) +VectorType::VectorType(IntrusivePtr element_type) + : BroType(TYPE_VECTOR), yield_type(std::move(element_type)) { } VectorType* VectorType::ShallowClone() { - if ( yield_type ) - yield_type->Ref(); - return new VectorType(yield_type); } -VectorType::~VectorType() - { - Unref(yield_type); - } +VectorType::~VectorType() = default; BroType* VectorType::YieldType() { @@ -1371,14 +1309,9 @@ BroType* VectorType::YieldType() // return any as that's what other code historically expects for type // comparisions. if ( IsUnspecifiedVector() ) - { - BroType* ret = ::base_type(TYPE_ANY); - Unref(ret); // unref, because this won't be held by anyone. - assert(ret); - return ret; - } + return base_type_no_ref(TYPE_ANY); - return yield_type; + return yield_type.get(); } const BroType* VectorType::YieldType() const @@ -1389,13 +1322,13 @@ const BroType* VectorType::YieldType() const // comparisions. if ( IsUnspecifiedVector() ) { - BroType* ret = ::base_type(TYPE_ANY); - Unref(ret); // unref, because this won't be held by anyone. + auto ret = ::base_type(TYPE_ANY); assert(ret); - return ret; + // release, because this won't be held by anyone. + return ret.release(); } - return yield_type; + return yield_type.get(); } int VectorType::MatchesIndex(ListExpr* const index) const @@ -1587,7 +1520,7 @@ int same_type(const BroType* t1, const BroType* t2, int is_init, bool match_reco const TypeDecl* td2 = rt2->FieldDecl(i); if ( (match_record_field_names && ! streq(td1->id, td2->id)) || - ! same_type(td1->type, td2->type, is_init, match_record_field_names) ) + ! same_type(td1->type.get(), td2->type.get(), is_init, match_record_field_names) ) return 0; } @@ -1767,7 +1700,7 @@ TypeTag max_type(TypeTag t1, TypeTag t2) } } -BroType* merge_types(const BroType* t1, const BroType* t2) +IntrusivePtr merge_types(const BroType* t1, const BroType* t2) { t1 = flatten_type(t1); t2 = flatten_type(t2); @@ -1781,7 +1714,7 @@ BroType* merge_types(const BroType* t1, const BroType* t2) if ( tg1 != tg2 ) { t1->Error("incompatible types", t2); - return 0; + return nullptr; } switch ( tg1 ) { @@ -1808,7 +1741,7 @@ BroType* merge_types(const BroType* t1, const BroType* t2) t1->GetName().data(), t2->GetName().data()); t1->Error(msg.data(), t2); - return 0; + return nullptr; } // Doing a lookup here as a roundabout way of ref-ing t1, without @@ -1821,14 +1754,14 @@ BroType* merge_types(const BroType* t1, const BroType* t2) // than a copy since it may be redef'd later in parsing. If we // return a copy, then whoever is using this return value won't // actually see those changes from the redef. - return id->AsType()->Ref(); + return {NewRef{}, id->AsType()}; std::string msg = fmt("incompatible enum types: '%s' and '%s'" " ('%s' enum type ID is invalid)", t1->GetName().data(), t2->GetName().data(), t1->GetName().data()); t1->Error(msg.data(), t2); - return 0; + return nullptr; } case TYPE_TABLE: @@ -1838,56 +1771,49 @@ BroType* merge_types(const BroType* t1, const BroType* t2) const type_list* tl1 = it1->IndexTypes(); const type_list* tl2 = it2->IndexTypes(); - TypeList* tl3 = 0; + IntrusivePtr tl3; if ( tl1 || tl2 ) { if ( ! tl1 || ! tl2 || tl1->length() != tl2->length() ) { t1->Error("incompatible types", t2); - return 0; + return nullptr; } - tl3 = new TypeList(); + tl3 = make_intrusive(); loop_over_list(*tl1, i) { - BroType* tl3_i = merge_types((*tl1)[i], (*tl2)[i]); + auto tl3_i = merge_types((*tl1)[i], (*tl2)[i]); if ( ! tl3_i ) - { - Unref(tl3); - return 0; - } + return nullptr; - tl3->Append(tl3_i); + tl3->Append(std::move(tl3_i)); } } const BroType* y1 = t1->YieldType(); const BroType* y2 = t2->YieldType(); - BroType* y3 = 0; + IntrusivePtr y3; if ( y1 || y2 ) { if ( ! y1 || ! y2 ) { t1->Error("incompatible types", t2); - Unref(tl3); - return 0; + return nullptr; } y3 = merge_types(y1, y2); if ( ! y3 ) - { - Unref(tl3); - return 0; - } + return nullptr; } if ( t1->IsSet() ) - return new SetType(tl3, 0); + return make_intrusive(std::move(tl3), nullptr); else - return new TableType(tl3, y3); + return make_intrusive(std::move(tl3), std::move(y3)); } case TYPE_FUNC: @@ -1895,16 +1821,17 @@ BroType* merge_types(const BroType* t1, const BroType* t2) if ( ! same_type(t1, t2) ) { t1->Error("incompatible types", t2); - return 0; + return nullptr; } const FuncType* ft1 = (const FuncType*) t1; const FuncType* ft2 = (const FuncType*) t1; - BroType* args = merge_types(ft1->Args(), ft2->Args()); - BroType* yield = t1->YieldType() ? - merge_types(t1->YieldType(), t2->YieldType()) : 0; + auto args = merge_types(ft1->Args(), ft2->Args()); + auto yield = t1->YieldType() ? + merge_types(t1->YieldType(), t2->YieldType()) : nullptr; - return new FuncType(args->AsRecordType(), yield, ft1->Flavor()); + return make_intrusive(IntrusivePtr{AdoptRef{}, args.release()->AsRecordType()}, + std::move(yield), ft1->Flavor()); } case TYPE_RECORD: @@ -1913,7 +1840,7 @@ BroType* merge_types(const BroType* t1, const BroType* t2) const RecordType* rt2 = (const RecordType*) t2; if ( rt1->NumFields() != rt2->NumFields() ) - return 0; + return nullptr; type_decl_list* tdl3 = new type_decl_list(rt1->NumFields()); @@ -1921,20 +1848,19 @@ BroType* merge_types(const BroType* t1, const BroType* t2) { const TypeDecl* td1 = rt1->FieldDecl(i); const TypeDecl* td2 = rt2->FieldDecl(i); - BroType* tdl3_i = merge_types(td1->type, td2->type); + auto tdl3_i = merge_types(td1->type.get(), td2->type.get()); if ( ! streq(td1->id, td2->id) || ! tdl3_i ) { t1->Error("incompatible record fields", t2); delete tdl3; - Unref(tdl3_i); - return 0; + return nullptr; } - tdl3->push_back(new TypeDecl(tdl3_i, copy_string(td1->id))); + tdl3->push_back(new TypeDecl(std::move(tdl3_i), copy_string(td1->id))); } - return new RecordType(tdl3); + return make_intrusive(tdl3); } case TYPE_LIST: @@ -1945,7 +1871,7 @@ BroType* merge_types(const BroType* t1, const BroType* t2) if ( tl1->IsPure() != tl2->IsPure() ) { tl1->Error("incompatible lists", tl2); - return 0; + return nullptr; } const type_list* l1 = tl1->Types(); @@ -1957,7 +1883,7 @@ BroType* merge_types(const BroType* t1, const BroType* t2) tl1->Error("empty list"); else tl2->Error("empty list"); - return 0; + return nullptr; } if ( tl1->IsPure() ) @@ -1974,10 +1900,10 @@ BroType* merge_types(const BroType* t1, const BroType* t2) if ( l1->length() != l2->length() ) { tl1->Error("different number of indices", tl2); - return 0; + return nullptr; } - TypeList* tl3 = new TypeList(); + auto tl3 = make_intrusive(); loop_over_list(*l1, i) tl3->Append(merge_types((*l1)[i], (*l2)[i])); @@ -1988,31 +1914,31 @@ BroType* merge_types(const BroType* t1, const BroType* t2) if ( ! same_type(t1->YieldType(), t2->YieldType()) ) { t1->Error("incompatible types", t2); - return 0; + return nullptr; } - return new VectorType(merge_types(t1->YieldType(), t2->YieldType())); + return make_intrusive(merge_types(t1->YieldType(), t2->YieldType())); case TYPE_FILE: if ( ! same_type(t1->YieldType(), t2->YieldType()) ) { t1->Error("incompatible types", t2); - return 0; + return nullptr; } - return new FileType(merge_types(t1->YieldType(), t2->YieldType())); + return make_intrusive(merge_types(t1->YieldType(), t2->YieldType())); case TYPE_UNION: reporter->InternalError("union type in merge_types()"); - return 0; + return nullptr; default: reporter->InternalError("bad type in merge_types()"); - return 0; + return nullptr; } } -BroType* merge_type_list(ListExpr* elements) +IntrusivePtr merge_type_list(ListExpr* elements) { TypeList* tl_type = elements->Type()->AsTypeList(); type_list* tl = tl_type->Types(); @@ -2020,20 +1946,16 @@ BroType* merge_type_list(ListExpr* elements) if ( tl->length() < 1 ) { reporter->Error("no type can be inferred for empty list"); - return 0; + return nullptr; } - BroType* t = (*tl)[0]->Ref(); + IntrusivePtr t{NewRef{}, (*tl)[0]}; if ( tl->length() == 1 ) return t; for ( int i = 1; t && i < tl->length(); ++i ) - { - BroType* t_new = merge_types(t, (*tl)[i]); - Unref(t); - t = t_new; - } + t = merge_types(t.get(), (*tl)[i]); if ( ! t ) reporter->Error("inconsistent types in list"); @@ -2060,7 +1982,7 @@ static BroType* reduce_type(BroType* t) return t; } -BroType* init_type(Expr* init) +IntrusivePtr init_type(Expr* init) { if ( init->Tag() != EXPR_LIST ) { @@ -2076,7 +1998,7 @@ BroType* init_type(Expr* init) return nullptr; } - return t.release(); + return t; } ListExpr* init_list = init->AsListExpr(); @@ -2094,7 +2016,7 @@ BroType* init_type(Expr* init) if ( e0->IsRecordElement(0) ) // ListExpr's know how to build a record from their // components. - return init_list->InitType().release(); + return init_list->InitType(); auto t = e0->InitType(); @@ -2115,7 +2037,7 @@ BroType* init_type(Expr* init) if ( same_type(t.get(), ti) ) continue; - t = IntrusivePtr{AdoptRef{}, merge_types(t.get(), ti)}; + t = merge_types(t.get(), ti); } if ( ! t ) @@ -2126,18 +2048,18 @@ BroType* init_type(Expr* init) if ( t->Tag() == TYPE_TABLE && ! t->AsTableType()->IsSet() ) // A list of table elements. - return t.release(); + return t; // 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 ) { - auto tl = make_intrusive(t.get()->Ref()); - tl->Append(t.release()); + auto tl = make_intrusive(t); + tl->Append(std::move(t)); t = std::move(tl); } - return new SetType(t.release()->AsTypeList(), 0); + return make_intrusive(IntrusivePtr{AdoptRef{}, t.release()->AsTypeList()}, nullptr); } bool is_atomic_type(const BroType* t) diff --git a/src/Type.h b/src/Type.h index 5fe5c5b6be..b6ba45a376 100644 --- a/src/Type.h +++ b/src/Type.h @@ -5,6 +5,7 @@ #include "Obj.h" #include "Attr.h" #include "BroList.h" +#include "IntrusivePtr.h" #include #include @@ -346,12 +347,11 @@ private: class TypeList : public BroType { public: - explicit TypeList(BroType* arg_pure_type = 0) : BroType(TYPE_LIST) + explicit TypeList(IntrusivePtr arg_pure_type = nullptr) + : BroType(TYPE_LIST), pure_type(std::move(arg_pure_type)) { - pure_type = arg_pure_type; - if ( pure_type ) - pure_type->Ref(); } + ~TypeList() override; const type_list* Types() const { return &types; } @@ -361,23 +361,23 @@ public: // Returns the underlying pure type, or nil if the list // is not pure or is empty. - BroType* PureType() { return pure_type; } - const BroType* PureType() const { return pure_type; } + BroType* PureType() { return pure_type.get(); } + const BroType* PureType() const { return pure_type.get(); } // True if all of the types match t, false otherwise. If // is_init is true, then the matching is done in the context // of an initialization. int AllMatch(const BroType* t, int is_init) const; - void Append(BroType* t); - void AppendEvenIfNotPure(BroType* t); + void Append(IntrusivePtr t); + void AppendEvenIfNotPure(IntrusivePtr t); void Describe(ODesc* d) const override; unsigned int MemoryAllocation() const override; protected: - BroType* pure_type; + IntrusivePtr pure_type; type_list types; }; @@ -385,7 +385,7 @@ class IndexType : public BroType { public: int MatchesIndex(ListExpr* index) const override; - TypeList* Indices() const { return indices; } + TypeList* Indices() const { return indices.get(); } const type_list* IndexTypes() const { return indices->Types(); } BroType* YieldType() override; const BroType* YieldType() const override; @@ -397,22 +397,22 @@ public: bool IsSubNetIndex() const; protected: - IndexType(){ indices = 0; yield_type = 0; } - IndexType(TypeTag t, TypeList* arg_indices, BroType* arg_yield_type) : - BroType(t) + IndexType(TypeTag t, IntrusivePtr arg_indices, + IntrusivePtr arg_yield_type) + : BroType(t), indices(std::move(arg_indices)), + yield_type(std::move(arg_yield_type)) { - indices = arg_indices; - yield_type = arg_yield_type; } + ~IndexType() override; - TypeList* indices; - BroType* yield_type; + IntrusivePtr indices; + IntrusivePtr yield_type; }; class TableType : public IndexType { public: - TableType(TypeList* ind, BroType* yield); + TableType(IntrusivePtr ind, IntrusivePtr yield); TableType* ShallowClone() override; @@ -421,87 +421,81 @@ public: bool IsUnspecifiedTable() const; protected: - TableType() {} - TypeList* ExpandRecordIndex(RecordType* rt) const; }; class SetType : public TableType { public: - SetType(TypeList* ind, ListExpr* arg_elements); + SetType(IntrusivePtr ind, IntrusivePtr arg_elements); ~SetType() override; SetType* ShallowClone() override; - ListExpr* SetElements() const { return elements; } + ListExpr* SetElements() const { return elements.get(); } protected: - SetType() {} - - ListExpr* elements; + IntrusivePtr elements; }; class FuncType : public BroType { public: - FuncType(RecordType* args, BroType* yield, function_flavor f); + FuncType(IntrusivePtr args, IntrusivePtr yield, + function_flavor f); FuncType* ShallowClone() override; ~FuncType() override; - RecordType* Args() const { return args; } + RecordType* Args() const { return args.get(); } BroType* YieldType() override; const BroType* YieldType() const override; - void SetYieldType(BroType* arg_yield) { yield = arg_yield; } + void SetYieldType(IntrusivePtr arg_yield) { yield = std::move(arg_yield); } function_flavor Flavor() const { return flavor; } std::string FlavorString() const; // Used to convert a function type to an event or hook type. void ClearYieldType(function_flavor arg_flav) - { Unref(yield); yield = 0; flavor = arg_flav; } + { yield = nullptr; flavor = arg_flav; } int MatchesIndex(ListExpr* index) const override; int CheckArgs(const type_list* args, bool is_init = false) const; - TypeList* ArgTypes() const { return arg_types; } + TypeList* ArgTypes() const { return arg_types.get(); } void Describe(ODesc* d) const override; void DescribeReST(ODesc* d, bool roles_only = false) const override; protected: - FuncType() : BroType(TYPE_FUNC) { args = 0; arg_types = 0; yield = 0; flavor = FUNC_FLAVOR_FUNCTION; } - RecordType* args; - TypeList* arg_types; - BroType* yield; + FuncType() : BroType(TYPE_FUNC) { flavor = FUNC_FLAVOR_FUNCTION; } + IntrusivePtr args; + IntrusivePtr arg_types; + IntrusivePtr yield; function_flavor flavor; }; class TypeType : public BroType { public: - explicit TypeType(BroType* t) : BroType(TYPE_TYPE) { type = t->Ref(); } + explicit TypeType(IntrusivePtr t) : BroType(TYPE_TYPE), type(std::move(t)) {} TypeType* ShallowClone() override { return new TypeType(type); } - ~TypeType() override { Unref(type); } - BroType* Type() { return type; } + BroType* Type() { return type.get(); } protected: - TypeType() {} - - BroType* type; + IntrusivePtr type; }; -class TypeDecl { +class TypeDecl final { public: - TypeDecl(BroType* t, const char* i, attr_list* attrs = 0, bool in_record = false); + TypeDecl(IntrusivePtr t, const char* i, attr_list* attrs = 0, bool in_record = false); TypeDecl(const TypeDecl& other); - virtual ~TypeDecl(); + ~TypeDecl(); const Attr* FindAttr(attr_tag a) const { return attrs ? attrs->FindAttr(a) : 0; } - virtual void DescribeReST(ODesc* d, bool roles_only = false) const; + void DescribeReST(ODesc* d, bool roles_only = false) const; - BroType* type; - Attributes* attrs; + IntrusivePtr type; + IntrusivePtr attrs; const char* id; }; @@ -517,7 +511,7 @@ public: int HasField(const char* field) const override; BroType* FieldType(const char* field) const override; BroType* FieldType(int field) const; - Val* FieldDefault(int field) const; // Ref's the returned value; 0 if none. + IntrusivePtr FieldDefault(int field) const; // A field's offset is its position in the type_decl_list, // starting at 0. Returns negative if the field doesn't exist. @@ -539,7 +533,7 @@ public: * @param rv an optional record value, if given the values of * all fields will be provided in the returned table. */ - TableVal* GetRecordFieldsVal(const RecordVal* rv = nullptr) const; + IntrusivePtr GetRecordFieldsVal(const RecordVal* rv = nullptr) const; // Returns 0 if all is ok, otherwise a pointer to an error message. // Takes ownership of list. @@ -579,8 +573,8 @@ public: class FileType : public BroType { public: - explicit FileType(BroType* yield_type); - FileType* ShallowClone() override { return new FileType(yield->Ref()); } + explicit FileType(IntrusivePtr yield_type); + FileType* ShallowClone() override { return new FileType(yield); } ~FileType() override; BroType* YieldType() override; @@ -588,9 +582,7 @@ public: void Describe(ODesc* d) const override; protected: - FileType() { yield = 0; } - - BroType* yield; + IntrusivePtr yield; }; class OpaqueType : public BroType { @@ -638,11 +630,9 @@ public: void DescribeReST(ODesc* d, bool roles_only = false) const override; - EnumVal* GetVal(bro_int_t i); + IntrusivePtr GetVal(bro_int_t i); protected: - EnumType() { counter = 0; } - void AddNameInternal(const std::string& module_name, const char* name, bro_int_t val, bool is_export); @@ -653,7 +643,7 @@ protected: typedef std::map NameMap; NameMap names; - using ValMap = std::unordered_map; + using ValMap = std::unordered_map>; ValMap vals; // The counter is initialized to 0 and incremented on every implicit @@ -667,7 +657,7 @@ protected: class VectorType : public BroType { public: - explicit VectorType(BroType* t); + explicit VectorType(IntrusivePtr t); VectorType* ShallowClone() override; ~VectorType() override; BroType* YieldType() override; @@ -683,9 +673,7 @@ public: void DescribeReST(ODesc* d, bool roles_only = false) const override; protected: - VectorType() { yield_type = 0; } - - BroType* yield_type; + IntrusivePtr yield_type; }; extern OpaqueType* md5_type; @@ -705,11 +693,11 @@ BroType* base_type_no_ref(TypeTag tag); // Returns the basic (non-parameterized) type with the given type. // The caller assumes responsibility for a reference to the type. -inline BroType* base_type(TypeTag tag) - { return base_type_no_ref(tag)->Ref(); } +inline IntrusivePtr base_type(TypeTag tag) + { return {NewRef{}, base_type_no_ref(tag)}; } // Returns the basic error type. -inline BroType* error_type() { return base_type(TYPE_ERROR); } +inline IntrusivePtr error_type() { return base_type(TYPE_ERROR); } // True if the two types are equivalent. If is_init is true then the test is // done in the context of an initialization. If match_record_field_names is @@ -735,15 +723,15 @@ extern TypeTag max_type(TypeTag t1, TypeTag t2); // Given two types, returns the "merge", in which promotable types // are promoted to the maximum of the two. Returns nil (and generates // an error message) if the types are incompatible. -extern BroType* merge_types(const BroType* t1, const BroType* t2); +IntrusivePtr merge_types(const BroType* t1, const BroType* t2); // Given a list of expressions, returns a (ref'd) type reflecting // a merged type consistent across all of them, or nil if this // cannot be done. -BroType* merge_type_list(ListExpr* elements); +IntrusivePtr merge_type_list(ListExpr* elements); // Given an expression, infer its type when used for an initialization. -extern BroType* init_type(Expr* init); +IntrusivePtr init_type(Expr* init); // Returns true if argument is an atomic type. bool is_atomic_type(const BroType* t); diff --git a/src/Val.cc b/src/Val.cc index 4185e122e5..d2e663c531 100644 --- a/src/Val.cc +++ b/src/Val.cc @@ -76,19 +76,24 @@ Val::~Val() #endif } -Val* Val::Clone() +IntrusivePtr Val::CloneState::NewClone(Val* src, IntrusivePtr dst) { - Val::CloneState state; - auto v = Clone(&state); - return v; + clones.insert(std::make_pair(src, dst.get())); + return dst; } -Val* Val::Clone(CloneState* state) +IntrusivePtr Val::Clone() + { + Val::CloneState state; + return Clone(&state); + } + +IntrusivePtr Val::Clone(CloneState* state) { auto i = state->clones.find(this); if ( i != state->clones.end() ) - return i->second->Ref(); + return {NewRef{}, i->second}; auto c = DoClone(state); @@ -98,25 +103,20 @@ Val* Val::Clone(CloneState* state) return c; } -Val* Val::DoClone(CloneState* state) +IntrusivePtr Val::DoClone(CloneState* state) { switch ( type->InternalType() ) { case TYPE_INTERNAL_INT: case TYPE_INTERNAL_UNSIGNED: case TYPE_INTERNAL_DOUBLE: // Immutable. - return Ref(); + return {NewRef{}, this}; case TYPE_INTERNAL_OTHER: // Derived classes are responsible for this. Exception: // Functions and files. There aren't any derived classes. if ( type->Tag() == TYPE_FUNC ) - { - auto c = AsFunc()->DoClone(); - auto rval = new Val(c); - Unref(c); - return rval; - } + return make_intrusive(AsFunc()->DoClone().get()); if ( type->Tag() == TYPE_FILE ) { @@ -130,7 +130,7 @@ Val* Val::DoClone(CloneState* state) // automatically opened. This does not happen anymore - instead you // get the non-cached pointer back which is brought back into the // cache when written too. - return Ref(); + return {NewRef{}, this}; } // Fall-through. @@ -240,36 +240,36 @@ double Val::CoerceToDouble() const return 0.0; } -Val* Val::SizeVal() const +IntrusivePtr Val::SizeVal() const { switch ( type->InternalType() ) { case TYPE_INTERNAL_INT: // Return abs value. However abs() only works on ints and llabs // doesn't work on Mac OS X 10.5. So we do it by hand if ( val.int_val < 0 ) - return val_mgr->GetCount(-val.int_val); + return {AdoptRef{}, val_mgr->GetCount(-val.int_val)}; else - return val_mgr->GetCount(val.int_val); + return {AdoptRef{}, val_mgr->GetCount(val.int_val)}; case TYPE_INTERNAL_UNSIGNED: - return val_mgr->GetCount(val.uint_val); + return {AdoptRef{}, val_mgr->GetCount(val.uint_val)}; case TYPE_INTERNAL_DOUBLE: - return new Val(fabs(val.double_val), TYPE_DOUBLE); + return make_intrusive(fabs(val.double_val), TYPE_DOUBLE); case TYPE_INTERNAL_OTHER: if ( type->Tag() == TYPE_FUNC ) - return val_mgr->GetCount(val.func_val->FType()->ArgTypes()->Types()->length()); + return {AdoptRef{}, val_mgr->GetCount(val.func_val->FType()->ArgTypes()->Types()->length())}; if ( type->Tag() == TYPE_FILE ) - return new Val(val.file_val->Size(), TYPE_DOUBLE); + return make_intrusive(val.file_val->Size(), TYPE_DOUBLE); break; default: break; } - return val_mgr->GetCount(0); + return {AdoptRef{}, val_mgr->GetCount(0)}; } unsigned int Val::MemoryAllocation() const @@ -403,14 +403,14 @@ bool Val::WouldOverflow(const BroType* from_type, const BroType* to_type, const return false; } -TableVal* Val::GetRecordFields() +IntrusivePtr Val::GetRecordFields() { auto t = Type(); if ( t->Tag() != TYPE_RECORD && t->Tag() != TYPE_TYPE ) { reporter->Error("non-record value/type passed to record_fields"); - return new TableVal(internal_type("record_field_table")->AsTableType()); + return make_intrusive(IntrusivePtr{NewRef{}, internal_type("record_field_table")->AsTableType()}); } RecordType* rt = nullptr; @@ -428,7 +428,7 @@ TableVal* Val::GetRecordFields() if ( t->Tag() != TYPE_RECORD ) { reporter->Error("non-record value/type passed to record_fields"); - return new TableVal(internal_type("record_field_table")->AsTableType()); + return make_intrusive(IntrusivePtr{NewRef{}, internal_type("record_field_table")->AsTableType()}); } rt = t->AsRecordType(); @@ -577,7 +577,7 @@ static void BuildJSON(threading::formatter::JSON::NullDoubleWriter& writer, Val* for ( auto i = 0; i < rt->NumFields(); ++i ) { - Val* value = rval->LookupWithDefault(i); + auto value = rval->LookupWithDefault(i); if ( value && ( ! only_loggable || rt->FieldHasAttr(i, ATTR_LOG) ) ) { @@ -595,10 +595,8 @@ static void BuildJSON(threading::formatter::JSON::NullDoubleWriter& writer, Val* else key_str = field_name; - BuildJSON(writer, value, only_loggable, re, key_str); + BuildJSON(writer, value.get(), only_loggable, re, key_str); } - - Unref(value); } writer.EndObject(); @@ -649,14 +647,14 @@ static void BuildJSON(threading::formatter::JSON::NullDoubleWriter& writer, Val* } } -StringVal* Val::ToJSON(bool only_loggable, RE_Matcher* re) +IntrusivePtr Val::ToJSON(bool only_loggable, RE_Matcher* re) { rapidjson::StringBuffer buffer; threading::formatter::JSON::NullDoubleWriter writer(buffer); BuildJSON(writer, this, only_loggable, re, ""); - return new StringVal(buffer.GetString()); + return make_intrusive(buffer.GetString()); } IntervalVal::IntervalVal(double quantity, double units) : @@ -737,6 +735,11 @@ void IntervalVal::ValDescribe(ODesc* d) const } } +IntrusivePtr PortVal::SizeVal() const + { + return {AdoptRef{}, val_mgr->GetInt(val.uint_val)}; + } + uint32_t PortVal::Mask(uint32_t port_num, TransportProto port_type) { // Note, for ICMP one-way connections: @@ -813,10 +816,10 @@ void PortVal::ValDescribe(ODesc* d) const d->Add(Protocol()); } -Val* PortVal::DoClone(CloneState* state) +IntrusivePtr PortVal::DoClone(CloneState* state) { // Immutable. - return Ref(); + return {NewRef{}, this}; } AddrVal::AddrVal(const char* text) : Val(new IPAddr(text), TYPE_ADDR) @@ -850,18 +853,18 @@ unsigned int AddrVal::MemoryAllocation() const return padded_sizeof(*this) + val.addr_val->MemoryAllocation(); } -Val* AddrVal::SizeVal() const +IntrusivePtr AddrVal::SizeVal() const { if ( val.addr_val->GetFamily() == IPv4 ) - return val_mgr->GetCount(32); + return {AdoptRef{}, val_mgr->GetCount(32)}; else - return val_mgr->GetCount(128); + return {AdoptRef{}, val_mgr->GetCount(128)}; } -Val* AddrVal::DoClone(CloneState* state) +IntrusivePtr AddrVal::DoClone(CloneState* state) { // Immutable. - return Ref(); + return {NewRef{}, this}; } SubNetVal::SubNetVal(const char* text) : Val(new IPPrefix(), TYPE_SUBNET) @@ -910,10 +913,10 @@ unsigned int SubNetVal::MemoryAllocation() const return padded_sizeof(*this) + val.subnet_val->MemoryAllocation(); } -Val* SubNetVal::SizeVal() const +IntrusivePtr SubNetVal::SizeVal() const { int retained = 128 - val.subnet_val->LengthIPv6(); - return new Val(pow(2.0, double(retained)), TYPE_DOUBLE); + return make_intrusive(pow(2.0, double(retained)), TYPE_DOUBLE); } void SubNetVal::ValDescribe(ODesc* d) const @@ -955,10 +958,10 @@ bool SubNetVal::Contains(const IPAddr& addr) const return val.subnet_val->Contains(addr); } -Val* SubNetVal::DoClone(CloneState* state) +IntrusivePtr SubNetVal::DoClone(CloneState* state) { // Immutable. - return Ref(); + return {NewRef{}, this}; } StringVal::StringVal(BroString* s) : Val(s, TYPE_STRING) @@ -979,9 +982,9 @@ StringVal::StringVal(const string& s) : StringVal(s.length(), s.data()) { } -Val* StringVal::SizeVal() const +IntrusivePtr StringVal::SizeVal() const { - return val_mgr->GetCount(val.string_val->Len()); + return {AdoptRef{}, val_mgr->GetCount(val.string_val->Len())}; } int StringVal::Len() @@ -1110,17 +1113,18 @@ Val* StringVal::Substitute(RE_Matcher* re, StringVal* repl, bool do_all) return new StringVal(new BroString(1, result, r - result)); } -Val* StringVal::DoClone(CloneState* state) +IntrusivePtr StringVal::DoClone(CloneState* state) { // We could likely treat this type as immutable and return a reference // instead of creating a new copy, but we first need to be careful and // audit whether anything internal actually does mutate it. - return state->NewClone(this, new StringVal( + return state->NewClone(this, make_intrusive( new BroString((u_char*) val.string_val->Bytes(), val.string_val->Len(), 1))); } -PatternVal::PatternVal(RE_Matcher* re) : Val(base_type(TYPE_PATTERN)) +PatternVal::PatternVal(RE_Matcher* re) + : Val(base_type_no_ref(TYPE_PATTERN)) { val.re_val = re; } @@ -1168,7 +1172,7 @@ unsigned int PatternVal::MemoryAllocation() const return padded_sizeof(*this) + val.re_val->MemoryAllocation(); } -Val* PatternVal::DoClone(CloneState* state) +IntrusivePtr PatternVal::DoClone(CloneState* state) { // We could likely treat this type as immutable and return a reference // instead of creating a new copy, but we first need to be careful and @@ -1176,11 +1180,11 @@ Val* PatternVal::DoClone(CloneState* state) auto re = new RE_Matcher(val.re_val->PatternText(), val.re_val->AnywherePatternText()); re->Compile(); - return state->NewClone(this, new PatternVal(re)); + return state->NewClone(this, make_intrusive(re)); } ListVal::ListVal(TypeTag t) -: Val(new TypeList(t == TYPE_ANY ? 0 : base_type_no_ref(t))) + : Val(new TypeList(t == TYPE_ANY ? nullptr : base_type(t))) { tag = t; } @@ -1192,6 +1196,11 @@ ListVal::~ListVal() Unref(type); } +IntrusivePtr ListVal::SizeVal() const + { + return {AdoptRef{}, val_mgr->GetCount(vals.length())}; + } + RE_Matcher* ListVal::BuildRE() const { if ( tag != TYPE_STRING ) @@ -1216,7 +1225,7 @@ void ListVal::Append(Val* v) } vals.push_back(v); - type->AsTypeList()->Append(v->Type()->Ref()); + type->AsTypeList()->Append({NewRef{}, v->Type()}); } TableVal* ListVal::ConvertToSet() const @@ -1224,15 +1233,15 @@ TableVal* ListVal::ConvertToSet() const if ( tag == TYPE_ANY ) Internal("conversion of heterogeneous list to set"); - TypeList* set_index = new TypeList(type->AsTypeList()->PureType()); + auto set_index = make_intrusive( + IntrusivePtr{NewRef{}, type->AsTypeList()->PureType()}); set_index->Append(base_type(tag)); - SetType* s = new SetType(set_index, 0); - TableVal* t = new TableVal(s); + auto s = make_intrusive(std::move(set_index), nullptr); + TableVal* t = new TableVal(std::move(s)); for ( const auto& val : vals ) t->Assign(val, 0); - Unref(s); return t; } @@ -1261,14 +1270,14 @@ void ListVal::Describe(ODesc* d) const } } -Val* ListVal::DoClone(CloneState* state) +IntrusivePtr ListVal::DoClone(CloneState* state) { - auto lv = new ListVal(tag); + auto lv = make_intrusive(tag); lv->vals.resize(vals.length()); state->NewClone(this, lv); for ( const auto& val : vals ) - lv->Append(val->Clone(state)); + lv->Append(val->Clone(state).release()); return lv; } @@ -1283,6 +1292,13 @@ unsigned int ListVal::MemoryAllocation() const + type->MemoryAllocation(); } +TableEntryVal* TableEntryVal::Clone(Val::CloneState* state) + { + auto rval = new TableEntryVal(val ? val->Clone(state) : nullptr); + rval->last_access_time = last_access_time; + rval->expire_access_time = expire_access_time; + return rval; + } TableValTimer::TableValTimer(TableVal* val, double t) : Timer(t, TIMER_TABLE_VAL) { @@ -1306,27 +1322,25 @@ void TableValTimer::Dispatch(double t, int is_expire) static void table_entry_val_delete_func(void* val) { TableEntryVal* tv = (TableEntryVal*) val; - tv->Unref(); delete tv; } -TableVal::TableVal(TableType* t, Attributes* a) : Val(t) +TableVal::TableVal(IntrusivePtr t, IntrusivePtr a) : Val(t.get()) { - Init(t); - SetAttrs(a); + Init(std::move(t)); + SetAttrs(std::move(a)); } -void TableVal::Init(TableType* t) +void TableVal::Init(IntrusivePtr t) { - ::Ref(t); - table_type = t; + table_type = std::move(t); expire_func = 0; expire_time = 0; expire_cookie = 0; timer = 0; def_val = 0; - if ( t->IsSubNetIndex() ) + if ( table_type->IsSubNetIndex() ) subnets = new PrefixTable; else subnets = 0; @@ -1342,15 +1356,9 @@ TableVal::~TableVal() if ( timer ) timer_mgr->Cancel(timer); - Unref(table_type); delete table_hash; delete AsTable(); delete subnets; - Unref(attrs); - Unref(def_val); - Unref(expire_func); - Unref(expire_time); - Unref(change_func); } void TableVal::RemoveAll() @@ -1388,31 +1396,26 @@ int TableVal::RecursiveSize() const return n; } -void TableVal::SetAttrs(Attributes* a) +void TableVal::SetAttrs(IntrusivePtr a) { - attrs = a; + attrs = std::move(a); - if ( ! a ) + if ( ! attrs ) return; - ::Ref(attrs); - CheckExpireAttr(ATTR_EXPIRE_READ); CheckExpireAttr(ATTR_EXPIRE_WRITE); CheckExpireAttr(ATTR_EXPIRE_CREATE); Attr* ef = attrs->FindAttr(ATTR_EXPIRE_FUNC); + if ( ef ) - { - expire_func = ef->AttrExpr(); - expire_func->Ref(); - } + expire_func = {NewRef{}, ef->AttrExpr()}; + auto cf = attrs->FindAttr(ATTR_ON_CHANGE); + if ( cf ) - { - change_func = cf->AttrExpr(); - change_func->Ref(); - } + change_func = {NewRef{}, cf->AttrExpr()}; } void TableVal::CheckExpireAttr(attr_tag at) @@ -1421,8 +1424,7 @@ void TableVal::CheckExpireAttr(attr_tag at) if ( a ) { - expire_time = a->AttrExpr(); - expire_time->Ref(); + expire_time = {NewRef{}, a->AttrExpr()}; if ( expire_time->Type()->Tag() != TYPE_INTERVAL ) { @@ -1442,20 +1444,24 @@ void TableVal::CheckExpireAttr(attr_tag at) } } -int TableVal::Assign(Val* index, Val* new_val) +int TableVal::Assign(Val* index, IntrusivePtr new_val) { HashKey* k = ComputeHash(index); if ( ! k ) { - Unref(new_val); index->Error("index type doesn't match table", table_type->Indices()); return 0; } - return Assign(index, k, new_val); + return Assign(index, k, std::move(new_val)); } -int TableVal::Assign(Val* index, HashKey* k, Val* new_val) +int TableVal::Assign(Val* index, Val* new_val) + { + return Assign(index, {AdoptRef{}, new_val}); + } + +int TableVal::Assign(Val* index, HashKey* k, IntrusivePtr new_val) { int is_set = table_type->IsSet(); @@ -1493,20 +1499,26 @@ int TableVal::Assign(Val* index, HashKey* k, Val* new_val) if ( change_func ) { Val* change_index = index ? index->Ref() : RecoverIndex(&k_copy); - Val* v = old_entry_val ? old_entry_val->Value() : new_val; + Val* v = old_entry_val ? old_entry_val->Value() : new_val.get(); CallChangeFunc(change_index, v, old_entry_val ? ELEMENT_CHANGED : ELEMENT_NEW); Unref(change_index); } - if ( old_entry_val ) - { - old_entry_val->Unref(); - delete old_entry_val; - } + delete old_entry_val; return 1; } +int TableVal::Assign(Val* index, HashKey* k, Val* new_val) + { + return Assign(index, k, {AdoptRef{}, new_val}); + } + +IntrusivePtr TableVal::SizeVal() const + { + return {AdoptRef{}, val_mgr->GetCount(Size())}; + } + int TableVal::AddTo(Val* val, int is_first_init) const { return AddTo(val, is_first_init, true); @@ -1537,10 +1549,9 @@ int TableVal::AddTo(Val* val, int is_first_init, bool propagate_ops) const { if ( is_first_init && t->AsTable()->Lookup(k) ) { - Val* key = table_hash->RecoverVals(k); + auto key = table_hash->RecoverVals(k); // ### Shouldn't complain if their values are equal. key->Warn("multiple initializations for index"); - Unref(key); continue; } @@ -1551,8 +1562,7 @@ int TableVal::AddTo(Val* val, int is_first_init, bool propagate_ops) const } else { - v->Ref(); - if ( ! t->Assign(0, k, v->Value()) ) + if ( ! t->Assign(0, k, {NewRef{}, v->Value()}) ) return 0; } } @@ -1587,7 +1597,7 @@ int TableVal::RemoveFrom(Val* val) const // OTOH, they are both the same type, so as long as // we don't have hash keys that are keyed per dictionary, // it should work ... - Unref(t->Delete(k)); + t->Delete(k); delete k; } @@ -1617,7 +1627,7 @@ TableVal* TableVal::Intersect(const TableVal* tv) const // Here we leverage the same assumption about consistent // hashes as in TableVal::RemoveFrom above. if ( t0->Lookup(k) ) - t2->Insert(k, new TableEntryVal(0)); + t2->Insert(k, new TableEntryVal(nullptr)); delete k; } @@ -1728,12 +1738,12 @@ int TableVal::ExpandAndInit(IntrusivePtr index, IntrusivePtr new_val) } -Val* TableVal::Default(Val* index) +IntrusivePtr TableVal::Default(Val* index) { Attr* def_attr = FindAttr(ATTR_DEFAULT); if ( ! def_attr ) - return 0; + return nullptr; if ( ! def_val ) { @@ -1748,24 +1758,24 @@ Val* TableVal::Default(Val* index) auto coerce = make_intrusive( IntrusivePtr{NewRef{}, def_attr->AttrExpr()}, IntrusivePtr{NewRef{}, ytype->AsRecordType()}); - def_val = coerce->Eval(0).release(); + def_val = coerce->Eval(0); } else - def_val = def_attr->AttrExpr()->Eval(0).release(); + def_val = def_attr->AttrExpr()->Eval(0); } if ( ! def_val ) { Error("non-constant default attribute"); - return 0; + return nullptr; } if ( def_val->Type()->Tag() != TYPE_FUNC || same_type(def_val->Type(), Type()->YieldType()) ) { if ( def_attr->AttrExpr()->IsConst() ) - return def_val->Ref(); + return def_val; try { @@ -1775,7 +1785,7 @@ Val* TableVal::Default(Val* index) { /* Already reported. */ } Error("&default value for table is not clone-able"); - return 0; + return nullptr; } const Func* f = def_val->AsFunc(); @@ -1793,7 +1803,7 @@ Val* TableVal::Default(Val* index) vl = val_list{index->Ref()}; } - Val* result = 0; + IntrusivePtr result; try { @@ -1806,22 +1816,14 @@ Val* TableVal::Default(Val* index) if ( ! result ) { Error("no value returned from &default function"); - return 0; + return nullptr; } return result; } -Val* TableVal::Lookup(Val* index, bool use_default_val) +IntrusivePtr TableVal::Lookup(Val* index, bool use_default_val) { - static Val* last_default = 0; - - if ( last_default ) - { - Unref(last_default); - last_default = 0; - } - if ( subnets ) { TableEntryVal* v = (TableEntryVal*) subnets->Lookup(index); @@ -1830,16 +1832,13 @@ Val* TableVal::Lookup(Val* index, bool use_default_val) if ( attrs && attrs->FindAttr(ATTR_EXPIRE_READ) ) v->SetExpireAccess(network_time); - return v->Value() ? v->Value() : this; + return {NewRef{}, v->Value() ? v->Value() : this}; } if ( ! use_default_val ) - return 0; + return nullptr; - Val* def = Default(index); - last_default = def; - - return def; + return Default(index); } const PDict* tbl = AsTable(); @@ -1857,43 +1856,37 @@ Val* TableVal::Lookup(Val* index, bool use_default_val) if ( attrs && attrs->FindAttr(ATTR_EXPIRE_READ) ) v->SetExpireAccess(network_time); - return v->Value() ? v->Value() : this; + return {NewRef{}, v->Value() ? v->Value() : this}; } } } if ( ! use_default_val ) - return 0; + return nullptr; - Val* def = Default(index); - - last_default = def; - return def; + return Default(index); } -VectorVal* TableVal::LookupSubnets(const SubNetVal* search) +IntrusivePtr TableVal::LookupSubnets(const SubNetVal* search) { if ( ! subnets ) reporter->InternalError("LookupSubnets called on wrong table type"); - VectorVal* result = new VectorVal(internal_type("subnet_vec")->AsVectorType()); + auto result = make_intrusive(internal_type("subnet_vec")->AsVectorType()); auto matches = subnets->FindAll(search); for ( auto element : matches ) - { - SubNetVal* s = new SubNetVal(get<0>(element)); - result->Assign(result->Size(), s); - } + result->Assign(result->Size(), make_intrusive(get<0>(element))); return result; } -TableVal* TableVal::LookupSubnetValues(const SubNetVal* search) +IntrusivePtr TableVal::LookupSubnetValues(const SubNetVal* search) { if ( ! subnets ) reporter->InternalError("LookupSubnetValues called on wrong table type"); - TableVal* nt = new TableVal(this->Type()->Ref()->AsTableType()); + auto nt = make_intrusive(IntrusivePtr{NewRef{}, this->Type()->AsTableType()}); auto matches = subnets->FindAll(search); for ( auto element : matches ) @@ -1902,7 +1895,7 @@ TableVal* TableVal::LookupSubnetValues(const SubNetVal* search) TableEntryVal* entry = reinterpret_cast(get<1>(element)); if ( entry && entry->Value() ) - nt->Assign(s, entry->Value()->Ref()); + nt->Assign(s, {NewRef{}, entry->Value()}); else nt->Assign(s, 0); // set @@ -1945,7 +1938,7 @@ bool TableVal::UpdateTimestamp(Val* index) ListVal* TableVal::RecoverIndex(const HashKey* k) const { - return table_hash->RecoverVals(k); + return table_hash->RecoverVals(k).release(); } void TableVal::CallChangeFunc(const Val* index, Val* old_value, OnChangeType tpe) @@ -1973,7 +1966,8 @@ void TableVal::CallChangeFunc(const Val* index, Val* old_value, OnChangeType tpe const Func* f = thefunc->AsFunc(); val_list vl { Ref() }; - EnumVal* type = nullptr; + IntrusivePtr type; + switch ( tpe ) { case ELEMENT_NEW: @@ -1988,7 +1982,8 @@ void TableVal::CallChangeFunc(const Val* index, Val* old_value, OnChangeType tpe case ELEMENT_EXPIRED: type = BifType::Enum::TableChange->GetVal(BifEnum::TableChange::TABLE_ELEMENT_EXPIRED); } - vl.append(type); + + vl.append(type.release()); for ( const auto& v : *index->AsListVal()->Vals() ) vl.append(v->Ref()); @@ -2006,11 +2001,11 @@ void TableVal::CallChangeFunc(const Val* index, Val* old_value, OnChangeType tpe in_change_func = false; } -Val* TableVal::Delete(const Val* index) +IntrusivePtr TableVal::Delete(const Val* index) { HashKey* k = ComputeHash(index); TableEntryVal* v = k ? AsNonConstTable()->RemoveEntry(k) : 0; - Val* va = v ? (v->Value() ? v->Value() : this->Ref()) : 0; + IntrusivePtr va{NewRef{}, v ? (v->Value() ? v->Value() : this) : nullptr}; if ( subnets && ! subnets->Remove(index) ) reporter->InternalWarning("index not in prefix table"); @@ -2021,22 +2016,22 @@ Val* TableVal::Delete(const Val* index) Modified(); if ( change_func ) - CallChangeFunc(index, va, ELEMENT_REMOVED); + CallChangeFunc(index, va.get(), ELEMENT_REMOVED); return va; } -Val* TableVal::Delete(const HashKey* k) +IntrusivePtr TableVal::Delete(const HashKey* k) { TableEntryVal* v = AsNonConstTable()->RemoveEntry(k); - Val* va = v ? (v->Value() ? v->Value() : this->Ref()) : 0; + IntrusivePtr va{NewRef{}, v ? (v->Value() ? v->Value() : this) : nullptr}; if ( subnets ) { - Val* index = table_hash->RecoverVals(k); - if ( ! subnets->Remove(index) ) + auto index = table_hash->RecoverVals(k); + + if ( ! subnets->Remove(index.get()) ) reporter->InternalWarning("index not in prefix table"); - Unref(index); } delete v; @@ -2046,8 +2041,7 @@ Val* TableVal::Delete(const HashKey* k) if ( change_func && va ) { auto index = table_hash->RecoverVals(k); - CallChangeFunc(index, va->Ref(), ELEMENT_REMOVED); - Unref(index); + CallChangeFunc(index.get(), va.get(), ELEMENT_REMOVED); } return va; @@ -2063,19 +2057,17 @@ ListVal* TableVal::ConvertToList(TypeTag t) const HashKey* k; while ( tbl->NextEntry(k, c) ) { - ListVal* index = table_hash->RecoverVals(k); + auto index = table_hash->RecoverVals(k); if ( t == TYPE_ANY ) - l->Append(index); + l->Append(index.release()); else { - // We're expecting a pure list, flatten the - // ListVal. + // We're expecting a pure list, flatten the ListVal. if ( index->Length() != 1 ) InternalWarning("bad index in TableVal::ConvertToList"); - Val* flat_v = index->Index(0)->Ref(); - Unref(index); - l->Append(flat_v); + + l->Append(index->Index(0)->Ref()); } delete k; @@ -2130,7 +2122,7 @@ void TableVal::Describe(ODesc* d) const if ( ! v ) reporter->InternalError("hash table underflow in TableVal::Describe"); - ListVal* vl = table_hash->RecoverVals(k); + auto vl = table_hash->RecoverVals(k); int dim = vl->Length(); if ( i > 0 ) @@ -2155,7 +2147,6 @@ void TableVal::Describe(ODesc* d) const vl->Describe(d); delete k; - Unref(vl); if ( table_type->IsSet() ) { // We're a set, not a table. @@ -2223,12 +2214,12 @@ int TableVal::CheckAndAssign(Val* index, IntrusivePtr new_val) // We need an exact match here. v = (Val*) subnets->Lookup(index, true); else - v = Lookup(index, false); + v = Lookup(index, false).get(); if ( v ) index->Warn("multiple initializations for index"); - return Assign(index, new_val.release()); + return Assign(index, std::move(new_val)); } void TableVal::InitDefaultFunc(Frame* f) @@ -2250,7 +2241,7 @@ void TableVal::InitDefaultFunc(Frame* f) ytype->AsRecordType()) ) return; // TableVal::Default will handle this. - def_val = def_attr->AttrExpr()->Eval(f).release(); + def_val = def_attr->AttrExpr()->Eval(f); } void TableVal::InitTimer(double delay) @@ -2346,7 +2337,6 @@ void TableVal::DoExpire(double t) CallChangeFunc(idx, v->Value(), ELEMENT_EXPIRED); } Unref(idx); - Unref(v->Value()); delete v; modified = true; } @@ -2456,15 +2446,10 @@ double TableVal::CallExpireFunc(Val* idx) else vl.append(idx); - Val* result = 0; - - result = f->Call(&vl); + auto result = f->Call(&vl); if ( result ) - { secs = result->AsInterval(); - Unref(result); - } } catch ( InterpreterException& e ) @@ -2474,9 +2459,9 @@ double TableVal::CallExpireFunc(Val* idx) return secs; } -Val* TableVal::DoClone(CloneState* state) +IntrusivePtr TableVal::DoClone(CloneState* state) { - auto tv = new TableVal(table_type); + auto tv = make_intrusive(table_type); state->NewClone(this, tv); const PDict* tbl = AsTable(); @@ -2499,15 +2484,11 @@ Val* TableVal::DoClone(CloneState* state) delete key; } - if ( attrs ) - { - ::Ref(attrs); - tv->attrs = attrs; - } + tv->attrs = attrs; if ( expire_time ) { - tv->expire_time = expire_time->Ref(); + tv->expire_time = expire_time; // As network_time is not necessarily initialized yet, we set // a timer which fires immediately. @@ -2516,7 +2497,7 @@ Val* TableVal::DoClone(CloneState* state) } if ( expire_func ) - tv->expire_func = expire_func->Ref(); + tv->expire_func = expire_func; if ( def_val ) tv->def_val = def_val->Clone(); @@ -2569,20 +2550,19 @@ RecordVal::RecordVal(RecordType* t, bool init_fields) : Val(t) // by default). for ( int i = 0; i < n; ++i ) { - Attributes* a = t->FieldDecl(i)->attrs; + Attributes* a = t->FieldDecl(i)->attrs.get(); Attr* def_attr = a ? a->FindAttr(ATTR_DEFAULT) : nullptr; auto def = def_attr ? def_attr->AttrExpr()->Eval(nullptr) : nullptr; - BroType* type = t->FieldDecl(i)->type; + BroType* type = t->FieldDecl(i)->type.get(); if ( def && type->Tag() == TYPE_RECORD && def->Type()->Tag() == TYPE_RECORD && ! same_type(def->Type(), type) ) { - Val* tmp = def->AsRecordVal()->CoerceTo(type->AsRecordType()); + auto tmp = def->AsRecordVal()->CoerceTo(type->AsRecordType()); + if ( tmp ) - { - def = {AdoptRef{}, tmp}; - } + def = std::move(tmp); } if ( ! def && ! (a && a->FindAttr(ATTR_OPTIONAL)) ) @@ -2593,7 +2573,8 @@ RecordVal::RecordVal(RecordType* t, bool init_fields) : Val(t) def = make_intrusive(type->AsRecordType()); else if ( tag == TYPE_TABLE ) - def = make_intrusive(type->AsTableType(), a); + def = make_intrusive(IntrusivePtr{NewRef{}, type->AsTableType()}, + IntrusivePtr{NewRef{}, a}); else if ( tag == TYPE_VECTOR ) def = make_intrusive(type->AsVectorType()); @@ -2608,24 +2589,34 @@ RecordVal::~RecordVal() delete_vals(AsNonConstRecord()); } -void RecordVal::Assign(int field, Val* new_val) +IntrusivePtr RecordVal::SizeVal() const { - Val* old_val = AsNonConstRecord()->replace(field, new_val); + return {AdoptRef{}, val_mgr->GetCount(Type()->AsRecordType()->NumFields())}; + } + +void RecordVal::Assign(int field, IntrusivePtr new_val) + { + Val* old_val = AsNonConstRecord()->replace(field, new_val.release()); Unref(old_val); Modified(); } +void RecordVal::Assign(int field, Val* new_val) + { + Assign(field, {AdoptRef{}, new_val}); + } + Val* RecordVal::Lookup(int field) const { return (*AsRecord())[field]; } -Val* RecordVal::LookupWithDefault(int field) const +IntrusivePtr RecordVal::LookupWithDefault(int field) const { Val* val = (*AsRecord())[field]; if ( val ) - return val->Ref(); + return {NewRef{}, val}; return Type()->AsRecordType()->FieldDefault(field); } @@ -2653,20 +2644,20 @@ void RecordVal::ResizeParseTimeRecords() parse_time_records.clear(); } -Val* RecordVal::Lookup(const char* field, bool with_default) const +IntrusivePtr RecordVal::Lookup(const char* field, bool with_default) const { int idx = Type()->AsRecordType()->FieldOffset(field); if ( idx < 0 ) reporter->InternalError("missing record field: %s", field); - return with_default ? LookupWithDefault(idx) : Lookup(idx); + return with_default ? LookupWithDefault(idx) : IntrusivePtr{NewRef{}, Lookup(idx)}; } -RecordVal* RecordVal::CoerceTo(const RecordType* t, Val* aggr, bool allow_orphaning) const +IntrusivePtr RecordVal::CoerceTo(const RecordType* t, Val* aggr, bool allow_orphaning) const { if ( ! record_promotion_compatible(t->AsRecordType(), Type()->AsRecordType()) ) - return 0; + return nullptr; if ( ! aggr ) aggr = new RecordVal(const_cast(t->AsRecordType())); @@ -2706,11 +2697,11 @@ RecordVal* RecordVal::CoerceTo(const RecordType* t, Val* aggr, bool allow_orphan 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(nullptr).release()); + ar->Assign(t_i, e->Eval(nullptr)); continue; } - ar->Assign(t_i, v->Ref()); + ar->Assign(t_i, {NewRef{}, v}); } for ( i = 0; i < ar_t->NumFields(); ++i ) @@ -2723,21 +2714,18 @@ RecordVal* RecordVal::CoerceTo(const RecordType* t, Val* aggr, bool allow_orphan Error(buf); } - return ar; + return {AdoptRef{}, ar}; } -RecordVal* RecordVal::CoerceTo(RecordType* t, bool allow_orphaning) +IntrusivePtr RecordVal::CoerceTo(RecordType* t, bool allow_orphaning) { if ( same_type(Type(), t) ) - { - this->Ref(); - return this; - } + return {NewRef{}, this}; return CoerceTo(t, 0, allow_orphaning); } -TableVal* RecordVal::GetRecordFieldsVal() const +IntrusivePtr RecordVal::GetRecordFieldsVal() const { return Type()->AsRecordType()->GetRecordFieldsVal(this); } @@ -2808,21 +2796,21 @@ void RecordVal::DescribeReST(ODesc* d) const d->Add("}"); } -Val* RecordVal::DoClone(CloneState* state) +IntrusivePtr RecordVal::DoClone(CloneState* state) { // We set origin to 0 here. Origin only seems to be used for exactly one // purpose - to find the connection record that is associated with a // record. As we cannot guarantee that it will ber zeroed out at the // approproate time (as it seems to be guaranteed for the original record) // we don't touch it. - auto rv = new RecordVal(Type()->AsRecordType(), false); + auto rv = make_intrusive(Type()->AsRecordType(), false); rv->origin = nullptr; state->NewClone(this, rv); for ( const auto& vlv : *val.val_list_val ) { - Val* v = vlv ? vlv->Clone(state) : nullptr; - rv->val.val_list_val->push_back(v); + auto v = vlv ? vlv->Clone(state) : nullptr; + rv->val.val_list_val->push_back(v.release()); } return rv; @@ -2842,6 +2830,11 @@ unsigned int RecordVal::MemoryAllocation() const return size + padded_sizeof(*this) + val.val_list_val->MemoryAllocation(); } +IntrusivePtr EnumVal::SizeVal() const + { + return {AdoptRef{}, val_mgr->GetInt(val.int_val)}; + } + void EnumVal::ValDescribe(ODesc* d) const { const char* ename = type->AsEnumType()->Lookup(val.int_val); @@ -2852,10 +2845,10 @@ void EnumVal::ValDescribe(ODesc* d) const d->Add(ename); } -Val* EnumVal::DoClone(CloneState* state) +IntrusivePtr EnumVal::DoClone(CloneState* state) { // Immutable. - return Ref(); + return {NewRef{}, this}; } VectorVal::VectorVal(VectorType* t) : Val(t) @@ -2874,14 +2867,16 @@ VectorVal::~VectorVal() delete val.vector_val; } -bool VectorVal::Assign(unsigned int index, Val* element) +IntrusivePtr VectorVal::SizeVal() const + { + return {AdoptRef{}, val_mgr->GetCount(uint32_t(val.vector_val->size()))}; + } + +bool VectorVal::Assign(unsigned int index, IntrusivePtr element) { if ( element && ! same_type(element->Type(), vector_type->YieldType(), 0) ) - { - Unref(element); return false; - } Val* val_at_index = 0; @@ -2895,19 +2890,24 @@ bool VectorVal::Assign(unsigned int index, Val* element) // Note: we do *not* Ref() the element, if any, at this point. // AssignExpr::Eval() already does this; other callers must remember // to do it similarly. - (*val.vector_val)[index] = element; + (*val.vector_val)[index] = element.release(); Modified(); return true; } +bool VectorVal::Assign(unsigned int index, Val* element) + { + return Assign(index, {AdoptRef{}, element}); + } + bool VectorVal::AssignRepeat(unsigned int index, unsigned int how_many, Val* element) { ResizeAtLeast(index + how_many); for ( unsigned int i = index; i < index + how_many; ++i ) - if ( ! Assign(i, element->Ref() ) ) + if ( ! Assign(i, {NewRef{}, element}) ) return false; return true; @@ -2971,7 +2971,7 @@ int VectorVal::AddTo(Val* val, int /* is_first_init */) const auto last_idx = v->Size(); for ( auto i = 0u; i < Size(); ++i ) - v->Assign(last_idx++, Lookup(i)->Ref()); + v->Assign(last_idx++, {NewRef{}, Lookup(i)}); return 1; } @@ -3001,16 +3001,16 @@ unsigned int VectorVal::ResizeAtLeast(unsigned int new_num_elements) return Resize(new_num_elements); } -Val* VectorVal::DoClone(CloneState* state) +IntrusivePtr VectorVal::DoClone(CloneState* state) { - auto vv = new VectorVal(vector_type); + auto vv = make_intrusive(vector_type); vv->val.vector_val->reserve(val.vector_val->size()); state->NewClone(this, vv); for ( unsigned int i = 0; i < val.vector_val->size(); ++i ) { auto v = (*val.vector_val)[i]->Clone(state); - vv->val.vector_val->push_back(v); + vv->val.vector_val->push_back(v.release()); } return vv; diff --git a/src/Val.h b/src/Val.h index ae8915fa08..10a5916665 100644 --- a/src/Val.h +++ b/src/Val.h @@ -2,6 +2,7 @@ #pragma once +#include "IntrusivePtr.h" #include "Type.h" #include "Timer.h" #include "Notifier.h" @@ -27,9 +28,7 @@ using std::string; #define UDP_PORT_MASK 0x20000 #define ICMP_PORT_MASK 0x30000 -template class IntrusivePtr; template class PDict; -template class IntrusivePtr; class IterCookie; class Val; @@ -130,7 +129,7 @@ union BroValUnion { class Val : public BroObj { public: Val(double d, TypeTag t) - : val(d), type(base_type(t)) + : val(d), type(base_type(t).release()) { } @@ -142,19 +141,19 @@ public: // Extra arg to differentiate from protected version. Val(BroType* t, bool type_type) - : type(new TypeType(t->Ref())) + : type(new TypeType({NewRef{}, t})) { } Val() - : val(bro_int_t(0)), type(base_type(TYPE_ERROR)) + : val(bro_int_t(0)), type(base_type(TYPE_ERROR).release()) { } ~Val() override; Val* Ref() { ::Ref(this); return this; } - Val* Clone(); + IntrusivePtr Clone(); int IsZero() const; int IsOne() const; @@ -169,7 +168,7 @@ public: // Returns a new Val with the "size" of this Val. What constitutes // size depends on the Val's type. - virtual Val* SizeVal() const; + virtual IntrusivePtr SizeVal() const; // Bytes in total value object. virtual unsigned int MemoryAllocation() const; @@ -323,9 +322,9 @@ public: static bool WouldOverflow(const BroType* from_type, const BroType* to_type, const Val* val); - TableVal* GetRecordFields(); + IntrusivePtr GetRecordFields(); - StringVal* ToJSON(bool only_loggable=false, RE_Matcher* re=nullptr); + IntrusivePtr ToJSON(bool only_loggable=false, RE_Matcher* re=nullptr); protected: @@ -356,7 +355,7 @@ protected: template Val(V &&v, TypeTag t) noexcept - : val(std::forward(v)), type(base_type(t)) + : val(std::forward(v)), type(base_type(t).release()) { } @@ -379,17 +378,13 @@ protected: // Caches a cloned value for later reuse during the same // cloning operation. For recursive types, call this *before* // descending down. - Val* NewClone(Val *src, Val* dst) - { - clones.insert(std::make_pair(src, dst)); - return dst; - } + IntrusivePtr NewClone(Val* src, IntrusivePtr dst); std::unordered_map clones; }; - Val* Clone(CloneState* state); - virtual Val* DoClone(CloneState* state); + IntrusivePtr Clone(CloneState* state); + virtual IntrusivePtr DoClone(CloneState* state); BroValUnion val; BroType* type; @@ -476,7 +471,7 @@ protected: class PortVal : public Val { public: - Val* SizeVal() const override { return val_mgr->GetInt(val.uint_val); } + IntrusivePtr SizeVal() const override; // Returns the port number in host order (not including the mask). uint32_t Port() const; @@ -507,7 +502,7 @@ protected: PortVal(uint32_t p); void ValDescribe(ODesc* d) const override; - Val* DoClone(CloneState* state) override; + IntrusivePtr DoClone(CloneState* state) override; }; class AddrVal : public Val { @@ -516,7 +511,7 @@ public: explicit AddrVal(const std::string& text); ~AddrVal() override; - Val* SizeVal() const override; + IntrusivePtr SizeVal() const override; // Constructor for address already in network order. explicit AddrVal(uint32_t addr); // IPv4. @@ -526,7 +521,7 @@ public: unsigned int MemoryAllocation() const override; protected: - Val* DoClone(CloneState* state) override; + IntrusivePtr DoClone(CloneState* state) override; }; class SubNetVal : public Val { @@ -539,7 +534,7 @@ public: explicit SubNetVal(const IPPrefix& prefix); ~SubNetVal() override; - Val* SizeVal() const override; + IntrusivePtr SizeVal() const override; const IPAddr& Prefix() const; int Width() const; @@ -551,7 +546,7 @@ public: protected: void ValDescribe(ODesc* d) const override; - Val* DoClone(CloneState* state) override; + IntrusivePtr DoClone(CloneState* state) override; }; class StringVal : public Val { @@ -561,7 +556,7 @@ public: explicit StringVal(const string& s); StringVal(int length, const char* s); - Val* SizeVal() const override; + IntrusivePtr SizeVal() const override; int Len(); const u_char* Bytes(); @@ -581,7 +576,7 @@ public: protected: void ValDescribe(ODesc* d) const override; - Val* DoClone(CloneState* state) override; + IntrusivePtr DoClone(CloneState* state) override; }; class PatternVal : public Val { @@ -597,7 +592,7 @@ public: protected: void ValDescribe(ODesc* d) const override; - Val* DoClone(CloneState* state) override; + IntrusivePtr DoClone(CloneState* state) override; }; // ListVals are mainly used to index tables that have more than one @@ -609,7 +604,7 @@ public: TypeTag BaseTag() const { return tag; } - Val* SizeVal() const override { return val_mgr->GetCount(vals.length()); } + IntrusivePtr SizeVal() const override; int Length() const { return vals.length(); } Val* Index(const int n) { return vals[n]; } @@ -638,7 +633,7 @@ public: unsigned int MemoryAllocation() const override; protected: - Val* DoClone(CloneState* state) override; + IntrusivePtr DoClone(CloneState* state) override; val_list vals; TypeTag tag; @@ -648,27 +643,18 @@ extern double bro_start_network_time; class TableEntryVal { public: - explicit TableEntryVal(Val* v) + template + explicit TableEntryVal(V&& v) + : val(std::forward(v)) { - val = v; last_access_time = network_time; expire_access_time = int(network_time - bro_start_network_time); } - TableEntryVal* Clone(Val::CloneState* state) - { - auto rval = new TableEntryVal(val ? val->Clone(state) : nullptr); - rval->last_access_time = last_access_time; - rval->expire_access_time = expire_access_time; - return rval; - } + TableEntryVal* Clone(Val::CloneState* state); - ~TableEntryVal() { } - - Val* Value() { return val; } - void Ref() { val->Ref(); } - void Unref() { ::Unref(val); } + Val* Value() { return val.get(); } // Returns/sets time of last expiration relevant access to this value. double ExpireAccessTime() const @@ -679,7 +665,7 @@ public: protected: friend class TableVal; - Val* val; + IntrusivePtr val; double last_access_time; // The next entry stores seconds since Bro's start. We use ints here @@ -707,7 +693,7 @@ class Frame; class TableVal : public Val, public notifier::Modifiable { public: - explicit TableVal(TableType* t, Attributes* attrs = 0); + explicit TableVal(IntrusivePtr t, IntrusivePtr attrs = nullptr); ~TableVal() override; // Returns true if the assignment typechecked, false if not. The @@ -715,10 +701,12 @@ public: // version takes a HashKey and Unref()'s it when done. If we're a // set, new_val has to be nil. If we aren't a set, index may be nil // in the second version. + int Assign(Val* index, IntrusivePtr new_val); int Assign(Val* index, Val* new_val); + int Assign(Val* index, HashKey* k, IntrusivePtr new_val); int Assign(Val* index, HashKey* k, Val* new_val); - Val* SizeVal() const override { return val_mgr->GetCount(Size()); } + IntrusivePtr SizeVal() const override; // Add the entire contents of the table to the given value, // which must also be a TableVal. @@ -761,17 +749,17 @@ public: // Returns the element's value if it exists in the table, // nil otherwise. Note, "index" is not const because we // need to Ref/Unref it when calling the default function. - Val* Lookup(Val* index, bool use_default_val = true); + IntrusivePtr Lookup(Val* index, bool use_default_val = true); // For a table[subnet]/set[subnet], return all subnets that cover // the given subnet. // Causes an internal error if called for any other kind of table. - VectorVal* LookupSubnets(const SubNetVal* s); + IntrusivePtr LookupSubnets(const SubNetVal* s); // For a set[subnet]/table[subnet], return a new table that only contains // entries that cover the given subnet. // Causes an internal error if called for any other kind of table. - TableVal* LookupSubnetValues(const SubNetVal* s); + IntrusivePtr LookupSubnetValues(const SubNetVal* s); // Sets the timestamp for the given index to network time. // Returns false if index does not exist. @@ -781,16 +769,16 @@ public: ListVal* RecoverIndex(const HashKey* k) const; // Returns the element if it was in the table, false otherwise. - Val* Delete(const Val* index); - Val* Delete(const HashKey* k); + IntrusivePtr Delete(const Val* index); + IntrusivePtr Delete(const HashKey* k); // Returns a ListVal representation of the table (which must be a set). ListVal* ConvertToList(TypeTag t=TYPE_ANY) const; ListVal* ConvertToPureList() const; // must be single index type - void SetAttrs(Attributes* attrs); + void SetAttrs(IntrusivePtr attrs); Attr* FindAttr(attr_tag t) const; - Attributes* Attrs() { return attrs; } + Attributes* Attrs() { return attrs.get(); } // Returns the size of the table. int Size() const; @@ -824,14 +812,14 @@ public: notifier::Modifiable* Modifiable() override { return this; } protected: - void Init(TableType* t); + void Init(IntrusivePtr t); void CheckExpireAttr(attr_tag at); int ExpandCompoundAndInit(val_list* vl, int k, IntrusivePtr new_val); int CheckAndAssign(Val* index, IntrusivePtr new_val); // Calculates default value for index. Returns 0 if none. - Val* Default(Val* index); + IntrusivePtr Default(Val* index); // Returns true if item expiration is enabled. bool ExpirationEnabled() { return expire_time != 0; } @@ -851,18 +839,18 @@ protected: // Calls &change_func. Does not take ownership of values. (Refs if needed). void CallChangeFunc(const Val* index, Val* old_value, OnChangeType tpe); - Val* DoClone(CloneState* state) override; + IntrusivePtr DoClone(CloneState* state) override; - TableType* table_type; + IntrusivePtr table_type; CompositeHash* table_hash; - Attributes* attrs; - Expr* expire_time; - Expr* expire_func; + IntrusivePtr attrs; + IntrusivePtr expire_time; + IntrusivePtr expire_func; TableValTimer* timer; IterCookie* expire_cookie; PrefixTable* subnets; - Val* def_val; - Expr* change_func = nullptr; + IntrusivePtr def_val; + IntrusivePtr change_func; // prevent recursion of change functions bool in_change_func = false; }; @@ -872,12 +860,12 @@ public: explicit RecordVal(RecordType* t, bool init_fields = true); ~RecordVal() override; - Val* SizeVal() const override - { return val_mgr->GetCount(Type()->AsRecordType()->NumFields()); } + IntrusivePtr SizeVal() const override; + void Assign(int field, IntrusivePtr new_val); void Assign(int field, Val* new_val); Val* Lookup(int field) const; // Does not Ref() value. - Val* LookupWithDefault(int field) const; // Does Ref() value. + IntrusivePtr LookupWithDefault(int field) const; /** * Looks up the value of a field by field name. If the field doesn't @@ -885,17 +873,16 @@ public: * @param field name of field to lookup. * @param with_default whether to rely on field's &default attribute when * the field has yet to be initialized. - * @return the value in field \a field. It is Ref()'d only if - * \a with_default is true. + * @return the value in field \a field. */ - Val* Lookup(const char* field, bool with_default = false) const; + IntrusivePtr Lookup(const char* field, bool with_default = false) const; void Describe(ODesc* d) const override; /** * Returns a "record_field_table" value for introspection purposes. */ - TableVal* GetRecordFieldsVal() const; + IntrusivePtr GetRecordFieldsVal() const; // This is an experiment to associate a BroObj within the // event engine to a record value in bro script. @@ -913,8 +900,8 @@ public: // // The *allow_orphaning* parameter allows for a record to be demoted // down to a record type that contains less fields. - RecordVal* CoerceTo(const RecordType* other, Val* aggr, bool allow_orphaning = false) const; - RecordVal* CoerceTo(RecordType* other, bool allow_orphaning = false); + IntrusivePtr CoerceTo(const RecordType* other, Val* aggr, bool allow_orphaning = false) const; + IntrusivePtr CoerceTo(RecordType* other, bool allow_orphaning = false); unsigned int MemoryAllocation() const override; void DescribeReST(ODesc* d) const override; @@ -927,7 +914,7 @@ public: static void ResizeParseTimeRecords(); protected: - Val* DoClone(CloneState* state) override; + IntrusivePtr DoClone(CloneState* state) override; BroObj* origin; @@ -936,7 +923,7 @@ protected: class EnumVal : public Val { public: - Val* SizeVal() const override { return val_mgr->GetInt(val.int_val); } + IntrusivePtr SizeVal() const override; protected: friend class Val; @@ -947,7 +934,7 @@ protected: } void ValDescribe(ODesc* d) const override; - Val* DoClone(CloneState* state) override; + IntrusivePtr DoClone(CloneState* state) override; }; @@ -956,8 +943,7 @@ public: explicit VectorVal(VectorType* t); ~VectorVal() override; - Val* SizeVal() const override - { return val_mgr->GetCount(uint32_t(val.vector_val->size())); } + IntrusivePtr SizeVal() const override; // Returns false if the type of the argument was wrong. // The vector will automatically grow to accomodate the index. @@ -965,11 +951,14 @@ public: // Note: does NOT Ref() the element! Remember to do so unless // the element was just created and thus has refcount 1. // + bool Assign(unsigned int index, IntrusivePtr element); bool Assign(unsigned int index, Val* element); - bool Assign(Val* index, Val* element) + + template + bool Assign(Val* index, E&& element) { return Assign(index->AsListVal()->Index(0)->CoerceToUnsigned(), - element); + std::forward(element)); } // Assigns the value to how_many locations starting at index. @@ -1009,7 +998,7 @@ public: protected: void ValDescribe(ODesc* d) const override; - Val* DoClone(CloneState* state) override; + IntrusivePtr DoClone(CloneState* state) override; VectorType* vector_type; }; diff --git a/src/Var.cc b/src/Var.cc index b520c1e498..c447517b53 100644 --- a/src/Var.cc +++ b/src/Var.cc @@ -64,7 +64,7 @@ static void make_var(ID* id, IntrusivePtr t, init_class c, if ( id->Type() && id->Type()->Tag() != TYPE_ERROR ) { if ( dt != VAR_REDEF && - (! init || ! do_init || (! t && ! (t = {AdoptRef{}, init_type(init.get())}))) ) + (! init || ! do_init || (! t && ! (t = init_type(init.get())))) ) { id->Error("already defined", init.get()); return; @@ -103,10 +103,10 @@ static void make_var(ID* id, IntrusivePtr t, init_class c, return; } - t = {AdoptRef{}, init_type(init.get())}; + t = init_type(init.get()); if ( ! t ) { - id->SetType({AdoptRef{}, error_type()}); + id->SetType(error_type()); return; } } @@ -114,7 +114,7 @@ static void make_var(ID* id, IntrusivePtr t, init_class c, id->SetType(t); if ( attr ) - id->AddAttrs(make_intrusive(attr, t.get(), false, id->IsGlobal())); + id->AddAttrs(make_intrusive(attr, t, false, id->IsGlobal())); if ( init ) { @@ -168,7 +168,8 @@ static void make_var(ID* id, IntrusivePtr t, init_class c, } else if ( t->Tag() == TYPE_TABLE ) - aggr = make_intrusive(t->AsTableType(), id->Attrs()); + aggr = make_intrusive(IntrusivePtr{NewRef{}, t->AsTableType()}, + IntrusivePtr{NewRef{}, id->Attrs()}); else if ( t->Tag() == TYPE_VECTOR ) aggr = make_intrusive(t->AsVectorType()); @@ -254,7 +255,7 @@ IntrusivePtr add_local(IntrusivePtr id, IntrusivePtr t, else { - current_scope()->AddInit(id.release()); + current_scope()->AddInit(std::move(id)); return make_intrusive(); } } @@ -294,7 +295,7 @@ void add_type(ID* id, IntrusivePtr t, attr_list* attr) id->MakeType(); if ( attr ) - id->SetAttrs(make_intrusive(attr, tnew.get(), false, false)); + id->SetAttrs(make_intrusive(attr, tnew, false, false)); } static void transfer_arg_defaults(RecordType* args, RecordType* recv) @@ -312,11 +313,11 @@ static void transfer_arg_defaults(RecordType* args, RecordType* recv) if ( ! recv_i->attrs ) { attr_list* a = new attr_list{def}; - recv_i->attrs = new Attributes(a, recv_i->type, true, false); + recv_i->attrs = make_intrusive(a, recv_i->type, true, false); } else if ( ! recv_i->attrs->FindAttr(ATTR_DEFAULT) ) - recv_i->attrs->AddAttr(def); + recv_i->attrs->AddAttr({NewRef{}, def}); } } @@ -394,7 +395,7 @@ void begin_func(ID* id, const char* module_name, function_flavor flavor, else id->SetType(t); - push_scope(id, attrs); + push_scope({NewRef{}, id}, attrs); RecordType* args = t->Args(); int num_args = args->NumFields(); @@ -408,11 +409,11 @@ void begin_func(ID* id, const char* module_name, function_flavor flavor, arg_id->Error("argument name used twice"); arg_id = install_ID(arg_i->id, module_name, false, false); - arg_id->SetType({NewRef{}, arg_i->type}); + arg_id->SetType(arg_i->type); } if ( Attr* depr_attr = find_attr(attrs, ATTR_DEPRECATED) ) - id->MakeDeprecated(depr_attr->AttrExpr()); + id->MakeDeprecated({NewRef{}, depr_attr->AttrExpr()}); } class OuterIDBindingFinder : public TraversalCallback { @@ -473,12 +474,11 @@ TraversalCode OuterIDBindingFinder::PostExpr(const Expr* expr) void end_func(IntrusivePtr body) { - auto ingredients = std::make_unique( - pop_scope().release(), body.release()); + auto ingredients = std::make_unique(pop_scope(), std::move(body)); if ( streq(ingredients->id->Name(), "anonymous-function") ) { - OuterIDBindingFinder cb(ingredients->scope); + OuterIDBindingFinder cb(ingredients->scope.get()); ingredients->body->Traverse(&cb); for ( size_t i = 0; i < cb.outer_id_references.size(); ++i ) @@ -495,7 +495,7 @@ void end_func(IntrusivePtr body) else { Func* f = new BroFunc( - ingredients->id, + ingredients->id.get(), ingredients->body, ingredients->inits, ingredients->frame_size, diff --git a/src/analyzer/Manager.cc b/src/analyzer/Manager.cc index 0bcf690a74..667f371407 100644 --- a/src/analyzer/Manager.cc +++ b/src/analyzer/Manager.cc @@ -4,6 +4,7 @@ #include "Hash.h" #include "Val.h" +#include "IntrusivePtr.h" #include "protocol/conn-size/ConnSize.h" #include "protocol/icmp/ICMP.h" @@ -440,13 +441,12 @@ bool Manager::BuildInitialAnalyzerTree(Connection* conn) if ( tcp_contents && ! reass ) { auto dport = val_mgr->GetPort(ntohs(conn->RespPort()), TRANSPORT_TCP); - Val* result; if ( ! reass ) - reass = tcp_content_delivery_ports_orig->Lookup(dport); + reass = (bool)tcp_content_delivery_ports_orig->Lookup(dport); if ( ! reass ) - reass = tcp_content_delivery_ports_resp->Lookup(dport); + reass = (bool)tcp_content_delivery_ports_resp->Lookup(dport); Unref(dport); } diff --git a/src/analyzer/protocol/bittorrent/BitTorrentTracker.cc b/src/analyzer/protocol/bittorrent/BitTorrentTracker.cc index acfac33a75..301f37eb6c 100644 --- a/src/analyzer/protocol/bittorrent/BitTorrentTracker.cc +++ b/src/analyzer/protocol/bittorrent/BitTorrentTracker.cc @@ -45,7 +45,7 @@ BitTorrentTracker_Analyzer::BitTorrentTracker_Analyzer(Connection* c) req_buf_pos = req_buf; req_buf_len = 0; req_val_uri = 0; - req_val_headers = new TableVal(bt_tracker_headers); + req_val_headers = new TableVal({NewRef{}, bt_tracker_headers}); res_state = BTT_RES_STATUS; res_allow_blank_line = false; @@ -53,9 +53,9 @@ BitTorrentTracker_Analyzer::BitTorrentTracker_Analyzer(Connection* c) res_buf_pos = res_buf; res_buf_len = 0; res_status = 0; - res_val_headers = new TableVal(bt_tracker_headers); - res_val_peers = new TableVal(bittorrent_peer_set); - res_val_benc = new TableVal(bittorrent_benc_dir); + res_val_headers = new TableVal({NewRef{}, bt_tracker_headers}); + res_val_peers = new TableVal({NewRef{}, bittorrent_peer_set}); + res_val_benc = new TableVal({NewRef{}, bittorrent_benc_dir}); InitBencParser(); @@ -137,7 +137,7 @@ void BitTorrentTracker_Analyzer::ClientRequest(int len, const u_char* data) memmove(req_buf, req_buf_pos, req_buf_len); req_buf_pos = req_buf; req_val_headers = - new TableVal(bt_tracker_headers); + new TableVal({NewRef{}, bt_tracker_headers}); } } } @@ -199,9 +199,9 @@ void BitTorrentTracker_Analyzer::ServerReply(int len, const u_char* data) res_buf_pos = res_buf; res_status = 0; - res_val_headers = new TableVal(bt_tracker_headers); - res_val_peers = new TableVal(bittorrent_peer_set); - res_val_benc = new TableVal(bittorrent_benc_dir); + res_val_headers = new TableVal({NewRef{}, bt_tracker_headers}); + res_val_peers = new TableVal({NewRef{}, bittorrent_peer_set}); + res_val_benc = new TableVal({NewRef{}, bittorrent_benc_dir}); InitBencParser(); } @@ -481,7 +481,7 @@ void BitTorrentTracker_Analyzer::ResponseBenc(int name_len, char* name, uint16_t pt = ntohs((value[4] << 8) | value[5]); RecordVal* peer = new RecordVal(bittorrent_peer); - peer->Assign(0, new AddrVal(ad)); + peer->Assign(0, make_intrusive(ad)); peer->Assign(1, val_mgr->GetPort(pt, TRANSPORT_TCP)); res_val_peers->Assign(peer, 0); @@ -491,9 +491,9 @@ void BitTorrentTracker_Analyzer::ResponseBenc(int name_len, char* name, else { StringVal* name_ = new StringVal(name_len, name); - RecordVal* benc_value = new RecordVal(bittorrent_benc_value); - benc_value->Assign(type, new StringVal(value_len, value)); - res_val_benc->Assign(name_, benc_value); + auto benc_value = make_intrusive(bittorrent_benc_value); + benc_value->Assign(type, make_intrusive(value_len, value)); + res_val_benc->Assign(name_, std::move(benc_value)); Unref(name_); } diff --git a/src/analyzer/protocol/dce-rpc/dce_rpc-analyzer.pac b/src/analyzer/protocol/dce-rpc/dce_rpc-analyzer.pac index 70165054f6..bc0f168d64 100644 --- a/src/analyzer/protocol/dce-rpc/dce_rpc-analyzer.pac +++ b/src/analyzer/protocol/dce-rpc/dce_rpc-analyzer.pac @@ -42,7 +42,7 @@ refine connection DCE_RPC_Conn += { ${header.is_orig}, fid, ${header.PTYPE}, - BifType::Enum::DCE_RPC::PType->GetVal(${header.PTYPE})); + BifType::Enum::DCE_RPC::PType->GetVal(${header.PTYPE}).release()); } return true; %} diff --git a/src/analyzer/protocol/dhcp/dhcp-analyzer.pac b/src/analyzer/protocol/dhcp/dhcp-analyzer.pac index 82218ebacb..91c4f5b0d9 100644 --- a/src/analyzer/protocol/dhcp/dhcp-analyzer.pac +++ b/src/analyzer/protocol/dhcp/dhcp-analyzer.pac @@ -61,13 +61,13 @@ refine flow DHCP_Flow += { dhcp_msg_val->Assign(0, val_mgr->GetCount(${msg.op})); dhcp_msg_val->Assign(1, val_mgr->GetCount(${msg.type})); dhcp_msg_val->Assign(2, val_mgr->GetCount(${msg.xid})); - dhcp_msg_val->Assign(3, new Val(secs, TYPE_INTERVAL)); + dhcp_msg_val->Assign(3, make_intrusive(secs, TYPE_INTERVAL)); dhcp_msg_val->Assign(4, val_mgr->GetCount(${msg.flags})); - dhcp_msg_val->Assign(5, new AddrVal(htonl(${msg.ciaddr}))); - dhcp_msg_val->Assign(6, new AddrVal(htonl(${msg.yiaddr}))); - dhcp_msg_val->Assign(7, new AddrVal(htonl(${msg.siaddr}))); - dhcp_msg_val->Assign(8, new AddrVal(htonl(${msg.giaddr}))); - dhcp_msg_val->Assign(9, new StringVal(mac_str)); + dhcp_msg_val->Assign(5, make_intrusive(htonl(${msg.ciaddr}))); + dhcp_msg_val->Assign(6, make_intrusive(htonl(${msg.yiaddr}))); + dhcp_msg_val->Assign(7, make_intrusive(htonl(${msg.siaddr}))); + dhcp_msg_val->Assign(8, make_intrusive(htonl(${msg.giaddr}))); + dhcp_msg_val->Assign(9, make_intrusive(mac_str)); int last_non_null = 0; @@ -78,8 +78,8 @@ refine flow DHCP_Flow += { } if ( last_non_null > 0 ) - dhcp_msg_val->Assign(10, new StringVal(last_non_null + 1, - reinterpret_cast(${msg.sname}.begin()))); + dhcp_msg_val->Assign(10, make_intrusive(last_non_null + 1, + reinterpret_cast(${msg.sname}.begin()))); last_non_null = 0; @@ -90,8 +90,8 @@ refine flow DHCP_Flow += { } if ( last_non_null > 0 ) - dhcp_msg_val->Assign(11, new StringVal(last_non_null + 1, - reinterpret_cast(${msg.file_n}.begin()))); + dhcp_msg_val->Assign(11, make_intrusive(last_non_null + 1, + reinterpret_cast(${msg.file_n}.begin()))); init_options(); diff --git a/src/analyzer/protocol/dhcp/dhcp-options.pac b/src/analyzer/protocol/dhcp/dhcp-options.pac index f1b45fbc6f..ac36c2b304 100644 --- a/src/analyzer/protocol/dhcp/dhcp-options.pac +++ b/src/analyzer/protocol/dhcp/dhcp-options.pac @@ -11,7 +11,7 @@ refine casetype OptionValue += { refine flow DHCP_Flow += { function process_subnet_option(v: OptionValue): bool %{ - ${context.flow}->options->Assign(1, new AddrVal(htonl(${v.subnet}))); + ${context.flow}->options->Assign(1, make_intrusive(htonl(${v.subnet}))); return true; %} }; @@ -64,7 +64,7 @@ refine flow DHCP_Flow += { for ( int i = 0; i < num_routers; ++i ) { uint32 raddr = (*rlist)[i]; - router_list->Assign(i, new AddrVal(htonl(raddr))); + router_list->Assign(i, make_intrusive(htonl(raddr))); } ${context.flow}->options->Assign(2, router_list); @@ -98,7 +98,7 @@ refine flow DHCP_Flow += { for ( int i = 0; i < num_servers; ++i ) { uint32 raddr = (*rlist)[i]; - timeserver_list->Assign(i, new AddrVal(htonl(raddr))); + timeserver_list->Assign(i, make_intrusive(htonl(raddr))); } ${context.flow}->options->Assign(26, timeserver_list); @@ -132,7 +132,7 @@ refine flow DHCP_Flow += { for ( int i = 0; i < num_servers; ++i ) { uint32 raddr = (*rlist)[i]; - nameserver_list->Assign(i, new AddrVal(htonl(raddr))); + nameserver_list->Assign(i, make_intrusive(htonl(raddr))); } ${context.flow}->options->Assign(27, nameserver_list); @@ -166,7 +166,7 @@ refine flow DHCP_Flow += { for ( int i = 0; i < num_servers; ++i ) { uint32 raddr = (*rlist)[i]; - server_list->Assign(i, new AddrVal(htonl(raddr))); + server_list->Assign(i, make_intrusive(htonl(raddr))); } ${context.flow}->options->Assign(3, server_list); @@ -192,7 +192,7 @@ refine casetype OptionValue += { refine flow DHCP_Flow += { function process_host_name_option(v: OptionValue): bool %{ - ${context.flow}->options->Assign(4, new StringVal(${v.host_name}.length(), + ${context.flow}->options->Assign(4, make_intrusive(${v.host_name}.length(), reinterpret_cast(${v.host_name}.begin()))); return true; @@ -225,7 +225,7 @@ refine flow DHCP_Flow += { last_non_null = i; } - ${context.flow}->options->Assign(5, new StringVal(last_non_null == 0 ? 0 : last_non_null + 1, + ${context.flow}->options->Assign(5, make_intrusive(last_non_null == 0 ? 0 : last_non_null + 1, reinterpret_cast(${v.domain_name}.begin()))); return true; @@ -274,7 +274,7 @@ refine casetype OptionValue += { refine flow DHCP_Flow += { function process_broadcast_address_option(v: OptionValue): bool %{ - ${context.flow}->options->Assign(7, new AddrVal(htonl(${v.broadcast_address}))); + ${context.flow}->options->Assign(7, make_intrusive(htonl(${v.broadcast_address}))); return true; %} @@ -305,7 +305,7 @@ refine flow DHCP_Flow += { for ( int i = 0; i < num_servers; ++i ) { uint32 raddr = (*rlist)[i]; - ntpserver_list->Assign(i, new AddrVal(htonl(raddr))); + ntpserver_list->Assign(i, make_intrusive(htonl(raddr))); } ${context.flow}->options->Assign(28, ntpserver_list); @@ -331,7 +331,7 @@ refine casetype OptionValue += { refine flow DHCP_Flow += { function process_vendor_specific_option(v: OptionValue): bool %{ - ${context.flow}->options->Assign(8, new StringVal(${v.vendor_specific}.length(), + ${context.flow}->options->Assign(8, make_intrusive(${v.vendor_specific}.length(), reinterpret_cast(${v.vendor_specific}.begin()))); return true; @@ -363,7 +363,7 @@ refine flow DHCP_Flow += { for ( int i = 0; i < num_servers; ++i ) { uint32 raddr = (*rlist)[i]; - server_list->Assign(i, new AddrVal(htonl(raddr))); + server_list->Assign(i, make_intrusive(htonl(raddr))); } ${context.flow}->options->Assign(9, server_list); @@ -389,7 +389,7 @@ refine casetype OptionValue += { refine flow DHCP_Flow += { function process_addr_request_option(v: OptionValue): bool %{ - ${context.flow}->options->Assign(10, new AddrVal(htonl(${v.addr_request}))); + ${context.flow}->options->Assign(10, make_intrusive(htonl(${v.addr_request}))); return true; %} @@ -414,7 +414,7 @@ refine flow DHCP_Flow += { function process_lease_option(v: OptionValue): bool %{ double lease = static_cast(${v.lease}); - ${context.flow}->options->Assign(11, new Val(lease, TYPE_INTERVAL)); + ${context.flow}->options->Assign(11, make_intrusive(lease, TYPE_INTERVAL)); return true; %} @@ -438,7 +438,7 @@ refine casetype OptionValue += { refine flow DHCP_Flow += { function process_serv_id_option(v: OptionValue): bool %{ - ${context.flow}->options->Assign(12, new AddrVal(htonl(${v.serv_addr}))); + ${context.flow}->options->Assign(12, make_intrusive(htonl(${v.serv_addr}))); return true; %} @@ -496,7 +496,7 @@ refine casetype OptionValue += { refine flow DHCP_Flow += { function process_message_option(v: OptionValue): bool %{ - ${context.flow}->options->Assign(14, new StringVal(${v.message}.length(), + ${context.flow}->options->Assign(14, make_intrusive(${v.message}.length(), reinterpret_cast(${v.message}.begin()))); return true; @@ -546,7 +546,7 @@ refine flow DHCP_Flow += { function process_renewal_time_option(v: OptionValue): bool %{ double renewal_time = static_cast(${v.renewal_time}); - ${context.flow}->options->Assign(16, new Val(renewal_time, TYPE_INTERVAL)); + ${context.flow}->options->Assign(16, make_intrusive(renewal_time, TYPE_INTERVAL)); return true; %} @@ -571,7 +571,7 @@ refine flow DHCP_Flow += { function process_rebinding_time_option(v: OptionValue): bool %{ double rebinding_time = static_cast(${v.rebinding_time}); - ${context.flow}->options->Assign(17, new Val(rebinding_time, TYPE_INTERVAL)); + ${context.flow}->options->Assign(17, make_intrusive(rebinding_time, TYPE_INTERVAL)); return true; %} @@ -595,7 +595,7 @@ refine casetype OptionValue += { refine flow DHCP_Flow += { function process_vendor_class_option(v: OptionValue): bool %{ - ${context.flow}->options->Assign(18, new StringVal(${v.vendor_class}.length(), + ${context.flow}->options->Assign(18, make_intrusive(${v.vendor_class}.length(), reinterpret_cast(${v.vendor_class}.begin()))); return true; @@ -627,7 +627,7 @@ refine flow DHCP_Flow += { %{ RecordVal* client_id = new RecordVal(BifType::Record::DHCP::ClientID); client_id->Assign(0, val_mgr->GetCount(${v.client_id.hwtype})); - client_id->Assign(1, new StringVal(fmt_mac(${v.client_id.hwaddr}.begin(), ${v.client_id.hwaddr}.length()))); + client_id->Assign(1, make_intrusive(fmt_mac(${v.client_id.hwaddr}.begin(), ${v.client_id.hwaddr}.length()))); ${context.flow}->options->Assign(19, client_id); @@ -653,7 +653,7 @@ refine casetype OptionValue += { refine flow DHCP_Flow += { function process_user_class_option(v: OptionValue): bool %{ - ${context.flow}->options->Assign(20, new StringVal(${v.user_class}.length(), + ${context.flow}->options->Assign(20, make_intrusive(${v.user_class}.length(), reinterpret_cast(${v.user_class}.begin()))); return true; @@ -690,7 +690,7 @@ refine flow DHCP_Flow += { client_fqdn->Assign(1, val_mgr->GetCount(${v.client_fqdn.rcode1})); client_fqdn->Assign(2, val_mgr->GetCount(${v.client_fqdn.rcode2})); const char* domain_name = reinterpret_cast(${v.client_fqdn.domain_name}.begin()); - client_fqdn->Assign(3, new StringVal(${v.client_fqdn.domain_name}.length(), domain_name)); + client_fqdn->Assign(3, make_intrusive(${v.client_fqdn.domain_name}.length(), domain_name)); ${context.flow}->options->Assign(21, client_fqdn); @@ -809,7 +809,7 @@ refine flow DHCP_Flow += { if ( string_len == 0 ) { - ${context.flow}->options->Assign(24, new StringVal(0, "")); + ${context.flow}->options->Assign(24, make_intrusive(0, "")); return true; } @@ -821,7 +821,7 @@ refine flow DHCP_Flow += { if ( has_newline ) --string_len; - ${context.flow}->options->Assign(24, new StringVal(string_len, + ${context.flow}->options->Assign(24, make_intrusive(string_len, reinterpret_cast(${v.auto_proxy_config}.begin()))); return true; diff --git a/src/analyzer/protocol/dns/DNS.cc b/src/analyzer/protocol/dns/DNS.cc index 38293f92ac..ac82a042ab 100644 --- a/src/analyzer/protocol/dns/DNS.cc +++ b/src/analyzer/protocol/dns/DNS.cc @@ -603,13 +603,13 @@ int DNS_Interpreter::ParseRR_SOA(DNS_MsgInfo* msg, if ( dns_SOA_reply && ! msg->skip_event ) { RecordVal* r = new RecordVal(dns_soa); - r->Assign(0, new StringVal(new BroString(mname, mname_end - mname, 1))); - r->Assign(1, new StringVal(new BroString(rname, rname_end - rname, 1))); + r->Assign(0, make_intrusive(new BroString(mname, mname_end - mname, 1))); + r->Assign(1, make_intrusive(new BroString(rname, rname_end - rname, 1))); r->Assign(2, val_mgr->GetCount(serial)); - r->Assign(3, new IntervalVal(double(refresh), Seconds)); - r->Assign(4, new IntervalVal(double(retry), Seconds)); - r->Assign(5, new IntervalVal(double(expire), Seconds)); - r->Assign(6, new IntervalVal(double(minimum), Seconds)); + r->Assign(3, make_intrusive(double(refresh), Seconds)); + r->Assign(4, make_intrusive(double(retry), Seconds)); + r->Assign(5, make_intrusive(double(expire), Seconds)); + r->Assign(6, make_intrusive(double(minimum), Seconds)); analyzer->ConnectionEventFast(dns_SOA_reply, { analyzer->BuildConnVal(), @@ -1029,7 +1029,7 @@ int DNS_Interpreter::ParseRR_NSEC(DNS_MsgInfo* msg, } BroString* bitmap = ExtractStream(data, len, bmlen); - char_strings->Assign(char_strings->Size(), new StringVal(bitmap)); + char_strings->Assign(char_strings->Size(), make_intrusive(bitmap)); typebitmaps_len = typebitmaps_len - (2 + bmlen); } @@ -1106,7 +1106,7 @@ int DNS_Interpreter::ParseRR_NSEC3(DNS_MsgInfo* msg, } BroString* bitmap = ExtractStream(data, len, bmlen); - char_strings->Assign(char_strings->Size(), new StringVal(bitmap)); + char_strings->Assign(char_strings->Size(), make_intrusive(bitmap)); typebitmaps_len = typebitmaps_len - (2 + bmlen); } @@ -1496,7 +1496,7 @@ Val* DNS_MsgInfo::BuildAnswerVal() r->Assign(1, query_name); r->Assign(2, val_mgr->GetCount(atype)); r->Assign(3, val_mgr->GetCount(aclass)); - r->Assign(4, new IntervalVal(double(ttl), Seconds)); + r->Assign(4, make_intrusive(double(ttl), Seconds)); return r; } @@ -1531,7 +1531,7 @@ Val* DNS_MsgInfo::BuildEDNS_Val() r->Assign(4, val_mgr->GetCount(return_error)); r->Assign(5, val_mgr->GetCount(version)); r->Assign(6, val_mgr->GetCount(z)); - r->Assign(7, new IntervalVal(double(ttl), Seconds)); + r->Assign(7, make_intrusive(double(ttl), Seconds)); r->Assign(8, val_mgr->GetCount(is_query)); return r; @@ -1546,10 +1546,10 @@ Val* DNS_MsgInfo::BuildTSIG_Val(struct TSIG_DATA* tsig) // r->Assign(0, val_mgr->GetCount(int(answer_type))); r->Assign(0, query_name); r->Assign(1, val_mgr->GetCount(int(answer_type))); - r->Assign(2, new StringVal(tsig->alg_name)); - r->Assign(3, new StringVal(tsig->sig)); - r->Assign(4, new Val(rtime, TYPE_TIME)); - r->Assign(5, new Val(double(tsig->fudge), TYPE_TIME)); + r->Assign(2, make_intrusive(tsig->alg_name)); + r->Assign(3, make_intrusive(tsig->sig)); + r->Assign(4, make_intrusive(rtime, TYPE_TIME)); + r->Assign(5, make_intrusive(double(tsig->fudge), TYPE_TIME)); r->Assign(6, val_mgr->GetCount(tsig->orig_id)); r->Assign(7, val_mgr->GetCount(tsig->rr_error)); r->Assign(8, val_mgr->GetCount(is_query)); @@ -1567,12 +1567,12 @@ Val* DNS_MsgInfo::BuildRRSIG_Val(RRSIG_DATA* rrsig) r->Assign(2, val_mgr->GetCount(rrsig->type_covered)); r->Assign(3, val_mgr->GetCount(rrsig->algorithm)); r->Assign(4, val_mgr->GetCount(rrsig->labels)); - r->Assign(5, new IntervalVal(double(rrsig->orig_ttl), Seconds)); - r->Assign(6, new Val(double(rrsig->sig_exp), TYPE_TIME)); - r->Assign(7, new Val(double(rrsig->sig_incep), TYPE_TIME)); + r->Assign(5, make_intrusive(double(rrsig->orig_ttl), Seconds)); + r->Assign(6, make_intrusive(double(rrsig->sig_exp), TYPE_TIME)); + r->Assign(7, make_intrusive(double(rrsig->sig_incep), TYPE_TIME)); r->Assign(8, val_mgr->GetCount(rrsig->key_tag)); - r->Assign(9, new StringVal(rrsig->signer_name)); - r->Assign(10, new StringVal(rrsig->signature)); + r->Assign(9, make_intrusive(rrsig->signer_name)); + r->Assign(10, make_intrusive(rrsig->signature)); r->Assign(11, val_mgr->GetCount(is_query)); return r; @@ -1588,7 +1588,7 @@ Val* DNS_MsgInfo::BuildDNSKEY_Val(DNSKEY_DATA* dnskey) r->Assign(2, val_mgr->GetCount(dnskey->dflags)); r->Assign(3, val_mgr->GetCount(dnskey->dprotocol)); r->Assign(4, val_mgr->GetCount(dnskey->dalgorithm)); - r->Assign(5, new StringVal(dnskey->public_key)); + r->Assign(5, make_intrusive(dnskey->public_key)); r->Assign(6, val_mgr->GetCount(is_query)); return r; @@ -1605,9 +1605,9 @@ Val* DNS_MsgInfo::BuildNSEC3_Val(NSEC3_DATA* nsec3) r->Assign(3, val_mgr->GetCount(nsec3->nsec_hash_algo)); r->Assign(4, val_mgr->GetCount(nsec3->nsec_iter)); r->Assign(5, val_mgr->GetCount(nsec3->nsec_salt_len)); - r->Assign(6, new StringVal(nsec3->nsec_salt)); + r->Assign(6, make_intrusive(nsec3->nsec_salt)); r->Assign(7, val_mgr->GetCount(nsec3->nsec_hlen)); - r->Assign(8, new StringVal(nsec3->nsec_hash)); + r->Assign(8, make_intrusive(nsec3->nsec_hash)); r->Assign(9, nsec3->bitmaps); r->Assign(10, val_mgr->GetCount(is_query)); @@ -1624,7 +1624,7 @@ Val* DNS_MsgInfo::BuildDS_Val(DS_DATA* ds) r->Assign(2, val_mgr->GetCount(ds->key_tag)); r->Assign(3, val_mgr->GetCount(ds->algorithm)); r->Assign(4, val_mgr->GetCount(ds->digest_type)); - r->Assign(5, new StringVal(ds->digest_val)); + r->Assign(5, make_intrusive(ds->digest_val)); r->Assign(6, val_mgr->GetCount(is_query)); return r; diff --git a/src/analyzer/protocol/ftp/functions.bif b/src/analyzer/protocol/ftp/functions.bif index 7f2b6cf643..304c7674d5 100644 --- a/src/analyzer/protocol/ftp/functions.bif +++ b/src/analyzer/protocol/ftp/functions.bif @@ -33,13 +33,13 @@ static Val* parse_port(const char* line) good = 0; } - r->Assign(0, new AddrVal(htonl(addr))); + r->Assign(0, make_intrusive(htonl(addr))); r->Assign(1, val_mgr->GetPort(port, TRANSPORT_TCP)); r->Assign(2, val_mgr->GetBool(good)); } else { - r->Assign(0, new AddrVal(uint32_t(0))); + r->Assign(0, make_intrusive(uint32_t(0))); r->Assign(1, val_mgr->GetPort(0, TRANSPORT_TCP)); r->Assign(2, val_mgr->GetBool(0)); } @@ -109,7 +109,7 @@ static Val* parse_eftp(const char* line) } - r->Assign(0, new AddrVal(addr)); + r->Assign(0, make_intrusive(addr)); r->Assign(1, val_mgr->GetPort(port, TRANSPORT_TCP)); r->Assign(2, val_mgr->GetBool(good)); diff --git a/src/analyzer/protocol/gtpv1/gtpv1-analyzer.pac b/src/analyzer/protocol/gtpv1/gtpv1-analyzer.pac index 1ef11e1f90..3c9f43a4a0 100644 --- a/src/analyzer/protocol/gtpv1/gtpv1-analyzer.pac +++ b/src/analyzer/protocol/gtpv1/gtpv1-analyzer.pac @@ -97,15 +97,15 @@ Val* BuildEndUserAddr(const InformationElement* ie) switch ( ie->end_user_addr()->pdp_type_num() ) { case 0x21: - ev->Assign(2, new AddrVal( + ev->Assign(2, make_intrusive( IPAddr(IPv4, (const uint32*) d, IPAddr::Network))); break; case 0x57: - ev->Assign(2, new AddrVal( + ev->Assign(2, make_intrusive( IPAddr(IPv6, (const uint32*) d, IPAddr::Network))); break; default: - ev->Assign(3, new StringVal( + ev->Assign(3, make_intrusive( new BroString((const u_char*) d, len, 0))); break; } @@ -136,13 +136,13 @@ Val* BuildGSN_Addr(const InformationElement* ie) const uint8* d = ie->gsn_addr()->value().data(); if ( len == 4 ) - ev->Assign(0, new AddrVal( + ev->Assign(0, make_intrusive( IPAddr(IPv4, (const uint32*) d, IPAddr::Network))); else if ( len == 16 ) - ev->Assign(0, new AddrVal( + ev->Assign(0, make_intrusive( IPAddr(IPv6, (const uint32*) d, IPAddr::Network))); else - ev->Assign(1, new StringVal(new BroString((const u_char*) d, len, 0))); + ev->Assign(1, make_intrusive(new BroString((const u_char*) d, len, 0))); return ev; } @@ -162,7 +162,7 @@ Val* BuildQoS_Profile(const InformationElement* ie) int len = ie->qos_profile()->data().length(); ev->Assign(0, val_mgr->GetCount(ie->qos_profile()->alloc_retention_priority())); - ev->Assign(1, new StringVal(new BroString(d, len, 0))); + ev->Assign(1, make_intrusive(new BroString(d, len, 0))); return ev; } @@ -196,7 +196,7 @@ Val* BuildPrivateExt(const InformationElement* ie) int len = ie->private_ext()->value().length(); ev->Assign(0, val_mgr->GetCount(ie->private_ext()->id())); - ev->Assign(1, new StringVal(new BroString((const u_char*) d, len, 0))); + ev->Assign(1, make_intrusive(new BroString((const u_char*) d, len, 0))); return ev; } diff --git a/src/analyzer/protocol/http/HTTP.cc b/src/analyzer/protocol/http/HTTP.cc index c0cc761c6f..7c7190d936 100644 --- a/src/analyzer/protocol/http/HTTP.cc +++ b/src/analyzer/protocol/http/HTTP.cc @@ -617,9 +617,9 @@ Val* HTTP_Message::BuildMessageStat(const int interrupted, const char* msg) { RecordVal* stat = new RecordVal(http_message_stat); int field = 0; - stat->Assign(field++, new Val(start_time, TYPE_TIME)); + stat->Assign(field++, make_intrusive(start_time, TYPE_TIME)); stat->Assign(field++, val_mgr->GetBool(interrupted)); - stat->Assign(field++, new StringVal(msg)); + stat->Assign(field++, make_intrusive(msg)); stat->Assign(field++, val_mgr->GetCount(body_length)); stat->Assign(field++, val_mgr->GetCount(content_gap_length)); stat->Assign(field++, val_mgr->GetCount(header_length)); @@ -1185,8 +1185,8 @@ void HTTP_Analyzer::GenStats() RecordVal* r = new RecordVal(http_stats_rec); r->Assign(0, val_mgr->GetCount(num_requests)); r->Assign(1, val_mgr->GetCount(num_replies)); - r->Assign(2, new Val(request_version.ToDouble(), TYPE_DOUBLE)); - r->Assign(3, new Val(reply_version.ToDouble(), TYPE_DOUBLE)); + r->Assign(2, make_intrusive(request_version.ToDouble(), TYPE_DOUBLE)); + r->Assign(3, make_intrusive(reply_version.ToDouble(), TYPE_DOUBLE)); // DEBUG_MSG("%.6f http_stats\n", network_time); ConnectionEventFast(http_stats, {BuildConnVal(), r}); diff --git a/src/analyzer/protocol/icmp/ICMP.cc b/src/analyzer/protocol/icmp/ICMP.cc index 145c00dfee..f5e9bbf3dd 100644 --- a/src/analyzer/protocol/icmp/ICMP.cc +++ b/src/analyzer/protocol/icmp/ICMP.cc @@ -228,8 +228,8 @@ RecordVal* ICMP_Analyzer::BuildICMPVal(const struct icmp* icmpp, int len, { icmp_conn_val = new RecordVal(icmp_conn); - icmp_conn_val->Assign(0, new AddrVal(Conn()->OrigAddr())); - icmp_conn_val->Assign(1, new AddrVal(Conn()->RespAddr())); + icmp_conn_val->Assign(0, make_intrusive(Conn()->OrigAddr())); + icmp_conn_val->Assign(1, make_intrusive(Conn()->RespAddr())); icmp_conn_val->Assign(2, val_mgr->GetCount(icmpp->icmp_type)); icmp_conn_val->Assign(3, val_mgr->GetCount(icmpp->icmp_code)); icmp_conn_val->Assign(4, val_mgr->GetCount(len)); @@ -356,9 +356,9 @@ RecordVal* ICMP_Analyzer::ExtractICMP4Context(int len, const u_char*& data) RecordVal* iprec = new RecordVal(icmp_context); RecordVal* id_val = new RecordVal(conn_id); - id_val->Assign(0, new AddrVal(src_addr)); + id_val->Assign(0, make_intrusive(src_addr)); id_val->Assign(1, val_mgr->GetPort(src_port, proto)); - id_val->Assign(2, new AddrVal(dst_addr)); + id_val->Assign(2, make_intrusive(dst_addr)); id_val->Assign(3, val_mgr->GetPort(dst_port, proto)); iprec->Assign(0, id_val); @@ -415,9 +415,9 @@ RecordVal* ICMP_Analyzer::ExtractICMP6Context(int len, const u_char*& data) RecordVal* iprec = new RecordVal(icmp_context); RecordVal* id_val = new RecordVal(conn_id); - id_val->Assign(0, new AddrVal(src_addr)); + id_val->Assign(0, make_intrusive(src_addr)); id_val->Assign(1, val_mgr->GetPort(src_port, proto)); - id_val->Assign(2, new AddrVal(dst_addr)); + id_val->Assign(2, make_intrusive(dst_addr)); id_val->Assign(3, val_mgr->GetPort(dst_port, proto)); iprec->Assign(0, id_val); @@ -778,7 +778,7 @@ VectorVal* ICMP_Analyzer::BuildNDOptionsVal(int caplen, const u_char* data) if ( caplen >= length ) { BroString* link_addr = new BroString(data, length, 0); - rv->Assign(2, new StringVal(link_addr)); + rv->Assign(2, make_intrusive(link_addr)); } else set_payload_field = true; @@ -801,9 +801,9 @@ VectorVal* ICMP_Analyzer::BuildNDOptionsVal(int caplen, const u_char* data) info->Assign(0, val_mgr->GetCount(prefix_len)); info->Assign(1, val_mgr->GetBool(L_flag)); info->Assign(2, val_mgr->GetBool(A_flag)); - info->Assign(3, new IntervalVal((double)ntohl(valid_life), Seconds)); - info->Assign(4, new IntervalVal((double)ntohl(prefer_life), Seconds)); - info->Assign(5, new AddrVal(IPAddr(prefix))); + info->Assign(3, make_intrusive((double)ntohl(valid_life), Seconds)); + info->Assign(4, make_intrusive((double)ntohl(prefer_life), Seconds)); + info->Assign(5, make_intrusive(IPAddr(prefix))); rv->Assign(3, info); } @@ -849,7 +849,7 @@ VectorVal* ICMP_Analyzer::BuildNDOptionsVal(int caplen, const u_char* data) { BroString* payload = new BroString(data, min((int)length, caplen), 0); - rv->Assign(6, new StringVal(payload)); + rv->Assign(6, make_intrusive(payload)); } data += length; diff --git a/src/analyzer/protocol/imap/imap-analyzer.pac b/src/analyzer/protocol/imap/imap-analyzer.pac index ac1652086e..2061243fc5 100644 --- a/src/analyzer/protocol/imap/imap-analyzer.pac +++ b/src/analyzer/protocol/imap/imap-analyzer.pac @@ -63,7 +63,7 @@ refine connection IMAP_Conn += { for ( unsigned int i = 0; i< capabilities->size(); i++ ) { const bytestring& capability = (*capabilities)[i]->cap(); - capv->Assign(i, new StringVal(capability.length(), (const char*)capability.data())); + capv->Assign(i, make_intrusive(capability.length(), (const char*)capability.data())); } BifEvent::generate_imap_capabilities(bro_analyzer(), bro_analyzer()->Conn(), capv); diff --git a/src/analyzer/protocol/irc/IRC.cc b/src/analyzer/protocol/irc/IRC.cc index de8a494c6c..d380b7742c 100644 --- a/src/analyzer/protocol/irc/IRC.cc +++ b/src/analyzer/protocol/irc/IRC.cc @@ -270,7 +270,7 @@ void IRC_Analyzer::DeliverStream(int length, const u_char* line, bool orig) if ( parts.size() > 0 && parts[0][0] == ':' ) parts[0] = parts[0].substr(1); - TableVal* set = new TableVal(string_set); + TableVal* set = new TableVal({NewRef{}, string_set}); for ( unsigned int i = 0; i < parts.size(); ++i ) { @@ -463,7 +463,7 @@ void IRC_Analyzer::DeliverStream(int length, const u_char* line, bool orig) if ( parts.size() > 0 && parts[0][0] == ':' ) parts[0] = parts[0].substr(1); - TableVal* set = new TableVal(string_set); + TableVal* set = new TableVal({NewRef{}, string_set}); for ( unsigned int i = 0; i < parts.size(); ++i ) { @@ -841,7 +841,7 @@ void IRC_Analyzer::DeliverStream(int length, const u_char* line, bool orig) nickname = prefix.substr(0, pos); } - TableVal* list = new TableVal(irc_join_list); + TableVal* list = new TableVal({NewRef{}, irc_join_list}); vector channels = SplitWords(parts[0], ','); vector passwords; @@ -853,14 +853,14 @@ void IRC_Analyzer::DeliverStream(int length, const u_char* line, bool orig) for ( unsigned int i = 0; i < channels.size(); ++i ) { RecordVal* info = new RecordVal(irc_join_info); - info->Assign(0, new StringVal(nickname.c_str())); - info->Assign(1, new StringVal(channels[i].c_str())); + info->Assign(0, make_intrusive(nickname.c_str())); + info->Assign(1, make_intrusive(channels[i].c_str())); if ( i < passwords.size() ) - info->Assign(2, new StringVal(passwords[i].c_str())); + info->Assign(2, make_intrusive(passwords[i].c_str())); else - info->Assign(2, new StringVal(empty_string.c_str())); + info->Assign(2, make_intrusive(empty_string.c_str())); // User mode. - info->Assign(3, new StringVal(empty_string.c_str())); + info->Assign(3, make_intrusive(empty_string.c_str())); list->Assign(info, 0); Unref(info); } @@ -886,7 +886,7 @@ void IRC_Analyzer::DeliverStream(int length, const u_char* line, bool orig) parts[1] = parts[1].substr(1); vector users = SplitWords(parts[1], ','); - TableVal* list = new TableVal(irc_join_list); + TableVal* list = new TableVal({NewRef{}, irc_join_list}); string empty_string = ""; @@ -916,12 +916,12 @@ void IRC_Analyzer::DeliverStream(int length, const u_char* line, bool orig) mode = "voice"; } - info->Assign(0, new StringVal(nick.c_str())); - info->Assign(1, new StringVal(channel.c_str())); + info->Assign(0, make_intrusive(nick.c_str())); + info->Assign(1, make_intrusive(channel.c_str())); // Password: - info->Assign(2, new StringVal(empty_string.c_str())); + info->Assign(2, make_intrusive(empty_string.c_str())); // User mode: - info->Assign(3, new StringVal(mode.c_str())); + info->Assign(3, make_intrusive(mode.c_str())); list->Assign(info, 0); Unref(info); } @@ -957,7 +957,7 @@ void IRC_Analyzer::DeliverStream(int length, const u_char* line, bool orig) nick = nick.substr(0, pos); vector channelList = SplitWords(channels, ','); - TableVal* set = new TableVal(string_set); + TableVal* set = new TableVal({NewRef{}, string_set}); for ( unsigned int i = 0; i < channelList.size(); ++i ) { diff --git a/src/analyzer/protocol/krb/krb-types.pac b/src/analyzer/protocol/krb/krb-types.pac index d7cbb17ae6..64b745d99a 100644 --- a/src/analyzer/protocol/krb/krb-types.pac +++ b/src/analyzer/protocol/krb/krb-types.pac @@ -61,7 +61,7 @@ RecordVal* proc_host_address(const BroAnalyzer a, const KRB_Host_Address* addr) } auto bytes = reinterpret_cast(addr_bytes.data()); - rv->Assign(0, new AddrVal(IPAddr(IPv4, bytes, IPAddr::Network))); + rv->Assign(0, make_intrusive(IPAddr(IPv4, bytes, IPAddr::Network))); return rv; } case 24: @@ -73,7 +73,7 @@ RecordVal* proc_host_address(const BroAnalyzer a, const KRB_Host_Address* addr) } auto bytes = reinterpret_cast(addr_bytes.data()); - rv->Assign(0, new AddrVal(IPAddr(IPv6, bytes, IPAddr::Network))); + rv->Assign(0, make_intrusive(IPAddr(IPv6, bytes, IPAddr::Network))); return rv; } case 20: diff --git a/src/analyzer/protocol/mime/MIME.cc b/src/analyzer/protocol/mime/MIME.cc index e13688d81b..e597ae6275 100644 --- a/src/analyzer/protocol/mime/MIME.cc +++ b/src/analyzer/protocol/mime/MIME.cc @@ -1299,7 +1299,7 @@ RecordVal* MIME_Message::BuildHeaderVal(MIME_Header* h) TableVal* MIME_Message::BuildHeaderTable(MIME_HeaderList& hlist) { - TableVal* t = new TableVal(mime_header_list); + TableVal* t = new TableVal({NewRef{}, mime_header_list}); for ( unsigned int i = 0; i < hlist.size(); ++i ) { diff --git a/src/analyzer/protocol/mqtt/commands/connect.pac b/src/analyzer/protocol/mqtt/commands/connect.pac index 92ff4abd90..c8050ba6f8 100644 --- a/src/analyzer/protocol/mqtt/commands/connect.pac +++ b/src/analyzer/protocol/mqtt/commands/connect.pac @@ -45,12 +45,12 @@ refine flow MQTT_Flow += { if ( mqtt_connect ) { auto m = new RecordVal(BifType::Record::MQTT::ConnectMsg); - m->Assign(0, new StringVal(${msg.protocol_name.str}.length(), + m->Assign(0, make_intrusive(${msg.protocol_name.str}.length(), reinterpret_cast(${msg.protocol_name.str}.begin()))); m->Assign(1, val_mgr->GetCount(${msg.protocol_version})); - m->Assign(2, new StringVal(${msg.client_id.str}.length(), + m->Assign(2, make_intrusive(${msg.client_id.str}.length(), reinterpret_cast(${msg.client_id.str}.begin()))); - m->Assign(3, new IntervalVal(double(${msg.keep_alive}), Seconds)); + m->Assign(3, make_intrusive(double(${msg.keep_alive}), Seconds)); m->Assign(4, val_mgr->GetBool(${msg.clean_session})); m->Assign(5, val_mgr->GetBool(${msg.will_retain})); @@ -58,20 +58,20 @@ refine flow MQTT_Flow += { if ( ${msg.will_flag} ) { - m->Assign(7, new StringVal(${msg.will.topic.str}.length(), + m->Assign(7, make_intrusive(${msg.will.topic.str}.length(), reinterpret_cast(${msg.will.topic.str}.begin()))); - m->Assign(8, new StringVal(${msg.will.msg.str}.length(), + m->Assign(8, make_intrusive(${msg.will.msg.str}.length(), reinterpret_cast(${msg.will.msg.str}.begin()))); } if ( ${msg.username} ) { - m->Assign(9, new StringVal(${msg.uname.str}.length(), + m->Assign(9, make_intrusive(${msg.uname.str}.length(), reinterpret_cast(${msg.uname.str}.begin()))); } if ( ${msg.password} ) { - m->Assign(10, new StringVal(${msg.pass.str}.length(), + m->Assign(10, make_intrusive(${msg.pass.str}.length(), reinterpret_cast(${msg.pass.str}.begin()))); } diff --git a/src/analyzer/protocol/mysql/mysql-analyzer.pac b/src/analyzer/protocol/mysql/mysql-analyzer.pac index a6981e9e87..a288c554d3 100644 --- a/src/analyzer/protocol/mysql/mysql-analyzer.pac +++ b/src/analyzer/protocol/mysql/mysql-analyzer.pac @@ -87,7 +87,7 @@ refine flow MySQL_Flow += { auto& bstring = ${msg.row.first_field.val}; auto ptr = reinterpret_cast(bstring.data()); - vv->Assign(vv->Size(), new StringVal(bstring.length(), ptr)); + vv->Assign(vv->Size(), make_intrusive(bstring.length(), ptr)); auto& fields = *${msg.row.fields}; @@ -95,7 +95,7 @@ refine flow MySQL_Flow += { { auto& bstring = f->val(); auto ptr = reinterpret_cast(bstring.data()); - vv->Assign(vv->Size(), new StringVal(bstring.length(), ptr)); + vv->Assign(vv->Size(), make_intrusive(bstring.length(), ptr)); } BifEvent::generate_mysql_result_row(connection()->bro_analyzer(), diff --git a/src/analyzer/protocol/ntp/ntp-analyzer.pac b/src/analyzer/protocol/ntp/ntp-analyzer.pac index 961557b079..fe3bed6b0f 100644 --- a/src/analyzer/protocol/ntp/ntp-analyzer.pac +++ b/src/analyzer/protocol/ntp/ntp-analyzer.pac @@ -38,8 +38,8 @@ refine flow NTP_Flow += { RecordVal* rv = new RecordVal(BifType::Record::NTP::StandardMessage); rv->Assign(0, val_mgr->GetCount(${nsm.stratum})); - rv->Assign(1, new Val(pow(2, ${nsm.poll}), TYPE_INTERVAL)); - rv->Assign(2, new Val(pow(2, ${nsm.precision}), TYPE_INTERVAL)); + rv->Assign(1, make_intrusive(pow(2, ${nsm.poll}), TYPE_INTERVAL)); + rv->Assign(2, make_intrusive(pow(2, ${nsm.precision}), TYPE_INTERVAL)); rv->Assign(3, proc_ntp_short(${nsm.root_delay})); rv->Assign(4, proc_ntp_short(${nsm.root_dispersion})); @@ -55,7 +55,7 @@ refine flow NTP_Flow += { default: { const uint8* d = ${nsm.reference_id}.data(); - rv->Assign(7, new AddrVal(IPAddr(IPv4, (const uint32*) d, IPAddr::Network))); + rv->Assign(7, make_intrusive(IPAddr(IPv4, (const uint32*) d, IPAddr::Network))); } break; } diff --git a/src/analyzer/protocol/radius/radius-analyzer.pac b/src/analyzer/protocol/radius/radius-analyzer.pac index e727bc4f02..7aab1ba04e 100644 --- a/src/analyzer/protocol/radius/radius-analyzer.pac +++ b/src/analyzer/protocol/radius/radius-analyzer.pac @@ -14,13 +14,13 @@ refine flow RADIUS_Flow += { if ( ${msg.attributes}->size() ) { - TableVal* attributes = new TableVal(BifType::Table::RADIUS::Attributes); + TableVal* attributes = new TableVal({NewRef{}, BifType::Table::RADIUS::Attributes}); for ( uint i = 0; i < ${msg.attributes}->size(); ++i ) { Val* index = val_mgr->GetCount(${msg.attributes[i].code}); // Do we already have a vector of attributes for this type? - Val* current = attributes->Lookup(index); + auto current = attributes->Lookup(index); Val* val = bytestring_to_val(${msg.attributes[i].value}); if ( current ) diff --git a/src/analyzer/protocol/rpc/MOUNT.cc b/src/analyzer/protocol/rpc/MOUNT.cc index 8cdb3c20e2..7265001fe3 100644 --- a/src/analyzer/protocol/rpc/MOUNT.cc +++ b/src/analyzer/protocol/rpc/MOUNT.cc @@ -139,7 +139,7 @@ int MOUNT_Interp::RPC_BuildReply(RPC_CallInfo* c, BifEnum::rpc_status rpc_status // Otherwise DeliverRPC would complain about // excess_RPC. n = 0; - reply = BifType::Enum::MOUNT3::proc_t->GetVal(c->Proc()); + reply = BifType::Enum::MOUNT3::proc_t->GetVal(c->Proc()).release(); event = mount_proc_not_implemented; } else @@ -201,16 +201,16 @@ val_list MOUNT_Interp::event_common_vl(RPC_CallInfo *c, RecordVal* info = new RecordVal(BifType::Record::MOUNT3::info_t); info->Assign(0, BifType::Enum::rpc_status->GetVal(rpc_status)); info->Assign(1, BifType::Enum::MOUNT3::status_t->GetVal(mount_status)); - info->Assign(2, new Val(c->StartTime(), TYPE_TIME)); - info->Assign(3, new Val(c->LastTime() - c->StartTime(), TYPE_INTERVAL)); + info->Assign(2, make_intrusive(c->StartTime(), TYPE_TIME)); + info->Assign(3, make_intrusive(c->LastTime() - c->StartTime(), TYPE_INTERVAL)); info->Assign(4, val_mgr->GetCount(c->RPCLen())); - info->Assign(5, new Val(rep_start_time, TYPE_TIME)); - info->Assign(6, new Val(rep_last_time - rep_start_time, TYPE_INTERVAL)); + info->Assign(5, make_intrusive(rep_start_time, TYPE_TIME)); + info->Assign(6, make_intrusive(rep_last_time - rep_start_time, TYPE_INTERVAL)); info->Assign(7, val_mgr->GetCount(reply_len)); info->Assign(8, val_mgr->GetCount(c->Uid())); info->Assign(9, val_mgr->GetCount(c->Gid())); info->Assign(10, val_mgr->GetCount(c->Stamp())); - info->Assign(11, new StringVal(c->MachineName())); + info->Assign(11, make_intrusive(c->MachineName())); info->Assign(12, auxgids); vl.push_back(info); @@ -220,7 +220,7 @@ val_list MOUNT_Interp::event_common_vl(RPC_CallInfo *c, EnumVal* MOUNT_Interp::mount3_auth_flavor(const u_char*& buf, int& n) { BifEnum::MOUNT3::auth_flavor_t t = (BifEnum::MOUNT3::auth_flavor_t)extract_XDR_uint32(buf, n); - return BifType::Enum::MOUNT3::auth_flavor_t->GetVal(t); + return BifType::Enum::MOUNT3::auth_flavor_t->GetVal(t).release(); } StringVal* MOUNT_Interp::mount3_fh(const u_char*& buf, int& n) diff --git a/src/analyzer/protocol/rpc/NFS.cc b/src/analyzer/protocol/rpc/NFS.cc index eb9aa229ec..96b7c59c78 100644 --- a/src/analyzer/protocol/rpc/NFS.cc +++ b/src/analyzer/protocol/rpc/NFS.cc @@ -251,7 +251,7 @@ int NFS_Interp::RPC_BuildReply(RPC_CallInfo* c, BifEnum::rpc_status rpc_status, // Otherwise DeliverRPC would complain about // excess_RPC. n = 0; - reply = BifType::Enum::NFS3::proc_t->GetVal(c->Proc()); + reply = BifType::Enum::NFS3::proc_t->GetVal(c->Proc()).release(); event = nfs_proc_not_implemented; } else @@ -335,16 +335,16 @@ val_list NFS_Interp::event_common_vl(RPC_CallInfo *c, BifEnum::rpc_status rpc_st RecordVal *info = new RecordVal(BifType::Record::NFS3::info_t); info->Assign(0, BifType::Enum::rpc_status->GetVal(rpc_status)); info->Assign(1, BifType::Enum::NFS3::status_t->GetVal(nfs_status)); - info->Assign(2, new Val(c->StartTime(), TYPE_TIME)); - info->Assign(3, new Val(c->LastTime()-c->StartTime(), TYPE_INTERVAL)); + info->Assign(2, make_intrusive(c->StartTime(), TYPE_TIME)); + info->Assign(3, make_intrusive(c->LastTime()-c->StartTime(), TYPE_INTERVAL)); info->Assign(4, val_mgr->GetCount(c->RPCLen())); - info->Assign(5, new Val(rep_start_time, TYPE_TIME)); - info->Assign(6, new Val(rep_last_time-rep_start_time, TYPE_INTERVAL)); + info->Assign(5, make_intrusive(rep_start_time, TYPE_TIME)); + info->Assign(6, make_intrusive(rep_last_time-rep_start_time, TYPE_INTERVAL)); info->Assign(7, val_mgr->GetCount(reply_len)); info->Assign(8, val_mgr->GetCount(c->Uid())); info->Assign(9, val_mgr->GetCount(c->Gid())); info->Assign(10, val_mgr->GetCount(c->Stamp())); - info->Assign(11, new StringVal(c->MachineName())); + info->Assign(11, make_intrusive(c->MachineName())); info->Assign(12, auxgids); vl.push_back(info); @@ -437,13 +437,13 @@ RecordVal* NFS_Interp::nfs3_fattr(const u_char*& buf, int& n) EnumVal* NFS_Interp::nfs3_time_how(const u_char*& buf, int& n) { BifEnum::NFS3::time_how_t t = (BifEnum::NFS3::time_how_t)extract_XDR_uint32(buf, n); - return BifType::Enum::NFS3::time_how_t->GetVal(t); + return BifType::Enum::NFS3::time_how_t->GetVal(t).release(); } EnumVal* NFS_Interp::nfs3_ftype(const u_char*& buf, int& n) { BifEnum::NFS3::file_type_t t = (BifEnum::NFS3::file_type_t)extract_XDR_uint32(buf, n); - return BifType::Enum::NFS3::file_type_t->GetVal(t); + return BifType::Enum::NFS3::file_type_t->GetVal(t).release(); } RecordVal* NFS_Interp::nfs3_wcc_attr(const u_char*& buf, int& n) @@ -532,7 +532,7 @@ RecordVal* NFS_Interp::nfs3_pre_op_attr(const u_char*& buf, int& n) EnumVal *NFS_Interp::nfs3_stable_how(const u_char*& buf, int& n) { BifEnum::NFS3::stable_how_t stable = (BifEnum::NFS3::stable_how_t)extract_XDR_uint32(buf, n); - return BifType::Enum::NFS3::stable_how_t->GetVal(stable); + return BifType::Enum::NFS3::stable_how_t->GetVal(stable).release(); } RecordVal* NFS_Interp::nfs3_lookup_reply(const u_char*& buf, int& n, BifEnum::NFS3::status_t status) diff --git a/src/analyzer/protocol/rpc/Portmap.cc b/src/analyzer/protocol/rpc/Portmap.cc index d1dafc49c5..2b3445ec20 100644 --- a/src/analyzer/protocol/rpc/Portmap.cc +++ b/src/analyzer/protocol/rpc/Portmap.cc @@ -139,7 +139,7 @@ int PortmapperInterp::RPC_BuildReply(RPC_CallInfo* c, BifEnum::rpc_status status event = success ? pm_request_dump : pm_attempt_dump; if ( success ) { - TableVal* mappings = new TableVal(pm_mappings); + TableVal* mappings = new TableVal({NewRef{}, pm_mappings}); uint32_t nmap = 0; // Each call in the loop test pulls the next "opted" @@ -295,7 +295,7 @@ void PortmapperInterp::Event(EventHandlerPtr f, Val* request, BifEnum::rpc_statu } else { - vl.push_back(BifType::Enum::rpc_status->GetVal(status)); + vl.push_back(BifType::Enum::rpc_status->GetVal(status).release()); if ( request ) vl.push_back(request); } diff --git a/src/analyzer/protocol/rpc/RPC.cc b/src/analyzer/protocol/rpc/RPC.cc index 9a87117435..b76cd7d643 100644 --- a/src/analyzer/protocol/rpc/RPC.cc +++ b/src/analyzer/protocol/rpc/RPC.cc @@ -344,7 +344,7 @@ void RPC_Interpreter::Event_RPC_Dialogue(RPC_CallInfo* c, BifEnum::rpc_status st val_mgr->GetCount(c->Program()), val_mgr->GetCount(c->Version()), val_mgr->GetCount(c->Proc()), - BifType::Enum::rpc_status->GetVal(status), + BifType::Enum::rpc_status->GetVal(status).release(), new Val(c->StartTime(), TYPE_TIME), val_mgr->GetCount(c->CallLen()), val_mgr->GetCount(reply_len), @@ -374,7 +374,7 @@ void RPC_Interpreter::Event_RPC_Reply(uint32_t xid, BifEnum::rpc_status status, analyzer->ConnectionEventFast(rpc_reply, { analyzer->BuildConnVal(), val_mgr->GetCount(xid), - BifType::Enum::rpc_status->GetVal(status), + BifType::Enum::rpc_status->GetVal(status).release(), val_mgr->GetCount(reply_len), }); } diff --git a/src/analyzer/protocol/sip/sip-analyzer.pac b/src/analyzer/protocol/sip/sip-analyzer.pac index 1d8e6dad5a..f8b77e68e8 100644 --- a/src/analyzer/protocol/sip/sip-analyzer.pac +++ b/src/analyzer/protocol/sip/sip-analyzer.pac @@ -65,7 +65,7 @@ refine flow SIP_Flow += { function build_sip_headers_val(): BroVal %{ - TableVal* t = new TableVal(mime_header_list); + TableVal* t = new TableVal({NewRef{}, mime_header_list}); for ( unsigned int i = 0; i < headers.size(); ++i ) { // index starting from 1 diff --git a/src/analyzer/protocol/socks/socks-analyzer.pac b/src/analyzer/protocol/socks/socks-analyzer.pac index b0ec62e2b9..726ccb8d0a 100644 --- a/src/analyzer/protocol/socks/socks-analyzer.pac +++ b/src/analyzer/protocol/socks/socks-analyzer.pac @@ -25,7 +25,7 @@ refine connection SOCKS_Conn += { if ( socks_request ) { RecordVal* sa = new RecordVal(socks_address); - sa->Assign(0, new AddrVal(htonl(${request.addr}))); + sa->Assign(0, make_intrusive(htonl(${request.addr}))); if ( ${request.v4a} ) sa->Assign(1, array_to_string(${request.name})); @@ -49,7 +49,7 @@ refine connection SOCKS_Conn += { if ( socks_reply ) { RecordVal* sa = new RecordVal(socks_address); - sa->Assign(0, new AddrVal(htonl(${reply.addr}))); + sa->Assign(0, make_intrusive(htonl(${reply.addr}))); BifEvent::generate_socks_reply(bro_analyzer(), bro_analyzer()->Conn(), @@ -86,16 +86,16 @@ refine connection SOCKS_Conn += { switch ( ${request.remote_name.addr_type} ) { case 1: - sa->Assign(0, new AddrVal(htonl(${request.remote_name.ipv4}))); + sa->Assign(0, make_intrusive(htonl(${request.remote_name.ipv4}))); break; case 3: - sa->Assign(1, new StringVal(${request.remote_name.domain_name.name}.length(), + sa->Assign(1, make_intrusive(${request.remote_name.domain_name.name}.length(), (const char*) ${request.remote_name.domain_name.name}.data())); break; case 4: - sa->Assign(0, new AddrVal(IPAddr(IPv6, (const uint32_t*) ${request.remote_name.ipv6}, IPAddr::Network))); + sa->Assign(0, make_intrusive(IPAddr(IPv6, (const uint32_t*) ${request.remote_name.ipv6}, IPAddr::Network))); break; default: @@ -128,16 +128,16 @@ refine connection SOCKS_Conn += { switch ( ${reply.bound.addr_type} ) { case 1: - sa->Assign(0, new AddrVal(htonl(${reply.bound.ipv4}))); + sa->Assign(0, make_intrusive(htonl(${reply.bound.ipv4}))); break; case 3: - sa->Assign(1, new StringVal(${reply.bound.domain_name.name}.length(), + sa->Assign(1, make_intrusive(${reply.bound.domain_name.name}.length(), (const char*) ${reply.bound.domain_name.name}.data())); break; case 4: - sa->Assign(0, new AddrVal(IPAddr(IPv6, (const uint32_t*) ${reply.bound.ipv6}, IPAddr::Network))); + sa->Assign(0, make_intrusive(IPAddr(IPv6, (const uint32_t*) ${reply.bound.ipv6}, IPAddr::Network))); break; default: diff --git a/src/analyzer/protocol/ssh/ssh-analyzer.pac b/src/analyzer/protocol/ssh/ssh-analyzer.pac index f9c41755d4..38e450f69a 100644 --- a/src/analyzer/protocol/ssh/ssh-analyzer.pac +++ b/src/analyzer/protocol/ssh/ssh-analyzer.pac @@ -32,7 +32,7 @@ VectorVal* name_list_to_vector(const bytestring& nl) { word = name_list.substr(start, split_pos - start); if ( word.size() > 0 && word[0] != ',' ) - vv->Assign(vv->Size(), new StringVal(word)); + vv->Assign(vv->Size(), make_intrusive(word)); start = split_pos + 1; } @@ -41,7 +41,7 @@ VectorVal* name_list_to_vector(const bytestring& nl) if ( start < name_list.size() ) { word = name_list.substr(start, name_list.size() - start); - vv->Assign(vv->Size(), new StringVal(word)); + vv->Assign(vv->Size(), make_intrusive(word)); } return vv; } diff --git a/src/analyzer/protocol/ssl/tls-handshake-analyzer.pac b/src/analyzer/protocol/ssl/tls-handshake-analyzer.pac index 583ae33f30..45b7c636d4 100644 --- a/src/analyzer/protocol/ssl/tls-handshake-analyzer.pac +++ b/src/analyzer/protocol/ssl/tls-handshake-analyzer.pac @@ -183,7 +183,7 @@ refine connection Handshake_Conn += { if ( protocols ) { for ( unsigned int i = 0; i < protocols->size(); ++i ) - plist->Assign(i, new StringVal((*protocols)[i]->name().length(), (const char*) (*protocols)[i]->name().data())); + plist->Assign(i, make_intrusive((*protocols)[i]->name().length(), (const char*) (*protocols)[i]->name().data())); } BifEvent::generate_ssl_extension_application_layer_protocol_negotiation(bro_analyzer(), bro_analyzer()->Conn(), @@ -208,7 +208,7 @@ refine connection Handshake_Conn += { } if ( servername->host_name() ) - servers->Assign(j++, new StringVal(servername->host_name()->host_name().length(), (const char*) servername->host_name()->host_name().data())); + servers->Assign(j++, make_intrusive(servername->host_name()->host_name().length(), (const char*) servername->host_name()->host_name().data())); else bro_analyzer()->Weird("Empty server_name extension in ssl connection"); } @@ -487,7 +487,7 @@ refine connection Handshake_Conn += { for ( auto&& identity : *(identities->identities()) ) { RecordVal* el = new RecordVal(BifType::Record::SSL::PSKIdentity); - el->Assign(0, new StringVal(identity->identity().length(), (const char*) identity->identity().data())); + el->Assign(0, make_intrusive(identity->identity().length(), (const char*) identity->identity().data())); el->Assign(1, val_mgr->GetCount(identity->obfuscated_ticket_age())); slist->Assign(slist->Size(), el); } @@ -497,7 +497,7 @@ refine connection Handshake_Conn += { if ( binders && binders->binders() ) { for ( auto&& binder : *(binders->binders()) ) - blist->Assign(blist->Size(), new StringVal(binder->binder().length(), (const char*) binder->binder().data())); + blist->Assign(blist->Size(), make_intrusive(binder->binder().length(), (const char*) binder->binder().data())); } BifEvent::generate_ssl_extension_pre_shared_key_client_hello(bro_analyzer(), bro_analyzer()->Conn(), diff --git a/src/analyzer/protocol/tcp/TCP.cc b/src/analyzer/protocol/tcp/TCP.cc index a19f425df3..256bce19cc 100644 --- a/src/analyzer/protocol/tcp/TCP.cc +++ b/src/analyzer/protocol/tcp/TCP.cc @@ -1366,7 +1366,7 @@ int TCP_Analyzer::ParseTCPOptions(const struct tcphdr* tcp, bool is_orig) auto data_len = olen - 2; auto data = reinterpret_cast(odata + 2); - rv->Assign(2, new StringVal(data_len, data)); + rv->Assign(2, make_intrusive(data_len, data)); }; for ( const auto& o : opts ) diff --git a/src/analyzer/protocol/tcp/TCP_Reassembler.cc b/src/analyzer/protocol/tcp/TCP_Reassembler.cc index 4ae9305145..23b400e585 100644 --- a/src/analyzer/protocol/tcp/TCP_Reassembler.cc +++ b/src/analyzer/protocol/tcp/TCP_Reassembler.cc @@ -47,7 +47,7 @@ TCP_Reassembler::TCP_Reassembler(analyzer::Analyzer* arg_dst_analyzer, TableVal* ports = IsOrig() ? tcp_content_delivery_ports_orig : tcp_content_delivery_ports_resp; - Val* result = ports->Lookup(dst_port_val); + auto result = ports->Lookup(dst_port_val); if ( (IsOrig() && tcp_content_deliver_all_orig) || (! IsOrig() && tcp_content_deliver_all_resp) || diff --git a/src/analyzer/protocol/teredo/Teredo.cc b/src/analyzer/protocol/teredo/Teredo.cc index cccb400ef2..7f2b134b54 100644 --- a/src/analyzer/protocol/teredo/Teredo.cc +++ b/src/analyzer/protocol/teredo/Teredo.cc @@ -118,9 +118,9 @@ RecordVal* TeredoEncapsulation::BuildVal(const IP_Hdr* inner) const uint8_t au_len = *((uint8_t*)(auth + 3)); uint64_t nonce = ntohll(*((uint64_t*)(auth + 4 + id_len + au_len))); uint8_t conf = *((uint8_t*)(auth + 4 + id_len + au_len + 8)); - teredo_auth->Assign(0, new StringVal( + teredo_auth->Assign(0, make_intrusive( new BroString(auth + 4, id_len, 1))); - teredo_auth->Assign(1, new StringVal( + teredo_auth->Assign(1, make_intrusive( new BroString(auth + 4 + id_len, au_len, 1))); teredo_auth->Assign(2, val_mgr->GetCount(nonce)); teredo_auth->Assign(3, val_mgr->GetCount(conf)); @@ -133,7 +133,7 @@ RecordVal* TeredoEncapsulation::BuildVal(const IP_Hdr* inner) const uint16_t port = ntohs(*((uint16_t*)(origin_indication + 2))) ^ 0xFFFF; uint32_t addr = ntohl(*((uint32_t*)(origin_indication + 4))) ^ 0xFFFFFFFF; teredo_origin->Assign(0, val_mgr->GetPort(port, TRANSPORT_UDP)); - teredo_origin->Assign(1, new AddrVal(htonl(addr))); + teredo_origin->Assign(1, make_intrusive(htonl(addr))); teredo_hdr->Assign(1, teredo_origin); } diff --git a/src/analyzer/protocol/udp/UDP.cc b/src/analyzer/protocol/udp/UDP.cc index 06a971398d..4be93e49f7 100644 --- a/src/analyzer/protocol/udp/UDP.cc +++ b/src/analyzer/protocol/udp/UDP.cc @@ -135,23 +135,20 @@ void UDP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, if ( udp_contents ) { auto port_val = val_mgr->GetPort(ntohs(up->uh_dport), TRANSPORT_UDP); - Val* result = 0; bool do_udp_contents = false; if ( is_orig ) { - result = udp_content_delivery_ports_orig->Lookup( - port_val); - if ( udp_content_deliver_all_orig || - (result && result->AsBool()) ) + auto result = udp_content_delivery_ports_orig->Lookup(port_val); + + if ( udp_content_deliver_all_orig || (result && result->AsBool()) ) do_udp_contents = true; } else { - result = udp_content_delivery_ports_resp->Lookup( - port_val); - if ( udp_content_deliver_all_resp || - (result && result->AsBool()) ) + auto result = udp_content_delivery_ports_resp->Lookup(port_val); + + if ( udp_content_deliver_all_resp || (result && result->AsBool()) ) do_udp_contents = true; } diff --git a/src/broker/Data.cc b/src/broker/Data.cc index 7a92998fd2..f8de5c4415 100644 --- a/src/broker/Data.cc +++ b/src/broker/Data.cc @@ -196,7 +196,7 @@ struct val_converter { if ( i == -1 ) return nullptr; - return etype->GetVal(i); + return etype->GetVal(i).release(); } return nullptr; @@ -208,7 +208,7 @@ struct val_converter { return nullptr; auto tt = type->AsTableType(); - auto rval = make_intrusive(tt); + auto rval = make_intrusive(IntrusivePtr{NewRef{}, tt}); for ( auto& item : a ) { @@ -268,7 +268,7 @@ struct val_converter { return nullptr; auto tt = type->AsTableType(); - auto rval = make_intrusive(tt); + auto rval = make_intrusive(IntrusivePtr{NewRef{}, tt}); for ( auto& item : a ) { @@ -321,7 +321,7 @@ struct val_converter { if ( ! value_val ) return nullptr; - rval->Assign(list_val.get(), value_val.release()); + rval->Assign(list_val.get(), std::move(value_val)); } return rval.release(); @@ -341,7 +341,7 @@ struct val_converter { if ( ! item_val ) return nullptr; - rval->Assign(rval->Size(), item_val.release()); + rval->Assign(rval->Size(), std::move(item_val)); } return rval.release(); @@ -410,7 +410,7 @@ struct val_converter { if ( ! item_val ) return nullptr; - rval->Assign(i, item_val.release()); + rval->Assign(i, std::move(item_val)); ++idx; } @@ -997,8 +997,7 @@ broker::expected bro_broker::val_to_data(const Val* v) continue; } - auto item = val_to_data(item_val); - Unref(item_val); + auto item = val_to_data(item_val.get()); if ( ! item ) return broker::ec::invalid_data; @@ -1040,7 +1039,7 @@ RecordVal* bro_broker::make_data_val(Val* v) auto data = val_to_data(v); if ( data ) - rval->Assign(0, new DataVal(move(*data))); + rval->Assign(0, make_intrusive(move(*data))); else reporter->Warning("did not get a value from val_to_data"); @@ -1050,7 +1049,7 @@ RecordVal* bro_broker::make_data_val(Val* v) RecordVal* bro_broker::make_data_val(broker::data d) { auto rval = new RecordVal(BifType::Record::Broker::Data); - rval->Assign(0, new DataVal(move(d))); + rval->Assign(0, make_intrusive(move(d))); return rval; } @@ -1059,72 +1058,72 @@ struct data_type_getter { result_type operator()(broker::none) { - return BifType::Enum::Broker::DataType->GetVal(BifEnum::Broker::NONE); + return BifType::Enum::Broker::DataType->GetVal(BifEnum::Broker::NONE).release(); } result_type operator()(bool) { - return BifType::Enum::Broker::DataType->GetVal(BifEnum::Broker::BOOL); + return BifType::Enum::Broker::DataType->GetVal(BifEnum::Broker::BOOL).release(); } result_type operator()(uint64_t) { - return BifType::Enum::Broker::DataType->GetVal(BifEnum::Broker::COUNT); + return BifType::Enum::Broker::DataType->GetVal(BifEnum::Broker::COUNT).release(); } result_type operator()(int64_t) { - return BifType::Enum::Broker::DataType->GetVal(BifEnum::Broker::INT); + return BifType::Enum::Broker::DataType->GetVal(BifEnum::Broker::INT).release(); } result_type operator()(double) { - return BifType::Enum::Broker::DataType->GetVal(BifEnum::Broker::DOUBLE); + return BifType::Enum::Broker::DataType->GetVal(BifEnum::Broker::DOUBLE).release(); } result_type operator()(const std::string&) { - return BifType::Enum::Broker::DataType->GetVal(BifEnum::Broker::STRING); + return BifType::Enum::Broker::DataType->GetVal(BifEnum::Broker::STRING).release(); } result_type operator()(const broker::address&) { - return BifType::Enum::Broker::DataType->GetVal(BifEnum::Broker::ADDR); + return BifType::Enum::Broker::DataType->GetVal(BifEnum::Broker::ADDR).release(); } result_type operator()(const broker::subnet&) { - return BifType::Enum::Broker::DataType->GetVal(BifEnum::Broker::SUBNET); + return BifType::Enum::Broker::DataType->GetVal(BifEnum::Broker::SUBNET).release(); } result_type operator()(const broker::port&) { - return BifType::Enum::Broker::DataType->GetVal(BifEnum::Broker::PORT); + return BifType::Enum::Broker::DataType->GetVal(BifEnum::Broker::PORT).release(); } result_type operator()(const broker::timestamp&) { - return BifType::Enum::Broker::DataType->GetVal(BifEnum::Broker::TIME); + return BifType::Enum::Broker::DataType->GetVal(BifEnum::Broker::TIME).release(); } result_type operator()(const broker::timespan&) { - return BifType::Enum::Broker::DataType->GetVal(BifEnum::Broker::INTERVAL); + return BifType::Enum::Broker::DataType->GetVal(BifEnum::Broker::INTERVAL).release(); } result_type operator()(const broker::enum_value&) { - return BifType::Enum::Broker::DataType->GetVal(BifEnum::Broker::ENUM); + return BifType::Enum::Broker::DataType->GetVal(BifEnum::Broker::ENUM).release(); } result_type operator()(const broker::set&) { - return BifType::Enum::Broker::DataType->GetVal(BifEnum::Broker::SET); + return BifType::Enum::Broker::DataType->GetVal(BifEnum::Broker::SET).release(); } result_type operator()(const broker::table&) { - return BifType::Enum::Broker::DataType->GetVal(BifEnum::Broker::TABLE); + return BifType::Enum::Broker::DataType->GetVal(BifEnum::Broker::TABLE).release(); } result_type operator()(const broker::vector&) @@ -1132,7 +1131,7 @@ struct data_type_getter { // Note that Broker uses vectors to store record data, so there's // no actual way to tell if this data was originally associated // with a Bro record. - return BifType::Enum::Broker::DataType->GetVal(BifEnum::Broker::VECTOR); + return BifType::Enum::Broker::DataType->GetVal(BifEnum::Broker::VECTOR).release(); } }; diff --git a/src/broker/Manager.cc b/src/broker/Manager.cc index 0a24a5ebc4..6fbf0f06f4 100644 --- a/src/broker/Manager.cc +++ b/src/broker/Manager.cc @@ -158,7 +158,7 @@ void Manager::InitPostScript() opaque_of_vector_iterator = new OpaqueType("Broker::VectorIterator"); opaque_of_record_iterator = new OpaqueType("Broker::RecordIterator"); opaque_of_store_handle = new OpaqueType("Broker::Store"); - vector_of_data_type = new VectorType(internal_type("Broker::Data")->Ref()); + vector_of_data_type = new VectorType({NewRef{}, internal_type("Broker::Data")}); // Register as a "dont-count" source first, we may change that later. iosource_mgr->Register(this, true); @@ -550,7 +550,7 @@ bool Manager::PublishLogWrite(EnumVal* stream, EnumVal* writer, string path, int new StringVal(path), }; - Val* v = log_topic_func->Call(&vl); + auto v = log_topic_func->Call(&vl); if ( ! v ) { @@ -561,7 +561,6 @@ bool Manager::PublishLogWrite(EnumVal* stream, EnumVal* writer, string path, int } std::string topic = v->AsString()->CheckString(); - Unref(v); auto bstream_id = broker::enum_value(move(stream_id)); auto bwriter_id = broker::enum_value(move(writer_id)); @@ -734,7 +733,7 @@ RecordVal* Manager::MakeEvent(val_list* args, Frame* frame) return rval; } - rval->Assign(0, new StringVal(func->Name())); + rval->Assign(0, make_intrusive(func->Name())); continue; } @@ -1252,24 +1251,24 @@ void Manager::ProcessStatus(broker::status stat) if ( ctx ) { - endpoint_info->Assign(0, new StringVal(to_string(ctx->node))); + endpoint_info->Assign(0, make_intrusive(to_string(ctx->node))); auto ni = internal_type("Broker::NetworkInfo")->AsRecordType(); - auto network_info = new RecordVal(ni); + auto network_info = make_intrusive(ni); if ( ctx->network ) { - network_info->Assign(0, new StringVal(ctx->network->address.data())); + network_info->Assign(0, make_intrusive(ctx->network->address.data())); network_info->Assign(1, val_mgr->GetPort(ctx->network->port, TRANSPORT_TCP)); } else { // TODO: are there any status messages where the ctx->network // is not set and actually could be? - network_info->Assign(0, new StringVal("")); + network_info->Assign(0, make_intrusive("")); network_info->Assign(1, val_mgr->GetPort(0, TRANSPORT_TCP)); } - endpoint_info->Assign(1, network_info); + endpoint_info->Assign(1, std::move(network_info)); } auto str = stat.message(); @@ -1353,7 +1352,7 @@ void Manager::ProcessError(broker::error err) } mgr.QueueEventFast(Broker::error, { - BifType::Enum::Broker::ErrorCode->GetVal(ec), + BifType::Enum::Broker::ErrorCode->GetVal(ec).release(), new StringVal(msg), }); } diff --git a/src/broker/Store.cc b/src/broker/Store.cc index c542ff45c2..81138edcd9 100644 --- a/src/broker/Store.cc +++ b/src/broker/Store.cc @@ -20,7 +20,7 @@ EnumVal* query_status(bool success) failure_val = store_query_status->Lookup("Broker", "FAILURE"); } - return store_query_status->GetVal(success ? success_val : failure_val); + return store_query_status->GetVal(success ? success_val : failure_val).release(); } void StoreHandleVal::ValDescribe(ODesc* d) const diff --git a/src/broker/Store.h b/src/broker/Store.h index 48c435191e..dc1ff844df 100644 --- a/src/broker/Store.h +++ b/src/broker/Store.h @@ -28,7 +28,7 @@ inline RecordVal* query_result() { auto rval = new RecordVal(BifType::Record::Broker::QueryResult); rval->Assign(0, query_status(false)); - rval->Assign(1, new RecordVal(BifType::Record::Broker::Data)); + rval->Assign(1, make_intrusive(BifType::Record::Broker::Data)); return rval; } diff --git a/src/broker/comm.bif b/src/broker/comm.bif index 660701e058..8748788622 100644 --- a/src/broker/comm.bif +++ b/src/broker/comm.bif @@ -109,16 +109,16 @@ function Broker::__peers%(%): PeerInfos if ( n ) { - network_info->Assign(0, new AddrVal(IPAddr(n->address))); + network_info->Assign(0, make_intrusive(IPAddr(n->address))); network_info->Assign(1, val_mgr->GetPort(n->port, TRANSPORT_TCP)); } else { - network_info->Assign(0, new AddrVal("0.0.0.0")); + network_info->Assign(0, make_intrusive("0.0.0.0")); network_info->Assign(1, val_mgr->GetPort(0, TRANSPORT_TCP)); } - endpoint_info->Assign(0, new StringVal(to_string(p.peer.node))); + endpoint_info->Assign(0, make_intrusive(to_string(p.peer.node))); endpoint_info->Assign(1, network_info); auto ps = (BifEnum::Broker::PeerStatus)p.status; diff --git a/src/broker/data.bif b/src/broker/data.bif index 15fa215756..7daca31b14 100644 --- a/src/broker/data.bif +++ b/src/broker/data.bif @@ -154,7 +154,7 @@ function Broker::__set_iterator_value%(it: opaque of Broker::SetIterator%): Brok return rval; } - rval->Assign(0, new bro_broker::DataVal(*set_it->it)); + rval->Assign(0, make_intrusive(*set_it->it)); return rval; %} @@ -312,8 +312,8 @@ function Broker::__table_iterator_value%(it: opaque of Broker::TableIterator%): return rval; } - key_val->Assign(0, new bro_broker::DataVal(ti->it->first)); - val_val->Assign(0, new bro_broker::DataVal(ti->it->second)); + key_val->Assign(0, make_intrusive(ti->it->first)); + val_val->Assign(0, make_intrusive(ti->it->second)); return rval; %} @@ -431,7 +431,7 @@ function Broker::__vector_iterator_value%(it: opaque of Broker::VectorIterator%) return rval; } - rval->Assign(0, new bro_broker::DataVal(*vi->it)); + rval->Assign(0, make_intrusive(*vi->it)); return rval; %} @@ -513,6 +513,6 @@ function Broker::__record_iterator_value%(it: opaque of Broker::RecordIterator%) if ( caf::get_if(&(*ri->it)) ) return rval; // field isn't set - rval->Assign(0, new bro_broker::DataVal(*ri->it)); + rval->Assign(0, make_intrusive(*ri->it)); return rval; %} diff --git a/src/broker/messaging.bif b/src/broker/messaging.bif index 1bc950d2cc..1e1ef1eabd 100644 --- a/src/broker/messaging.bif +++ b/src/broker/messaging.bif @@ -187,10 +187,7 @@ function Cluster::publish_rr%(pool: Pool, key: string, ...%): bool auto topic = topic_func->Call(&vl); if ( ! topic->AsString()->Len() ) - { - Unref(topic); return val_mgr->GetFalse(); - } val_list* bif_args = @ARGS@; val_list args(bif_args->length() - 2); @@ -199,7 +196,6 @@ function Cluster::publish_rr%(pool: Pool, key: string, ...%): bool args.push_back((*bif_args)[i]); auto rval = publish_event_args(args, topic->AsString(), frame); - Unref(topic); return val_mgr->GetBool(rval); %} @@ -228,10 +224,7 @@ function Cluster::publish_hrw%(pool: Pool, key: any, ...%): bool auto topic = topic_func->Call(&vl); if ( ! topic->AsString()->Len() ) - { - Unref(topic); return val_mgr->GetFalse(); - } val_list* bif_args = @ARGS@; val_list args(bif_args->length() - 2); @@ -240,6 +233,5 @@ function Cluster::publish_hrw%(pool: Pool, key: any, ...%): bool args.push_back((*bif_args)[i]); auto rval = publish_event_args(args, topic->AsString(), frame); - Unref(topic); return val_mgr->GetBool(rval); %} diff --git a/src/file_analysis/AnalyzerSet.cc b/src/file_analysis/AnalyzerSet.cc index 53c677eff3..e2eed8e4ac 100644 --- a/src/file_analysis/AnalyzerSet.cc +++ b/src/file_analysis/AnalyzerSet.cc @@ -21,8 +21,8 @@ static void analyzer_del_func(void* v) AnalyzerSet::AnalyzerSet(File* arg_file) : file(arg_file) { auto t = make_intrusive(); - t->Append(file_mgr->GetTagEnumType()->Ref()); - t->Append(BifType::Record::Files::AnalyzerArgs->Ref()); + t->Append({NewRef{}, file_mgr->GetTagEnumType()}); + t->Append({NewRef{}, BifType::Record::Files::AnalyzerArgs}); analyzer_hash = new CompositeHash(std::move(t)); analyzer_map.SetDeleteFunc(analyzer_del_func); } diff --git a/src/file_analysis/File.cc b/src/file_analysis/File.cc index 131bb7cbef..3c88c90511 100644 --- a/src/file_analysis/File.cc +++ b/src/file_analysis/File.cc @@ -23,20 +23,19 @@ using namespace file_analysis; static Val* empty_connection_table() { - TypeList* tbl_index = new TypeList(conn_id); - tbl_index->Append(conn_id->Ref()); - TableType* tbl_type = new TableType(tbl_index, connection_type->Ref()); - Val* rval = new TableVal(tbl_type); - Unref(tbl_type); - return rval; + auto tbl_index = make_intrusive(IntrusivePtr{NewRef{}, conn_id}); + tbl_index->Append({NewRef{}, conn_id}); + auto tbl_type = make_intrusive(std::move(tbl_index), + IntrusivePtr{NewRef{}, connection_type}); + return new TableVal(std::move(tbl_type)); } static RecordVal* get_conn_id_val(const Connection* conn) { RecordVal* v = new RecordVal(conn_id); - v->Assign(0, new AddrVal(conn->OrigAddr())); + v->Assign(0, make_intrusive(conn->OrigAddr())); v->Assign(1, val_mgr->GetPort(ntohs(conn->OrigPort()), conn->ConnTransport())); - v->Assign(2, new AddrVal(conn->RespAddr())); + v->Assign(2, make_intrusive(conn->RespAddr())); v->Assign(3, val_mgr->GetPort(ntohs(conn->RespPort()), conn->ConnTransport())); return v; } @@ -93,7 +92,7 @@ File::File(const string& file_id, const string& source_name, Connection* conn, DBG_LOG(DBG_FILE_ANALYSIS, "[%s] Creating new File object", file_id.c_str()); val = new RecordVal(fa_file_type); - val->Assign(id_idx, new StringVal(file_id.c_str())); + val->Assign(id_idx, make_intrusive(file_id.c_str())); SetSource(source_name); if ( conn ) @@ -117,7 +116,7 @@ File::~File() void File::UpdateLastActivityTime() { - val->Assign(last_active_idx, new Val(network_time, TYPE_TIME)); + val->Assign(last_active_idx, make_intrusive(network_time, TYPE_TIME)); } double File::GetLastActivityTime() const @@ -165,18 +164,14 @@ void File::RaiseFileOverNewConnection(Connection* conn, bool is_orig) uint64_t File::LookupFieldDefaultCount(int idx) const { - Val* v = val->LookupWithDefault(idx); - uint64_t rval = v->AsCount(); - Unref(v); - return rval; + auto v = val->LookupWithDefault(idx); + return v->AsCount(); } double File::LookupFieldDefaultInterval(int idx) const { - Val* v = val->LookupWithDefault(idx); - double rval = v->AsInterval(); - Unref(v); - return rval; + auto v = val->LookupWithDefault(idx); + return v->AsInterval(); } int File::Idx(const string& field, const RecordType* type) @@ -199,7 +194,7 @@ string File::GetSource() const void File::SetSource(const string& source) { - val->Assign(source_idx, new StringVal(source.c_str())); + val->Assign(source_idx, make_intrusive(source.c_str())); } double File::GetTimeoutInterval() const @@ -209,7 +204,7 @@ double File::GetTimeoutInterval() const void File::SetTimeoutInterval(double interval) { - val->Assign(timeout_interval_idx, new Val(interval, TYPE_INTERVAL)); + val->Assign(timeout_interval_idx, make_intrusive(interval, TYPE_INTERVAL)); } bool File::SetExtractionLimit(RecordVal* args, uint64_t bytes) @@ -305,7 +300,7 @@ bool File::SetMime(const string& mime_type) return false; RecordVal* meta = new RecordVal(fa_metadata_type); - meta->Assign(meta_mime_type_idx, new StringVal(mime_type)); + meta->Assign(meta_mime_type_idx, make_intrusive(mime_type)); meta->Assign(meta_inferred_idx, val_mgr->GetBool(0)); FileEvent(file_sniff, {val->Ref(), meta}); @@ -369,7 +364,7 @@ bool File::BufferBOF(const u_char* data, uint64_t len) if ( bof_buffer.size > 0 ) { BroString* bs = concatenate(bof_buffer.chunks); - val->Assign(bof_buffer_idx, new StringVal(bs)); + val->Assign(bof_buffer_idx, make_intrusive(bs)); } return false; diff --git a/src/file_analysis/Manager.cc b/src/file_analysis/Manager.cc index 36fa76e9f8..a36aa54c0a 100644 --- a/src/file_analysis/Manager.cc +++ b/src/file_analysis/Manager.cc @@ -449,16 +449,13 @@ bool Manager::IsDisabled(const analyzer::Tag& tag) disabled = internal_const_val("Files::disable")->AsTableVal(); Val* index = val_mgr->GetCount(bool(tag)); - Val* yield = disabled->Lookup(index); + auto yield = disabled->Lookup(index); Unref(index); if ( ! yield ) return false; - bool rval = yield->AsBool(); - Unref(yield); - - return rval; + return yield->AsBool(); } Analyzer* Manager::InstantiateAnalyzer(const Tag& tag, RecordVal* args, File* f) const @@ -528,7 +525,7 @@ VectorVal* file_analysis::GenMIMEMatchesVal(const RuleMatcher::MIME_Matches& m) it2 != it->second.end(); ++it2 ) { element->Assign(0, val_mgr->GetInt(it->first)); - element->Assign(1, new StringVal(*it2)); + element->Assign(1, make_intrusive(*it2)); } rval->Assign(rval->Size(), element); diff --git a/src/file_analysis/analyzer/data_event/DataEvent.cc b/src/file_analysis/analyzer/data_event/DataEvent.cc index 7614127ea7..80e2de25e7 100644 --- a/src/file_analysis/analyzer/data_event/DataEvent.cc +++ b/src/file_analysis/analyzer/data_event/DataEvent.cc @@ -21,8 +21,8 @@ DataEvent::DataEvent(RecordVal* args, File* file, file_analysis::Analyzer* DataEvent::Instantiate(RecordVal* args, File* file) { - Val* chunk_val = args->Lookup("chunk_event"); - Val* stream_val = args->Lookup("stream_event"); + auto chunk_val = args->Lookup("chunk_event"); + auto stream_val = args->Lookup("stream_event"); if ( ! chunk_val && ! stream_val ) return 0; diff --git a/src/file_analysis/analyzer/entropy/Entropy.cc b/src/file_analysis/analyzer/entropy/Entropy.cc index 6a3bf23f12..959babfb3a 100644 --- a/src/file_analysis/analyzer/entropy/Entropy.cc +++ b/src/file_analysis/analyzer/entropy/Entropy.cc @@ -61,11 +61,11 @@ void Entropy::Finalize() entropy->Get(&ent, &chisq, &mean, &montepi, &scc); RecordVal* ent_result = new RecordVal(entropy_test_result); - ent_result->Assign(0, new Val(ent, TYPE_DOUBLE)); - ent_result->Assign(1, new Val(chisq, TYPE_DOUBLE)); - ent_result->Assign(2, new Val(mean, TYPE_DOUBLE)); - ent_result->Assign(3, new Val(montepi, TYPE_DOUBLE)); - ent_result->Assign(4, new Val(scc, TYPE_DOUBLE)); + ent_result->Assign(0, make_intrusive(ent, TYPE_DOUBLE)); + ent_result->Assign(1, make_intrusive(chisq, TYPE_DOUBLE)); + ent_result->Assign(2, make_intrusive(mean, TYPE_DOUBLE)); + ent_result->Assign(3, make_intrusive(montepi, TYPE_DOUBLE)); + ent_result->Assign(4, make_intrusive(scc, TYPE_DOUBLE)); mgr.QueueEventFast(file_entropy, { GetFile()->GetVal()->Ref(), diff --git a/src/file_analysis/analyzer/extract/Extract.cc b/src/file_analysis/analyzer/extract/Extract.cc index d023036930..69ab2f16c7 100644 --- a/src/file_analysis/analyzer/extract/Extract.cc +++ b/src/file_analysis/analyzer/extract/Extract.cc @@ -32,9 +32,9 @@ Extract::~Extract() safe_close(fd); } -static Val* get_extract_field_val(RecordVal* args, const char* name) +static IntrusivePtr get_extract_field_val(RecordVal* args, const char* name) { - Val* rval = args->Lookup(name); + auto rval = args->Lookup(name); if ( ! rval ) reporter->Error("File extraction analyzer missing arg field: %s", name); @@ -44,8 +44,8 @@ static Val* get_extract_field_val(RecordVal* args, const char* name) file_analysis::Analyzer* Extract::Instantiate(RecordVal* args, File* file) { - Val* fname = get_extract_field_val(args, "extract_filename"); - Val* limit = get_extract_field_val(args, "extract_limit"); + auto fname = get_extract_field_val(args, "extract_filename"); + auto limit = get_extract_field_val(args, "extract_limit"); if ( ! fname || ! limit ) return 0; diff --git a/src/file_analysis/analyzer/extract/functions.bif b/src/file_analysis/analyzer/extract/functions.bif index bdec388380..ddf342fee7 100644 --- a/src/file_analysis/analyzer/extract/functions.bif +++ b/src/file_analysis/analyzer/extract/functions.bif @@ -9,12 +9,11 @@ module FileExtract; ## :zeek:see:`FileExtract::set_limit`. function FileExtract::__set_limit%(file_id: string, args: any, n: count%): bool - %{ + %{ using BifType::Record::Files::AnalyzerArgs; - RecordVal* rv = args->AsRecordVal()->CoerceTo(AnalyzerArgs); - bool result = file_mgr->SetExtractionLimit(file_id->CheckString(), rv, n); - Unref(rv); - return val_mgr->GetBool(result); - %} + auto rv = args->AsRecordVal()->CoerceTo(AnalyzerArgs); + bool result = file_mgr->SetExtractionLimit(file_id->CheckString(), rv.get(), n); + return val_mgr->GetBool(result); + %} module GLOBAL; diff --git a/src/file_analysis/analyzer/pe/pe-analyzer.pac b/src/file_analysis/analyzer/pe/pe-analyzer.pac index 0cadf53334..b5cdb27f3e 100644 --- a/src/file_analysis/analyzer/pe/pe-analyzer.pac +++ b/src/file_analysis/analyzer/pe/pe-analyzer.pac @@ -25,7 +25,7 @@ refine flow File += { function characteristics_to_bro(c: uint32, len: uint8): TableVal %{ uint64 mask = (len==16) ? 0xFFFF : 0xFFFFFFFF; - TableVal* char_set = new TableVal(internal_type("count_set")->AsTableType()); + TableVal* char_set = new TableVal({NewRef{}, internal_type("count_set")->AsTableType()}); for ( uint16 i=0; i < len; ++i ) { if ( ((c >> i) & 0x1) == 1 ) @@ -43,7 +43,7 @@ refine flow File += { if ( pe_dos_header ) { RecordVal* dh = new RecordVal(BifType::Record::PE::DOSHeader); - dh->Assign(0, new StringVal(${h.signature}.length(), (const char*) ${h.signature}.data())); + dh->Assign(0, make_intrusive(${h.signature}.length(), (const char*) ${h.signature}.data())); dh->Assign(1, val_mgr->GetCount(${h.UsedBytesInTheLastPage})); dh->Assign(2, val_mgr->GetCount(${h.FileSizeInPages})); dh->Assign(3, val_mgr->GetCount(${h.NumberOfRelocationItems})); @@ -97,7 +97,7 @@ refine flow File += { { RecordVal* fh = new RecordVal(BifType::Record::PE::FileHeader); fh->Assign(0, val_mgr->GetCount(${h.Machine})); - fh->Assign(1, new Val(static_cast(${h.TimeDateStamp}), TYPE_TIME)); + fh->Assign(1, make_intrusive(static_cast(${h.TimeDateStamp}), TYPE_TIME)); fh->Assign(2, val_mgr->GetCount(${h.PointerToSymbolTable})); fh->Assign(3, val_mgr->GetCount(${h.NumberOfSymbols})); fh->Assign(4, val_mgr->GetCount(${h.SizeOfOptionalHeader})); @@ -176,7 +176,7 @@ refine flow File += { name_len = ${h.name}.length(); else name_len = first_null - ${h.name}.data(); - section_header->Assign(0, new StringVal(name_len, (const char*) ${h.name}.data())); + section_header->Assign(0, make_intrusive(name_len, (const char*) ${h.name}.data())); section_header->Assign(1, val_mgr->GetCount(${h.virtual_size})); section_header->Assign(2, val_mgr->GetCount(${h.virtual_addr})); diff --git a/src/file_analysis/analyzer/unified2/unified2-analyzer.pac b/src/file_analysis/analyzer/unified2/unified2-analyzer.pac index a4a7da5081..d47707033e 100644 --- a/src/file_analysis/analyzer/unified2/unified2-analyzer.pac +++ b/src/file_analysis/analyzer/unified2/unified2-analyzer.pac @@ -69,7 +69,7 @@ refine flow Flow += { RecordVal* ids_event = new RecordVal(BifType::Record::Unified2::IDSEvent); ids_event->Assign(0, val_mgr->GetCount(${ev.sensor_id})); ids_event->Assign(1, val_mgr->GetCount(${ev.event_id})); - ids_event->Assign(2, new Val(ts_to_double(${ev.ts}), TYPE_TIME)); + ids_event->Assign(2, make_intrusive(ts_to_double(${ev.ts}), TYPE_TIME)); ids_event->Assign(3, val_mgr->GetCount(${ev.signature_id})); ids_event->Assign(4, val_mgr->GetCount(${ev.generator_id})); ids_event->Assign(5, val_mgr->GetCount(${ev.signature_revision})); @@ -97,7 +97,7 @@ refine flow Flow += { RecordVal* ids_event = new RecordVal(BifType::Record::Unified2::IDSEvent); ids_event->Assign(0, val_mgr->GetCount(${ev.sensor_id})); ids_event->Assign(1, val_mgr->GetCount(${ev.event_id})); - ids_event->Assign(2, new Val(ts_to_double(${ev.ts}), TYPE_TIME)); + ids_event->Assign(2, make_intrusive(ts_to_double(${ev.ts}), TYPE_TIME)); ids_event->Assign(3, val_mgr->GetCount(${ev.signature_id})); ids_event->Assign(4, val_mgr->GetCount(${ev.generator_id})); ids_event->Assign(5, val_mgr->GetCount(${ev.signature_revision})); @@ -131,7 +131,7 @@ refine flow Flow += { packet->Assign(0, val_mgr->GetCount(${pkt.sensor_id})); packet->Assign(1, val_mgr->GetCount(${pkt.event_id})); packet->Assign(2, val_mgr->GetCount(${pkt.event_second})); - packet->Assign(3, new Val(ts_to_double(${pkt.packet_ts}), TYPE_TIME)); + packet->Assign(3, make_intrusive(ts_to_double(${pkt.packet_ts}), TYPE_TIME)); packet->Assign(4, val_mgr->GetCount(${pkt.link_type})); packet->Assign(5, bytestring_to_val(${pkt.packet_data})); diff --git a/src/file_analysis/analyzer/x509/OCSP.cc b/src/file_analysis/analyzer/x509/OCSP.cc index c861e1bcb5..30b7e4283c 100644 --- a/src/file_analysis/analyzer/x509/OCSP.cc +++ b/src/file_analysis/analyzer/x509/OCSP.cc @@ -32,9 +32,9 @@ using namespace file_analysis; #define OCSP_STRING_BUF_SIZE 2048 -static Val* get_ocsp_type(RecordVal* args, const char* name) +static IntrusivePtr get_ocsp_type(RecordVal* args, const char* name) { - Val* rval = args->Lookup(name); + auto rval = args->Lookup(name); if ( ! rval ) reporter->Error("File extraction analyzer missing arg field: %s", name); @@ -624,7 +624,7 @@ void file_analysis::OCSP::ParseResponse(OCSP_RESPONSE *resp) //i2a_ASN1_OBJECT(bio, basic_resp->signature); //len = BIO_read(bio, buf, sizeof(buf)); - //ocsp_resp_record->Assign(7, new StringVal(len, buf)); + //ocsp_resp_record->Assign(7, make_intrusive(len, buf)); //BIO_reset(bio); certs_vector = new VectorVal(internal_type("x509_opaque_vector")->AsVectorType()); @@ -644,7 +644,7 @@ void file_analysis::OCSP::ParseResponse(OCSP_RESPONSE *resp) ::X509 *this_cert = X509_dup(helper_sk_X509_value(certs, i)); //::X509 *this_cert = X509_dup(sk_X509_value(certs, i)); if (this_cert) - certs_vector->Assign(i, new file_analysis::X509Val(this_cert)); + certs_vector->Assign(i, make_intrusive(this_cert)); else reporter->Weird("OpenSSL returned null certificate"); } diff --git a/src/file_analysis/analyzer/x509/X509.cc b/src/file_analysis/analyzer/x509/X509.cc index e909fe84c1..f25ea7c177 100644 --- a/src/file_analysis/analyzer/x509/X509.cc +++ b/src/file_analysis/analyzer/x509/X509.cc @@ -51,7 +51,7 @@ bool file_analysis::X509::EndOfFile() hash_final(ctx, buf); std::string cert_sha256 = sha256_digest_print(buf); auto index = make_intrusive(cert_sha256); - auto* entry = certificate_cache->Lookup(index.get(), false); + auto entry = certificate_cache->Lookup(index.get(), false); if ( entry ) // in this case, the certificate is in the cache and we do not // do any further processing here. However, if there is a callback, we execute it. @@ -62,9 +62,9 @@ bool file_analysis::X509::EndOfFile() val_list vl(3); vl.push_back(GetFile()->GetVal()->Ref()); - vl.push_back(entry->Ref()); + vl.push_back(entry.release()); vl.push_back(new StringVal(cert_sha256)); - IntrusivePtr v{AdoptRef{}, cache_hit_callback->Call(&vl)}; + cache_hit_callback->Call(&vl); return false; } } @@ -126,12 +126,12 @@ RecordVal* file_analysis::X509::ParseCertificate(X509Val* cert_val, File* f) pX509Cert->Assign(0, val_mgr->GetCount((uint64_t) X509_get_version(ssl_cert) + 1)); i2a_ASN1_INTEGER(bio, X509_get_serialNumber(ssl_cert)); int len = BIO_read(bio, buf, sizeof(buf)); - pX509Cert->Assign(1, new StringVal(len, buf)); + pX509Cert->Assign(1, make_intrusive(len, buf)); BIO_reset(bio); X509_NAME_print_ex(bio, X509_get_subject_name(ssl_cert), 0, XN_FLAG_RFC2253); len = BIO_gets(bio, buf, sizeof(buf)); - pX509Cert->Assign(2, new StringVal(len, buf)); + pX509Cert->Assign(2, make_intrusive(len, buf)); BIO_reset(bio); X509_NAME *subject_name = X509_get_subject_name(ssl_cert); @@ -151,17 +151,17 @@ RecordVal* file_analysis::X509::ParseCertificate(X509Val* cert_val, File* f) // we found a common name ASN1_STRING_print(bio, X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subject_name, namepos))); len = BIO_gets(bio, buf, sizeof(buf)); - pX509Cert->Assign(4, new StringVal(len, buf)); + pX509Cert->Assign(4, make_intrusive(len, buf)); BIO_reset(bio); } X509_NAME_print_ex(bio, X509_get_issuer_name(ssl_cert), 0, XN_FLAG_RFC2253); len = BIO_gets(bio, buf, sizeof(buf)); - pX509Cert->Assign(3, new StringVal(len, buf)); + pX509Cert->Assign(3, make_intrusive(len, buf)); BIO_free(bio); - pX509Cert->Assign(5, new Val(GetTimeFromAsn1(X509_get_notBefore(ssl_cert), f, reporter), TYPE_TIME)); - pX509Cert->Assign(6, new Val(GetTimeFromAsn1(X509_get_notAfter(ssl_cert), f, reporter), TYPE_TIME)); + pX509Cert->Assign(5, make_intrusive(GetTimeFromAsn1(X509_get_notBefore(ssl_cert), f, reporter), TYPE_TIME)); + pX509Cert->Assign(6, make_intrusive(GetTimeFromAsn1(X509_get_notAfter(ssl_cert), f, reporter), TYPE_TIME)); // we only read 255 bytes because byte 256 is always 0. // if the string is longer than 255, that will be our null-termination, @@ -171,7 +171,7 @@ RecordVal* file_analysis::X509::ParseCertificate(X509Val* cert_val, File* f) if ( ! i2t_ASN1_OBJECT(buf, 255, algorithm) ) buf[0] = 0; - pX509Cert->Assign(7, new StringVal(buf)); + pX509Cert->Assign(7, make_intrusive(buf)); // Special case for RDP server certificates. For some reason some (all?) RDP server // certificates like to specify their key algorithm as md5WithRSAEncryption, which @@ -193,25 +193,25 @@ RecordVal* file_analysis::X509::ParseCertificate(X509Val* cert_val, File* f) if ( ! i2t_ASN1_OBJECT(buf, 255, OBJ_nid2obj(X509_get_signature_nid(ssl_cert))) ) buf[0] = 0; - pX509Cert->Assign(8, new StringVal(buf)); + pX509Cert->Assign(8, make_intrusive(buf)); // Things we can do when we have the key... EVP_PKEY *pkey = X509_extract_key(ssl_cert); if ( pkey != NULL ) { if ( EVP_PKEY_base_id(pkey) == EVP_PKEY_DSA ) - pX509Cert->Assign(9, new StringVal("dsa")); + pX509Cert->Assign(9, make_intrusive("dsa")); else if ( EVP_PKEY_base_id(pkey) == EVP_PKEY_RSA ) { - pX509Cert->Assign(9, new StringVal("rsa")); + pX509Cert->Assign(9, make_intrusive("rsa")); const BIGNUM *e; RSA_get0_key(EVP_PKEY_get0_RSA(pkey), NULL, &e, NULL); char *exponent = BN_bn2dec(e); if ( exponent != NULL ) { - pX509Cert->Assign(11, new StringVal(exponent)); + pX509Cert->Assign(11, make_intrusive(exponent)); OPENSSL_free(exponent); exponent = NULL; } @@ -219,7 +219,7 @@ RecordVal* file_analysis::X509::ParseCertificate(X509Val* cert_val, File* f) #ifndef OPENSSL_NO_EC else if ( EVP_PKEY_base_id(pkey) == EVP_PKEY_EC ) { - pX509Cert->Assign(9, new StringVal("ecdsa")); + pX509Cert->Assign(9, make_intrusive("ecdsa")); pX509Cert->Assign(12, KeyCurve(pkey)); } #endif @@ -401,10 +401,10 @@ void file_analysis::X509::ParseSAN(X509_EXTENSION* ext) uint32_t* addr = (uint32_t*) gen->d.ip->data; if( gen->d.ip->length == 4 ) - ips->Assign(ips->Size(), new AddrVal(*addr)); + ips->Assign(ips->Size(), make_intrusive(*addr)); else if ( gen->d.ip->length == 16 ) - ips->Assign(ips->Size(), new AddrVal(addr)); + ips->Assign(ips->Size(), make_intrusive(addr)); else { @@ -545,9 +545,9 @@ X509Val::~X509Val() X509_free(certificate); } -Val* X509Val::DoClone(CloneState* state) +IntrusivePtr X509Val::DoClone(CloneState* state) { - auto copy = new X509Val(); + auto copy = make_intrusive(); if ( certificate ) copy->certificate = X509_dup(certificate); diff --git a/src/file_analysis/analyzer/x509/X509.h b/src/file_analysis/analyzer/x509/X509.h index 56d12da2c3..54f32b49f8 100644 --- a/src/file_analysis/analyzer/x509/X509.h +++ b/src/file_analysis/analyzer/x509/X509.h @@ -169,7 +169,7 @@ public: * * @return A cloned X509Val. */ - Val* DoClone(CloneState* state) override; + IntrusivePtr DoClone(CloneState* state) override; /** * Destructor. diff --git a/src/file_analysis/analyzer/x509/X509Common.cc b/src/file_analysis/analyzer/x509/X509Common.cc index dcad79ed7f..a2eb1d7d9a 100644 --- a/src/file_analysis/analyzer/x509/X509Common.cc +++ b/src/file_analysis/analyzer/x509/X509Common.cc @@ -263,12 +263,12 @@ void file_analysis::X509Common::ParseExtension(X509_EXTENSION* ex, const EventHa ext_val = new StringVal(0, ""); RecordVal* pX509Ext = new RecordVal(BifType::Record::X509::Extension); - pX509Ext->Assign(0, new StringVal(name)); + pX509Ext->Assign(0, make_intrusive(name)); if ( short_name and strlen(short_name) > 0 ) - pX509Ext->Assign(1, new StringVal(short_name)); + pX509Ext->Assign(1, make_intrusive(short_name)); - pX509Ext->Assign(2, new StringVal(oid)); + pX509Ext->Assign(2, make_intrusive(oid)); pX509Ext->Assign(3, val_mgr->GetBool(critical)); pX509Ext->Assign(4, ext_val); diff --git a/src/file_analysis/analyzer/x509/functions.bif b/src/file_analysis/analyzer/x509/functions.bif index 77eaca4e26..85a1af2fa8 100644 --- a/src/file_analysis/analyzer/x509/functions.bif +++ b/src/file_analysis/analyzer/x509/functions.bif @@ -16,7 +16,7 @@ RecordVal* x509_result_record(uint64_t num, const char* reason, Val* chainVector RecordVal* rrecord = new RecordVal(BifType::Record::X509::Result); rrecord->Assign(0, val_mgr->GetInt(num)); - rrecord->Assign(1, new StringVal(reason)); + rrecord->Assign(1, make_intrusive(reason)); if ( chainVector ) rrecord->Assign(2, chainVector); @@ -564,7 +564,7 @@ function x509_verify%(certs: x509_opaque_vector, root_certs: table_string_of_str if ( currcert ) // X509Val takes ownership of currcert. - chainVector->Assign(i, new file_analysis::X509Val(currcert)); + chainVector->Assign(i, make_intrusive(currcert)); else { reporter->InternalWarning("OpenSSL returned null certificate"); diff --git a/src/file_analysis/file_analysis.bif b/src/file_analysis/file_analysis.bif index d85d8cdb5a..bd7cd72a02 100644 --- a/src/file_analysis/file_analysis.bif +++ b/src/file_analysis/file_analysis.bif @@ -42,10 +42,9 @@ function Files::__set_reassembly_buffer%(file_id: string, max: count%): bool function Files::__add_analyzer%(file_id: string, tag: Files::Tag, args: any%): bool %{ using BifType::Record::Files::AnalyzerArgs; - RecordVal* rv = args->AsRecordVal()->CoerceTo(AnalyzerArgs); + auto rv = args->AsRecordVal()->CoerceTo(AnalyzerArgs); bool result = file_mgr->AddAnalyzer(file_id->CheckString(), - file_mgr->GetComponentTag(tag), rv); - Unref(rv); + file_mgr->GetComponentTag(tag), rv.get()); return val_mgr->GetBool(result); %} @@ -53,10 +52,9 @@ function Files::__add_analyzer%(file_id: string, tag: Files::Tag, args: any%): b function Files::__remove_analyzer%(file_id: string, tag: Files::Tag, args: any%): bool %{ using BifType::Record::Files::AnalyzerArgs; - RecordVal* rv = args->AsRecordVal()->CoerceTo(AnalyzerArgs); + auto rv = args->AsRecordVal()->CoerceTo(AnalyzerArgs); bool result = file_mgr->RemoveAnalyzer(file_id->CheckString(), - file_mgr->GetComponentTag(tag) , rv); - Unref(rv); + file_mgr->GetComponentTag(tag) , rv.get()); return val_mgr->GetBool(result); %} diff --git a/src/input/Manager.cc b/src/input/Manager.cc index c85bc82575..2f21725956 100644 --- a/src/input/Manager.cc +++ b/src/input/Manager.cc @@ -88,17 +88,10 @@ Manager::Stream::Stream(StreamType t) Manager::Stream::~Stream() { - if ( type ) - Unref(type); - - if ( description ) - Unref(description); - - if ( config ) - Unref(config); - - if ( reader ) - delete(reader); + Unref(type); + Unref(description); + Unref(config); + delete reader; } class Manager::TableStream: public Manager::Stream { @@ -239,9 +232,7 @@ bool Manager::CreateStream(Stream* info, RecordVal* description) return false; } - Val* name_val = description->Lookup("name", true); - string name = name_val->AsString()->CheckString(); - Unref(name_val); + string name = description->Lookup("name", true)->AsString()->CheckString(); Stream *i = FindStream(name); if ( i != 0 ) @@ -251,20 +242,17 @@ bool Manager::CreateStream(Stream* info, RecordVal* description) return false; } - EnumVal* reader = description->Lookup("reader", true)->AsEnumVal(); + auto reader = description->Lookup("reader", true); // get the source ... - Val* sourceval = description->Lookup("source", true); - assert ( sourceval != 0 ); - const BroString* bsource = sourceval->AsString(); + const BroString* bsource = description->Lookup("source", true)->AsString(); string source((const char*) bsource->Bytes(), bsource->Len()); - Unref(sourceval); ReaderBackend::ReaderInfo rinfo; rinfo.source = copy_string(source.c_str()); rinfo.name = copy_string(name.c_str()); - EnumVal* mode = description->Lookup("mode", true)->AsEnumVal(); + auto mode = description->Lookup("mode", true)->AsEnumVal(); switch ( mode->InternalInt() ) { case 0: @@ -281,14 +269,11 @@ bool Manager::CreateStream(Stream* info, RecordVal* description) default: reporter->InternalWarning("unknown input reader mode"); - Unref(mode); return false; } - Unref(mode); - - Val* config = description->Lookup("config", true); - info->config = config->AsTableVal(); // ref'd by LookupWithDefault + auto config = description->Lookup("config", true); + info->config = config.release()->AsTableVal(); { // create config mapping in ReaderInfo. Has to be done before the construction of reader_obj. @@ -305,15 +290,13 @@ bool Manager::CreateStream(Stream* info, RecordVal* description) Unref(index); delete k; } - } - - ReaderFrontend* reader_obj = new ReaderFrontend(rinfo, reader); + ReaderFrontend* reader_obj = new ReaderFrontend(rinfo, reader->AsEnumVal()); assert(reader_obj); info->reader = reader_obj; - info->type = reader->AsEnumVal(); // ref'd by lookupwithdefault + info->type = reader.release()->AsEnumVal(); info->name = name; Ref(description); @@ -335,19 +318,14 @@ bool Manager::CreateEventStream(RecordVal* fval) return false; } - Val* name_val = fval->Lookup("name", true); - string stream_name = name_val->AsString()->CheckString(); - Unref(name_val); + string stream_name = fval->Lookup("name", true)->AsString()->CheckString(); - Val* fields_val = fval->Lookup("fields", true); - RecordType *fields = fields_val->AsType()->AsTypeType()->Type()->AsRecordType(); - Unref(fields_val); + auto fields_val = fval->Lookup("fields", true); + RecordType* fields = fields_val->AsType()->AsTypeType()->Type()->AsRecordType(); - Val *want_record = fval->Lookup("want_record", true); + auto want_record = fval->Lookup("want_record", true); - Val* event_val = fval->Lookup("ev", true); - Func* event = event_val->AsFunc(); - Unref(event_val); + Func* event = fval->Lookup("ev", true)->AsFunc(); FuncType* etype = event->FType()->AsFuncType(); @@ -435,9 +413,8 @@ bool Manager::CreateEventStream(RecordVal* fval) else assert(false); - Val* error_event_val = fval->Lookup("error_ev", true); + auto error_event_val = fval->Lookup("error_ev", true); Func* error_event = error_event_val ? error_event_val->AsFunc() : nullptr; - Unref(error_event_val); if ( ! CheckErrorEventTypes(stream_name, error_event, false) ) return false; @@ -467,13 +444,11 @@ bool Manager::CreateEventStream(RecordVal* fval) for ( unsigned int i = 0; i < fieldsV.size(); i++ ) logf[i] = fieldsV[i]; - Unref(fields); // ref'd by lookupwithdefault stream->num_fields = fieldsV.size(); stream->fields = fields->Ref()->AsRecordType(); stream->event = event_registry->Lookup(event->Name()); stream->error_event = error_event ? event_registry->Lookup(error_event->Name()) : nullptr; stream->want_record = ( want_record->InternalInt() == 1 ); - Unref(want_record); // ref'd by lookupwithdefault assert(stream->reader); @@ -496,26 +471,19 @@ bool Manager::CreateTableStream(RecordVal* fval) return false; } - Val* name_val = fval->Lookup("name", true); - string stream_name = name_val->AsString()->CheckString(); - Unref(name_val); + string stream_name = fval->Lookup("name", true)->AsString()->CheckString(); - Val* pred = fval->Lookup("pred", true); + auto pred = fval->Lookup("pred", true); + auto idx_val = fval->Lookup("idx", true); + RecordType* idx = idx_val->AsType()->AsTypeType()->Type()->AsRecordType(); - Val* idx_val = fval->Lookup("idx", true); - RecordType *idx = idx_val->AsType()->AsTypeType()->Type()->AsRecordType(); - Unref(idx_val); + IntrusivePtr val; + auto val_val = fval->Lookup("val", true); - RecordType *val = 0; - - Val* val_val = fval->Lookup("val", true); if ( val_val ) - { - val = val_val->AsType()->AsTypeType()->Type()->AsRecordType(); - Unref(val_val); - } + val = {NewRef{}, val_val->AsType()->AsTypeType()->Type()->AsRecordType()}; - TableVal *dst = fval->Lookup("destination", true)->AsTableVal(); + auto dst = fval->Lookup("destination", true); // check if index fields match table description int num = idx->NumFields(); @@ -550,12 +518,12 @@ bool Manager::CreateTableStream(RecordVal* fval) return false; } - Val *want_record = fval->Lookup("want_record", true); + auto want_record = fval->Lookup("want_record", true); if ( val ) { const BroType* table_yield = dst->Type()->AsTableType()->YieldType(); - const BroType* compare_type = val; + const BroType* compare_type = val.get(); if ( want_record->InternalInt() == 0 ) compare_type = val->FieldType(0); @@ -583,9 +551,8 @@ bool Manager::CreateTableStream(RecordVal* fval) } } - Val* event_val = fval->Lookup("ev", true); + auto event_val = fval->Lookup("ev", true); Func* event = event_val ? event_val->AsFunc() : 0; - Unref(event_val); if ( event ) { @@ -628,7 +595,7 @@ bool Manager::CreateTableStream(RecordVal* fval) return false; } - if ( want_record->InternalInt() == 1 && val && ! same_type((*args)[3], val) ) + if ( want_record->InternalInt() == 1 && val && ! same_type((*args)[3], val.get()) ) { ODesc desc1; ODesc desc2; @@ -657,9 +624,8 @@ bool Manager::CreateTableStream(RecordVal* fval) assert(want_record->InternalInt() == 1 || want_record->InternalInt() == 0); } - Val* error_event_val = fval->Lookup("error_ev", true); + auto error_event_val = fval->Lookup("error_ev", true); Func* error_event = error_event_val ? error_event_val->AsFunc() : nullptr; - Unref(error_event_val); if ( ! CheckErrorEventTypes(stream_name, error_event, true) ) return false; @@ -671,7 +637,7 @@ bool Manager::CreateTableStream(RecordVal* fval) int idxfields = fieldsV.size(); if ( val ) // if we are not a set - status = status || ! UnrollRecordType(&fieldsV, val, "", BifConst::Input::accept_unsupported_types); + status = status || ! UnrollRecordType(&fieldsV, val.get(), "", BifConst::Input::accept_unsupported_types); int valfields = fieldsV.size() - idxfields; @@ -710,9 +676,9 @@ bool Manager::CreateTableStream(RecordVal* fval) stream->pred = pred ? pred->AsFunc() : 0; stream->num_idx_fields = idxfields; stream->num_val_fields = valfields; - stream->tab = dst->AsTableVal(); // ref'd by lookupwithdefault - stream->rtype = val ? val->AsRecordType() : 0; - stream->itype = idx->AsRecordType(); + stream->tab = dst.release()->AsTableVal(); + stream->rtype = val.release(); + stream->itype = idx->Ref()->AsRecordType(); stream->event = event ? event_registry->Lookup(event->Name()) : 0; stream->error_event = error_event ? event_registry->Lookup(error_event->Name()) : nullptr; stream->currDict = new PDict; @@ -721,9 +687,6 @@ bool Manager::CreateTableStream(RecordVal* fval) stream->lastDict->SetDeleteFunc(input_hash_delete_func); stream->want_record = ( want_record->InternalInt() == 1 ); - Unref(want_record); // ref'd by lookupwithdefault - Unref(pred); - assert(stream->reader); stream->reader->Init(fieldsV.size(), fields ); @@ -1035,7 +998,7 @@ bool Manager::ForceUpdate(const string &name) Val* Manager::RecordValToIndexVal(RecordVal *r) const { - Val* idxval; + IntrusivePtr idxval; RecordType *type = r->Type()->AsRecordType(); @@ -1046,15 +1009,15 @@ Val* Manager::RecordValToIndexVal(RecordVal *r) const else { - ListVal *l = new ListVal(TYPE_ANY); + auto l = make_intrusive(TYPE_ANY); for ( int j = 0 ; j < num_fields; j++ ) - l->Append(r->LookupWithDefault(j)); + l->Append(r->LookupWithDefault(j).release()); - idxval = l; + idxval = std::move(l); } - return idxval; + return idxval.release(); } @@ -1109,7 +1072,7 @@ void Manager::SendEntry(ReaderFrontend* reader, Value* *vals) else if ( i->stream_type == EVENT_STREAM ) { - EnumVal *type = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_NEW); + EnumVal* type = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_NEW).release(); readFields = SendEventStreamEvent(i, type, vals); } @@ -1215,9 +1178,9 @@ int Manager::SendEntryTable(Stream* i, const Value* const *vals) if ( ! pred_convert_error ) { if ( updated ) - ev = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_CHANGED); + ev = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_CHANGED).release(); else - ev = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_NEW); + ev = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_NEW).release(); bool result; if ( stream->num_val_fields > 0 ) // we have values @@ -1275,7 +1238,7 @@ int Manager::SendEntryTable(Stream* i, const Value* const *vals) assert(idxval); - Val* oldval = 0; + IntrusivePtr oldval; if ( updated == true ) { assert(stream->num_val_fields > 0); @@ -1291,9 +1254,6 @@ int Manager::SendEntryTable(Stream* i, const Value* const *vals) ih->idxkey = new HashKey(k->Key(), k->Size(), k->Hash()); ih->valhash = valhash; - if ( oldval && stream->event && updated ) - Ref(oldval); // otherwise it is no longer accessible after the assignment - stream->tab->Assign(idxval, k, valval); Unref(idxval); // asssign does not consume idxval. @@ -1319,13 +1279,13 @@ int Manager::SendEntryTable(Stream* i, const Value* const *vals) else if ( updated ) { // in case of update send back the old value. assert ( stream->num_val_fields > 0 ); - ev = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_CHANGED); + ev = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_CHANGED).release(); assert ( oldval != 0 ); - SendEvent(stream->event, 4, stream->description->Ref(), ev, predidx, oldval); + SendEvent(stream->event, 4, stream->description->Ref(), ev, predidx, oldval.release()); } else { - ev = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_NEW); + ev = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_NEW).release(); if ( stream->num_val_fields == 0 ) { Ref(stream->description); @@ -1376,7 +1336,7 @@ void Manager::EndCurrentSend(ReaderFrontend* reader) while ( ( ih = stream->lastDict->NextEntry(lastDictIdxKey, c) ) ) { ListVal * idx = 0; - Val *val = 0; + IntrusivePtr val; Val* predidx = 0; EnumVal* ev = 0; @@ -1390,7 +1350,7 @@ void Manager::EndCurrentSend(ReaderFrontend* reader) assert(val != 0); predidx = ListValToRecordVal(idx, stream->itype, &startpos); Unref(idx); - ev = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_REMOVED); + ev = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_REMOVED).release(); } if ( stream->pred ) @@ -1399,9 +1359,8 @@ void Manager::EndCurrentSend(ReaderFrontend* reader) Ref(ev); Ref(predidx); - Ref(val); - bool result = CallPred(stream->pred, 3, ev, predidx, val); + bool result = CallPred(stream->pred, 3, ev, predidx, IntrusivePtr{val}.release()); if ( result == false ) { @@ -1418,9 +1377,8 @@ void Manager::EndCurrentSend(ReaderFrontend* reader) if ( stream->event ) { Ref(predidx); - Ref(val); Ref(ev); - SendEvent(stream->event, 4, stream->description->Ref(), ev, predidx, val); + SendEvent(stream->event, 4, stream->description->Ref(), ev, predidx, IntrusivePtr{val}.release()); } if ( predidx ) // if we have a stream or an event... @@ -1429,7 +1387,7 @@ void Manager::EndCurrentSend(ReaderFrontend* reader) if ( ev ) Unref(ev); - Unref(stream->tab->Delete(ih->idxkey)); + stream->tab->Delete(ih->idxkey); stream->lastDict->Remove(lastDictIdxKey); // delete in next line delete lastDictIdxKey; delete(ih); @@ -1499,7 +1457,7 @@ void Manager::Put(ReaderFrontend* reader, Value* *vals) else if ( i->stream_type == EVENT_STREAM ) { - EnumVal *type = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_NEW); + EnumVal* type = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_NEW).release(); readFields = SendEventStreamEvent(i, type, vals); } @@ -1608,7 +1566,7 @@ int Manager::PutTable(Stream* i, const Value* const *vals) if ( stream->pred || stream->event ) { bool updated = false; - Val* oldval = 0; + IntrusivePtr oldval; if ( stream->num_val_fields > 0 ) { @@ -1620,7 +1578,6 @@ int Manager::PutTable(Stream* i, const Value* const *vals) { // it is an update updated = true; - Ref(oldval); // have to do that, otherwise it may disappear in assign } @@ -1637,9 +1594,9 @@ int Manager::PutTable(Stream* i, const Value* const *vals) else { if ( updated ) - ev = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_CHANGED); + ev = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_CHANGED).release(); else - ev = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_NEW); + ev = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_NEW).release(); bool result; if ( stream->num_val_fields > 0 ) // we have values @@ -1655,7 +1612,6 @@ int Manager::PutTable(Stream* i, const Value* const *vals) // do nothing Unref(idxval); Unref(valval); - Unref(oldval); return stream->num_val_fields + stream->num_idx_fields; } } @@ -1679,14 +1635,14 @@ int Manager::PutTable(Stream* i, const Value* const *vals) { // in case of update send back the old value. assert ( stream->num_val_fields > 0 ); - ev = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_CHANGED); + ev = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_CHANGED).release(); assert ( oldval != 0 ); SendEvent(stream->event, 4, stream->description->Ref(), - ev, predidx, oldval); + ev, predidx, oldval.release()); } else { - ev = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_NEW); + ev = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_NEW).release(); if ( stream->num_val_fields == 0 ) SendEvent(stream->event, 4, stream->description->Ref(), ev, predidx); @@ -1760,7 +1716,7 @@ bool Manager::Delete(ReaderFrontend* reader, Value* *vals) if ( stream->pred || stream->event ) { - Val *val = stream->tab->Lookup(idxval); + auto val = stream->tab->Lookup(idxval); if ( stream->pred ) { @@ -1771,10 +1727,9 @@ bool Manager::Delete(ReaderFrontend* reader, Value* *vals) Unref(predidx); else { - Ref(val); - EnumVal *ev = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_REMOVED); + EnumVal* ev = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_REMOVED).release(); - streamresult = CallPred(stream->pred, 3, ev, predidx, val); + streamresult = CallPred(stream->pred, 3, ev, predidx, IntrusivePtr{val}.release()); if ( streamresult == false ) { @@ -1791,28 +1746,22 @@ bool Manager::Delete(ReaderFrontend* reader, Value* *vals) { Ref(idxval); assert(val != 0); - Ref(val); - EnumVal *ev = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_REMOVED); - SendEvent(stream->event, 4, stream->description->Ref(), ev, idxval, val); + EnumVal* ev = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_REMOVED).release(); + SendEvent(stream->event, 4, stream->description->Ref(), ev, idxval, IntrusivePtr{val}.release()); } } // only if stream = true -> no streaming if ( streamresult ) { - Val* retptr = stream->tab->Delete(idxval); - success = ( retptr != 0 ); - if ( ! success ) + if ( ! stream->tab->Delete(idxval) ) Warning(i, "Internal error while deleting values from input table"); - else - Unref(retptr); } - } else if ( i->stream_type == EVENT_STREAM ) { - EnumVal *type = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_REMOVED); + EnumVal* type = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_REMOVED).release(); readVals = SendEventStreamEvent(i, type, vals); success = true; } @@ -1845,12 +1794,9 @@ bool Manager::CallPred(Func* pred_func, const int numvals, ...) const va_end(lP); - Val* v = pred_func->Call(&vl); + auto v = pred_func->Call(&vl); if ( v ) - { result = v->AsBool(); - Unref(v); - } return result; } @@ -2390,10 +2336,10 @@ Val* Manager::ValueToVal(const Stream* i, const Value* val, BroType* request_typ { // all entries have to have the same type... BroType* type = request_type->AsTableType()->Indices()->PureType(); - TypeList* set_index = new TypeList(type->Ref()); - set_index->Append(type->Ref()); - SetType* s = new SetType(set_index, 0); - TableVal* t = new TableVal(s); + auto set_index = make_intrusive(IntrusivePtr{NewRef{}, type}); + set_index->Append({NewRef{}, type}); + auto s = make_intrusive(std::move(set_index), nullptr); + TableVal* t = new TableVal(std::move(s)); for ( int j = 0; j < val->val.set_val.size; j++ ) { Val* assignval = ValueToVal(i, val->val.set_val.vals[j], type, have_error); @@ -2402,7 +2348,6 @@ Val* Manager::ValueToVal(const Stream* i, const Value* val, BroType* request_typ Unref(assignval); // index is not consumed by assign. } - Unref(s); return t; } @@ -2410,7 +2355,7 @@ Val* Manager::ValueToVal(const Stream* i, const Value* val, BroType* request_typ { // all entries have to have the same type... BroType* type = request_type->AsVectorType()->YieldType(); - VectorType* vt = new VectorType(type->Ref()); + VectorType* vt = new VectorType({NewRef{}, type}); VectorVal* v = new VectorVal(vt); for ( int j = 0; j < val->val.vector_val.size; j++ ) { @@ -2442,7 +2387,7 @@ Val* Manager::ValueToVal(const Stream* i, const Value* val, BroType* request_typ return nullptr; } - return request_type->Ref()->AsEnumType()->GetVal(index); + return request_type->AsEnumType()->GetVal(index).release(); } default: @@ -2537,10 +2482,10 @@ Val* Manager::ValueToVal(const Stream* i, const Value* val, bool& have_error) co case TYPE_TABLE: { - TypeList* set_index; + IntrusivePtr set_index; if ( val->val.set_val.size == 0 && val->subtype == TYPE_VOID ) // don't know type - unspecified table. - set_index = new TypeList(); + set_index = make_intrusive(); else { // all entries have to have the same type... @@ -2548,7 +2493,7 @@ Val* Manager::ValueToVal(const Stream* i, const Value* val, bool& have_error) co if ( stag == TYPE_VOID ) TypeTag stag = val->val.set_val.vals[0]->type; - BroType* index_type; + IntrusivePtr index_type; if ( stag == TYPE_ENUM ) { @@ -2566,17 +2511,17 @@ Val* Manager::ValueToVal(const Stream* i, const Value* val, bool& have_error) co return nullptr; } - index_type = enum_id->Type()->AsEnumType(); + index_type = {NewRef{}, enum_id->Type()->AsEnumType()}; } else - index_type = base_type_no_ref(stag); + index_type = base_type(stag); - set_index = new TypeList(index_type); - set_index->Append(index_type->Ref()); + set_index = make_intrusive(index_type); + set_index->Append(std::move(index_type)); } - SetType* s = new SetType(set_index, 0); - TableVal* t = new TableVal(s); + auto s = make_intrusive(std::move(set_index), nullptr); + TableVal* t = new TableVal(std::move(s)); for ( int j = 0; j < val->val.set_val.size; j++ ) { Val* assignval = ValueToVal(i, val->val.set_val.vals[j], have_error); @@ -2585,13 +2530,13 @@ Val* Manager::ValueToVal(const Stream* i, const Value* val, bool& have_error) co Unref(assignval); // index is not consumed by assign. } - Unref(s); return t; } case TYPE_VECTOR: { - BroType* type; + IntrusivePtr type; + if ( val->val.vector_val.size == 0 && val->subtype == TYPE_VOID ) // don't know type - unspecified table. type = base_type(TYPE_ANY); @@ -2604,14 +2549,12 @@ Val* Manager::ValueToVal(const Stream* i, const Value* val, bool& have_error) co type = base_type(val->subtype); } - VectorType* vt = new VectorType(type->Ref()); - VectorVal* v = new VectorVal(vt); - for ( int j = 0; j < val->val.vector_val.size; j++ ) - { - v->Assign(j, ValueToVal(i, val->val.vector_val.vals[j], have_error)); - } + auto vt = make_intrusive(std::move(type)); + VectorVal* v = new VectorVal(vt.get()); + + for ( int j = 0; j < val->val.vector_val.size; j++ ) + v->Assign(j, ValueToVal(i, val->val.vector_val.vals[j], have_error)); - Unref(vt); return v; } @@ -2642,7 +2585,7 @@ Val* Manager::ValueToVal(const Stream* i, const Value* val, bool& have_error) co return nullptr; } - return t->GetVal(intval); + return t->GetVal(intval).release(); } default: @@ -2774,15 +2717,15 @@ void Manager::ErrorHandler(const Stream* i, ErrorType et, bool reporter_send, co switch (et) { case ErrorType::INFO: - ev = BifType::Enum::Reporter::Level->GetVal(BifEnum::Reporter::INFO); + ev = BifType::Enum::Reporter::Level->GetVal(BifEnum::Reporter::INFO).release(); break; case ErrorType::WARNING: - ev = BifType::Enum::Reporter::Level->GetVal(BifEnum::Reporter::WARNING); + ev = BifType::Enum::Reporter::Level->GetVal(BifEnum::Reporter::WARNING).release(); break; case ErrorType::ERROR: - ev = BifType::Enum::Reporter::Level->GetVal(BifEnum::Reporter::ERROR); + ev = BifType::Enum::Reporter::Level->GetVal(BifEnum::Reporter::ERROR).release(); break; default: diff --git a/src/input/readers/config/Config.cc b/src/input/readers/config/Config.cc index ab11f80487..2908484f37 100644 --- a/src/input/readers/config/Config.cc +++ b/src/input/readers/config/Config.cc @@ -31,7 +31,7 @@ Config::Config(ReaderFrontend *frontend) : ReaderBackend(frontend) for ( const auto& entry : globals ) { - ID* id = entry.second; + ID* id = entry.second.get(); if ( ! id->IsOption() ) continue; diff --git a/src/logging/Manager.cc b/src/logging/Manager.cc index d89d86d755..cdcfda73f9 100644 --- a/src/logging/Manager.cc +++ b/src/logging/Manager.cc @@ -11,6 +11,7 @@ #include "Type.h" #include "File.h" #include "input.h" +#include "IntrusivePtr.h" #include "broker/Manager.h" #include "threading/Manager.h" @@ -262,7 +263,7 @@ bool Manager::CreateStream(EnumVal* id, RecordVal* sval) return false; } - Val* event_val = sval->Lookup("ev"); + auto event_val = sval->Lookup("ev"); Func* event = event_val ? event_val->AsFunc() : 0; if ( event ) @@ -476,7 +477,7 @@ bool Manager::TraverseRecord(Stream* stream, Filter* filter, RecordType* rt, if ( include ) { StringVal* new_path_val = new StringVal(new_path.c_str()); - bool result = include->Lookup(new_path_val); + bool result = (bool)include->Lookup(new_path_val); Unref(new_path_val); @@ -488,7 +489,7 @@ bool Manager::TraverseRecord(Stream* stream, Filter* filter, RecordType* rt, if ( exclude ) { StringVal* new_path_val = new StringVal(new_path.c_str()); - bool result = exclude->Lookup(new_path_val); + bool result = (bool)exclude->Lookup(new_path_val); Unref(new_path_val); @@ -547,18 +548,18 @@ bool Manager::AddFilter(EnumVal* id, RecordVal* fval) // Create a new Filter instance. - Val* name = fval->Lookup("name", true); - Val* pred = fval->Lookup("pred", true); - Val* path_func = fval->Lookup("path_func", true); - Val* log_local = fval->Lookup("log_local", true); - Val* log_remote = fval->Lookup("log_remote", true); - Val* interv = fval->Lookup("interv", true); - Val* postprocessor = fval->Lookup("postprocessor", true); - Val* config = fval->Lookup("config", true); - Val* field_name_map = fval->Lookup("field_name_map", true); - Val* scope_sep = fval->Lookup("scope_sep", true); - Val* ext_prefix = fval->Lookup("ext_prefix", true); - Val* ext_func = fval->Lookup("ext_func", true); + auto name = fval->Lookup("name", true); + auto pred = fval->Lookup("pred", true); + auto path_func = fval->Lookup("path_func", true); + auto log_local = fval->Lookup("log_local", true); + auto log_remote = fval->Lookup("log_remote", true); + auto interv = fval->Lookup("interv", true); + auto postprocessor = fval->Lookup("postprocessor", true); + auto config = fval->Lookup("config", true); + auto field_name_map = fval->Lookup("field_name_map", true); + auto scope_sep = fval->Lookup("scope_sep", true); + auto ext_prefix = fval->Lookup("ext_prefix", true); + auto ext_func = fval->Lookup("ext_func", true); Filter* filter = new Filter; filter->fval = fval->Ref(); @@ -577,23 +578,10 @@ bool Manager::AddFilter(EnumVal* id, RecordVal* fval) filter->ext_prefix = ext_prefix->AsString()->CheckString(); filter->ext_func = ext_func ? ext_func->AsFunc() : 0; - Unref(name); - Unref(pred); - Unref(path_func); - Unref(log_local); - Unref(log_remote); - Unref(interv); - Unref(postprocessor); - Unref(config); - Unref(field_name_map); - Unref(scope_sep); - Unref(ext_prefix); - Unref(ext_func); - // Build the list of fields that the filter wants included, including // potentially rolling out fields. - Val* include = fval->Lookup("include"); - Val* exclude = fval->Lookup("exclude"); + auto include = fval->Lookup("include"); + auto exclude = fval->Lookup("exclude"); filter->num_ext_fields = 0; if ( filter->ext_func ) @@ -618,8 +606,8 @@ bool Manager::AddFilter(EnumVal* id, RecordVal* fval) filter->num_fields = 0; filter->fields = 0; if ( ! TraverseRecord(stream, filter, stream->columns, - include ? include->AsTableVal() : 0, - exclude ? exclude->AsTableVal() : 0, + include ? include->AsTableVal() : nullptr, + exclude ? exclude->AsTableVal() : nullptr, "", list()) ) { delete filter; @@ -627,12 +615,12 @@ bool Manager::AddFilter(EnumVal* id, RecordVal* fval) } // Get the path for the filter. - Val* path_val = fval->Lookup("path"); + auto path_val = fval->Lookup("path"); if ( path_val ) { filter->path = path_val->AsString()->CheckString(); - filter->path_val = path_val->Ref(); + filter->path_val = path_val.release(); } else @@ -703,7 +691,7 @@ bool Manager::RemoveFilter(EnumVal* id, const string& name) return true; } -bool Manager::Write(EnumVal* id, RecordVal* columns) +bool Manager::Write(EnumVal* id, RecordVal* columns_arg) { Stream* stream = FindStream(id); if ( ! stream ) @@ -712,7 +700,7 @@ bool Manager::Write(EnumVal* id, RecordVal* columns) if ( ! stream->enabled ) return true; - columns = columns->CoerceTo(stream->columns); + auto columns = columns_arg->CoerceTo(stream->columns); if ( ! columns ) { @@ -739,12 +727,9 @@ bool Manager::Write(EnumVal* id, RecordVal* columns) int result = 1; - Val* v = filter->pred->Call(&vl); + auto v = filter->pred->Call(&vl); if ( v ) - { result = v->AsBool(); - Unref(v); - } if ( ! result ) continue; @@ -762,20 +747,13 @@ bool Manager::Write(EnumVal* id, RecordVal* columns) BroType* rt = filter->path_func->FType()->Args()->FieldType("rec"); if ( rt->Tag() == TYPE_RECORD ) - rec_arg = columns->CoerceTo(rt->AsRecordType(), true); + rec_arg = columns->CoerceTo(rt->AsRecordType(), true).release(); else // Can be TYPE_ANY here. rec_arg = columns->Ref(); - val_list vl{ - id->Ref(), - path_arg, - rec_arg, - }; - - Val* v = 0; - - v = filter->path_func->Call(&vl); + val_list vl{id->Ref(), path_arg, rec_arg}; + auto v = filter->path_func->Call(&vl); if ( ! v ) return false; @@ -783,7 +761,6 @@ bool Manager::Write(EnumVal* id, RecordVal* columns) if ( v->Type()->Tag() != TYPE_STRING ) { reporter->Error("path_func did not return string"); - Unref(v); return false; } @@ -794,7 +771,6 @@ bool Manager::Write(EnumVal* id, RecordVal* columns) } path = v->AsString()->CheckString(); - Unref(v); #ifdef DEBUG DBG_LOG(DBG_LOGGING, "Path function for filter '%s' on stream '%s' return '%s'", @@ -872,8 +848,7 @@ bool Manager::Write(EnumVal* id, RecordVal* columns) { const char* name = filter->fields[j]->name; StringVal *fn = new StringVal(name); - Val *val = 0; - if ( (val = filter->field_name_map->Lookup(fn, false)) != 0 ) + if ( auto val = filter->field_name_map->Lookup(fn, false) ) { delete [] filter->fields[j]->name; filter->fields[j]->name = copy_string(val->AsStringVal()->CheckString()); @@ -908,15 +883,12 @@ bool Manager::Write(EnumVal* id, RecordVal* columns) filter->remote, false, filter->name); if ( ! writer ) - { - Unref(columns); return false; - } } // Alright, can do the write now. - threading::Value** vals = RecordToFilterVals(stream, filter, columns); + threading::Value** vals = RecordToFilterVals(stream, filter, columns.get()); if ( ! PLUGIN_HOOK_WITH_RESULT(HOOK_LOG_WRITE, HookLogWrite(filter->writer->Type()->AsEnumType()->Lookup(filter->writer->InternalInt()), @@ -925,7 +897,6 @@ bool Manager::Write(EnumVal* id, RecordVal* columns) filter->fields, vals), true) ) { - Unref(columns); DeleteVals(filter->num_fields, vals); #ifdef DEBUG @@ -945,8 +916,6 @@ bool Manager::Write(EnumVal* id, RecordVal* columns) #endif } - Unref(columns); - return true; } @@ -1084,15 +1053,17 @@ threading::Value* Manager::ValToLogVal(Val* val, BroType* ty) } threading::Value** Manager::RecordToFilterVals(Stream* stream, Filter* filter, - RecordVal* columns) + RecordVal* columns) { - RecordVal* ext_rec = nullptr; + IntrusivePtr ext_rec; + if ( filter->num_ext_fields > 0 ) { val_list vl{filter->path_val->Ref()}; - Val* res = filter->ext_func->Call(&vl); + auto res = filter->ext_func->Call(&vl); + if ( res ) - ext_rec = res->AsRecordVal(); + ext_rec = {AdoptRef{}, res.release()->AsRecordVal()}; } threading::Value** vals = new threading::Value*[filter->num_fields]; @@ -1109,7 +1080,7 @@ threading::Value** Manager::RecordToFilterVals(Stream* stream, Filter* filter, continue; } - val = ext_rec; + val = ext_rec.get(); } else val = columns; @@ -1134,9 +1105,6 @@ threading::Value** Manager::RecordToFilterVals(Stream* stream, Filter* filter, vals[i] = ValToLogVal(val); } - if ( ext_rec ) - Unref(ext_rec); - return vals; } @@ -1326,12 +1294,11 @@ void Manager::SendAllWritersTo(const broker::endpoint_info& ei) WriterFrontend* writer = i->second->writer; auto writer_val = et->GetVal(i->first.first); broker_mgr->PublishLogCreate((*s)->id, - writer_val, + writer_val.get(), *i->second->info, writer->NumFields(), writer->Fields(), ei); - Unref(writer_val); } } } @@ -1551,10 +1518,10 @@ bool Manager::FinishedRotation(WriterFrontend* writer, const char* new_name, con // Create the RotationInfo record. RecordVal* info = new RecordVal(BifType::Record::Log::RotationInfo); info->Assign(0, winfo->type->Ref()); - info->Assign(1, new StringVal(new_name)); - info->Assign(2, new StringVal(winfo->writer->Info().path)); - info->Assign(3, new Val(open, TYPE_TIME)); - info->Assign(4, new Val(close, TYPE_TIME)); + info->Assign(1, make_intrusive(new_name)); + info->Assign(2, make_intrusive(winfo->writer->Info().path)); + info->Assign(3, make_intrusive(open, TYPE_TIME)); + info->Assign(4, make_intrusive(close, TYPE_TIME)); info->Assign(5, val_mgr->GetBool(terminating)); Func* func = winfo->postprocessor; @@ -1572,12 +1539,9 @@ bool Manager::FinishedRotation(WriterFrontend* writer, const char* new_name, con int result = 0; - Val* v = func->Call(&vl); + auto v = func->Call(&vl); if ( v ) - { result = v->AsBool(); - Unref(v); - } return result; } diff --git a/src/option.bif b/src/option.bif index 5355216ee7..13b2215923 100644 --- a/src/option.bif +++ b/src/option.bif @@ -7,10 +7,10 @@ module Option; #include "NetVar.h" #include "broker/Data.h" -static bool call_option_handlers_and_set_value(StringVal* name, ID* i, Val* val, +static bool call_option_handlers_and_set_value(StringVal* name, ID* i, + IntrusivePtr val, StringVal* location) { - val->Ref(); if ( i->HasOptionHandlers() ) { for ( auto handler_function : i->GetOptionHandlers() ) @@ -18,12 +18,13 @@ static bool call_option_handlers_and_set_value(StringVal* name, ID* i, Val* val, bool add_loc = handler_function->FType()->AsFuncType()->ArgTypes()->Types()->length() == 3; val_list vl(2 + add_loc); vl.push_back(name->Ref()); - vl.push_back(val); + vl.push_back(val->Ref()); if ( add_loc ) vl.push_back(location->Ref()); val = handler_function->Call(&vl); // consumed by next call. + if ( ! val ) { // Someone messed up, don't change value and just return @@ -33,8 +34,7 @@ static bool call_option_handlers_and_set_value(StringVal* name, ID* i, Val* val, } // clone to prevent changes - i->SetVal({AdoptRef{}, val->Clone()}); - Unref(val); // Either ref'd once or function call result. + i->SetVal(val->Clone()); return true; } %%} @@ -90,7 +90,7 @@ function Option::set%(ID: string, val: any, location: string &default=""%): bool return val_mgr->GetBool(0); } - auto rval = call_option_handlers_and_set_value(ID, i, val_from_data.get(), location); + auto rval = call_option_handlers_and_set_value(ID, i, std::move(val_from_data), location); return val_mgr->GetBool(rval); } @@ -101,10 +101,10 @@ function Option::set%(ID: string, val: any, location: string &default=""%): bool val->Type()->AsTableType()->IsUnspecifiedTable() ) { // Just coerce an empty/unspecified table to the right type. - auto tv = new TableVal(i->Type()->AsTableType(), - i->ID_Val()->AsTableVal()->Attrs()); - auto rval = call_option_handlers_and_set_value(ID, i, tv, location); - Unref(tv); + auto tv = make_intrusive( + IntrusivePtr{NewRef{}, i->Type()->AsTableType()}, + IntrusivePtr{NewRef{}, i->ID_Val()->AsTableVal()->Attrs()}); + auto rval = call_option_handlers_and_set_value(ID, i, std::move(tv), location); return val_mgr->GetBool(rval); } @@ -113,7 +113,7 @@ function Option::set%(ID: string, val: any, location: string &default=""%): bool return val_mgr->GetBool(0); } - auto rval = call_option_handlers_and_set_value(ID, i, val, location); + auto rval = call_option_handlers_and_set_value(ID, i, {NewRef{}, val}, location); return val_mgr->GetBool(rval); %} diff --git a/src/parse.y b/src/parse.y index 0e0145776c..7f379d44ec 100644 --- a/src/parse.y +++ b/src/parse.y @@ -702,7 +702,7 @@ expr: if ( ! id->Type() ) { id->Error("undeclared variable"); - id->SetType({AdoptRef{}, error_type()}); + id->SetType(error_type()); $$ = new NameExpr(std::move(id)); } @@ -713,7 +713,7 @@ expr: id->Name()); if ( intval < 0 ) reporter->InternalError("enum value not found for %s", id->Name()); - $$ = new ConstExpr({AdoptRef{}, t->GetVal(intval)}); + $$ = new ConstExpr(t->GetVal(intval)); } else { @@ -844,84 +844,84 @@ enum_body_elem: type: TOK_BOOL { set_location(@1); - $$ = base_type(TYPE_BOOL); + $$ = base_type(TYPE_BOOL).release(); } | TOK_INT { set_location(@1); - $$ = base_type(TYPE_INT); + $$ = base_type(TYPE_INT).release(); } | TOK_COUNT { set_location(@1); - $$ = base_type(TYPE_COUNT); + $$ = base_type(TYPE_COUNT).release(); } | TOK_COUNTER { set_location(@1); - $$ = base_type(TYPE_COUNTER); + $$ = base_type(TYPE_COUNTER).release(); } | TOK_DOUBLE { set_location(@1); - $$ = base_type(TYPE_DOUBLE); + $$ = base_type(TYPE_DOUBLE).release(); } | TOK_TIME { set_location(@1); - $$ = base_type(TYPE_TIME); + $$ = base_type(TYPE_TIME).release(); } | TOK_INTERVAL { set_location(@1); - $$ = base_type(TYPE_INTERVAL); + $$ = base_type(TYPE_INTERVAL).release(); } | TOK_STRING { set_location(@1); - $$ = base_type(TYPE_STRING); + $$ = base_type(TYPE_STRING).release(); } | TOK_PATTERN { set_location(@1); - $$ = base_type(TYPE_PATTERN); + $$ = base_type(TYPE_PATTERN).release(); } | TOK_TIMER { set_location(@1); - $$ = base_type(TYPE_TIMER); + $$ = base_type(TYPE_TIMER).release(); } | TOK_PORT { set_location(@1); - $$ = base_type(TYPE_PORT); + $$ = base_type(TYPE_PORT).release(); } | TOK_ADDR { set_location(@1); - $$ = base_type(TYPE_ADDR); + $$ = base_type(TYPE_ADDR).release(); } | TOK_SUBNET { set_location(@1); - $$ = base_type(TYPE_SUBNET); + $$ = base_type(TYPE_SUBNET).release(); } | TOK_ANY { set_location(@1); - $$ = base_type(TYPE_ANY); + $$ = base_type(TYPE_ANY).release(); } | TOK_TABLE '[' type_list ']' TOK_OF type { set_location(@1, @6); - $$ = new TableType($3, $6); + $$ = new TableType({AdoptRef{}, $3}, {AdoptRef{}, $6}); } | TOK_SET '[' type_list ']' { set_location(@1, @4); - $$ = new SetType($3, 0); + $$ = new SetType({AdoptRef{}, $3}, nullptr); } | TOK_RECORD '{' @@ -967,7 +967,7 @@ type: | TOK_VECTOR TOK_OF type { set_location(@1, @3); - $$ = new VectorType($3); + $$ = new VectorType({AdoptRef{}, $3}); } | TOK_FUNCTION func_params @@ -979,19 +979,19 @@ type: | TOK_EVENT '(' formal_args ')' { set_location(@1, @3); - $$ = new FuncType($3, 0, FUNC_FLAVOR_EVENT); + $$ = new FuncType({AdoptRef{}, $3}, nullptr, FUNC_FLAVOR_EVENT); } | TOK_HOOK '(' formal_args ')' { set_location(@1, @3); - $$ = new FuncType($3, base_type(TYPE_BOOL), FUNC_FLAVOR_HOOK); + $$ = new FuncType({AdoptRef{}, $3}, base_type(TYPE_BOOL), FUNC_FLAVOR_HOOK); } | TOK_FILE TOK_OF type { set_location(@1, @3); - $$ = new FileType($3); + $$ = new FileType({AdoptRef{}, $3}); } | TOK_FILE @@ -1013,7 +1013,7 @@ type: NullStmt here; if ( $1 ) $1->Error("not a Zeek type", &here); - $$ = error_type(); + $$ = error_type().release(); } else { @@ -1027,11 +1027,11 @@ type: type_list: type_list ',' type - { $1->AppendEvenIfNotPure($3); } + { $1->AppendEvenIfNotPure({AdoptRef{}, $3}); } | type { - $$ = new TypeList($1); - $$->Append($1); + $$ = new TypeList({NewRef{}, $1}); + $$->Append({AdoptRef{}, $1}); } ; @@ -1050,7 +1050,7 @@ type_decl: TOK_ID ':' type opt_attr ';' { set_location(@1, @4); - $$ = new TypeDecl($3, $1, $4, (in_record > 0)); + $$ = new TypeDecl({AdoptRef{}, $3}, $1, $4, (in_record > 0)); if ( in_record > 0 && cur_decl_type_id ) zeekygen_mgr->RecordField(cur_decl_type_id, $$, ::filename); @@ -1079,7 +1079,7 @@ formal_args_decl: TOK_ID ':' type opt_attr { set_location(@1, @4); - $$ = new TypeDecl($3, $1, $4, true); + $$ = new TypeDecl({AdoptRef{}, $3}, $1, $4, true); } ; @@ -1119,7 +1119,7 @@ decl: IntrusivePtr id{AdoptRef{}, $2}; IntrusivePtr init{AdoptRef{}, $5}; add_global(id.get(), {AdoptRef{}, $3}, $4, init, $6, VAR_REDEF); - zeekygen_mgr->Redef(id.get(), ::filename, $4, init.release()); + zeekygen_mgr->Redef(id.get(), ::filename, $4, std::move(init)); } | TOK_REDEF TOK_ENUM global_id TOK_ADD_TO '{' @@ -1261,8 +1261,8 @@ anonymous_function: // a lambda expression. // Gather the ingredients for a BroFunc from the current scope - auto ingredients = std::make_unique(current_scope(), $5); - id_list outer_ids = gather_outer_ids(pop_scope().get(), $5); + auto ingredients = std::make_unique(IntrusivePtr{NewRef{}, current_scope()}, IntrusivePtr{AdoptRef{}, $5}); + id_list outer_ids = gather_outer_ids(pop_scope().get(), ingredients->body.get()); $$ = new LambdaExpr(std::move(ingredients), std::move(outer_ids)); } @@ -1278,9 +1278,9 @@ begin_func: func_params: '(' formal_args ')' ':' type - { $$ = new FuncType($2, $5, FUNC_FLAVOR_FUNCTION); } + { $$ = new FuncType({AdoptRef{}, $2}, {AdoptRef{}, $5}, FUNC_FLAVOR_FUNCTION); } | '(' formal_args ')' - { $$ = new FuncType($2, base_type(TYPE_VOID), FUNC_FLAVOR_FUNCTION); } + { $$ = new FuncType({AdoptRef{}, $2}, base_type(TYPE_VOID), FUNC_FLAVOR_FUNCTION); } ; opt_type: @@ -1351,31 +1351,31 @@ attr_list: attr: TOK_ATTR_DEFAULT '=' expr - { $$ = new Attr(ATTR_DEFAULT, $3); } + { $$ = new Attr(ATTR_DEFAULT, {AdoptRef{}, $3}); } | TOK_ATTR_OPTIONAL { $$ = new Attr(ATTR_OPTIONAL); } | TOK_ATTR_REDEF { $$ = new Attr(ATTR_REDEF); } | TOK_ATTR_ADD_FUNC '=' expr - { $$ = new Attr(ATTR_ADD_FUNC, $3); } + { $$ = new Attr(ATTR_ADD_FUNC, {AdoptRef{}, $3}); } | TOK_ATTR_DEL_FUNC '=' expr - { $$ = new Attr(ATTR_DEL_FUNC, $3); } + { $$ = new Attr(ATTR_DEL_FUNC, {AdoptRef{}, $3}); } | TOK_ATTR_ON_CHANGE '=' expr - { $$ = new Attr(ATTR_ON_CHANGE, $3); } + { $$ = new Attr(ATTR_ON_CHANGE, {AdoptRef{}, $3}); } | TOK_ATTR_EXPIRE_FUNC '=' expr - { $$ = new Attr(ATTR_EXPIRE_FUNC, $3); } + { $$ = new Attr(ATTR_EXPIRE_FUNC, {AdoptRef{}, $3}); } | TOK_ATTR_EXPIRE_CREATE '=' expr - { $$ = new Attr(ATTR_EXPIRE_CREATE, $3); } + { $$ = new Attr(ATTR_EXPIRE_CREATE, {AdoptRef{}, $3}); } | TOK_ATTR_EXPIRE_READ '=' expr - { $$ = new Attr(ATTR_EXPIRE_READ, $3); } + { $$ = new Attr(ATTR_EXPIRE_READ, {AdoptRef{}, $3}); } | TOK_ATTR_EXPIRE_WRITE '=' expr - { $$ = new Attr(ATTR_EXPIRE_WRITE, $3); } + { $$ = new Attr(ATTR_EXPIRE_WRITE, {AdoptRef{}, $3}); } | TOK_ATTR_RAW_OUTPUT { $$ = new Attr(ATTR_RAW_OUTPUT); } | TOK_ATTR_PRIORITY '=' expr - { $$ = new Attr(ATTR_PRIORITY, $3); } + { $$ = new Attr(ATTR_PRIORITY, {AdoptRef{}, $3}); } | TOK_ATTR_TYPE_COLUMN '=' expr - { $$ = new Attr(ATTR_TYPE_COLUMN, $3); } + { $$ = new Attr(ATTR_TYPE_COLUMN, {AdoptRef{}, $3}); } | TOK_ATTR_LOG { $$ = new Attr(ATTR_LOG); } | TOK_ATTR_ERROR_HANDLER @@ -1385,7 +1385,7 @@ attr: | TOK_ATTR_DEPRECATED '=' TOK_CONSTANT { if ( IsString($3->Type()->Tag()) ) - $$ = new Attr(ATTR_DEPRECATED, new ConstExpr({AdoptRef{}, $3})); + $$ = new Attr(ATTR_DEPRECATED, make_intrusive(IntrusivePtr{AdoptRef{}, $3})); else { ODesc d; diff --git a/src/probabilistic/Topk.cc b/src/probabilistic/Topk.cc index c177ba4545..94c357357a 100644 --- a/src/probabilistic/Topk.cc +++ b/src/probabilistic/Topk.cc @@ -27,8 +27,8 @@ void TopkVal::Typify(BroType* t) { assert(!hash && !type); type = t->Ref(); - auto tl = make_intrusive(t); - tl->Append(t->Ref()); + auto tl = make_intrusive(IntrusivePtr{NewRef{}, t}); + tl->Append({NewRef{}, t}); hash = new CompositeHash(std::move(tl)); } @@ -184,11 +184,11 @@ void TopkVal::Merge(const TopkVal* value, bool doPrune) } } -Val* TopkVal::DoClone(CloneState* state) +IntrusivePtr TopkVal::DoClone(CloneState* state) { - auto clone = new TopkVal(size); + auto clone = make_intrusive(size); clone->Merge(this); - return state->NewClone(this, clone); + return state->NewClone(this, std::move(clone)); } VectorVal* TopkVal::GetTopK(int k) const // returns vector @@ -199,9 +199,9 @@ VectorVal* TopkVal::GetTopK(int k) const // returns vector return 0; } - TypeList* vector_index = new TypeList(type); - vector_index->Append(type->Ref()); - VectorType* v = new VectorType(vector_index); + auto vector_index = make_intrusive(IntrusivePtr{NewRef{}, type}); + vector_index->Append({NewRef{}, type}); + VectorType* v = new VectorType(std::move(vector_index)); VectorVal* t = new VectorVal(v); // this does no estimation if the results is correct! diff --git a/src/probabilistic/Topk.h b/src/probabilistic/Topk.h index 70df145e19..4a2c60e8b7 100644 --- a/src/probabilistic/Topk.h +++ b/src/probabilistic/Topk.h @@ -127,7 +127,7 @@ public: * * @returns cloned TopkVal */ - Val* DoClone(CloneState* state) override; + IntrusivePtr DoClone(CloneState* state) override; DECLARE_OPAQUE_VALUE(TopkVal) diff --git a/src/reporter.bif b/src/reporter.bif index c1f2d16430..00635947fb 100644 --- a/src/reporter.bif +++ b/src/reporter.bif @@ -153,7 +153,7 @@ function Reporter::file_weird%(name: string, f: fa_file, addl: string &default=" ## Returns: Current weird sampling whitelist function Reporter::get_weird_sampling_whitelist%(%): string_set %{ - TableVal* set = new TableVal(string_set); + TableVal* set = new TableVal({NewRef{}, string_set}); for ( auto el : reporter->GetWeirdSamplingWhitelist() ) { auto idx = make_intrusive(el); diff --git a/src/scan.l b/src/scan.l index 778615dba6..682f5c39c8 100644 --- a/src/scan.l +++ b/src/scan.l @@ -526,7 +526,7 @@ F RET_CONST(val_mgr->GetFalse()) "0x"{HEX}+ RET_CONST(val_mgr->GetCount(static_cast(strtoull(yytext, 0, 16)))) -{H}("."{H})+ RET_CONST(dns_mgr->LookupHost(yytext)) +{H}("."{H})+ RET_CONST(dns_mgr->LookupHost(yytext).release()) \"([^\\\n\"]|{ESCSEQ})*\" { const char* text = yytext; diff --git a/src/stats.bif b/src/stats.bif index 522bfe8913..911799ac4b 100644 --- a/src/stats.bif +++ b/src/stats.bif @@ -152,11 +152,11 @@ function get_proc_stats%(%): ProcStats r->Assign(n++, val_mgr->GetCount(0)); #endif - r->Assign(n++, new Val(bro_start_time, TYPE_TIME)); + r->Assign(n++, make_intrusive(bro_start_time, TYPE_TIME)); - r->Assign(n++, new IntervalVal(elapsed_time, Seconds)); - r->Assign(n++, new IntervalVal(user_time, Seconds)); - r->Assign(n++, new IntervalVal(system_time, Seconds)); + r->Assign(n++, make_intrusive(elapsed_time, Seconds)); + r->Assign(n++, make_intrusive(user_time, Seconds)); + r->Assign(n++, make_intrusive(system_time, Seconds)); uint64_t total_mem; get_memory_usage(&total_mem, NULL); @@ -470,7 +470,7 @@ function get_reporter_stats%(%): ReporterStats RecordVal* r = new RecordVal(ReporterStats); int n = 0; - TableVal* weirds_by_type = new TableVal(internal_type("table_string_of_count")->AsTableType()); + TableVal* weirds_by_type = new TableVal({NewRef{}, internal_type("table_string_of_count")->AsTableType()}); for ( auto& kv : reporter->GetWeirdsByType() ) { diff --git a/src/strings.bif b/src/strings.bif index ae1f8292d1..61a09b89a2 100644 --- a/src/strings.bif +++ b/src/strings.bif @@ -78,42 +78,6 @@ function string_cat%(...%): string return new StringVal(s); %} -%%{ -int string_array_to_vs(TableVal* tbl, int start, int end, - vector& vs) - { - vs.clear(); - for ( int i = start; i <= end; ++i ) - { - Val* ind = val_mgr->GetCount(i); - Val* v = tbl->Lookup(ind); - if ( ! v ) - return 0; - vs.push_back(v->AsString()); -#if 0 - char* str = v->AsString()->Render(); - DEBUG_MSG("string_array[%d] = \"%s\"\n", i, str); - delete [] str; -#endif - Unref(ind); - } - return 1; - } - -int vs_to_string_array(vector& vs, TableVal* tbl, - int start, int end) - { - for ( int i = start, j = 0; i <= end; ++i, ++j ) - { - Val* ind = val_mgr->GetCount(i); - tbl->Assign(ind, new StringVal(vs[j]->Len(), - (const char *)vs[j]->Bytes())); - Unref(ind); - } - return 1; - } -%%} - ## Joins all values in the given vector of strings with a separator placed ## between each element. ## @@ -266,7 +230,7 @@ VectorVal* do_split_string(StringVal* str_val, RE_Matcher* re, int incl_sep, n=0; } - rval->Assign(num++, new StringVal(offset, (const char*) s)); + rval->Assign(num++, make_intrusive(offset, (const char*) s)); // No more separators will be needed if this is the end of string. if ( n <= 0 ) @@ -274,7 +238,7 @@ VectorVal* do_split_string(StringVal* str_val, RE_Matcher* re, int incl_sep, if ( incl_sep ) { // including the part that matches the pattern - rval->Assign(num++, new StringVal(end_of_match, (const char*) s+offset)); + rval->Assign(num++, make_intrusive(end_of_match, (const char*) s+offset)); } if ( max_num_sep && num_sep >= max_num_sep ) @@ -294,7 +258,7 @@ VectorVal* do_split_string(StringVal* str_val, RE_Matcher* re, int incl_sep, Val* do_split(StringVal* str_val, RE_Matcher* re, int incl_sep, int max_num_sep) { - TableVal* a = new TableVal(string_array); + TableVal* a = new TableVal({NewRef{}, string_array}); const u_char* s = str_val->Bytes(); int n = str_val->Len(); const u_char* end_of_s = s + n; @@ -322,7 +286,7 @@ Val* do_split(StringVal* str_val, RE_Matcher* re, int incl_sep, int max_num_sep) } Val* ind = val_mgr->GetCount(++num); - a->Assign(ind, new StringVal(offset, (const char*) s)); + a->Assign(ind, make_intrusive(offset, (const char*) s)); Unref(ind); // No more separators will be needed if this is the end of string. @@ -332,7 +296,7 @@ Val* do_split(StringVal* str_val, RE_Matcher* re, int incl_sep, int max_num_sep) if ( incl_sep ) { // including the part that matches the pattern ind = val_mgr->GetCount(++num); - a->Assign(ind, new StringVal(end_of_match, (const char*) s+offset)); + a->Assign(ind, make_intrusive(end_of_match, (const char*) s+offset)); Unref(ind); } @@ -759,7 +723,7 @@ function str_split%(s: string, idx: index_vec%): string_vec for ( BroString::VecIt it = result->begin(); it != result->end(); ++it, ++i ) - result_v->Assign(i, new StringVal(*it)); + result_v->Assign(i, make_intrusive(*it)); // StringVal now possesses string. delete result; @@ -946,7 +910,7 @@ function safe_shell_quote%(source: string%): string ## .. zeek:see: find_last strstr function find_all%(str: string, re: pattern%) : string_set %{ - TableVal* a = new TableVal(string_set); + TableVal* a = new TableVal({NewRef{}, string_set}); const u_char* s = str->Bytes(); const u_char* e = s + str->Len(); diff --git a/src/supervisor/Supervisor.cc b/src/supervisor/Supervisor.cc index b6a6068a46..3f511816c4 100644 --- a/src/supervisor/Supervisor.cc +++ b/src/supervisor/Supervisor.cc @@ -1099,29 +1099,26 @@ Supervisor::NodeConfig Supervisor::NodeConfig::FromJSON(std::string_view json) std::string Supervisor::NodeConfig::ToJSON() const { auto re = std::make_unique("^_"); - auto node_val = ToRecord(); - IntrusivePtr json_val{AdoptRef{}, node_val->ToJSON(false, re.get())}; - auto rval = json_val->ToStdString(); - return rval; + return ToRecord()->ToJSON(false, re.get())->ToStdString(); } IntrusivePtr Supervisor::NodeConfig::ToRecord() const { auto rt = BifType::Record::Supervisor::NodeConfig; auto rval = make_intrusive(rt); - rval->Assign(rt->FieldOffset("name"), new StringVal(name)); + rval->Assign(rt->FieldOffset("name"), make_intrusive(name)); if ( interface ) - rval->Assign(rt->FieldOffset("interface"), new StringVal(*interface)); + rval->Assign(rt->FieldOffset("interface"), make_intrusive(*interface)); if ( directory ) - rval->Assign(rt->FieldOffset("directory"), new StringVal(*directory)); + rval->Assign(rt->FieldOffset("directory"), make_intrusive(*directory)); if ( stdout_file ) - rval->Assign(rt->FieldOffset("stdout_file"), new StringVal(*stdout_file)); + rval->Assign(rt->FieldOffset("stdout_file"), make_intrusive(*stdout_file)); if ( stderr_file ) - rval->Assign(rt->FieldOffset("stderr_file"), new StringVal(*stderr_file)); + rval->Assign(rt->FieldOffset("stderr_file"), make_intrusive(*stderr_file)); if ( cpu_affinity ) rval->Assign(rt->FieldOffset("cpu_affinity"), val_mgr->GetInt(*cpu_affinity)); @@ -1131,10 +1128,10 @@ IntrusivePtr Supervisor::NodeConfig::ToRecord() const rval->Assign(rt->FieldOffset("scripts"), scripts_val); for ( const auto& s : scripts ) - scripts_val->Assign(scripts_val->Size(), new StringVal(s)); + scripts_val->Assign(scripts_val->Size(), make_intrusive(s)); auto tt = BifType::Record::Supervisor::NodeConfig->FieldType("cluster"); - auto cluster_val = new TableVal(tt->AsTableType()); + auto cluster_val = new TableVal({NewRef{}, tt->AsTableType()}); rval->Assign(rt->FieldOffset("cluster"), cluster_val); for ( const auto& e : cluster ) @@ -1146,13 +1143,13 @@ IntrusivePtr Supervisor::NodeConfig::ToRecord() const auto val = make_intrusive(ept); val->Assign(ept->FieldOffset("role"), BifType::Enum::Supervisor::ClusterRole->GetVal(ep.role)); - val->Assign(ept->FieldOffset("host"), new AddrVal(ep.host)); + val->Assign(ept->FieldOffset("host"), make_intrusive(ep.host)); val->Assign(ept->FieldOffset("p"), val_mgr->GetPort(ep.port, TRANSPORT_TCP)); if ( ep.interface ) - val->Assign(ept->FieldOffset("interface"), new StringVal(*ep.interface)); + val->Assign(ept->FieldOffset("interface"), make_intrusive(*ep.interface)); - cluster_val->Assign(key.get(), val.release()); + cluster_val->Assign(key.get(), std::move(val)); } return rval; @@ -1163,7 +1160,7 @@ IntrusivePtr Supervisor::Node::ToRecord() const auto rt = BifType::Record::Supervisor::NodeStatus; auto rval = make_intrusive(rt); - rval->Assign(rt->FieldOffset("node"), config.ToRecord().release()); + rval->Assign(rt->FieldOffset("node"), config.ToRecord()); if ( pid ) rval->Assign(rt->FieldOffset("pid"), val_mgr->GetInt(pid)); @@ -1172,7 +1169,7 @@ IntrusivePtr Supervisor::Node::ToRecord() const } -static Val* supervisor_role_to_cluster_node_type(BifEnum::Supervisor::ClusterRole role) +static IntrusivePtr supervisor_role_to_cluster_node_type(BifEnum::Supervisor::ClusterRole role) { static auto node_type = global_scope()->Lookup("Cluster::NodeType")->AsType()->AsEnumType(); @@ -1218,19 +1215,19 @@ bool Supervisor::SupervisedNode::InitCluster() const auto val = make_intrusive(cluster_node_type); auto node_type = supervisor_role_to_cluster_node_type(ep.role); - val->Assign(cluster_node_type->FieldOffset("node_type"), node_type); - val->Assign(cluster_node_type->FieldOffset("ip"), new AddrVal(ep.host)); + val->Assign(cluster_node_type->FieldOffset("node_type"), std::move(node_type)); + val->Assign(cluster_node_type->FieldOffset("ip"), make_intrusive(ep.host)); val->Assign(cluster_node_type->FieldOffset("p"), val_mgr->GetPort(ep.port, TRANSPORT_TCP)); if ( ep.interface ) val->Assign(cluster_node_type->FieldOffset("interface"), - new StringVal(*ep.interface)); + make_intrusive(*ep.interface)); if ( manager_name && ep.role != BifEnum::Supervisor::MANAGER ) val->Assign(cluster_node_type->FieldOffset("manager"), - new StringVal(*manager_name)); + make_intrusive(*manager_name)); - cluster_nodes->Assign(key.get(), val.release()); + cluster_nodes->Assign(key.get(), std::move(val)); } cluster_manager_is_logger_id->SetVal({AdoptRef{}, val_mgr->GetBool(! has_logger)}); @@ -1318,7 +1315,7 @@ RecordVal* Supervisor::Status(std::string_view node_name) { auto rval = new RecordVal(BifType::Record::Supervisor::Status); auto tt = BifType::Record::Supervisor::Status->FieldType("nodes"); - auto node_table_val = new TableVal(tt->AsTableType()); + auto node_table_val = new TableVal({NewRef{}, tt->AsTableType()}); rval->Assign(0, node_table_val); if ( node_name.empty() ) @@ -1329,7 +1326,7 @@ RecordVal* Supervisor::Status(std::string_view node_name) const auto& node = n.second; auto key = make_intrusive(name); auto val = node.ToRecord(); - node_table_val->Assign(key.get(), val.release()); + node_table_val->Assign(key.get(), std::move(val)); } } else @@ -1343,7 +1340,7 @@ RecordVal* Supervisor::Status(std::string_view node_name) const auto& node = it->second; auto key = make_intrusive(name); auto val = node.ToRecord(); - node_table_val->Assign(key.get(), val.release()); + node_table_val->Assign(key.get(), std::move(val)); } return rval; diff --git a/src/zeek.bif b/src/zeek.bif index 272e1aa117..cbd7bc0b54 100644 --- a/src/zeek.bif +++ b/src/zeek.bif @@ -405,7 +405,7 @@ static bool prepare_environment(TableVal* tbl, bool set) for ( int i = 0; i < idxs->Length(); ++i ) { Val* key = idxs->Index(i); - Val* val = tbl->Lookup(key, false); + auto val = tbl->Lookup(key, false); if ( key->Type()->Tag() != TYPE_STRING || val->Type()->Tag() != TYPE_STRING ) @@ -1051,11 +1051,11 @@ function find_entropy%(data: string%): entropy_test_result e.Get(&ent, &chisq, &mean, &montepi, &scc); RecordVal* ent_result = new RecordVal(entropy_test_result); - ent_result->Assign(0, new Val(ent, TYPE_DOUBLE)); - ent_result->Assign(1, new Val(chisq, TYPE_DOUBLE)); - ent_result->Assign(2, new Val(mean, TYPE_DOUBLE)); - ent_result->Assign(3, new Val(montepi, TYPE_DOUBLE)); - ent_result->Assign(4, new Val(scc, TYPE_DOUBLE)); + ent_result->Assign(0, make_intrusive(ent, TYPE_DOUBLE)); + ent_result->Assign(1, make_intrusive(chisq, TYPE_DOUBLE)); + ent_result->Assign(2, make_intrusive(mean, TYPE_DOUBLE)); + ent_result->Assign(3, make_intrusive(montepi, TYPE_DOUBLE)); + ent_result->Assign(4, make_intrusive(scc, TYPE_DOUBLE)); return ent_result; %} @@ -1102,11 +1102,11 @@ function entropy_test_finish%(handle: opaque of entropy%): entropy_test_result static_cast(handle)->Get(&ent, &chisq, &mean, &montepi, &scc); RecordVal* ent_result = new RecordVal(entropy_test_result); - ent_result->Assign(0, new Val(ent, TYPE_DOUBLE)); - ent_result->Assign(1, new Val(chisq, TYPE_DOUBLE)); - ent_result->Assign(2, new Val(mean, TYPE_DOUBLE)); - ent_result->Assign(3, new Val(montepi, TYPE_DOUBLE)); - ent_result->Assign(4, new Val(scc, TYPE_DOUBLE)); + ent_result->Assign(0, make_intrusive(ent, TYPE_DOUBLE)); + ent_result->Assign(1, make_intrusive(chisq, TYPE_DOUBLE)); + ent_result->Assign(2, make_intrusive(mean, TYPE_DOUBLE)); + ent_result->Assign(3, make_intrusive(montepi, TYPE_DOUBLE)); + ent_result->Assign(4, make_intrusive(scc, TYPE_DOUBLE)); return ent_result; %} @@ -1176,7 +1176,7 @@ function matching_subnets%(search: subnet, t: any%): subnet_vec return nullptr; } - return t->AsTableVal()->LookupSubnets(search); + return t->AsTableVal()->LookupSubnets(search).release(); %} ## For a set[subnet]/table[subnet], create a new table that contains all entries @@ -1195,7 +1195,7 @@ function filter_subnet_table%(search: subnet, t: any%): any return nullptr; } - return t->AsTableVal()->LookupSubnetValues(search); + return t->AsTableVal()->LookupSubnetValues(search).release(); %} ## Checks if a specific subnet is a member of a set/table[subnet]. @@ -1339,9 +1339,8 @@ bool sort_function(Val* a, Val* b) sort_func_args.push_back(a->Ref()); sort_func_args.push_back(b->Ref()); - Val* result = sort_function_comp->Call(&sort_func_args); + auto result = sort_function_comp->Call(&sort_func_args); int int_result = result->CoerceToInt(); - Unref(result); return int_result < 0; } @@ -1834,10 +1833,7 @@ function record_type_to_vector%(rt: string%): string_vec if ( type ) { for ( int i = 0; i < type->NumFields(); ++i ) - { - StringVal* val = new StringVal(type->FieldName(i)); - result->Assign(i+1, val); - } + result->Assign(i+1, make_intrusive(type->FieldName(i))); } return result; @@ -1866,7 +1862,7 @@ function zeek_args%(%): string_vec auto rval = make_intrusive(sv); for ( auto i = 0; i < bro_argc; ++i ) - rval->Assign(rval->Size(), new StringVal(bro_argv[i])); + rval->Assign(rval->Size(), make_intrusive(bro_argv[i])); return rval.release(); %} @@ -1907,7 +1903,7 @@ function packet_source%(%): PacketSource if ( ps ) { r->Assign(0, val_mgr->GetBool(ps->IsLive())); - r->Assign(1, new StringVal(ps->Path())); + r->Assign(1, make_intrusive(ps->Path())); r->Assign(2, val_mgr->GetInt(ps->LinkType())); r->Assign(3, val_mgr->GetCount(ps->Netmask())); } @@ -1923,12 +1919,12 @@ function packet_source%(%): PacketSource ## .. zeek:see:: global_ids function global_sizes%(%): var_sizes %{ - TableVal* sizes = new TableVal(var_sizes); + TableVal* sizes = new TableVal({NewRef{}, var_sizes}); const auto& globals = global_scope()->Vars(); for ( const auto& global : globals ) { - ID* id = global.second; + ID* id = global.second.get(); if ( id->HasVal() ) { Val* id_name = new StringVal(id->Name()); @@ -1951,14 +1947,14 @@ function global_sizes%(%): var_sizes ## .. zeek:see:: global_sizes function global_ids%(%): id_table %{ - TableVal* ids = new TableVal(id_table); + TableVal* ids = new TableVal({NewRef{}, id_table}); const auto& globals = global_scope()->Vars(); for ( const auto& global : globals ) { - ID* id = global.second; - RecordVal* rec = new RecordVal(script_id); - rec->Assign(0, new StringVal(type_name(id->Type()->Tag()))); + ID* id = global.second.get(); + auto rec = make_intrusive(script_id); + rec->Assign(0, make_intrusive(type_name(id->Type()->Tag()))); rec->Assign(1, val_mgr->GetBool(id->IsExport())); rec->Assign(2, val_mgr->GetBool(id->IsConst())); rec->Assign(3, val_mgr->GetBool(id->IsEnumConst())); @@ -1972,9 +1968,8 @@ function global_ids%(%): id_table rec->Assign(6, val); } - Val* id_name = new StringVal(id->Name()); - ids->Assign(id_name, rec); - Unref(id_name); + auto id_name = make_intrusive(id->Name()); + ids->Assign(id_name.get(), std::move(rec)); } return ids; @@ -2014,13 +2009,13 @@ function record_fields%(rec: any%): record_field_table if ( ! id || ! id->AsType() || id->AsType()->Tag() != TYPE_RECORD ) { reporter->Error("record_fields string argument does not name a record type"); - return new TableVal(internal_type("record_field_table")->AsTableType()); + return new TableVal({NewRef{}, internal_type("record_field_table")->AsTableType()}); } - return id->AsType()->AsRecordType()->GetRecordFieldsVal(); + return id->AsType()->AsRecordType()->GetRecordFieldsVal().release(); } - return rec->GetRecordFields(); + return rec->GetRecordFields().release(); %} ## Enables detailed collection of profiling statistics. Statistics include @@ -2213,7 +2208,7 @@ function routing0_data_to_addrs%(s: string%): addr_vec while ( len > 0 ) { IPAddr a(IPv6, (const uint32_t*) bytes, IPAddr::Network); - rval->Assign(rval->Size(), new AddrVal(a)); + rval->Assign(rval->Size(), make_intrusive(a)); bytes += 16; len -= 16; } @@ -3223,20 +3218,16 @@ EnumVal* map_conn_type(TransportProto tp) { switch ( tp ) { case TRANSPORT_UNKNOWN: - return transport_proto->GetVal(0); - break; + return transport_proto->GetVal(0).release(); case TRANSPORT_TCP: - return transport_proto->GetVal(1); - break; + return transport_proto->GetVal(1).release(); case TRANSPORT_UDP: - return transport_proto->GetVal(2); - break; + return transport_proto->GetVal(2).release(); case TRANSPORT_ICMP: - return transport_proto->GetVal(3); - break; + return transport_proto->GetVal(3).release(); default: reporter->InternalError("bad connection type in map_conn_type()"); @@ -3262,7 +3253,7 @@ function get_conn_transport_proto%(cid: conn_id%): transport_proto if ( ! c ) { builtin_error("unknown connection id in get_conn_transport_proto()", cid); - return transport_proto->GetVal(0); + return transport_proto->GetVal(0).release(); } return map_conn_type(c->ConnTransport()); @@ -3317,26 +3308,26 @@ function lookup_connection%(cid: conn_id%): connection RecordVal* c = new RecordVal(connection_type); RecordVal* id_val = new RecordVal(conn_id); - id_val->Assign(0, new AddrVal((unsigned int) 0)); + id_val->Assign(0, make_intrusive((unsigned int) 0)); id_val->Assign(1, val_mgr->GetPort(ntohs(0), TRANSPORT_UDP)); - id_val->Assign(2, new AddrVal((unsigned int) 0)); + id_val->Assign(2, make_intrusive((unsigned int) 0)); id_val->Assign(3, val_mgr->GetPort(ntohs(0), TRANSPORT_UDP)); c->Assign(0, id_val); - RecordVal* orig_endp = new RecordVal(endpoint); + auto orig_endp = make_intrusive(endpoint); orig_endp->Assign(0, val_mgr->GetCount(0)); orig_endp->Assign(1, val_mgr->GetCount(int(0))); - RecordVal* resp_endp = new RecordVal(endpoint); + auto resp_endp = make_intrusive(endpoint); resp_endp->Assign(0, val_mgr->GetCount(0)); resp_endp->Assign(1, val_mgr->GetCount(int(0))); - c->Assign(1, orig_endp); - c->Assign(2, resp_endp); + c->Assign(1, std::move(orig_endp)); + c->Assign(2, std::move(resp_endp)); - c->Assign(3, new Val(network_time, TYPE_TIME)); - c->Assign(4, new Val(0.0, TYPE_INTERVAL)); - c->Assign(5, new TableVal(string_set)); // service + c->Assign(3, make_intrusive(network_time, TYPE_TIME)); + c->Assign(4, make_intrusive(0.0, TYPE_INTERVAL)); + c->Assign(5, make_intrusive(IntrusivePtr{NewRef{}, string_set})); // service c->Assign(6, val_mgr->GetEmptyString()); // history return c; @@ -3417,7 +3408,7 @@ function get_current_packet%(%) : pcap_packet pkt->Assign(1, val_mgr->GetCount(uint32_t(p->ts.tv_usec))); pkt->Assign(2, val_mgr->GetCount(p->cap_len)); pkt->Assign(3, val_mgr->GetCount(p->len)); - pkt->Assign(4, new StringVal(p->cap_len, (const char*)p->data)); + pkt->Assign(4, make_intrusive(p->cap_len, (const char*)p->data)); pkt->Assign(5, BifType::Enum::link_encap->GetVal(p->link_type)); return pkt; @@ -4618,8 +4609,8 @@ function rotate_file%(f: file%): rotate_info info = new RecordVal(rotate_info); info->Assign(0, val_mgr->GetEmptyString()); info->Assign(1, val_mgr->GetEmptyString()); - info->Assign(2, new Val(0.0, TYPE_TIME)); - info->Assign(3, new Val(0.0, TYPE_TIME)); + info->Assign(2, make_intrusive(0.0, TYPE_TIME)); + info->Assign(3, make_intrusive(0.0, TYPE_TIME)); return info; %} @@ -4659,8 +4650,8 @@ function rotate_file_by_name%(f: string%): rotate_info // Record indicating error. info->Assign(0, val_mgr->GetEmptyString()); info->Assign(1, val_mgr->GetEmptyString()); - info->Assign(2, new Val(0.0, TYPE_TIME)); - info->Assign(3, new Val(0.0, TYPE_TIME)); + info->Assign(2, make_intrusive(0.0, TYPE_TIME)); + info->Assign(3, make_intrusive(0.0, TYPE_TIME)); return info; } @@ -4668,12 +4659,12 @@ function rotate_file_by_name%(f: string%): rotate_info if ( is_pkt_dumper ) { - info->Assign(2, new Val(pkt_dumper->OpenTime(), TYPE_TIME)); + info->Assign(2, make_intrusive(pkt_dumper->OpenTime(), TYPE_TIME)); pkt_dumper->Open(); } if ( is_addl_pkt_dumper ) - info->Assign(2, new Val(addl_pkt_dumper->OpenTime(), TYPE_TIME)); + info->Assign(2, make_intrusive(addl_pkt_dumper->OpenTime(), TYPE_TIME)); return info; %} @@ -5100,5 +5091,5 @@ function anonymize_addr%(a: addr, cl: IPAddrAnonymizationClass%): addr ## .. zeek:see:: fmt cat cat_sep string_cat print_raw function to_json%(val: any, only_loggable: bool &default=F, field_escape_pattern: pattern &default=/^_/%): string %{ - return val->ToJSON(only_loggable, field_escape_pattern); + return val->ToJSON(only_loggable, field_escape_pattern).release(); %} diff --git a/src/zeekygen/IdentifierInfo.cc b/src/zeekygen/IdentifierInfo.cc index 49ae1ad856..e95de1ea9e 100644 --- a/src/zeekygen/IdentifierInfo.cc +++ b/src/zeekygen/IdentifierInfo.cc @@ -17,7 +17,7 @@ IdentifierInfo::IdentifierInfo(IntrusivePtr arg_id, ScriptInfo* script) last_field_seen(), declaring_script(script) { if ( id->ID_Val() && (id->IsOption() || id->IsRedefinable()) ) - initial_val = {AdoptRef{}, id->ID_Val()->Clone()}; + initial_val = id->ID_Val()->Clone(); } IdentifierInfo::~IdentifierInfo() @@ -32,9 +32,9 @@ IdentifierInfo::~IdentifierInfo() } void IdentifierInfo::AddRedef(const string& script, init_class ic, - Expr* init_expr, const vector& comments) + IntrusivePtr init_expr, const vector& comments) { - Redefinition* redef = new Redefinition(script, ic, init_expr, comments); + Redefinition* redef = new Redefinition(script, ic, std::move(init_expr), comments); redefs.push_back(redef); } @@ -142,49 +142,16 @@ time_t IdentifierInfo::DoGetModificationTime() const IdentifierInfo::Redefinition::Redefinition( std::string arg_script, init_class arg_ic, - Expr* arg_expr, + IntrusivePtr arg_expr, std::vector arg_comments) : from_script(std::move(arg_script)), ic(arg_ic), - init_expr(arg_expr ? arg_expr->Ref() : nullptr), + init_expr(std::move(arg_expr)), comments(std::move(arg_comments)) { } -IdentifierInfo::Redefinition::Redefinition(const IdentifierInfo::Redefinition& other) - { - from_script = other.from_script; - ic = other.ic; - init_expr = other.init_expr; - comments = other.comments; - - if ( init_expr ) - init_expr->Ref(); - } - -IdentifierInfo::Redefinition& -IdentifierInfo::Redefinition::operator=(const IdentifierInfo::Redefinition& other) - { - if ( &other == this ) - return *this; - - Unref(init_expr); - - from_script = other.from_script; - ic = other.ic; - init_expr = other.init_expr; - comments = other.comments; - - if ( init_expr ) - init_expr->Ref(); - - return *this; - } - -IdentifierInfo::Redefinition::~Redefinition() - { - Unref(init_expr); - } +IdentifierInfo::Redefinition::~Redefinition() = default; IdentifierInfo::RecordField::~RecordField() { diff --git a/src/zeekygen/IdentifierInfo.h b/src/zeekygen/IdentifierInfo.h index 947378d1f0..949a503664 100644 --- a/src/zeekygen/IdentifierInfo.h +++ b/src/zeekygen/IdentifierInfo.h @@ -71,7 +71,7 @@ public: * @param comments Comments associated with the redef statement. */ void AddRedef(const std::string& from_script, init_class ic, - Expr* init_expr, + IntrusivePtr init_expr, const std::vector& comments); /** @@ -128,17 +128,13 @@ public: struct Redefinition { std::string from_script; /**< Name of script doing the redef. */ init_class ic; - Expr* init_expr; + IntrusivePtr init_expr; std::vector comments; /**< Zeekygen comments on redef. */ Redefinition(std::string arg_script, init_class arg_ic, - Expr* arg_expr, + IntrusivePtr arg_expr, std::vector arg_comments); - Redefinition(const Redefinition& other); - - Redefinition& operator=(const Redefinition& other); - ~Redefinition(); }; diff --git a/src/zeekygen/Manager.cc b/src/zeekygen/Manager.cc index f9e4e48585..b61cb15404 100644 --- a/src/zeekygen/Manager.cc +++ b/src/zeekygen/Manager.cc @@ -7,6 +7,7 @@ #include "PackageInfo.h" #include "ScriptInfo.h" #include "IdentifierInfo.h" +#include "Expr.h" #include #include @@ -359,7 +360,7 @@ void Manager::RecordField(const ID* id, const TypeDecl* field, } void Manager::Redef(const ID* id, const string& path, - init_class ic, Expr* init_expr) + init_class ic, IntrusivePtr init_expr) { if ( disabled ) return; @@ -387,7 +388,7 @@ void Manager::Redef(const ID* id, const string& path, return; } - id_info->AddRedef(from_script, ic, init_expr, comment_buffer); + id_info->AddRedef(from_script, ic, std::move(init_expr), comment_buffer); script_info->AddRedef(id_info); comment_buffer.clear(); last_identifier_seen = id_info; @@ -395,6 +396,12 @@ void Manager::Redef(const ID* id, const string& path, id->Name(), from_script.c_str()); } +void Manager::Redef(const ID* id, const std::string& path, + init_class ic) + { + Redef(id, path, ic, nullptr); + } + void Manager::SummaryComment(const string& script, const string& comment) { if ( disabled ) diff --git a/src/zeekygen/Manager.h b/src/zeekygen/Manager.h index a22dada278..3c3b7a91b9 100644 --- a/src/zeekygen/Manager.h +++ b/src/zeekygen/Manager.h @@ -14,6 +14,7 @@ #include #include +template class IntrusivePtr; class TypeDecl; namespace zeekygen { @@ -138,7 +139,9 @@ public: * @param init_expr The intiialization expression that was used. */ void Redef(const ID* id, const std::string& path, - init_class ic = INIT_NONE, Expr* init_expr = nullptr); + init_class ic, IntrusivePtr init_expr); + void Redef(const ID* id, const std::string& path, + init_class ic = INIT_NONE); /** * Register Zeekygen script summary content. diff --git a/testing/btest/language/function-closures.zeek b/testing/btest/language/function-closures.zeek index 58f7ba9971..80112da0cf 100644 --- a/testing/btest/language/function-closures.zeek +++ b/testing/btest/language/function-closures.zeek @@ -34,6 +34,22 @@ function dog_maker(name: string, weight: count) : function (action: string) return dog; } +function make_lambda(start: count): function(): count + { + return function(): count + { + local dummy: string; + return 0; + }; + } + +event zeek_init() &priority=10 + { + # just checking use of unitialized locals "works" (doesn't crash) + local one = make_lambda(1); + local two = make_lambda(2); + } + event zeek_init() { # basic