Type: return IntrusivePtr

This commit is contained in:
Max Kellermann 2020-03-02 19:33:49 +01:00
parent 0a6ddfb6b5
commit ba35ebec4c
38 changed files with 319 additions and 334 deletions

View file

@ -180,7 +180,7 @@ char* CompositeHash::SingleValHash(int type_check, char* kp0,
for ( int i = 0; i < num_fields; ++i ) 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;
bool optional = (a && a->FindAttr(ATTR_OPTIONAL)); bool optional = (a && a->FindAttr(ATTR_OPTIONAL));
@ -249,9 +249,9 @@ char* CompositeHash::SingleValHash(int type_check, char* kp0,
if ( ! v->Type()->IsSet() ) if ( ! v->Type()->IsSet() )
{ {
Val* val = tv->Lookup(key); auto val = tv->Lookup(key);
if ( ! (kp1 = SingleValHash(type_check, kp1, val->Type(), if ( ! (kp1 = SingleValHash(type_check, kp1, val->Type(),
val, false)) ) val.get(), false)) )
{ {
Unref(lv); Unref(lv);
return 0; return 0;
@ -554,8 +554,8 @@ int CompositeHash::SingleTypeKeySize(BroType* bt, const Val* v,
if ( ! bt->IsSet() ) if ( ! bt->IsSet() )
{ {
Val* val = tv->Lookup(key); auto val = tv->Lookup(key);
sz = SingleTypeKeySize(val->Type(), val, type_check, sz, sz = SingleTypeKeySize(val->Type(), val.get(), type_check, sz,
false, calc_static_size); false, calc_static_size);
if ( ! sz ) if ( ! sz )
{ {
@ -772,7 +772,7 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0,
kp1 = reinterpret_cast<const char*>(kp+1); kp1 = reinterpret_cast<const char*>(kp+1);
if ( tag == TYPE_ENUM ) if ( tag == TYPE_ENUM )
pval = t->AsEnumType()->GetVal(*kp); pval = t->AsEnumType()->GetVal(*kp).release();
else if ( tag == TYPE_BOOL ) else if ( tag == TYPE_BOOL )
pval = val_mgr->GetBool(*kp); pval = val_mgr->GetBool(*kp);
else if ( tag == TYPE_INT ) else if ( tag == TYPE_INT )

View file

@ -755,14 +755,14 @@ IntrusivePtr<Val> BinaryExpr::SetFold(Val* v1, Val* v2) const
return {AdoptRef{}, tv1->Intersect(tv2)}; return {AdoptRef{}, tv1->Intersect(tv2)};
case EXPR_OR: case EXPR_OR:
result = v1->Clone()->AsTableVal(); result = v1->Clone().release()->AsTableVal();
if ( ! tv2->AddTo(result, false, false) ) if ( ! tv2->AddTo(result, false, false) )
reporter->InternalError("set union failed to type check"); reporter->InternalError("set union failed to type check");
return {AdoptRef{}, result}; return {AdoptRef{}, result};
case EXPR_SUB: case EXPR_SUB:
result = v1->Clone()->AsTableVal(); result = v1->Clone().release()->AsTableVal();
if ( ! tv2->RemoveFrom(result) ) if ( ! tv2->RemoveFrom(result) )
reporter->InternalError("set difference failed to type check"); reporter->InternalError("set difference failed to type check");
@ -909,7 +909,7 @@ IntrusivePtr<Val> CloneExpr::Eval(Frame* f) const
IntrusivePtr<Val> CloneExpr::Fold(Val* v) const IntrusivePtr<Val> CloneExpr::Fold(Val* v) const
{ {
return {AdoptRef{}, v->Clone()}; return v->Clone();
} }
IncrExpr::IncrExpr(BroExprTag arg_tag, IntrusivePtr<Expr> arg_op) IncrExpr::IncrExpr(BroExprTag arg_tag, IntrusivePtr<Expr> arg_op)
@ -1143,7 +1143,7 @@ IntrusivePtr<Val> SizeExpr::Eval(Frame* f) const
IntrusivePtr<Val> SizeExpr::Fold(Val* v) const IntrusivePtr<Val> SizeExpr::Fold(Val* v) const
{ {
return {AdoptRef{}, v->SizeVal()}; return v->SizeVal();
} }
AddExpr::AddExpr(IntrusivePtr<Expr> arg_op1, IntrusivePtr<Expr> arg_op2) AddExpr::AddExpr(IntrusivePtr<Expr> arg_op1, IntrusivePtr<Expr> arg_op2)
@ -2700,7 +2700,7 @@ IntrusivePtr<Val> IndexExpr::Fold(Val* v1, Val* v2) const
break; break;
case TYPE_TABLE: 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; break;
case TYPE_STRING: case TYPE_STRING:
@ -3053,8 +3053,7 @@ IntrusivePtr<Val> RecordConstructorExpr::InitVal(const BroType* t, IntrusivePtr<
if ( v ) if ( v )
{ {
RecordVal* rv = v->AsRecordVal(); RecordVal* rv = v->AsRecordVal();
IntrusivePtr<RecordVal> ar{AdoptRef{}, auto ar = rv->CoerceTo(t->AsRecordType(), aggr.get());
rv->CoerceTo(t->AsRecordType(), aggr.get())};
if ( ar ) if ( ar )
return ar; return ar;
@ -3669,9 +3668,7 @@ IntrusivePtr<Val> RecordCoerceExpr::InitVal(const BroType* t, IntrusivePtr<Val>
if ( v ) if ( v )
{ {
RecordVal* rv = v->AsRecordVal(); RecordVal* rv = v->AsRecordVal();
IntrusivePtr<Val> ar{AdoptRef{}, auto ar = rv->CoerceTo(t->AsRecordType(), aggr.release());
rv->CoerceTo(t->AsRecordType(), aggr.release())};
if ( ar ) if ( ar )
return ar; return ar;
} }
@ -3717,8 +3714,7 @@ IntrusivePtr<Val> RecordCoerceExpr::Fold(Val* v) const
field_type->Tag() == TYPE_RECORD && field_type->Tag() == TYPE_RECORD &&
! same_type(rhs_type, field_type) ) ! same_type(rhs_type, field_type) )
{ {
IntrusivePtr<Val> new_val{AdoptRef{}, auto new_val = rhs->AsRecordVal()->CoerceTo(field_type->AsRecordType());
rhs->AsRecordVal()->CoerceTo(field_type->AsRecordType())};
if ( new_val ) if ( new_val )
rhs = std::move(new_val); rhs = std::move(new_val);
@ -3749,11 +3745,11 @@ IntrusivePtr<Val> RecordCoerceExpr::Fold(Val* v) const
field_type->Tag() == TYPE_RECORD && field_type->Tag() == TYPE_RECORD &&
! same_type(def_type, field_type) ) ! same_type(def_type, field_type) )
{ {
Val* tmp = def_val->AsRecordVal()->CoerceTo( auto tmp = def_val->AsRecordVal()->CoerceTo(
field_type->AsRecordType()); field_type->AsRecordType());
if ( tmp ) if ( tmp )
def_val = {AdoptRef{}, tmp}; def_val = std::move(tmp);
} }
val->Assign(i, std::move(def_val)); val->Assign(i, std::move(def_val));
@ -4083,12 +4079,12 @@ IntrusivePtr<Val> InExpr::Fold(Val* v1, Val* v2) const
v2->Type()->Tag() == TYPE_SUBNET ) v2->Type()->Tag() == TYPE_SUBNET )
return {AdoptRef{}, val_mgr->GetBool(v2->AsSubNetVal()->Contains(v1->AsAddr()))}; return {AdoptRef{}, val_mgr->GetBool(v2->AsSubNetVal()->Contains(v1->AsAddr()))};
Val* res; bool res;
if ( is_vector(v2) ) if ( is_vector(v2) )
res = v2->AsVectorVal()->Lookup(v1); res = (bool)v2->AsVectorVal()->Lookup(v1);
else else
res = v2->AsTableVal()->Lookup(v1, false); res = (bool)v2->AsTableVal()->Lookup(v1, false);
return {AdoptRef{}, val_mgr->GetBool(res)}; return {AdoptRef{}, val_mgr->GetBool(res)};
} }

View file

@ -187,7 +187,7 @@ Frame* Frame::Clone() const
Ref(trigger); Ref(trigger);
for (int i = 0; i < size; i++) 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; return other;
} }
@ -215,8 +215,8 @@ static Val* clone_if_not_func(Val** frame, int offset, BroFunc* func,
} }
auto rval = v->Clone(); auto rval = v->Clone();
other->SetElement(offset, rval); other->SetElement(offset, rval.get());
return rval; return rval.release();
} }
Frame* Frame::SelectiveClone(const id_list& selection, BroFunc* func) const Frame* Frame::SelectiveClone(const id_list& selection, BroFunc* func) const

View file

@ -146,14 +146,14 @@ BroType* OpaqueVal::UnserializeType(const broker::data& data)
return base_type(static_cast<TypeTag>(*tag)); return base_type(static_cast<TypeTag>(*tag));
} }
Val* OpaqueVal::DoClone(CloneState* state) IntrusivePtr<Val> OpaqueVal::DoClone(CloneState* state)
{ {
auto d = OpaqueVal::Serialize(); auto d = OpaqueVal::Serialize();
if ( ! d ) if ( ! d )
return nullptr; return nullptr;
auto rval = OpaqueVal::Unserialize(std::move(*d)); auto rval = OpaqueVal::Unserialize(std::move(*d));
return state->NewClone(this, rval.release()); return state->NewClone(this, std::move(rval));
} }
bool HashVal::IsValid() const bool HashVal::IsValid() const
@ -223,9 +223,9 @@ MD5Val::~MD5Val()
EVP_MD_CTX_free(ctx); EVP_MD_CTX_free(ctx);
} }
Val* MD5Val::DoClone(CloneState* state) IntrusivePtr<Val> MD5Val::DoClone(CloneState* state)
{ {
auto out = new MD5Val(); auto out = make_intrusive<MD5Val>();
if ( IsValid() ) if ( IsValid() )
{ {
if ( ! out->Init() ) if ( ! out->Init() )
@ -233,7 +233,7 @@ Val* MD5Val::DoClone(CloneState* state)
EVP_MD_CTX_copy_ex(out->ctx, ctx); 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]) void MD5Val::digest(val_list& vlist, u_char result[MD5_DIGEST_LENGTH])
@ -374,9 +374,9 @@ SHA1Val::~SHA1Val()
EVP_MD_CTX_free(ctx); EVP_MD_CTX_free(ctx);
} }
Val* SHA1Val::DoClone(CloneState* state) IntrusivePtr<Val> SHA1Val::DoClone(CloneState* state)
{ {
auto out = new SHA1Val(); auto out = make_intrusive<SHA1Val>();
if ( IsValid() ) if ( IsValid() )
{ {
if ( ! out->Init() ) if ( ! out->Init() )
@ -384,7 +384,7 @@ Val* SHA1Val::DoClone(CloneState* state)
EVP_MD_CTX_copy_ex(out->ctx, ctx); 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]) void SHA1Val::digest(val_list& vlist, u_char result[SHA_DIGEST_LENGTH])
@ -518,9 +518,9 @@ SHA256Val::~SHA256Val()
EVP_MD_CTX_free(ctx); EVP_MD_CTX_free(ctx);
} }
Val* SHA256Val::DoClone(CloneState* state) IntrusivePtr<Val> SHA256Val::DoClone(CloneState* state)
{ {
auto out = new SHA256Val(); auto out = make_intrusive<SHA256Val>();
if ( IsValid() ) if ( IsValid() )
{ {
if ( ! out->Init() ) if ( ! out->Init() )
@ -528,7 +528,7 @@ Val* SHA256Val::DoClone(CloneState* state)
EVP_MD_CTX_copy_ex(out->ctx, ctx); 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]) void SHA256Val::digest(val_list& vlist, u_char result[SHA256_DIGEST_LENGTH])
@ -773,16 +773,16 @@ BloomFilterVal::BloomFilterVal(probabilistic::BloomFilter* bf)
bloom_filter = bf; bloom_filter = bf;
} }
Val* BloomFilterVal::DoClone(CloneState* state) IntrusivePtr<Val> BloomFilterVal::DoClone(CloneState* state)
{ {
if ( bloom_filter ) if ( bloom_filter )
{ {
auto bf = new BloomFilterVal(bloom_filter->Clone()); auto bf = make_intrusive<BloomFilterVal>(bloom_filter->Clone());
bf->Typify(type); 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<BloomFilterVal>());
} }
bool BloomFilterVal::Typify(BroType* arg_type) bool BloomFilterVal::Typify(BroType* arg_type)
@ -949,10 +949,10 @@ CardinalityVal::~CardinalityVal()
delete hash; delete hash;
} }
Val* CardinalityVal::DoClone(CloneState* state) IntrusivePtr<Val> CardinalityVal::DoClone(CloneState* state)
{ {
return state->NewClone(this, return state->NewClone(this,
new CardinalityVal(new probabilistic::CardinalityCounter(*c))); make_intrusive<CardinalityVal>(new probabilistic::CardinalityCounter(*c)));
} }
bool CardinalityVal::Typify(BroType* arg_type) bool CardinalityVal::Typify(BroType* arg_type)
@ -1097,10 +1097,10 @@ bool ParaglobVal::DoUnserialize(const broker::data& data)
return true; return true;
} }
Val* ParaglobVal::DoClone(CloneState* state) IntrusivePtr<Val> ParaglobVal::DoClone(CloneState* state)
{ {
try { try {
return new ParaglobVal return make_intrusive<ParaglobVal>
(std::make_unique<paraglob::Paraglob>(this->internal_paraglob->serialize())); (std::make_unique<paraglob::Paraglob>(this->internal_paraglob->serialize()));
} }
catch (const paraglob::underflow_error& e) catch (const paraglob::underflow_error& e)

View file

@ -140,7 +140,7 @@ protected:
* may also override this with a more efficient custom clone * may also override this with a more efficient custom clone
* implementation of their own. * implementation of their own.
*/ */
Val* DoClone(CloneState* state) override; IntrusivePtr<Val> DoClone(CloneState* state) override;
/** /**
* Helper function for derived class that need to record a type * Helper function for derived class that need to record a type
@ -191,7 +191,7 @@ public:
MD5Val(); MD5Val();
~MD5Val(); ~MD5Val();
Val* DoClone(CloneState* state) override; IntrusivePtr<Val> DoClone(CloneState* state) override;
protected: protected:
friend class Val; friend class Val;
@ -212,7 +212,7 @@ public:
SHA1Val(); SHA1Val();
~SHA1Val(); ~SHA1Val();
Val* DoClone(CloneState* state) override; IntrusivePtr<Val> DoClone(CloneState* state) override;
protected: protected:
friend class Val; friend class Val;
@ -233,7 +233,7 @@ public:
SHA256Val(); SHA256Val();
~SHA256Val(); ~SHA256Val();
Val* DoClone(CloneState* state) override; IntrusivePtr<Val> DoClone(CloneState* state) override;
protected: protected:
friend class Val; friend class Val;
@ -268,7 +268,7 @@ public:
explicit BloomFilterVal(probabilistic::BloomFilter* bf); explicit BloomFilterVal(probabilistic::BloomFilter* bf);
~BloomFilterVal() override; ~BloomFilterVal() override;
Val* DoClone(CloneState* state) override; IntrusivePtr<Val> DoClone(CloneState* state) override;
BroType* Type() const; BroType* Type() const;
bool Typify(BroType* type); bool Typify(BroType* type);
@ -304,7 +304,7 @@ public:
explicit CardinalityVal(probabilistic::CardinalityCounter*); explicit CardinalityVal(probabilistic::CardinalityCounter*);
~CardinalityVal() override; ~CardinalityVal() override;
Val* DoClone(CloneState* state) override; IntrusivePtr<Val> DoClone(CloneState* state) override;
void Add(const Val* val); void Add(const Val* val);
@ -327,7 +327,7 @@ class ParaglobVal : public OpaqueVal {
public: public:
explicit ParaglobVal(std::unique_ptr<paraglob::Paraglob> p); explicit ParaglobVal(std::unique_ptr<paraglob::Paraglob> p);
IntrusivePtr<VectorVal> Get(StringVal* &pattern); IntrusivePtr<VectorVal> Get(StringVal* &pattern);
Val* DoClone(CloneState* state) override; IntrusivePtr<Val> DoClone(CloneState* state) override;
bool operator==(const ParaglobVal& other) const; bool operator==(const ParaglobVal& other) const;
protected: protected:

View file

@ -202,9 +202,8 @@ static IntrusivePtr<EnumVal> lookup_enum_val(const char* module_name, const char
int index = et->Lookup(module_name, name); int index = et->Lookup(module_name, name);
assert(index >= 0); assert(index >= 0);
IntrusivePtr<EnumVal> rval{AdoptRef{}, et->GetVal(index)};
return rval; return et->GetVal(index);
} }
static void print_log(val_list* vals) static void print_log(val_list* vals)

View file

@ -2,6 +2,7 @@
#include "Tag.h" #include "Tag.h"
#include "Val.h" #include "Val.h"
#include "IntrusivePtr.h"
Tag::Tag(EnumType* etype, type_t arg_type, subtype_t arg_subtype) 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; subtype = arg_subtype;
int64_t i = (int64_t)(type) | ((int64_t)subtype << 31); int64_t i = (int64_t)(type) | ((int64_t)subtype << 31);
Ref(etype); Ref(etype);
val = etype->GetVal(i); val = etype->GetVal(i).release();
} }
Tag::Tag(EnumVal* arg_val) Tag::Tag(EnumVal* arg_val)
@ -85,7 +86,7 @@ EnumVal* Tag::AsEnumVal(EnumType* etype) const
{ {
assert(type == 0 && subtype == 0); assert(type == 0 && subtype == 0);
Ref(etype); Ref(etype);
val = etype->GetVal(0); val = etype->GetVal(0).release();
} }
return val; return val;

View file

@ -806,9 +806,9 @@ static string container_type_name(const BroType* ft)
return s; return s;
} }
TableVal* RecordType::GetRecordFieldsVal(const RecordVal* rv) const IntrusivePtr<TableVal> RecordType::GetRecordFieldsVal(const RecordVal* rv) const
{ {
auto rval = new TableVal(internal_type("record_field_table")->AsTableType()); auto rval = make_intrusive<TableVal>(internal_type("record_field_table")->AsTableType());
for ( int i = 0; i < NumFields(); ++i ) for ( int i = 0; i < NumFields(); ++i )
{ {
@ -1252,7 +1252,7 @@ EnumType::enum_name_list EnumType::Names() const
return n; return n;
} }
EnumVal* EnumType::GetVal(bro_int_t i) IntrusivePtr<EnumVal> EnumType::GetVal(bro_int_t i)
{ {
auto it = vals.find(i); auto it = vals.find(i);
EnumVal* rval; EnumVal* rval;
@ -1265,8 +1265,7 @@ EnumVal* EnumType::GetVal(bro_int_t i)
else else
rval = it->second; rval = it->second;
::Ref(rval); return {NewRef{}, rval};
return rval;
} }
void EnumType::DescribeReST(ODesc* d, bool roles_only) const void EnumType::DescribeReST(ODesc* d, bool roles_only) const

View file

@ -117,6 +117,7 @@ constexpr InternalTypeTag to_internal_type_tag(TypeTag tag) noexcept
// Returns the name of the type. // Returns the name of the type.
extern const char* type_name(TypeTag t); extern const char* type_name(TypeTag t);
template <class T> class IntrusivePtr;
class Expr; class Expr;
class Attributes; class Attributes;
class TypeList; class TypeList;
@ -539,7 +540,7 @@ public:
* @param rv an optional record value, if given the values of * @param rv an optional record value, if given the values of
* all fields will be provided in the returned table. * all fields will be provided in the returned table.
*/ */
TableVal* GetRecordFieldsVal(const RecordVal* rv = nullptr) const; IntrusivePtr<TableVal> GetRecordFieldsVal(const RecordVal* rv = nullptr) const;
// Returns 0 if all is ok, otherwise a pointer to an error message. // Returns 0 if all is ok, otherwise a pointer to an error message.
// Takes ownership of list. // Takes ownership of list.
@ -638,7 +639,7 @@ public:
void DescribeReST(ODesc* d, bool roles_only = false) const override; void DescribeReST(ODesc* d, bool roles_only = false) const override;
EnumVal* GetVal(bro_int_t i); IntrusivePtr<EnumVal> GetVal(bro_int_t i);
protected: protected:
EnumType() { counter = 0; } EnumType() { counter = 0; }

View file

@ -76,19 +76,24 @@ Val::~Val()
#endif #endif
} }
Val* Val::Clone() IntrusivePtr<Val> Val::CloneState::NewClone(Val *src, IntrusivePtr<Val> dst)
{ {
Val::CloneState state; clones.insert(std::make_pair(src, dst.get()));
auto v = Clone(&state); return dst;
return v;
} }
Val* Val::Clone(CloneState* state) IntrusivePtr<Val> Val::Clone()
{
Val::CloneState state;
return Clone(&state);
}
IntrusivePtr<Val> Val::Clone(CloneState* state)
{ {
auto i = state->clones.find(this); auto i = state->clones.find(this);
if ( i != state->clones.end() ) if ( i != state->clones.end() )
return i->second->Ref(); return {NewRef{}, i->second};
auto c = DoClone(state); auto c = DoClone(state);
@ -98,20 +103,20 @@ Val* Val::Clone(CloneState* state)
return c; return c;
} }
Val* Val::DoClone(CloneState* state) IntrusivePtr<Val> Val::DoClone(CloneState* state)
{ {
switch ( type->InternalType() ) { switch ( type->InternalType() ) {
case TYPE_INTERNAL_INT: case TYPE_INTERNAL_INT:
case TYPE_INTERNAL_UNSIGNED: case TYPE_INTERNAL_UNSIGNED:
case TYPE_INTERNAL_DOUBLE: case TYPE_INTERNAL_DOUBLE:
// Immutable. // Immutable.
return Ref(); return {NewRef{}, this};
case TYPE_INTERNAL_OTHER: case TYPE_INTERNAL_OTHER:
// Derived classes are responsible for this. Exception: // Derived classes are responsible for this. Exception:
// Functions and files. There aren't any derived classes. // Functions and files. There aren't any derived classes.
if ( type->Tag() == TYPE_FUNC ) if ( type->Tag() == TYPE_FUNC )
return new Val(AsFunc()->DoClone().get()); return make_intrusive<Val>(AsFunc()->DoClone().get());
if ( type->Tag() == TYPE_FILE ) if ( type->Tag() == TYPE_FILE )
{ {
@ -125,7 +130,7 @@ Val* Val::DoClone(CloneState* state)
// automatically opened. This does not happen anymore - instead you // automatically opened. This does not happen anymore - instead you
// get the non-cached pointer back which is brought back into the // get the non-cached pointer back which is brought back into the
// cache when written too. // cache when written too.
return Ref(); return {NewRef{}, this};
} }
// Fall-through. // Fall-through.
@ -235,36 +240,36 @@ double Val::CoerceToDouble() const
return 0.0; return 0.0;
} }
Val* Val::SizeVal() const IntrusivePtr<Val> Val::SizeVal() const
{ {
switch ( type->InternalType() ) { switch ( type->InternalType() ) {
case TYPE_INTERNAL_INT: case TYPE_INTERNAL_INT:
// Return abs value. However abs() only works on ints and llabs // 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 // doesn't work on Mac OS X 10.5. So we do it by hand
if ( val.int_val < 0 ) if ( val.int_val < 0 )
return val_mgr->GetCount(-val.int_val); return {AdoptRef{}, val_mgr->GetCount(-val.int_val)};
else else
return val_mgr->GetCount(val.int_val); return {AdoptRef{}, val_mgr->GetCount(val.int_val)};
case TYPE_INTERNAL_UNSIGNED: case TYPE_INTERNAL_UNSIGNED:
return val_mgr->GetCount(val.uint_val); return {AdoptRef{}, val_mgr->GetCount(val.uint_val)};
case TYPE_INTERNAL_DOUBLE: case TYPE_INTERNAL_DOUBLE:
return new Val(fabs(val.double_val), TYPE_DOUBLE); return make_intrusive<Val>(fabs(val.double_val), TYPE_DOUBLE);
case TYPE_INTERNAL_OTHER: case TYPE_INTERNAL_OTHER:
if ( type->Tag() == TYPE_FUNC ) 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 ) if ( type->Tag() == TYPE_FILE )
return new Val(val.file_val->Size(), TYPE_DOUBLE); return make_intrusive<Val>(val.file_val->Size(), TYPE_DOUBLE);
break; break;
default: default:
break; break;
} }
return val_mgr->GetCount(0); return {AdoptRef{}, val_mgr->GetCount(0)};
} }
unsigned int Val::MemoryAllocation() const unsigned int Val::MemoryAllocation() const
@ -398,14 +403,14 @@ bool Val::WouldOverflow(const BroType* from_type, const BroType* to_type, const
return false; return false;
} }
TableVal* Val::GetRecordFields() IntrusivePtr<TableVal> Val::GetRecordFields()
{ {
auto t = Type(); auto t = Type();
if ( t->Tag() != TYPE_RECORD && t->Tag() != TYPE_TYPE ) if ( t->Tag() != TYPE_RECORD && t->Tag() != TYPE_TYPE )
{ {
reporter->Error("non-record value/type passed to record_fields"); reporter->Error("non-record value/type passed to record_fields");
return new TableVal(internal_type("record_field_table")->AsTableType()); return make_intrusive<TableVal>(internal_type("record_field_table")->AsTableType());
} }
RecordType* rt = nullptr; RecordType* rt = nullptr;
@ -423,7 +428,7 @@ TableVal* Val::GetRecordFields()
if ( t->Tag() != TYPE_RECORD ) if ( t->Tag() != TYPE_RECORD )
{ {
reporter->Error("non-record value/type passed to record_fields"); reporter->Error("non-record value/type passed to record_fields");
return new TableVal(internal_type("record_field_table")->AsTableType()); return make_intrusive<TableVal>(internal_type("record_field_table")->AsTableType());
} }
rt = t->AsRecordType(); rt = t->AsRecordType();
@ -644,14 +649,14 @@ static void BuildJSON(threading::formatter::JSON::NullDoubleWriter& writer, Val*
} }
} }
StringVal* Val::ToJSON(bool only_loggable, RE_Matcher* re) IntrusivePtr<StringVal> Val::ToJSON(bool only_loggable, RE_Matcher* re)
{ {
rapidjson::StringBuffer buffer; rapidjson::StringBuffer buffer;
threading::formatter::JSON::NullDoubleWriter writer(buffer); threading::formatter::JSON::NullDoubleWriter writer(buffer);
BuildJSON(writer, this, only_loggable, re, ""); BuildJSON(writer, this, only_loggable, re, "");
return new StringVal(buffer.GetString()); return make_intrusive<StringVal>(buffer.GetString());
} }
IntervalVal::IntervalVal(double quantity, double units) : IntervalVal::IntervalVal(double quantity, double units) :
@ -732,6 +737,11 @@ void IntervalVal::ValDescribe(ODesc* d) const
} }
} }
IntrusivePtr<Val> PortVal::SizeVal() const
{
return {AdoptRef{}, val_mgr->GetInt(val.uint_val)};
}
uint32_t PortVal::Mask(uint32_t port_num, TransportProto port_type) uint32_t PortVal::Mask(uint32_t port_num, TransportProto port_type)
{ {
// Note, for ICMP one-way connections: // Note, for ICMP one-way connections:
@ -808,10 +818,10 @@ void PortVal::ValDescribe(ODesc* d) const
d->Add(Protocol()); d->Add(Protocol());
} }
Val* PortVal::DoClone(CloneState* state) IntrusivePtr<Val> PortVal::DoClone(CloneState* state)
{ {
// Immutable. // Immutable.
return Ref(); return {NewRef{}, this};
} }
AddrVal::AddrVal(const char* text) : Val(new IPAddr(text), TYPE_ADDR) AddrVal::AddrVal(const char* text) : Val(new IPAddr(text), TYPE_ADDR)
@ -845,18 +855,18 @@ unsigned int AddrVal::MemoryAllocation() const
return padded_sizeof(*this) + val.addr_val->MemoryAllocation(); return padded_sizeof(*this) + val.addr_val->MemoryAllocation();
} }
Val* AddrVal::SizeVal() const IntrusivePtr<Val> AddrVal::SizeVal() const
{ {
if ( val.addr_val->GetFamily() == IPv4 ) if ( val.addr_val->GetFamily() == IPv4 )
return val_mgr->GetCount(32); return {AdoptRef{}, val_mgr->GetCount(32)};
else else
return val_mgr->GetCount(128); return {AdoptRef{}, val_mgr->GetCount(128)};
} }
Val* AddrVal::DoClone(CloneState* state) IntrusivePtr<Val> AddrVal::DoClone(CloneState* state)
{ {
// Immutable. // Immutable.
return Ref(); return {NewRef{}, this};
} }
SubNetVal::SubNetVal(const char* text) : Val(new IPPrefix(), TYPE_SUBNET) SubNetVal::SubNetVal(const char* text) : Val(new IPPrefix(), TYPE_SUBNET)
@ -905,10 +915,10 @@ unsigned int SubNetVal::MemoryAllocation() const
return padded_sizeof(*this) + val.subnet_val->MemoryAllocation(); return padded_sizeof(*this) + val.subnet_val->MemoryAllocation();
} }
Val* SubNetVal::SizeVal() const IntrusivePtr<Val> SubNetVal::SizeVal() const
{ {
int retained = 128 - val.subnet_val->LengthIPv6(); int retained = 128 - val.subnet_val->LengthIPv6();
return new Val(pow(2.0, double(retained)), TYPE_DOUBLE); return make_intrusive<Val>(pow(2.0, double(retained)), TYPE_DOUBLE);
} }
void SubNetVal::ValDescribe(ODesc* d) const void SubNetVal::ValDescribe(ODesc* d) const
@ -950,10 +960,10 @@ bool SubNetVal::Contains(const IPAddr& addr) const
return val.subnet_val->Contains(addr); return val.subnet_val->Contains(addr);
} }
Val* SubNetVal::DoClone(CloneState* state) IntrusivePtr<Val> SubNetVal::DoClone(CloneState* state)
{ {
// Immutable. // Immutable.
return Ref(); return {NewRef{}, this};
} }
StringVal::StringVal(BroString* s) : Val(s, TYPE_STRING) StringVal::StringVal(BroString* s) : Val(s, TYPE_STRING)
@ -974,9 +984,9 @@ StringVal::StringVal(const string& s) : StringVal(s.length(), s.data())
{ {
} }
Val* StringVal::SizeVal() const IntrusivePtr<Val> StringVal::SizeVal() const
{ {
return val_mgr->GetCount(val.string_val->Len()); return {AdoptRef{}, val_mgr->GetCount(val.string_val->Len())};
} }
int StringVal::Len() int StringVal::Len()
@ -1105,12 +1115,12 @@ Val* StringVal::Substitute(RE_Matcher* re, StringVal* repl, bool do_all)
return new StringVal(new BroString(1, result, r - result)); return new StringVal(new BroString(1, result, r - result));
} }
Val* StringVal::DoClone(CloneState* state) IntrusivePtr<Val> StringVal::DoClone(CloneState* state)
{ {
// We could likely treat this type as immutable and return a reference // 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 // instead of creating a new copy, but we first need to be careful and
// audit whether anything internal actually does mutate it. // audit whether anything internal actually does mutate it.
return state->NewClone(this, new StringVal( return state->NewClone(this, make_intrusive<StringVal>(
new BroString((u_char*) val.string_val->Bytes(), new BroString((u_char*) val.string_val->Bytes(),
val.string_val->Len(), 1))); val.string_val->Len(), 1)));
} }
@ -1163,7 +1173,7 @@ unsigned int PatternVal::MemoryAllocation() const
return padded_sizeof(*this) + val.re_val->MemoryAllocation(); return padded_sizeof(*this) + val.re_val->MemoryAllocation();
} }
Val* PatternVal::DoClone(CloneState* state) IntrusivePtr<Val> PatternVal::DoClone(CloneState* state)
{ {
// We could likely treat this type as immutable and return a reference // 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 // instead of creating a new copy, but we first need to be careful and
@ -1171,7 +1181,7 @@ Val* PatternVal::DoClone(CloneState* state)
auto re = new RE_Matcher(val.re_val->PatternText(), auto re = new RE_Matcher(val.re_val->PatternText(),
val.re_val->AnywherePatternText()); val.re_val->AnywherePatternText());
re->Compile(); re->Compile();
return state->NewClone(this, new PatternVal(re)); return state->NewClone(this, make_intrusive<PatternVal>(re));
} }
ListVal::ListVal(TypeTag t) ListVal::ListVal(TypeTag t)
@ -1187,6 +1197,11 @@ ListVal::~ListVal()
Unref(type); Unref(type);
} }
IntrusivePtr<Val> ListVal::SizeVal() const
{
return {AdoptRef{}, val_mgr->GetCount(vals.length())};
}
RE_Matcher* ListVal::BuildRE() const RE_Matcher* ListVal::BuildRE() const
{ {
if ( tag != TYPE_STRING ) if ( tag != TYPE_STRING )
@ -1256,14 +1271,14 @@ void ListVal::Describe(ODesc* d) const
} }
} }
Val* ListVal::DoClone(CloneState* state) IntrusivePtr<Val> ListVal::DoClone(CloneState* state)
{ {
auto lv = new ListVal(tag); auto lv = make_intrusive<ListVal>(tag);
lv->vals.resize(vals.length()); lv->vals.resize(vals.length());
state->NewClone(this, lv); state->NewClone(this, lv);
for ( const auto& val : vals ) for ( const auto& val : vals )
lv->Append(val->Clone(state)); lv->Append(val->Clone(state).release());
return lv; return lv;
} }
@ -1278,6 +1293,13 @@ unsigned int ListVal::MemoryAllocation() const
+ type->MemoryAllocation(); + type->MemoryAllocation();
} }
TableEntryVal* TableEntryVal::Clone(Val::CloneState* state)
{
auto rval = new TableEntryVal(val ? val->Clone(state).release() : 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) TableValTimer::TableValTimer(TableVal* val, double t) : Timer(t, TIMER_TABLE_VAL)
{ {
@ -1511,6 +1533,11 @@ int TableVal::Assign(Val* index, HashKey* k, Val* new_val)
return Assign(index, k, {AdoptRef{}, new_val}); return Assign(index, k, {AdoptRef{}, new_val});
} }
IntrusivePtr<Val> TableVal::SizeVal() const
{
return {AdoptRef{}, val_mgr->GetCount(Size())};
}
int TableVal::AddTo(Val* val, int is_first_init) const int TableVal::AddTo(Val* val, int is_first_init) const
{ {
return AddTo(val, is_first_init, true); return AddTo(val, is_first_init, true);
@ -1732,7 +1759,7 @@ int TableVal::ExpandAndInit(IntrusivePtr<Val> index, IntrusivePtr<Val> new_val)
} }
Val* TableVal::Default(Val* index) IntrusivePtr<Val> TableVal::Default(Val* index)
{ {
Attr* def_attr = FindAttr(ATTR_DEFAULT); Attr* def_attr = FindAttr(ATTR_DEFAULT);
@ -1769,7 +1796,7 @@ Val* TableVal::Default(Val* index)
same_type(def_val->Type(), Type()->YieldType()) ) same_type(def_val->Type(), Type()->YieldType()) )
{ {
if ( def_attr->AttrExpr()->IsConst() ) if ( def_attr->AttrExpr()->IsConst() )
return def_val->Ref(); return {NewRef{}, def_val};
try try
{ {
@ -1813,19 +1840,11 @@ Val* TableVal::Default(Val* index)
return 0; return 0;
} }
return result.release(); return result;
} }
Val* TableVal::Lookup(Val* index, bool use_default_val) IntrusivePtr<Val> TableVal::Lookup(Val* index, bool use_default_val)
{ {
static Val* last_default = 0;
if ( last_default )
{
Unref(last_default);
last_default = 0;
}
if ( subnets ) if ( subnets )
{ {
TableEntryVal* v = (TableEntryVal*) subnets->Lookup(index); TableEntryVal* v = (TableEntryVal*) subnets->Lookup(index);
@ -1834,16 +1853,13 @@ Val* TableVal::Lookup(Val* index, bool use_default_val)
if ( attrs && attrs->FindAttr(ATTR_EXPIRE_READ) ) if ( attrs && attrs->FindAttr(ATTR_EXPIRE_READ) )
v->SetExpireAccess(network_time); v->SetExpireAccess(network_time);
return v->Value() ? v->Value() : this; return {NewRef{}, v->Value() ? v->Value() : this};
} }
if ( ! use_default_val ) if ( ! use_default_val )
return 0; return 0;
Val* def = Default(index); return Default(index);
last_default = def;
return def;
} }
const PDict<TableEntryVal>* tbl = AsTable(); const PDict<TableEntryVal>* tbl = AsTable();
@ -1861,7 +1877,7 @@ Val* TableVal::Lookup(Val* index, bool use_default_val)
if ( attrs && attrs->FindAttr(ATTR_EXPIRE_READ) ) if ( attrs && attrs->FindAttr(ATTR_EXPIRE_READ) )
v->SetExpireAccess(network_time); v->SetExpireAccess(network_time);
return v->Value() ? v->Value() : this; return {NewRef{}, v->Value() ? v->Value() : this};
} }
} }
} }
@ -1869,18 +1885,15 @@ Val* TableVal::Lookup(Val* index, bool use_default_val)
if ( ! use_default_val ) if ( ! use_default_val )
return 0; return 0;
Val* def = Default(index); return Default(index);
last_default = def;
return def;
} }
VectorVal* TableVal::LookupSubnets(const SubNetVal* search) IntrusivePtr<VectorVal> TableVal::LookupSubnets(const SubNetVal* search)
{ {
if ( ! subnets ) if ( ! subnets )
reporter->InternalError("LookupSubnets called on wrong table type"); reporter->InternalError("LookupSubnets called on wrong table type");
VectorVal* result = new VectorVal(internal_type("subnet_vec")->AsVectorType()); auto result = make_intrusive<VectorVal>(internal_type("subnet_vec")->AsVectorType());
auto matches = subnets->FindAll(search); auto matches = subnets->FindAll(search);
for ( auto element : matches ) for ( auto element : matches )
@ -1889,12 +1902,12 @@ VectorVal* TableVal::LookupSubnets(const SubNetVal* search)
return result; return result;
} }
TableVal* TableVal::LookupSubnetValues(const SubNetVal* search) IntrusivePtr<TableVal> TableVal::LookupSubnetValues(const SubNetVal* search)
{ {
if ( ! subnets ) if ( ! subnets )
reporter->InternalError("LookupSubnetValues called on wrong table type"); reporter->InternalError("LookupSubnetValues called on wrong table type");
TableVal* nt = new TableVal(this->Type()->Ref()->AsTableType()); auto nt = make_intrusive<TableVal>(this->Type()->Ref()->AsTableType());
auto matches = subnets->FindAll(search); auto matches = subnets->FindAll(search);
for ( auto element : matches ) for ( auto element : matches )
@ -1978,16 +1991,16 @@ void TableVal::CallChangeFunc(const Val* index, Val* old_value, OnChangeType tpe
switch ( tpe ) switch ( tpe )
{ {
case ELEMENT_NEW: case ELEMENT_NEW:
type = BifType::Enum::TableChange->GetVal(BifEnum::TableChange::TABLE_ELEMENT_NEW); type = BifType::Enum::TableChange->GetVal(BifEnum::TableChange::TABLE_ELEMENT_NEW).release();
break; break;
case ELEMENT_CHANGED: case ELEMENT_CHANGED:
type = BifType::Enum::TableChange->GetVal(BifEnum::TableChange::TABLE_ELEMENT_CHANGED); type = BifType::Enum::TableChange->GetVal(BifEnum::TableChange::TABLE_ELEMENT_CHANGED).release();
break; break;
case ELEMENT_REMOVED: case ELEMENT_REMOVED:
type = BifType::Enum::TableChange->GetVal(BifEnum::TableChange::TABLE_ELEMENT_REMOVED); type = BifType::Enum::TableChange->GetVal(BifEnum::TableChange::TABLE_ELEMENT_REMOVED).release();
break; break;
case ELEMENT_EXPIRED: case ELEMENT_EXPIRED:
type = BifType::Enum::TableChange->GetVal(BifEnum::TableChange::TABLE_ELEMENT_EXPIRED); type = BifType::Enum::TableChange->GetVal(BifEnum::TableChange::TABLE_ELEMENT_EXPIRED).release();
} }
vl.append(type); vl.append(type);
@ -2224,7 +2237,7 @@ int TableVal::CheckAndAssign(Val* index, IntrusivePtr<Val> new_val)
// We need an exact match here. // We need an exact match here.
v = (Val*) subnets->Lookup(index, true); v = (Val*) subnets->Lookup(index, true);
else else
v = Lookup(index, false); v = Lookup(index, false).get();
if ( v ) if ( v )
index->Warn("multiple initializations for index"); index->Warn("multiple initializations for index");
@ -2472,9 +2485,9 @@ double TableVal::CallExpireFunc(Val* idx)
return secs; return secs;
} }
Val* TableVal::DoClone(CloneState* state) IntrusivePtr<Val> TableVal::DoClone(CloneState* state)
{ {
auto tv = new TableVal(table_type); auto tv = make_intrusive<TableVal>(table_type);
state->NewClone(this, tv); state->NewClone(this, tv);
const PDict<TableEntryVal>* tbl = AsTable(); const PDict<TableEntryVal>* tbl = AsTable();
@ -2517,7 +2530,7 @@ Val* TableVal::DoClone(CloneState* state)
tv->expire_func = expire_func->Ref(); tv->expire_func = expire_func->Ref();
if ( def_val ) if ( def_val )
tv->def_val = def_val->Clone(); tv->def_val = def_val->Clone().release();
return tv; return tv;
} }
@ -2576,10 +2589,10 @@ RecordVal::RecordVal(RecordType* t, bool init_fields) : Val(t)
def->Type()->Tag() == TYPE_RECORD && def->Type()->Tag() == TYPE_RECORD &&
! same_type(def->Type(), type) ) ! same_type(def->Type(), type) )
{ {
Val* tmp = def->AsRecordVal()->CoerceTo(type->AsRecordType()); auto tmp = def->AsRecordVal()->CoerceTo(type->AsRecordType());
if ( tmp ) if ( tmp )
{ {
def = {AdoptRef{}, tmp}; def = std::move(tmp);
} }
} }
@ -2606,6 +2619,11 @@ RecordVal::~RecordVal()
delete_vals(AsNonConstRecord()); delete_vals(AsNonConstRecord());
} }
IntrusivePtr<Val> RecordVal::SizeVal() const
{
return {AdoptRef{}, val_mgr->GetCount(Type()->AsRecordType()->NumFields())};
}
void RecordVal::Assign(int field, IntrusivePtr<Val> new_val) void RecordVal::Assign(int field, IntrusivePtr<Val> new_val)
{ {
Val* old_val = AsNonConstRecord()->replace(field, new_val.release()); Val* old_val = AsNonConstRecord()->replace(field, new_val.release());
@ -2666,7 +2684,7 @@ Val* RecordVal::Lookup(const char* field, bool with_default) const
return with_default ? LookupWithDefault(idx) : Lookup(idx); return with_default ? LookupWithDefault(idx) : Lookup(idx);
} }
RecordVal* RecordVal::CoerceTo(const RecordType* t, Val* aggr, bool allow_orphaning) const IntrusivePtr<RecordVal> RecordVal::CoerceTo(const RecordType* t, Val* aggr, bool allow_orphaning) const
{ {
if ( ! record_promotion_compatible(t->AsRecordType(), Type()->AsRecordType()) ) if ( ! record_promotion_compatible(t->AsRecordType(), Type()->AsRecordType()) )
return 0; return 0;
@ -2726,21 +2744,18 @@ RecordVal* RecordVal::CoerceTo(const RecordType* t, Val* aggr, bool allow_orphan
Error(buf); Error(buf);
} }
return ar; return {AdoptRef{}, ar};
} }
RecordVal* RecordVal::CoerceTo(RecordType* t, bool allow_orphaning) IntrusivePtr<RecordVal> RecordVal::CoerceTo(RecordType* t, bool allow_orphaning)
{ {
if ( same_type(Type(), t) ) if ( same_type(Type(), t) )
{ return {NewRef{}, this};
this->Ref();
return this;
}
return CoerceTo(t, 0, allow_orphaning); return CoerceTo(t, 0, allow_orphaning);
} }
TableVal* RecordVal::GetRecordFieldsVal() const IntrusivePtr<TableVal> RecordVal::GetRecordFieldsVal() const
{ {
return Type()->AsRecordType()->GetRecordFieldsVal(this); return Type()->AsRecordType()->GetRecordFieldsVal(this);
} }
@ -2811,21 +2826,21 @@ void RecordVal::DescribeReST(ODesc* d) const
d->Add("}"); d->Add("}");
} }
Val* RecordVal::DoClone(CloneState* state) IntrusivePtr<Val> RecordVal::DoClone(CloneState* state)
{ {
// We set origin to 0 here. Origin only seems to be used for exactly one // 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 // purpose - to find the connection record that is associated with a
// record. As we cannot guarantee that it will ber zeroed out at the // 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) // approproate time (as it seems to be guaranteed for the original record)
// we don't touch it. // we don't touch it.
auto rv = new RecordVal(Type()->AsRecordType(), false); auto rv = make_intrusive<RecordVal>(Type()->AsRecordType(), false);
rv->origin = nullptr; rv->origin = nullptr;
state->NewClone(this, rv); state->NewClone(this, rv);
for ( const auto& vlv : *val.val_list_val ) for ( const auto& vlv : *val.val_list_val )
{ {
Val* v = vlv ? vlv->Clone(state) : nullptr; auto v = vlv ? vlv->Clone(state) : nullptr;
rv->val.val_list_val->push_back(v); rv->val.val_list_val->push_back(v.release());
} }
return rv; return rv;
@ -2845,6 +2860,11 @@ unsigned int RecordVal::MemoryAllocation() const
return size + padded_sizeof(*this) + val.val_list_val->MemoryAllocation(); return size + padded_sizeof(*this) + val.val_list_val->MemoryAllocation();
} }
IntrusivePtr<Val> EnumVal::SizeVal() const
{
return {AdoptRef{}, val_mgr->GetInt(val.int_val)};
}
void EnumVal::ValDescribe(ODesc* d) const void EnumVal::ValDescribe(ODesc* d) const
{ {
const char* ename = type->AsEnumType()->Lookup(val.int_val); const char* ename = type->AsEnumType()->Lookup(val.int_val);
@ -2855,10 +2875,10 @@ void EnumVal::ValDescribe(ODesc* d) const
d->Add(ename); d->Add(ename);
} }
Val* EnumVal::DoClone(CloneState* state) IntrusivePtr<Val> EnumVal::DoClone(CloneState* state)
{ {
// Immutable. // Immutable.
return Ref(); return {NewRef{}, this};
} }
VectorVal::VectorVal(VectorType* t) : Val(t) VectorVal::VectorVal(VectorType* t) : Val(t)
@ -2877,6 +2897,11 @@ VectorVal::~VectorVal()
delete val.vector_val; delete val.vector_val;
} }
IntrusivePtr<Val> VectorVal::SizeVal() const
{
return {AdoptRef{}, val_mgr->GetCount(uint32_t(val.vector_val->size()))};
}
bool VectorVal::Assign(unsigned int index, IntrusivePtr<Val> element) bool VectorVal::Assign(unsigned int index, IntrusivePtr<Val> element)
{ {
if ( element && if ( element &&
@ -3006,16 +3031,16 @@ unsigned int VectorVal::ResizeAtLeast(unsigned int new_num_elements)
return Resize(new_num_elements); return Resize(new_num_elements);
} }
Val* VectorVal::DoClone(CloneState* state) IntrusivePtr<Val> VectorVal::DoClone(CloneState* state)
{ {
auto vv = new VectorVal(vector_type); auto vv = make_intrusive<VectorVal>(vector_type);
vv->val.vector_val->reserve(val.vector_val->size()); vv->val.vector_val->reserve(val.vector_val->size());
state->NewClone(this, vv); state->NewClone(this, vv);
for ( unsigned int i = 0; i < val.vector_val->size(); ++i ) for ( unsigned int i = 0; i < val.vector_val->size(); ++i )
{ {
auto v = (*val.vector_val)[i]->Clone(state); 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; return vv;

View file

@ -154,7 +154,7 @@ public:
~Val() override; ~Val() override;
Val* Ref() { ::Ref(this); return this; } Val* Ref() { ::Ref(this); return this; }
Val* Clone(); IntrusivePtr<Val> Clone();
int IsZero() const; int IsZero() const;
int IsOne() const; int IsOne() const;
@ -169,7 +169,7 @@ public:
// Returns a new Val with the "size" of this Val. What constitutes // Returns a new Val with the "size" of this Val. What constitutes
// size depends on the Val's type. // size depends on the Val's type.
virtual Val* SizeVal() const; virtual IntrusivePtr<Val> SizeVal() const;
// Bytes in total value object. // Bytes in total value object.
virtual unsigned int MemoryAllocation() const; virtual unsigned int MemoryAllocation() const;
@ -323,9 +323,9 @@ public:
static bool WouldOverflow(const BroType* from_type, const BroType* to_type, const Val* val); static bool WouldOverflow(const BroType* from_type, const BroType* to_type, const Val* val);
TableVal* GetRecordFields(); IntrusivePtr<TableVal> GetRecordFields();
StringVal* ToJSON(bool only_loggable=false, RE_Matcher* re=nullptr); IntrusivePtr<StringVal> ToJSON(bool only_loggable=false, RE_Matcher* re=nullptr);
protected: protected:
@ -379,17 +379,13 @@ protected:
// Caches a cloned value for later reuse during the same // Caches a cloned value for later reuse during the same
// cloning operation. For recursive types, call this *before* // cloning operation. For recursive types, call this *before*
// descending down. // descending down.
Val* NewClone(Val *src, Val* dst) IntrusivePtr<Val> NewClone(Val *src, IntrusivePtr<Val> dst);
{
clones.insert(std::make_pair(src, dst));
return dst;
}
std::unordered_map<Val*, Val*> clones; std::unordered_map<Val*, Val*> clones;
}; };
Val* Clone(CloneState* state); IntrusivePtr<Val> Clone(CloneState* state);
virtual Val* DoClone(CloneState* state); virtual IntrusivePtr<Val> DoClone(CloneState* state);
BroValUnion val; BroValUnion val;
BroType* type; BroType* type;
@ -476,7 +472,7 @@ protected:
class PortVal : public Val { class PortVal : public Val {
public: public:
Val* SizeVal() const override { return val_mgr->GetInt(val.uint_val); } IntrusivePtr<Val> SizeVal() const override;
// Returns the port number in host order (not including the mask). // Returns the port number in host order (not including the mask).
uint32_t Port() const; uint32_t Port() const;
@ -507,7 +503,7 @@ protected:
PortVal(uint32_t p); PortVal(uint32_t p);
void ValDescribe(ODesc* d) const override; void ValDescribe(ODesc* d) const override;
Val* DoClone(CloneState* state) override; IntrusivePtr<Val> DoClone(CloneState* state) override;
}; };
class AddrVal : public Val { class AddrVal : public Val {
@ -516,7 +512,7 @@ public:
explicit AddrVal(const std::string& text); explicit AddrVal(const std::string& text);
~AddrVal() override; ~AddrVal() override;
Val* SizeVal() const override; IntrusivePtr<Val> SizeVal() const override;
// Constructor for address already in network order. // Constructor for address already in network order.
explicit AddrVal(uint32_t addr); // IPv4. explicit AddrVal(uint32_t addr); // IPv4.
@ -526,7 +522,7 @@ public:
unsigned int MemoryAllocation() const override; unsigned int MemoryAllocation() const override;
protected: protected:
Val* DoClone(CloneState* state) override; IntrusivePtr<Val> DoClone(CloneState* state) override;
}; };
class SubNetVal : public Val { class SubNetVal : public Val {
@ -539,7 +535,7 @@ public:
explicit SubNetVal(const IPPrefix& prefix); explicit SubNetVal(const IPPrefix& prefix);
~SubNetVal() override; ~SubNetVal() override;
Val* SizeVal() const override; IntrusivePtr<Val> SizeVal() const override;
const IPAddr& Prefix() const; const IPAddr& Prefix() const;
int Width() const; int Width() const;
@ -551,7 +547,7 @@ public:
protected: protected:
void ValDescribe(ODesc* d) const override; void ValDescribe(ODesc* d) const override;
Val* DoClone(CloneState* state) override; IntrusivePtr<Val> DoClone(CloneState* state) override;
}; };
class StringVal : public Val { class StringVal : public Val {
@ -561,7 +557,7 @@ public:
explicit StringVal(const string& s); explicit StringVal(const string& s);
StringVal(int length, const char* s); StringVal(int length, const char* s);
Val* SizeVal() const override; IntrusivePtr<Val> SizeVal() const override;
int Len(); int Len();
const u_char* Bytes(); const u_char* Bytes();
@ -581,7 +577,7 @@ public:
protected: protected:
void ValDescribe(ODesc* d) const override; void ValDescribe(ODesc* d) const override;
Val* DoClone(CloneState* state) override; IntrusivePtr<Val> DoClone(CloneState* state) override;
}; };
class PatternVal : public Val { class PatternVal : public Val {
@ -597,7 +593,7 @@ public:
protected: protected:
void ValDescribe(ODesc* d) const override; void ValDescribe(ODesc* d) const override;
Val* DoClone(CloneState* state) override; IntrusivePtr<Val> DoClone(CloneState* state) override;
}; };
// ListVals are mainly used to index tables that have more than one // ListVals are mainly used to index tables that have more than one
@ -609,7 +605,7 @@ public:
TypeTag BaseTag() const { return tag; } TypeTag BaseTag() const { return tag; }
Val* SizeVal() const override { return val_mgr->GetCount(vals.length()); } IntrusivePtr<Val> SizeVal() const override;
int Length() const { return vals.length(); } int Length() const { return vals.length(); }
Val* Index(const int n) { return vals[n]; } Val* Index(const int n) { return vals[n]; }
@ -638,7 +634,7 @@ public:
unsigned int MemoryAllocation() const override; unsigned int MemoryAllocation() const override;
protected: protected:
Val* DoClone(CloneState* state) override; IntrusivePtr<Val> DoClone(CloneState* state) override;
val_list vals; val_list vals;
TypeTag tag; TypeTag tag;
@ -656,13 +652,7 @@ public:
int(network_time - bro_start_network_time); int(network_time - bro_start_network_time);
} }
TableEntryVal* Clone(Val::CloneState* state) 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() { } ~TableEntryVal() { }
@ -720,7 +710,7 @@ public:
int Assign(Val* index, HashKey* k, IntrusivePtr<Val> new_val); int Assign(Val* index, HashKey* k, IntrusivePtr<Val> new_val);
int Assign(Val* index, HashKey* k, Val* new_val); int Assign(Val* index, HashKey* k, Val* new_val);
Val* SizeVal() const override { return val_mgr->GetCount(Size()); } IntrusivePtr<Val> SizeVal() const override;
// Add the entire contents of the table to the given value, // Add the entire contents of the table to the given value,
// which must also be a TableVal. // which must also be a TableVal.
@ -763,17 +753,17 @@ public:
// Returns the element's value if it exists in the table, // Returns the element's value if it exists in the table,
// nil otherwise. Note, "index" is not const because we // nil otherwise. Note, "index" is not const because we
// need to Ref/Unref it when calling the default function. // need to Ref/Unref it when calling the default function.
Val* Lookup(Val* index, bool use_default_val = true); IntrusivePtr<Val> Lookup(Val* index, bool use_default_val = true);
// For a table[subnet]/set[subnet], return all subnets that cover // For a table[subnet]/set[subnet], return all subnets that cover
// the given subnet. // the given subnet.
// Causes an internal error if called for any other kind of table. // Causes an internal error if called for any other kind of table.
VectorVal* LookupSubnets(const SubNetVal* s); IntrusivePtr<VectorVal> LookupSubnets(const SubNetVal* s);
// For a set[subnet]/table[subnet], return a new table that only contains // For a set[subnet]/table[subnet], return a new table that only contains
// entries that cover the given subnet. // entries that cover the given subnet.
// Causes an internal error if called for any other kind of table. // Causes an internal error if called for any other kind of table.
TableVal* LookupSubnetValues(const SubNetVal* s); IntrusivePtr<TableVal> LookupSubnetValues(const SubNetVal* s);
// Sets the timestamp for the given index to network time. // Sets the timestamp for the given index to network time.
// Returns false if index does not exist. // Returns false if index does not exist.
@ -833,7 +823,7 @@ protected:
int CheckAndAssign(Val* index, IntrusivePtr<Val> new_val); int CheckAndAssign(Val* index, IntrusivePtr<Val> new_val);
// Calculates default value for index. Returns 0 if none. // Calculates default value for index. Returns 0 if none.
Val* Default(Val* index); IntrusivePtr<Val> Default(Val* index);
// Returns true if item expiration is enabled. // Returns true if item expiration is enabled.
bool ExpirationEnabled() { return expire_time != 0; } bool ExpirationEnabled() { return expire_time != 0; }
@ -853,7 +843,7 @@ protected:
// Calls &change_func. Does not take ownership of values. (Refs if needed). // Calls &change_func. Does not take ownership of values. (Refs if needed).
void CallChangeFunc(const Val* index, Val* old_value, OnChangeType tpe); void CallChangeFunc(const Val* index, Val* old_value, OnChangeType tpe);
Val* DoClone(CloneState* state) override; IntrusivePtr<Val> DoClone(CloneState* state) override;
TableType* table_type; TableType* table_type;
CompositeHash* table_hash; CompositeHash* table_hash;
@ -874,8 +864,7 @@ public:
explicit RecordVal(RecordType* t, bool init_fields = true); explicit RecordVal(RecordType* t, bool init_fields = true);
~RecordVal() override; ~RecordVal() override;
Val* SizeVal() const override IntrusivePtr<Val> SizeVal() const override;
{ return val_mgr->GetCount(Type()->AsRecordType()->NumFields()); }
void Assign(int field, IntrusivePtr<Val> new_val); void Assign(int field, IntrusivePtr<Val> new_val);
void Assign(int field, Val* new_val); void Assign(int field, Val* new_val);
@ -898,7 +887,7 @@ public:
/** /**
* Returns a "record_field_table" value for introspection purposes. * Returns a "record_field_table" value for introspection purposes.
*/ */
TableVal* GetRecordFieldsVal() const; IntrusivePtr<TableVal> GetRecordFieldsVal() const;
// This is an experiment to associate a BroObj within the // This is an experiment to associate a BroObj within the
// event engine to a record value in bro script. // event engine to a record value in bro script.
@ -916,8 +905,8 @@ public:
// //
// The *allow_orphaning* parameter allows for a record to be demoted // The *allow_orphaning* parameter allows for a record to be demoted
// down to a record type that contains less fields. // down to a record type that contains less fields.
RecordVal* CoerceTo(const RecordType* other, Val* aggr, bool allow_orphaning = false) const; IntrusivePtr<RecordVal> CoerceTo(const RecordType* other, Val* aggr, bool allow_orphaning = false) const;
RecordVal* CoerceTo(RecordType* other, bool allow_orphaning = false); IntrusivePtr<RecordVal> CoerceTo(RecordType* other, bool allow_orphaning = false);
unsigned int MemoryAllocation() const override; unsigned int MemoryAllocation() const override;
void DescribeReST(ODesc* d) const override; void DescribeReST(ODesc* d) const override;
@ -930,7 +919,7 @@ public:
static void ResizeParseTimeRecords(); static void ResizeParseTimeRecords();
protected: protected:
Val* DoClone(CloneState* state) override; IntrusivePtr<Val> DoClone(CloneState* state) override;
BroObj* origin; BroObj* origin;
@ -939,7 +928,7 @@ protected:
class EnumVal : public Val { class EnumVal : public Val {
public: public:
Val* SizeVal() const override { return val_mgr->GetInt(val.int_val); } IntrusivePtr<Val> SizeVal() const override;
protected: protected:
friend class Val; friend class Val;
@ -950,7 +939,7 @@ protected:
} }
void ValDescribe(ODesc* d) const override; void ValDescribe(ODesc* d) const override;
Val* DoClone(CloneState* state) override; IntrusivePtr<Val> DoClone(CloneState* state) override;
}; };
@ -959,8 +948,7 @@ public:
explicit VectorVal(VectorType* t); explicit VectorVal(VectorType* t);
~VectorVal() override; ~VectorVal() override;
Val* SizeVal() const override IntrusivePtr<Val> SizeVal() const override;
{ return val_mgr->GetCount(uint32_t(val.vector_val->size())); }
// Returns false if the type of the argument was wrong. // Returns false if the type of the argument was wrong.
// The vector will automatically grow to accomodate the index. // The vector will automatically grow to accomodate the index.
@ -1015,7 +1003,7 @@ public:
protected: protected:
void ValDescribe(ODesc* d) const override; void ValDescribe(ODesc* d) const override;
Val* DoClone(CloneState* state) override; IntrusivePtr<Val> DoClone(CloneState* state) override;
VectorType* vector_type; VectorType* vector_type;
}; };

