mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
factor out record coercion; modernize management of coercion "map"
This commit is contained in:
parent
5f5ba3881c
commit
91c2e05099
3 changed files with 27 additions and 24 deletions
41
src/Expr.cc
41
src/Expr.cc
|
@ -3759,8 +3759,7 @@ ValPtr ArithCoerceExpr::Fold(Val* v) const
|
||||||
}
|
}
|
||||||
|
|
||||||
RecordCoerceExpr::RecordCoerceExpr(ExprPtr arg_op, RecordTypePtr r)
|
RecordCoerceExpr::RecordCoerceExpr(ExprPtr arg_op, RecordTypePtr r)
|
||||||
: UnaryExpr(EXPR_RECORD_COERCE, std::move(arg_op)),
|
: UnaryExpr(EXPR_RECORD_COERCE, std::move(arg_op))
|
||||||
map(nullptr), map_size(0)
|
|
||||||
{
|
{
|
||||||
if ( IsError() )
|
if ( IsError() )
|
||||||
return;
|
return;
|
||||||
|
@ -3778,12 +3777,12 @@ RecordCoerceExpr::RecordCoerceExpr(ExprPtr arg_op, RecordTypePtr r)
|
||||||
RecordType* t_r = type->AsRecordType();
|
RecordType* t_r = type->AsRecordType();
|
||||||
RecordType* sub_r = op->GetType()->AsRecordType();
|
RecordType* sub_r = op->GetType()->AsRecordType();
|
||||||
|
|
||||||
map_size = t_r->NumFields();
|
int map_size = t_r->NumFields();
|
||||||
map = new int[map_size];
|
map.reserve(map_size);
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for ( i = 0; i < map_size; ++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 )
|
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
|
ValPtr RecordCoerceExpr::InitVal(const zeek::Type* t, ValPtr aggr) const
|
||||||
{
|
{
|
||||||
if ( auto v = Eval(nullptr) )
|
if ( auto v = Eval(nullptr) )
|
||||||
|
@ -3892,7 +3886,15 @@ ValPtr RecordCoerceExpr::Fold(Val* v) const
|
||||||
if ( same_type(GetType(), Op()->GetType()) )
|
if ( same_type(GetType(), Op()->GetType()) )
|
||||||
return IntrusivePtr{NewRef{}, v};
|
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();
|
RecordType* val_type = val->GetType()->AsRecordType();
|
||||||
|
|
||||||
RecordVal* rv = v->AsRecordVal();
|
RecordVal* rv = v->AsRecordVal();
|
||||||
|
@ -3905,14 +3907,15 @@ ValPtr RecordCoerceExpr::Fold(Val* v) const
|
||||||
|
|
||||||
if ( ! rhs )
|
if ( ! rhs )
|
||||||
{
|
{
|
||||||
const auto& def = rv->GetType()->AsRecordType()->FieldDecl(
|
auto rv_rt = rv->GetType()->AsRecordType();
|
||||||
map[i])->GetAttr(ATTR_DEFAULT);
|
const auto& def = rv_rt->FieldDecl(map[i])->
|
||||||
|
GetAttr(ATTR_DEFAULT);
|
||||||
|
|
||||||
if ( def )
|
if ( def )
|
||||||
rhs = def->GetExpr()->Eval(nullptr);
|
rhs = def->GetExpr()->Eval(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(rhs || GetType()->AsRecordType()->FieldDecl(i)->GetAttr(ATTR_OPTIONAL));
|
assert(rhs || rt->FieldDecl(i)->GetAttr(ATTR_OPTIONAL));
|
||||||
|
|
||||||
if ( ! rhs )
|
if ( ! rhs )
|
||||||
{
|
{
|
||||||
|
@ -3934,21 +3937,19 @@ ValPtr RecordCoerceExpr::Fold(Val* v) const
|
||||||
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) )
|
||||||
{
|
{
|
||||||
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);
|
rhs = std::move(new_val);
|
||||||
else
|
|
||||||
RuntimeError("Failed type conversion");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val->Assign(i, std::move(rhs));
|
val->Assign(i, std::move(rhs));
|
||||||
}
|
}
|
||||||
else
|
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);
|
auto def_val = def->GetExpr()->Eval(nullptr);
|
||||||
const auto& def_type = def_val->GetType();
|
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 &&
|
if ( def_type->Tag() == TYPE_RECORD &&
|
||||||
field_type->Tag() == TYPE_RECORD &&
|
field_type->Tag() == TYPE_RECORD &&
|
||||||
|
|
|
@ -1170,21 +1170,24 @@ protected:
|
||||||
class RecordCoerceExpr final : public UnaryExpr {
|
class RecordCoerceExpr final : public UnaryExpr {
|
||||||
public:
|
public:
|
||||||
RecordCoerceExpr(ExprPtr op, RecordTypePtr r);
|
RecordCoerceExpr(ExprPtr op, RecordTypePtr r);
|
||||||
~RecordCoerceExpr() override;
|
|
||||||
|
|
||||||
// Optimization-related:
|
// Optimization-related:
|
||||||
ExprPtr Duplicate() override;
|
ExprPtr Duplicate() override;
|
||||||
|
|
||||||
|
const std::vector<int>& Map() const { return map; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ValPtr InitVal(const zeek::Type* t, ValPtr aggr) const override;
|
ValPtr InitVal(const zeek::Type* t, ValPtr aggr) const override;
|
||||||
ValPtr Fold(Val* v) const override;
|
ValPtr Fold(Val* v) const override;
|
||||||
|
|
||||||
// For each super-record slot, gives subrecord slot with which to
|
// For each super-record slot, gives subrecord slot with which to
|
||||||
// fill it.
|
// fill it.
|
||||||
int* map;
|
std::vector<int> map;
|
||||||
int map_size; // equivalent to Type()->AsRecordType()->NumFields()
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern RecordValPtr coerce_to_record(RecordTypePtr rt, Val* v,
|
||||||
|
const std::vector<int>& map);
|
||||||
|
|
||||||
class TableCoerceExpr final : public UnaryExpr {
|
class TableCoerceExpr final : public UnaryExpr {
|
||||||
public:
|
public:
|
||||||
TableCoerceExpr(ExprPtr op, TableTypePtr r);
|
TableCoerceExpr(ExprPtr op, TableTypePtr r);
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
### 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)
|
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
|
3
|
||||||
int
|
int
|
||||||
4
|
4
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue