factor out record coercion; modernize management of coercion "map"

This commit is contained in:
Vern Paxson 2021-03-18 10:08:31 -07:00
parent 5f5ba3881c
commit 91c2e05099
3 changed files with 27 additions and 24 deletions

View file

@ -3759,8 +3759,7 @@ ValPtr ArithCoerceExpr::Fold(Val* v) const
}
RecordCoerceExpr::RecordCoerceExpr(ExprPtr arg_op, RecordTypePtr r)
: UnaryExpr(EXPR_RECORD_COERCE, std::move(arg_op)),
map(nullptr), map_size(0)
: UnaryExpr(EXPR_RECORD_COERCE, std::move(arg_op))
{
if ( IsError() )
return;
@ -3778,12 +3777,12 @@ RecordCoerceExpr::RecordCoerceExpr(ExprPtr arg_op, RecordTypePtr r)
RecordType* t_r = type->AsRecordType();
RecordType* sub_r = op->GetType()->AsRecordType();
map_size = t_r->NumFields();
map = new int[map_size];
int map_size = t_r->NumFields();
map.reserve(map_size);
int i;
for ( i = 0; i < map_size; ++i )
map[i] = -1; // -1 = field is not mapped
map.emplace_back(-1); // -1 = field is not mapped
for ( i = 0; i < sub_r->NumFields(); ++i )
{
@ -3865,11 +3864,6 @@ RecordCoerceExpr::RecordCoerceExpr(ExprPtr arg_op, RecordTypePtr r)
}
}
RecordCoerceExpr::~RecordCoerceExpr()
{
delete [] map;
}
ValPtr RecordCoerceExpr::InitVal(const zeek::Type* t, ValPtr aggr) const
{
if ( auto v = Eval(nullptr) )
@ -3892,7 +3886,15 @@ ValPtr RecordCoerceExpr::Fold(Val* v) const
if ( same_type(GetType(), Op()->GetType()) )
return IntrusivePtr{NewRef{}, v};
auto val = make_intrusive<RecordVal>(GetType<RecordType>());
auto rt = cast_intrusive<RecordType>(GetType());
return coerce_to_record(rt, v, map);
}
RecordValPtr coerce_to_record(RecordTypePtr rt, Val* v,
const std::vector<int>& map)
{
auto map_size = map.size();
auto val = make_intrusive<RecordVal>(rt);
RecordType* val_type = val->GetType()->AsRecordType();
RecordVal* rv = v->AsRecordVal();
@ -3905,14 +3907,15 @@ ValPtr RecordCoerceExpr::Fold(Val* v) const
if ( ! rhs )
{
const auto& def = rv->GetType()->AsRecordType()->FieldDecl(
map[i])->GetAttr(ATTR_DEFAULT);
auto rv_rt = rv->GetType()->AsRecordType();
const auto& def = rv_rt->FieldDecl(map[i])->
GetAttr(ATTR_DEFAULT);
if ( def )
rhs = def->GetExpr()->Eval(nullptr);
}
assert(rhs || GetType()->AsRecordType()->FieldDecl(i)->GetAttr(ATTR_OPTIONAL));
assert(rhs || rt->FieldDecl(i)->GetAttr(ATTR_OPTIONAL));
if ( ! rhs )
{
@ -3934,21 +3937,19 @@ ValPtr RecordCoerceExpr::Fold(Val* v) const
else if ( BothArithmetic(rhs_type->Tag(), field_type->Tag()) &&
! same_type(rhs_type, field_type) )
{
if ( auto new_val = check_and_promote(rhs, field_type.get(), false, op->GetLocationInfo()) )
auto new_val = check_and_promote(rhs, field_type.get(), false);
rhs = std::move(new_val);
else
RuntimeError("Failed type conversion");
}
val->Assign(i, std::move(rhs));
}
else
{
if ( const auto& def = GetType()->AsRecordType()->FieldDecl(i)->GetAttr(ATTR_DEFAULT) )
if ( const auto& def = rt->FieldDecl(i)->GetAttr(ATTR_DEFAULT) )
{
auto def_val = def->GetExpr()->Eval(nullptr);
const auto& def_type = def_val->GetType();
const auto& field_type = GetType()->AsRecordType()->GetFieldType(i);
const auto& field_type = rt->GetFieldType(i);
if ( def_type->Tag() == TYPE_RECORD &&
field_type->Tag() == TYPE_RECORD &&

View file

@ -1170,21 +1170,24 @@ protected:
class RecordCoerceExpr final : public UnaryExpr {
public:
RecordCoerceExpr(ExprPtr op, RecordTypePtr r);
~RecordCoerceExpr() override;
// Optimization-related:
ExprPtr Duplicate() override;
const std::vector<int>& Map() const { return map; }
protected:
ValPtr InitVal(const zeek::Type* t, ValPtr aggr) const override;
ValPtr Fold(Val* v) const override;
// For each super-record slot, gives subrecord slot with which to
// fill it.
int* map;
int map_size; // equivalent to Type()->AsRecordType()->NumFields()
std::vector<int> map;
};
extern RecordValPtr coerce_to_record(RecordTypePtr rt, Val* v,
const std::vector<int>& map);
class TableCoerceExpr final : public UnaryExpr {
public:
TableCoerceExpr(ExprPtr op, TableTypePtr r);

View file

@ -1,6 +1,5 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
error in int and ./first_set.zeek, line 46: overflow promoting from unsigned/double to signed arithmetic value (int and 9223372036854775808)
expression error in ./first_set.zeek, line 46: Failed type conversion ((coerce [$ii=9223372036854775808] to record { ii:int &optional; cc:count &optional; dd:double &optional; }))
3
int
4