View file

@ -4,6 +4,7 @@
#include "Hash.h" #include "Hash.h"
#include "Val.h" #include "Val.h"
#include "IntrusivePtr.h"
#include "protocol/conn-size/ConnSize.h" #include "protocol/conn-size/ConnSize.h"
#include "protocol/icmp/ICMP.h" #include "protocol/icmp/ICMP.h"
@ -440,13 +441,12 @@ bool Manager::BuildInitialAnalyzerTree(Connection* conn)
if ( tcp_contents && ! reass ) if ( tcp_contents && ! reass )
{ {
auto dport = val_mgr->GetPort(ntohs(conn->RespPort()), TRANSPORT_TCP); auto dport = val_mgr->GetPort(ntohs(conn->RespPort()), TRANSPORT_TCP);
Val* result;
if ( ! reass ) if ( ! reass )
reass = tcp_content_delivery_ports_orig->Lookup(dport); reass = (bool)tcp_content_delivery_ports_orig->Lookup(dport);
if ( ! reass ) if ( ! reass )
reass = tcp_content_delivery_ports_resp->Lookup(dport); reass = (bool)tcp_content_delivery_ports_resp->Lookup(dport);
Unref(dport); Unref(dport);
} }

View file

@ -42,7 +42,7 @@ refine connection DCE_RPC_Conn += {
${header.is_orig}, ${header.is_orig},
fid, fid,
${header.PTYPE}, ${header.PTYPE},
BifType::Enum::DCE_RPC::PType->GetVal(${header.PTYPE})); BifType::Enum::DCE_RPC::PType->GetVal(${header.PTYPE}).release());
} }
return true; return true;
%} %}

View file

@ -20,7 +20,7 @@ refine flow RADIUS_Flow += {
Val* index = val_mgr->GetCount(${msg.attributes[i].code}); Val* index = val_mgr->GetCount(${msg.attributes[i].code});
// Do we already have a vector of attributes for this type? // 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}); Val* val = bytestring_to_val(${msg.attributes[i].value});
if ( current ) if ( current )

View file

@ -139,7 +139,7 @@ int MOUNT_Interp::RPC_BuildReply(RPC_CallInfo* c, BifEnum::rpc_status rpc_status
// Otherwise DeliverRPC would complain about // Otherwise DeliverRPC would complain about
// excess_RPC. // excess_RPC.
n = 0; 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; event = mount_proc_not_implemented;
} }
else else
@ -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) 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); 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) StringVal* MOUNT_Interp::mount3_fh(const u_char*& buf, int& n)

View file

@ -251,7 +251,7 @@ int NFS_Interp::RPC_BuildReply(RPC_CallInfo* c, BifEnum::rpc_status rpc_status,
// Otherwise DeliverRPC would complain about // Otherwise DeliverRPC would complain about
// excess_RPC. // excess_RPC.
n = 0; 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; event = nfs_proc_not_implemented;
} }
else else
@ -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) 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); 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) 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); 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) 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) 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); 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) RecordVal* NFS_Interp::nfs3_lookup_reply(const u_char*& buf, int& n, BifEnum::NFS3::status_t status)

