RecordType: Allow deferring &default=vector(), set(), table() fields

This commit is contained in:
Arne Welzel 2025-07-24 17:56:22 +02:00
parent 7894d88461
commit 23181e4811
3 changed files with 27 additions and 3 deletions

4
NEWS
View file

@ -331,6 +331,10 @@ Changed Functionality
- The PPPoE parser now respects the size value given in the PPPoE header. Data - The PPPoE parser now respects the size value given in the PPPoE header. Data
beyon the size given in the header will be truncated. beyon the size given in the header will be truncated.
- Record fields with ``&default`` attributes initializing empty ``vector``, ``table``
or ``set`` instances are now deferred until they are accessed, potentially
improving memory usage when such fields are never accessed.
Removed Functionality Removed Functionality
--------------------- ---------------------

View file

@ -929,6 +929,20 @@ public:
return rt->IsDeferrable() && constructor_list->Exprs().empty(); return rt->IsDeferrable() && constructor_list->Exprs().empty();
} }
// Allow deferring fairly common &default=vector() field initialization...
if ( init_expr->Tag() == EXPR_VECTOR_CONSTRUCTOR ) {
auto vce = zeek::cast_intrusive<VectorConstructorExpr>(init_expr);
return vce->GetType<zeek::VectorType>()->IsUnspecifiedVector();
}
// ...and also &default=table() and &default=set().
if ( init_expr->Tag() == EXPR_TABLE_COERCE || init_expr->Tag() == EXPR_TABLE_CONSTRUCTOR ||
init_expr->Tag() == EXPR_SET_CONSTRUCTOR ) {
auto une = zeek::cast_intrusive<UnaryExpr>(init_expr);
return une->Op()->GetType()->Tag() == TYPE_TABLE &&
une->Op()->GetType<zeek::TableType>()->IsUnspecifiedTable();
}
return false; return false;
} }
@ -1010,8 +1024,10 @@ private:
if ( ! ci.second->IsDeferrable() ) if ( ! ci.second->IsDeferrable() )
rt->creation_inits[i++] = std::move(ci); rt->creation_inits[i++] = std::move(ci);
else { else {
// std::fprintf(stderr, "deferred %s$%s: %s\n", obj_desc_short(rt).c_str(), rt->FieldName(ci.first), // std::fprintf(stderr, "deferred %s$%s: %s (%s)\n", obj_desc_short(rt).c_str(),
// ci.second->InitExpr() ? obj_desc_short(ci.second->InitExpr()).c_str() : "<none>"); // rt->FieldName(ci.first),
// ci.second->InitExpr() ? obj_desc_short(ci.second->InitExpr()).c_str() : "<none>",
// typeid(ci).name());
assert(! rt->deferred_inits[ci.first]); assert(! rt->deferred_inits[ci.first]);
rt->deferred_inits[ci.first].swap(ci.second); rt->deferred_inits[ci.first].swap(ci.second);
} }

View file

@ -1,2 +1,6 @@
### 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.
[a=<uninitialized>, b=<uninitialized>, c=<uninitialized>] [a={
}, b={
}, c=[]]