fixes for specialized ZAM operations needing to check whether record fields exist

This commit is contained in:
Vern Paxson 2025-07-28 17:27:30 -07:00 committed by Arne Welzel
parent db018253fe
commit 47bf6af6a5
7 changed files with 123 additions and 13 deletions

View file

@ -1269,7 +1269,7 @@ public:
/**
* Returns the value of a given field index if it's previously been
* assigned, * or else returns the value created from evaluating the
* assigned, or else returns the value created from evaluating the
* record field's &default expression.
* @param field The field index to retrieve.
* @return The value at the given field index or the default value if

View file

@ -76,7 +76,7 @@ macro AssignFromRec(rhs)
auto is_managed = Z_AUX->is_managed;
for ( size_t i = 0U; i < n; ++i )
{
auto rhs_i = rhs->RawField(rhs_map[i]);
auto rhs_i = FieldValWithCheck(rhs, rhs_map[i]);
auto& init_i = init_vals[lhs_map[i]];
if ( is_managed[i] )
{
@ -156,7 +156,7 @@ class VV
op-types R R
eval SetUpRecFieldOps(map)
for ( size_t i = 0U; i < n; ++i )
$1->RawOptField(lhs_map[i]) = $2->RawField(rhs_map[i]);
$1->RawOptField(lhs_map[i]) = FieldValWithCheck($2, rhs_map[i]);
macro DoManagedRecAssign(lhs, rhs)
auto is_managed = Z_AUX->is_managed;
@ -164,14 +164,14 @@ macro DoManagedRecAssign(lhs, rhs)
if ( is_managed[i] )
{
auto& lhs_i = lhs->RawOptField(lhs_map[i]);
auto rhs_i = rhs->RawField(rhs_map[i]);
auto rhs_i = FieldValWithCheck(rhs, rhs_map[i]);
zeek::Ref(rhs_i.ManagedVal());
if ( lhs_i )
ZVal::DeleteManagedType(*lhs_i);
lhs_i = rhs_i;
}
else
lhs->RawOptField(lhs_map[i]) = rhs->RawField(rhs_map[i]);
lhs->RawOptField(lhs_map[i]) = FieldValWithCheck(rhs, rhs_map[i]);
op Rec-Assign-Fields-Managed
op1-read
@ -188,7 +188,7 @@ eval SetUpRecFieldOps(map)
for ( size_t i = 0U; i < n; ++i )
{
auto& lhs_i = $1->RawOptField(lhs_map[i]);
auto rhs_i = $2->RawField(rhs_map[i]);
auto rhs_i = FieldValWithCheck($2, rhs_map[i]);
zeek::Ref(rhs_i.ManagedVal());
if ( lhs_i )
ZVal::DeleteManagedType(*lhs_i);
@ -201,7 +201,9 @@ class VV
op-types R R
eval SetUpRecFieldOps(map)
for ( size_t i = 0U; i < n; ++i )
$1->RawField(lhs_map[i]).AsIntRef() += $2->RawField(rhs_map[i]).AsInt();
$1->RawField(lhs_map[i]).AsIntRef() =
FieldValWithCheck($1, lhs_map[i]).AsInt() +
FieldValWithCheck($2, rhs_map[i]).AsInt();
op Rec-Add-Double-Fields
op1-read
@ -209,7 +211,9 @@ class VV
op-types R R
eval SetUpRecFieldOps(map)
for ( size_t i = 0U; i < n; ++i )
$1->RawField(lhs_map[i]).AsDoubleRef() += $2->RawField(rhs_map[i]).AsDouble();
$1->RawField(lhs_map[i]).AsDoubleRef() =
FieldValWithCheck($1, lhs_map[i]).AsDouble() +
FieldValWithCheck($2, rhs_map[i]).AsDouble();
op Rec-Add-Fields
op1-read
@ -219,8 +223,10 @@ eval SetUpRecFieldOps(map)
auto& types = Z_AUX->types;
for ( size_t i = 0U; i < n; ++i )
{
// We make this call to ensure that the field exists.
(void) FieldValWithCheck($1, lhs_map[i]);
auto& lhs_i = $1->RawField(lhs_map[i]);
auto rhs_i = $2->RawField(rhs_map[i]);
auto rhs_i = FieldValWithCheck($2, rhs_map[i]);
auto tag = types[i]->Tag();
if ( tag == TYPE_INT )
lhs_i.AsIntRef() += rhs_i.AsInt();

View file

@ -71,4 +71,6 @@ macro TableIter(slot) (*tiv_ptr)[slot]
macro DirectField(r, f) r->RawField(f)
macro DirectOptField(r, f) r->RawOptField(f)
macro FieldValWithCheck(r, f) ZBody::CheckAndLookupField(r, f, Z_LOC)
macro LogEnum(v) v.ToVal(ZAM::log_ID_enum_type)

View file

@ -34,10 +34,16 @@ internal-op Func-Id-String
class VV
op-types S R
eval auto id_rec = $1;
auto orig_h = DirectField(id_rec, 0).AsAddr()->AsAddr().AsString();
auto resp_h = DirectField(id_rec, 2).AsAddr()->AsAddr().AsString();
auto orig_p = static_cast<uint32_t>(DirectField(id_rec, 1).AsCount()) & ~PORT_SPACE_MASK;
auto resp_p = static_cast<uint32_t>(DirectField(id_rec, 3).AsCount()) & ~PORT_SPACE_MASK;
auto orig_h =
FieldValWithCheck(id_rec, 0).AsAddr()->AsAddr().AsString();
auto resp_h =
FieldValWithCheck(id_rec, 2).AsAddr()->AsAddr().AsString();
auto orig_p =
static_cast<uint32_t>(FieldValWithCheck(id_rec, 1).AsCount()) &
~PORT_SPACE_MASK;
auto resp_p =
static_cast<uint32_t>(FieldValWithCheck(id_rec, 3).AsCount()) &
~PORT_SPACE_MASK;
/* Maximum address size is for IPv6 with no compression. Each
* 8 16-bit hex elements plus 7 colons between them plus the two []'s
* = 8*4 + 7 + 2 = 41 characters.

View file

@ -65,6 +65,20 @@ public:
private:
friend class CPPCompile;
// Helper run-time function for looking up a field in a record, checking
// that it exists and complaining if it does not. A member here rather than
// a standalone run-time function because ZBody is a "friend" of RecordVal
// and can use its low-level record field accessors.
ZVal CheckAndLookupField(RecordVal* r, int f, const std::shared_ptr<ZAMLocInfo>& loc) {
auto opt_zv = r->RawOptField(f);
if ( ! opt_zv ) {
auto fn = r->GetType<RecordType>()->FieldName(f);
ZAM_run_time_error(loc, util::fmt("field value missing ($%s)", fn));
}
return *opt_zv;
}
auto Instructions() const { return insts; }
auto NumInsts() const { return end_pc; }