View file

@ -295,7 +295,7 @@ void PortmapperInterp::Event(EventHandlerPtr f, Val* request, BifEnum::rpc_statu
} }
else else
{ {
vl.push_back(BifType::Enum::rpc_status->GetVal(status)); vl.push_back(BifType::Enum::rpc_status->GetVal(status).release());
if ( request ) if ( request )
vl.push_back(request); vl.push_back(request);
} }

View file

@ -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->Program()),
val_mgr->GetCount(c->Version()), val_mgr->GetCount(c->Version()),
val_mgr->GetCount(c->Proc()), val_mgr->GetCount(c->Proc()),
BifType::Enum::rpc_status->GetVal(status), BifType::Enum::rpc_status->GetVal(status).release(),
new Val(c->StartTime(), TYPE_TIME), new Val(c->StartTime(), TYPE_TIME),
val_mgr->GetCount(c->CallLen()), val_mgr->GetCount(c->CallLen()),
val_mgr->GetCount(reply_len), 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->ConnectionEventFast(rpc_reply, {
analyzer->BuildConnVal(), analyzer->BuildConnVal(),
val_mgr->GetCount(xid), val_mgr->GetCount(xid),
BifType::Enum::rpc_status->GetVal(status), BifType::Enum::rpc_status->GetVal(status).release(),
val_mgr->GetCount(reply_len), val_mgr->GetCount(reply_len),
}); });
} }

