diff --git a/NEWS b/NEWS index b11090acc4..cfbb95b6b7 100644 --- a/NEWS +++ b/NEWS @@ -331,6 +331,10 @@ Changed Functionality - The PPPoE parser now respects the size value given in the PPPoE header. Data 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 --------------------- diff --git a/src/Type.cc b/src/Type.cc index 10104dbc74..eb38c19b0b 100644 --- a/src/Type.cc +++ b/src/Type.cc @@ -929,6 +929,20 @@ public: 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(init_expr); + return vce->GetType()->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(init_expr); + return une->Op()->GetType()->Tag() == TYPE_TABLE && + une->Op()->GetType()->IsUnspecifiedTable(); + } + return false; } @@ -1010,8 +1024,10 @@ private: if ( ! ci.second->IsDeferrable() ) rt->creation_inits[i++] = std::move(ci); else { - // std::fprintf(stderr, "deferred %s$%s: %s\n", obj_desc_short(rt).c_str(), rt->FieldName(ci.first), - // ci.second->InitExpr() ? obj_desc_short(ci.second->InitExpr()).c_str() : ""); + // std::fprintf(stderr, "deferred %s$%s: %s (%s)\n", obj_desc_short(rt).c_str(), + // rt->FieldName(ci.first), + // ci.second->InitExpr() ? obj_desc_short(ci.second->InitExpr()).c_str() : "", + // typeid(ci).name()); assert(! rt->deferred_inits[ci.first]); rt->deferred_inits[ci.first].swap(ci.second); } diff --git a/testing/btest/Baseline/language.delete-field-set/output b/testing/btest/Baseline/language.delete-field-set/output index 85fc672ea8..e99c5e4bf8 100644 --- a/testing/btest/Baseline/language.delete-field-set/output +++ b/testing/btest/Baseline/language.delete-field-set/output @@ -1,2 +1,6 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -[a=, b=, c=] +[a={ + +}, b={ + +}, c=[]]