Switch RecordVal::CoerceTo() to use IntrusivePtr

This commit is contained in:
Jon Siwek 2020-05-18 17:52:54 -07:00
parent fcaade6e31
commit cda4738407
6 changed files with 39 additions and 28 deletions

View file

@ -3018,7 +3018,10 @@ IntrusivePtr<Val> RecordConstructorExpr::InitVal(const BroType* t, IntrusivePtr<
if ( v ) if ( v )
{ {
RecordVal* rv = v->AsRecordVal(); RecordVal* rv = v->AsRecordVal();
auto ar = rv->CoerceTo(t->AsRecordType(), aggr.release()); auto bt = const_cast<BroType*>(t);
IntrusivePtr<RecordType> rt{NewRef{}, bt->AsRecordType()};
auto aggr_rec = cast_intrusive<RecordVal>(std::move(aggr));
auto ar = rv->CoerceTo(std::move(rt), std::move(aggr_rec));
if ( ar ) if ( ar )
return ar; return ar;
@ -3633,7 +3636,11 @@ IntrusivePtr<Val> RecordCoerceExpr::InitVal(const BroType* t, IntrusivePtr<Val>
if ( auto v = Eval(nullptr) ) if ( auto v = Eval(nullptr) )
{ {
RecordVal* rv = v->AsRecordVal(); RecordVal* rv = v->AsRecordVal();
if ( auto ar = rv->CoerceTo(t->AsRecordType(), aggr.release()) ) auto bt = const_cast<BroType*>(t);
IntrusivePtr<RecordType> rt{NewRef{}, bt->AsRecordType()};
auto aggr_rec = cast_intrusive<RecordVal>(std::move(aggr));
if ( auto ar = rv->CoerceTo(std::move(rt), std::move(aggr_rec)) )
return ar; return ar;
} }
@ -3673,19 +3680,19 @@ IntrusivePtr<Val> RecordCoerceExpr::Fold(Val* v) const
} }
BroType* rhs_type = rhs->GetType().get(); BroType* rhs_type = rhs->GetType().get();
BroType* field_type = val_type->GetFieldType(i).get(); const auto& field_type = val_type->GetFieldType(i);
if ( rhs_type->Tag() == TYPE_RECORD && if ( rhs_type->Tag() == TYPE_RECORD &&
field_type->Tag() == TYPE_RECORD && field_type->Tag() == TYPE_RECORD &&
! same_type(rhs_type, field_type) ) ! same_type(rhs_type, field_type.get()) )
{ {
if ( auto new_val = rhs->AsRecordVal()->CoerceTo(field_type->AsRecordType()) ) if ( auto new_val = rhs->AsRecordVal()->CoerceTo(cast_intrusive<RecordType>(field_type)) )
rhs = std::move(new_val); rhs = std::move(new_val);
} }
else if ( BothArithmetic(rhs_type->Tag(), field_type->Tag()) && else if ( BothArithmetic(rhs_type->Tag(), field_type->Tag()) &&
! same_type(rhs_type, field_type) ) ! same_type(rhs_type, field_type.get()) )
{ {
if ( auto new_val = check_and_promote(rhs, field_type, false, op->GetLocationInfo()) ) if ( auto new_val = check_and_promote(rhs, field_type.get(), false, op->GetLocationInfo()) )
rhs = std::move(new_val); rhs = std::move(new_val);
else else
RuntimeError("Failed type conversion"); RuntimeError("Failed type conversion");
@ -3706,7 +3713,7 @@ IntrusivePtr<Val> RecordCoerceExpr::Fold(Val* v) const
! same_type(def_type.get(), field_type.get()) ) ! same_type(def_type.get(), field_type.get()) )
{ {
auto tmp = def_val->AsRecordVal()->CoerceTo( auto tmp = def_val->AsRecordVal()->CoerceTo(
field_type->AsRecordType()); cast_intrusive<RecordType>(field_type));
if ( tmp ) if ( tmp )
def_val = std::move(tmp); def_val = std::move(tmp);

View file

@ -2694,7 +2694,7 @@ RecordVal::RecordVal(IntrusivePtr<RecordType> t, bool init_fields) : Val(std::mo
def->GetType()->Tag() == TYPE_RECORD && def->GetType()->Tag() == TYPE_RECORD &&
! same_type(def->GetType().get(), type.get()) ) ! same_type(def->GetType().get(), type.get()) )
{ {
auto tmp = def->AsRecordVal()->CoerceTo(type->AsRecordType()); auto tmp = def->AsRecordVal()->CoerceTo(cast_intrusive<RecordType>(type));
if ( tmp ) if ( tmp )
def = std::move(tmp); def = std::move(tmp);
@ -2796,17 +2796,17 @@ IntrusivePtr<Val> RecordVal::Lookup(const char* field, bool with_default) const
return with_default ? LookupWithDefault(idx) : IntrusivePtr{NewRef{}, Lookup(idx)}; return with_default ? LookupWithDefault(idx) : IntrusivePtr{NewRef{}, Lookup(idx)};
} }
IntrusivePtr<RecordVal> RecordVal::CoerceTo(const RecordType* t, Val* aggr, bool allow_orphaning) const IntrusivePtr<RecordVal> RecordVal::CoerceTo(IntrusivePtr<RecordType> t,
IntrusivePtr<RecordVal> aggr,
bool allow_orphaning) const
{ {
if ( ! record_promotion_compatible(t->AsRecordType(), GetType()->AsRecordType()) ) if ( ! record_promotion_compatible(t.get(), GetType()->AsRecordType()) )
return nullptr; return nullptr;
if ( ! aggr ) if ( ! aggr )
aggr = new RecordVal({NewRef{}, const_cast<RecordType*>(t)}); aggr = make_intrusive<RecordVal>(std::move(t));
RecordVal* ar = aggr->AsRecordVal();
RecordType* ar_t = aggr->GetType()->AsRecordType(); RecordType* ar_t = aggr->GetType()->AsRecordType();
const RecordType* rv_t = GetType()->AsRecordType(); const RecordType* rv_t = GetType()->AsRecordType();
int i; int i;
@ -2840,15 +2840,15 @@ IntrusivePtr<RecordVal> RecordVal::CoerceTo(const RecordType* t, Val* aggr, bool
auto rhs = make_intrusive<ConstExpr>(IntrusivePtr{NewRef{}, v}); auto rhs = make_intrusive<ConstExpr>(IntrusivePtr{NewRef{}, v});
auto e = make_intrusive<RecordCoerceExpr>(std::move(rhs), auto e = make_intrusive<RecordCoerceExpr>(std::move(rhs),
cast_intrusive<RecordType>(ft)); cast_intrusive<RecordType>(ft));
ar->Assign(t_i, e->Eval(nullptr)); aggr->Assign(t_i, e->Eval(nullptr));
continue; continue;
} }
ar->Assign(t_i, {NewRef{}, v}); aggr->Assign(t_i, {NewRef{}, v});
} }
for ( i = 0; i < ar_t->NumFields(); ++i ) for ( i = 0; i < ar_t->NumFields(); ++i )
if ( ! ar->Lookup(i) && if ( ! aggr->Lookup(i) &&
! ar_t->FieldDecl(i)->FindAttr(ATTR_OPTIONAL) ) ! ar_t->FieldDecl(i)->FindAttr(ATTR_OPTIONAL) )
{ {
char buf[512]; char buf[512];
@ -2857,15 +2857,16 @@ IntrusivePtr<RecordVal> RecordVal::CoerceTo(const RecordType* t, Val* aggr, bool
Error(buf); Error(buf);
} }
return {AdoptRef{}, ar}; return aggr;
} }
IntrusivePtr<RecordVal> RecordVal::CoerceTo(RecordType* t, bool allow_orphaning) IntrusivePtr<RecordVal> RecordVal::CoerceTo(IntrusivePtr<RecordType> t,
bool allow_orphaning)
{ {
if ( same_type(GetType().get(), t) ) if ( same_type(GetType().get(), t.get()) )
return {NewRef{}, this}; return {NewRef{}, this};
return CoerceTo(t, nullptr, allow_orphaning); return CoerceTo(std::move(t), nullptr, allow_orphaning);
} }
IntrusivePtr<TableVal> RecordVal::GetRecordFieldsVal() const IntrusivePtr<TableVal> RecordVal::GetRecordFieldsVal() const

View file

@ -983,8 +983,11 @@ 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.
IntrusivePtr<RecordVal> CoerceTo(const RecordType* other, Val* aggr, bool allow_orphaning = false) const; IntrusivePtr<RecordVal> CoerceTo(IntrusivePtr<RecordType> other,
IntrusivePtr<RecordVal> CoerceTo(RecordType* other, bool allow_orphaning = false); IntrusivePtr<RecordVal> aggr,
bool allow_orphaning = false) const;
IntrusivePtr<RecordVal> CoerceTo(IntrusivePtr<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;

View file

@ -11,7 +11,7 @@ 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 zeek::BifType::Record::Files::AnalyzerArgs; using zeek::BifType::Record::Files::AnalyzerArgs;
auto rv = args->AsRecordVal()->CoerceTo(AnalyzerArgs.get()); auto rv = args->AsRecordVal()->CoerceTo(AnalyzerArgs);
bool result = file_mgr->SetExtractionLimit(file_id->CheckString(), rv.get(), n); bool result = file_mgr->SetExtractionLimit(file_id->CheckString(), rv.get(), n);
return val_mgr->Bool(result); return val_mgr->Bool(result);
%} %}