View file

@ -47,7 +47,7 @@ TCP_Reassembler::TCP_Reassembler(analyzer::Analyzer* arg_dst_analyzer,
TableVal* ports = IsOrig() ? TableVal* ports = IsOrig() ?
tcp_content_delivery_ports_orig : tcp_content_delivery_ports_orig :
tcp_content_delivery_ports_resp; 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) || if ( (IsOrig() && tcp_content_deliver_all_orig) ||
(! IsOrig() && tcp_content_deliver_all_resp) || (! IsOrig() && tcp_content_deliver_all_resp) ||

View file

@ -135,12 +135,11 @@ void UDP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig,
if ( udp_contents ) if ( udp_contents )
{ {
auto port_val = val_mgr->GetPort(ntohs(up->uh_dport), TRANSPORT_UDP); auto port_val = val_mgr->GetPort(ntohs(up->uh_dport), TRANSPORT_UDP);
Val* result = 0;
bool do_udp_contents = false; bool do_udp_contents = false;
if ( is_orig ) if ( is_orig )
{ {
result = udp_content_delivery_ports_orig->Lookup( auto result = udp_content_delivery_ports_orig->Lookup(
port_val); port_val);
if ( udp_content_deliver_all_orig || if ( udp_content_deliver_all_orig ||
(result && result->AsBool()) ) (result && result->AsBool()) )
@ -148,7 +147,7 @@ void UDP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig,
} }
else else
{ {
result = udp_content_delivery_ports_resp->Lookup( auto result = udp_content_delivery_ports_resp->Lookup(
port_val); port_val);
if ( udp_content_deliver_all_resp || if ( udp_content_deliver_all_resp ||
(result && result->AsBool()) ) (result && result->AsBool()) )

View file

@ -196,7 +196,7 @@ struct val_converter {
if ( i == -1 ) if ( i == -1 )
return nullptr; return nullptr;
return etype->GetVal(i); return etype->GetVal(i).release();
} }
return nullptr; return nullptr;
@ -1059,72 +1059,72 @@ struct data_type_getter {
result_type operator()(broker::none) 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) 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) 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) 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) 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&) 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&) 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&) 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&) 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&) 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&) 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&) 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&) 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&) 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&) result_type operator()(const broker::vector&)
@ -1132,7 +1132,7 @@ struct data_type_getter {
// Note that Broker uses vectors to store record data, so there's // Note that Broker uses vectors to store record data, so there's
// no actual way to tell if this data was originally associated // no actual way to tell if this data was originally associated
// with a Bro record. // with a Bro record.
return BifType::Enum::Broker::DataType->GetVal(BifEnum::Broker::VECTOR); return BifType::Enum::Broker::DataType->GetVal(BifEnum::Broker::VECTOR).release();
} }
}; };

View file

@ -1352,7 +1352,7 @@ void Manager::ProcessError(broker::error err)
} }
mgr.QueueEventFast(Broker::error, { mgr.QueueEventFast(Broker::error, {
BifType::Enum::Broker::ErrorCode->GetVal(ec), BifType::Enum::Broker::ErrorCode->GetVal(ec).release(),
new StringVal(msg), new StringVal(msg),
}); });
} }

View file

@ -20,7 +20,7 @@ EnumVal* query_status(bool success)
failure_val = store_query_status->Lookup("Broker", "FAILURE"); 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 void StoreHandleVal::ValDescribe(ODesc* d) const

View file

@ -449,16 +449,13 @@ bool Manager::IsDisabled(const analyzer::Tag& tag)
disabled = internal_const_val("Files::disable")->AsTableVal(); disabled = internal_const_val("Files::disable")->AsTableVal();
Val* index = val_mgr->GetCount(bool(tag)); Val* index = val_mgr->GetCount(bool(tag));
Val* yield = disabled->Lookup(index); auto yield = disabled->Lookup(index);
Unref(index); Unref(index);
if ( ! yield ) if ( ! yield )
return false; return false;
bool rval = yield->AsBool(); return yield->AsBool();
Unref(yield);
return rval;
} }
Analyzer* Manager::InstantiateAnalyzer(const Tag& tag, RecordVal* args, File* f) const Analyzer* Manager::InstantiateAnalyzer(const Tag& tag, RecordVal* args, File* f) const