View file

@ -42,7 +42,7 @@ 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 zeek::BifType::Record::Files::AnalyzerArgs; using zeek::BifType::Record::Files::AnalyzerArgs;
auto rv = args->AsRecordVal()->CoerceTo(AnalyzerArgs.get()); 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.get()); file_mgr->GetComponentTag(tag), rv.get());
return val_mgr->Bool(result); return val_mgr->Bool(result);
@ -52,7 +52,7 @@ 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 zeek::BifType::Record::Files::AnalyzerArgs; using zeek::BifType::Record::Files::AnalyzerArgs;
auto rv = args->AsRecordVal()->CoerceTo(AnalyzerArgs.get()); 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.get()); file_mgr->GetComponentTag(tag) , rv.get());
return val_mgr->Bool(result); return val_mgr->Bool(result);

View file

@ -701,7 +701,7 @@ bool Manager::Write(EnumVal* id, RecordVal* columns_arg)
if ( ! stream->enabled ) if ( ! stream->enabled )
return true; return true;
auto columns = columns_arg->CoerceTo(stream->columns); auto columns = columns_arg->CoerceTo({NewRef{}, stream->columns});
if ( ! columns ) if ( ! columns )
{ {
@ -747,7 +747,7 @@ bool Manager::Write(EnumVal* id, RecordVal* columns_arg)
const auto& rt = filter->path_func->GetType()->Params()->GetFieldType("rec"); const auto& rt = filter->path_func->GetType()->Params()->GetFieldType("rec");
if ( rt->Tag() == TYPE_RECORD ) if ( rt->Tag() == TYPE_RECORD )
rec_arg = columns->CoerceTo(rt->AsRecordType(), true); rec_arg = columns->CoerceTo(cast_intrusive<RecordType>(rt), true);
else else
// Can be TYPE_ANY here. // Can be TYPE_ANY here.
rec_arg = columns; rec_arg = columns;