View file

@ -11,9 +11,8 @@ module FileExtract;
function FileExtract::__set_limit%(file_id: string, args: any, n: count%): bool function FileExtract::__set_limit%(file_id: string, args: any, n: count%): bool
%{ %{
using BifType::Record::Files::AnalyzerArgs; using BifType::Record::Files::AnalyzerArgs;
RecordVal* rv = args->AsRecordVal()->CoerceTo(AnalyzerArgs); auto rv = args->AsRecordVal()->CoerceTo(AnalyzerArgs);
bool result = file_mgr->SetExtractionLimit(file_id->CheckString(), rv, n); bool result = file_mgr->SetExtractionLimit(file_id->CheckString(), rv.get(), n);
Unref(rv);
return val_mgr->GetBool(result); return val_mgr->GetBool(result);
%} %}

View file

@ -523,9 +523,9 @@ X509Val::~X509Val()
X509_free(certificate); X509_free(certificate);
} }
Val* X509Val::DoClone(CloneState* state) IntrusivePtr<Val> X509Val::DoClone(CloneState* state)
{ {
auto copy = new X509Val(); auto copy = make_intrusive<X509Val>();
if ( certificate ) if ( certificate )
copy->certificate = X509_dup(certificate); copy->certificate = X509_dup(certificate);

View file

@ -154,7 +154,7 @@ public:
* *
* @return A cloned X509Val. * @return A cloned X509Val.
*/ */
Val* DoClone(CloneState* state) override; IntrusivePtr<Val> DoClone(CloneState* state) override;
/** /**
* Destructor. * Destructor.

View file

@ -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 function Files::__add_analyzer%(file_id: string, tag: Files::Tag, args: any%): bool
%{ %{
using BifType::Record::Files::AnalyzerArgs; 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(), bool result = file_mgr->AddAnalyzer(file_id->CheckString(),
file_mgr->GetComponentTag(tag), rv); file_mgr->GetComponentTag(tag), rv.get());
Unref(rv);
return val_mgr->GetBool(result); 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 function Files::__remove_analyzer%(file_id: string, tag: Files::Tag, args: any%): bool
%{ %{
using BifType::Record::Files::AnalyzerArgs; 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(), bool result = file_mgr->RemoveAnalyzer(file_id->CheckString(),
file_mgr->GetComponentTag(tag) , rv); file_mgr->GetComponentTag(tag) , rv.get());
Unref(rv);
return val_mgr->GetBool(result); return val_mgr->GetBool(result);
%} %}

View file

@ -1108,7 +1108,7 @@ void Manager::SendEntry(ReaderFrontend* reader, Value* *vals)
else if ( i->stream_type == EVENT_STREAM ) 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); readFields = SendEventStreamEvent(i, type, vals);
} }
@ -1214,9 +1214,9 @@ int Manager::SendEntryTable(Stream* i, const Value* const *vals)
if ( ! pred_convert_error ) if ( ! pred_convert_error )
{ {
if ( updated ) if ( updated )
ev = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_CHANGED); ev = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_CHANGED).release();
else else
ev = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_NEW); ev = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_NEW).release();
bool result; bool result;
if ( stream->num_val_fields > 0 ) // we have values if ( stream->num_val_fields > 0 ) // we have values
@ -1274,7 +1274,7 @@ int Manager::SendEntryTable(Stream* i, const Value* const *vals)
assert(idxval); assert(idxval);
Val* oldval = 0; IntrusivePtr<Val> oldval;
if ( updated == true ) if ( updated == true )
{ {
assert(stream->num_val_fields > 0); assert(stream->num_val_fields > 0);
@ -1290,9 +1290,6 @@ int Manager::SendEntryTable(Stream* i, const Value* const *vals)
ih->idxkey = new HashKey(k->Key(), k->Size(), k->Hash()); ih->idxkey = new HashKey(k->Key(), k->Size(), k->Hash());
ih->valhash = valhash; 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); stream->tab->Assign(idxval, k, valval);
Unref(idxval); // asssign does not consume idxval. Unref(idxval); // asssign does not consume idxval.
@ -1318,13 +1315,13 @@ int Manager::SendEntryTable(Stream* i, const Value* const *vals)
else if ( updated ) else if ( updated )
{ // in case of update send back the old value. { // in case of update send back the old value.
assert ( stream->num_val_fields > 0 ); 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 ); 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 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 ) if ( stream->num_val_fields == 0 )
{ {
Ref(stream->description); Ref(stream->description);
@ -1375,7 +1372,7 @@ void Manager::EndCurrentSend(ReaderFrontend* reader)
while ( ( ih = stream->lastDict->NextEntry(lastDictIdxKey, c) ) ) while ( ( ih = stream->lastDict->NextEntry(lastDictIdxKey, c) ) )
{ {
ListVal * idx = 0; ListVal * idx = 0;
Val *val = 0; IntrusivePtr<Val> val;
Val* predidx = 0; Val* predidx = 0;
EnumVal* ev = 0; EnumVal* ev = 0;
@ -1389,7 +1386,7 @@ void Manager::EndCurrentSend(ReaderFrontend* reader)
assert(val != 0); assert(val != 0);
predidx = ListValToRecordVal(idx, stream->itype, &startpos); predidx = ListValToRecordVal(idx, stream->itype, &startpos);
Unref(idx); 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 ) if ( stream->pred )
@ -1398,9 +1395,8 @@ void Manager::EndCurrentSend(ReaderFrontend* reader)
Ref(ev); Ref(ev);
Ref(predidx); 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 ) if ( result == false )
{ {
@ -1417,9 +1413,8 @@ void Manager::EndCurrentSend(ReaderFrontend* reader)
if ( stream->event ) if ( stream->event )
{ {
Ref(predidx); Ref(predidx);
Ref(val);
Ref(ev); 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... if ( predidx ) // if we have a stream or an event...
@ -1498,7 +1493,7 @@ void Manager::Put(ReaderFrontend* reader, Value* *vals)
else if ( i->stream_type == EVENT_STREAM ) 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); readFields = SendEventStreamEvent(i, type, vals);
} }
@ -1607,7 +1602,7 @@ int Manager::PutTable(Stream* i, const Value* const *vals)
if ( stream->pred || stream->event ) if ( stream->pred || stream->event )
{ {
bool updated = false; bool updated = false;
Val* oldval = 0; IntrusivePtr<Val> oldval;
if ( stream->num_val_fields > 0 ) if ( stream->num_val_fields > 0 )
{ {
@ -1619,7 +1614,6 @@ int Manager::PutTable(Stream* i, const Value* const *vals)
{ {
// it is an update // it is an update
updated = true; updated = true;
Ref(oldval); // have to do that, otherwise it may disappear in assign
} }
@ -1636,9 +1630,9 @@ int Manager::PutTable(Stream* i, const Value* const *vals)
else else
{ {
if ( updated ) if ( updated )
ev = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_CHANGED); ev = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_CHANGED).release();
else else
ev = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_NEW); ev = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_NEW).release();
bool result; bool result;
if ( stream->num_val_fields > 0 ) // we have values if ( stream->num_val_fields > 0 ) // we have values
@ -1654,7 +1648,6 @@ int Manager::PutTable(Stream* i, const Value* const *vals)
// do nothing // do nothing
Unref(idxval); Unref(idxval);
Unref(valval); Unref(valval);
Unref(oldval);
return stream->num_val_fields + stream->num_idx_fields; return stream->num_val_fields + stream->num_idx_fields;
} }
} }
@ -1678,14 +1671,14 @@ int Manager::PutTable(Stream* i, const Value* const *vals)
{ {
// in case of update send back the old value. // in case of update send back the old value.
assert ( stream->num_val_fields > 0 ); 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 ); assert ( oldval != 0 );
SendEvent(stream->event, 4, stream->description->Ref(), SendEvent(stream->event, 4, stream->description->Ref(),
ev, predidx, oldval); ev, predidx, oldval.release());
} }
else 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 ) if ( stream->num_val_fields == 0 )
SendEvent(stream->event, 4, stream->description->Ref(), SendEvent(stream->event, 4, stream->description->Ref(),
ev, predidx); ev, predidx);
@ -1759,7 +1752,7 @@ bool Manager::Delete(ReaderFrontend* reader, Value* *vals)
if ( stream->pred || stream->event ) if ( stream->pred || stream->event )
{ {
Val *val = stream->tab->Lookup(idxval); auto val = stream->tab->Lookup(idxval);
if ( stream->pred ) if ( stream->pred )
{ {
@ -1770,10 +1763,9 @@ bool Manager::Delete(ReaderFrontend* reader, Value* *vals)
Unref(predidx); Unref(predidx);
else else
{ {
Ref(val); EnumVal *ev = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_REMOVED).release();
EnumVal *ev = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_REMOVED);
streamresult = CallPred(stream->pred, 3, ev, predidx, val); streamresult = CallPred(stream->pred, 3, ev, predidx, IntrusivePtr{val}.release());
if ( streamresult == false ) if ( streamresult == false )
{ {
@ -1790,9 +1782,8 @@ bool Manager::Delete(ReaderFrontend* reader, Value* *vals)
{ {
Ref(idxval); Ref(idxval);
assert(val != 0); assert(val != 0);
Ref(val); EnumVal *ev = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_REMOVED).release();
EnumVal *ev = BifType::Enum::Input::Event->GetVal(BifEnum::Input::EVENT_REMOVED); SendEvent(stream->event, 4, stream->description->Ref(), ev, idxval, IntrusivePtr{val}.release());
SendEvent(stream->event, 4, stream->description->Ref(), ev, idxval, val);
} }
} }
@ -1811,7 +1802,7 @@ bool Manager::Delete(ReaderFrontend* reader, Value* *vals)
else if ( i->stream_type == EVENT_STREAM ) 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); readVals = SendEventStreamEvent(i, type, vals);
success = true; success = true;
} }
@ -2438,7 +2429,7 @@ Val* Manager::ValueToVal(const Stream* i, const Value* val, BroType* request_typ
return nullptr; return nullptr;
} }
return request_type->Ref()->AsEnumType()->GetVal(index); return request_type->Ref()->AsEnumType()->GetVal(index).release();
} }
default: default:
@ -2638,7 +2629,7 @@ Val* Manager::ValueToVal(const Stream* i, const Value* val, bool& have_error) co
return nullptr; return nullptr;
} }
return t->GetVal(intval); return t->GetVal(intval).release();
} }
default: default:
@ -2770,15 +2761,15 @@ void Manager::ErrorHandler(const Stream* i, ErrorType et, bool reporter_send, co
switch (et) switch (et)
{ {
case ErrorType::INFO: case ErrorType::INFO:
ev = BifType::Enum::Reporter::Level->GetVal(BifEnum::Reporter::INFO); ev = BifType::Enum::Reporter::Level->GetVal(BifEnum::Reporter::INFO).release();
break; break;
case ErrorType::WARNING: case ErrorType::WARNING:
ev = BifType::Enum::Reporter::Level->GetVal(BifEnum::Reporter::WARNING); ev = BifType::Enum::Reporter::Level->GetVal(BifEnum::Reporter::WARNING).release();
break; break;
case ErrorType::ERROR: case ErrorType::ERROR:
ev = BifType::Enum::Reporter::Level->GetVal(BifEnum::Reporter::ERROR); ev = BifType::Enum::Reporter::Level->GetVal(BifEnum::Reporter::ERROR).release();
break; break;
default: default:

View file

@ -11,6 +11,7 @@
#include "Type.h" #include "Type.h"
#include "File.h" #include "File.h"
#include "input.h" #include "input.h"
#include "IntrusivePtr.h"
#include "broker/Manager.h" #include "broker/Manager.h"
#include "threading/Manager.h" #include "threading/Manager.h"
@ -476,7 +477,7 @@ bool Manager::TraverseRecord(Stream* stream, Filter* filter, RecordType* rt,
if ( include ) if ( include )
{ {
StringVal* new_path_val = new StringVal(new_path.c_str()); 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); Unref(new_path_val);
@ -488,7 +489,7 @@ bool Manager::TraverseRecord(Stream* stream, Filter* filter, RecordType* rt,
if ( exclude ) if ( exclude )
{ {
StringVal* new_path_val = new StringVal(new_path.c_str()); 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); Unref(new_path_val);
@ -712,7 +713,7 @@ bool Manager::Write(EnumVal* id, RecordVal* columns)
if ( ! stream->enabled ) if ( ! stream->enabled )
return true; return true;
columns = columns->CoerceTo(stream->columns); columns = columns->CoerceTo(stream->columns).release();
if ( ! columns ) if ( ! columns )
{ {
@ -759,7 +760,7 @@ bool Manager::Write(EnumVal* id, RecordVal* columns)
BroType* rt = filter->path_func->FType()->Args()->FieldType("rec"); BroType* rt = filter->path_func->FType()->Args()->FieldType("rec");
if ( rt->Tag() == TYPE_RECORD ) if ( rt->Tag() == TYPE_RECORD )
rec_arg = columns->CoerceTo(rt->AsRecordType(), true); rec_arg = columns->CoerceTo(rt->AsRecordType(), true).release();
else else
// Can be TYPE_ANY here. // Can be TYPE_ANY here.
rec_arg = columns->Ref(); rec_arg = columns->Ref();
@ -865,8 +866,7 @@ bool Manager::Write(EnumVal* id, RecordVal* columns)
{ {
const char* name = filter->fields[j]->name; const char* name = filter->fields[j]->name;
StringVal *fn = new StringVal(name); StringVal *fn = new StringVal(name);
Val *val = 0; if ( auto val = filter->field_name_map->Lookup(fn, false) )
if ( (val = filter->field_name_map->Lookup(fn, false)) != 0 )
{ {
delete [] filter->fields[j]->name; delete [] filter->fields[j]->name;
filter->fields[j]->name = copy_string(val->AsStringVal()->CheckString()); filter->fields[j]->name = copy_string(val->AsStringVal()->CheckString());
@ -1319,12 +1319,11 @@ void Manager::SendAllWritersTo(const broker::endpoint_info& ei)
WriterFrontend* writer = i->second->writer; WriterFrontend* writer = i->second->writer;
auto writer_val = et->GetVal(i->first.first); auto writer_val = et->GetVal(i->first.first);
broker_mgr->PublishLogCreate((*s)->id, broker_mgr->PublishLogCreate((*s)->id,
writer_val, writer_val.get(),
*i->second->info, *i->second->info,
writer->NumFields(), writer->NumFields(),
writer->Fields(), writer->Fields(),
ei); ei);
Unref(writer_val);
} }
} }
} }

View file

@ -33,7 +33,7 @@ static bool call_option_handlers_and_set_value(StringVal* name, ID* i, Val* val,
} }
// clone to prevent changes // clone to prevent changes
i->SetVal({AdoptRef{}, val->Clone()}); i->SetVal(val->Clone());
Unref(val); // Either ref'd once or function call result. Unref(val); // Either ref'd once or function call result.
return true; return true;
} }

View file

@ -713,7 +713,7 @@ expr:
id->Name()); id->Name());
if ( intval < 0 ) if ( intval < 0 )
reporter->InternalError("enum value not found for %s", id->Name()); reporter->InternalError("enum value not found for %s", id->Name());
$$ = new ConstExpr({AdoptRef{}, t->GetVal(intval)}); $$ = new ConstExpr(t->GetVal(intval));
} }
else else
{ {

View file

@ -184,11 +184,11 @@ void TopkVal::Merge(const TopkVal* value, bool doPrune)
} }
} }
Val* TopkVal::DoClone(CloneState* state) IntrusivePtr<Val> TopkVal::DoClone(CloneState* state)
{ {
auto clone = new TopkVal(size); auto clone = make_intrusive<TopkVal>(size);
clone->Merge(this); clone->Merge(this);
return state->NewClone(this, clone); return state->NewClone(this, std::move(clone));
} }
VectorVal* TopkVal::GetTopK(int k) const // returns vector VectorVal* TopkVal::GetTopK(int k) const // returns vector

View file

@ -127,7 +127,7 @@ public:
* *
* @returns cloned TopkVal * @returns cloned TopkVal
*/ */
Val* DoClone(CloneState* state) override; IntrusivePtr<Val> DoClone(CloneState* state) override;
DECLARE_OPAQUE_VALUE(TopkVal) DECLARE_OPAQUE_VALUE(TopkVal)

View file

@ -86,10 +86,10 @@ int string_array_to_vs(TableVal* tbl, int start, int end,
for ( int i = start; i <= end; ++i ) for ( int i = start; i <= end; ++i )
{ {
Val* ind = val_mgr->GetCount(i); Val* ind = val_mgr->GetCount(i);
Val* v = tbl->Lookup(ind); auto v = tbl->Lookup(ind);
if ( ! v ) if ( ! v )
return 0; return 0;
vs.push_back(v->AsString()); vs.push_back(v.release()->AsString());
#if 0 #if 0
char* str = v->AsString()->Render(); char* str = v->AsString()->Render();
DEBUG_MSG("string_array[%d] = \"%s\"\n", i, str); DEBUG_MSG("string_array[%d] = \"%s\"\n", i, str);

View file

@ -1099,10 +1099,7 @@ Supervisor::NodeConfig Supervisor::NodeConfig::FromJSON(std::string_view json)
std::string Supervisor::NodeConfig::ToJSON() const std::string Supervisor::NodeConfig::ToJSON() const
{ {
auto re = std::make_unique<RE_Matcher>("^_"); auto re = std::make_unique<RE_Matcher>("^_");
auto node_val = ToRecord(); return ToRecord()->ToJSON(false, re.get())->ToStdString();
IntrusivePtr<StringVal> json_val{AdoptRef{}, node_val->ToJSON(false, re.get())};
auto rval = json_val->ToStdString();
return rval;
} }
IntrusivePtr<RecordVal> Supervisor::NodeConfig::ToRecord() const IntrusivePtr<RecordVal> Supervisor::NodeConfig::ToRecord() const
@ -1172,7 +1169,7 @@ IntrusivePtr<RecordVal> Supervisor::Node::ToRecord() const
} }
static Val* supervisor_role_to_cluster_node_type(BifEnum::Supervisor::ClusterRole role) static IntrusivePtr<Val> supervisor_role_to_cluster_node_type(BifEnum::Supervisor::ClusterRole role)
{ {
static auto node_type = global_scope()->Lookup("Cluster::NodeType")->AsType()->AsEnumType(); static auto node_type = global_scope()->Lookup("Cluster::NodeType")->AsType()->AsEnumType();
@ -1218,7 +1215,7 @@ bool Supervisor::SupervisedNode::InitCluster() const
auto val = make_intrusive<RecordVal>(cluster_node_type); auto val = make_intrusive<RecordVal>(cluster_node_type);
auto node_type = supervisor_role_to_cluster_node_type(ep.role); 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("node_type"), std::move(node_type));
val->Assign(cluster_node_type->FieldOffset("ip"), make_intrusive<AddrVal>(ep.host)); val->Assign(cluster_node_type->FieldOffset("ip"), make_intrusive<AddrVal>(ep.host));
val->Assign(cluster_node_type->FieldOffset("p"), val_mgr->GetPort(ep.port, TRANSPORT_TCP)); val->Assign(cluster_node_type->FieldOffset("p"), val_mgr->GetPort(ep.port, TRANSPORT_TCP));

View file

@ -405,7 +405,7 @@ static bool prepare_environment(TableVal* tbl, bool set)
for ( int i = 0; i < idxs->Length(); ++i ) for ( int i = 0; i < idxs->Length(); ++i )
{ {
Val* key = idxs->Index(i); Val* key = idxs->Index(i);
Val* val = tbl->Lookup(key, false); auto val = tbl->Lookup(key, false);
if ( key->Type()->Tag() != TYPE_STRING || if ( key->Type()->Tag() != TYPE_STRING ||
val->Type()->Tag() != TYPE_STRING ) val->Type()->Tag() != TYPE_STRING )
@ -1176,7 +1176,7 @@ function matching_subnets%(search: subnet, t: any%): subnet_vec
return nullptr; 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 ## 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 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]. ## Checks if a specific subnet is a member of a set/table[subnet].
@ -2012,10 +2012,10 @@ function record_fields%(rec: any%): record_field_table
return new TableVal(internal_type("record_field_table")->AsTableType()); return new TableVal(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 ## Enables detailed collection of profiling statistics. Statistics include
@ -3218,20 +3218,16 @@ EnumVal* map_conn_type(TransportProto tp)
{ {
switch ( tp ) { switch ( tp ) {
case TRANSPORT_UNKNOWN: case TRANSPORT_UNKNOWN:
return transport_proto->GetVal(0); return transport_proto->GetVal(0).release();
break;
case TRANSPORT_TCP: case TRANSPORT_TCP:
return transport_proto->GetVal(1); return transport_proto->GetVal(1).release();
break;
case TRANSPORT_UDP: case TRANSPORT_UDP:
return transport_proto->GetVal(2); return transport_proto->GetVal(2).release();
break;
case TRANSPORT_ICMP: case TRANSPORT_ICMP:
return transport_proto->GetVal(3); return transport_proto->GetVal(3).release();
break;
default: default:
reporter->InternalError("bad connection type in map_conn_type()"); reporter->InternalError("bad connection type in map_conn_type()");
@ -3257,7 +3253,7 @@ function get_conn_transport_proto%(cid: conn_id%): transport_proto
if ( ! c ) if ( ! c )
{ {
builtin_error("unknown connection id in get_conn_transport_proto()", cid); 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()); return map_conn_type(c->ConnTransport());
@ -5095,5 +5091,5 @@ function anonymize_addr%(a: addr, cl: IPAddrAnonymizationClass%): addr
## .. zeek:see:: fmt cat cat_sep string_cat print_raw ## .. 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 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();
%} %}

View file

@ -17,7 +17,7 @@ IdentifierInfo::IdentifierInfo(IntrusivePtr<ID> arg_id, ScriptInfo* script)
last_field_seen(), declaring_script(script) last_field_seen(), declaring_script(script)
{ {
if ( id->ID_Val() && (id->IsOption() || id->IsRedefinable()) ) if ( id->ID_Val() && (id->IsOption() || id->IsRedefinable()) )
initial_val = {AdoptRef{}, id->ID_Val()->Clone()}; initial_val = id->ID_Val()->Clone();
} }
IdentifierInfo::~IdentifierInfo() IdentifierInfo::~IdentifierInfo()