diff --git a/src/Frame.cc b/src/Frame.cc
index d4aff1c844..7c1470d2dc 100644
--- a/src/Frame.cc
+++ b/src/Frame.cc
@@ -17,7 +17,7 @@ std::vector g_frame_stack;
Frame::Frame(int arg_size, const BroFunc* func, const zeek::Args* fn_args)
{
size = arg_size;
- frame = std::make_unique[]>(size);
+ frame = std::make_unique(size);
function = func;
func_args = fn_args;
@@ -50,8 +50,6 @@ Frame::~Frame()
for ( int i = 0; i < size; ++i )
ClearElement(i);
-
- delete [] weak_refs;
}
void Frame::AddFunctionWithClosureRef(BroFunc* func)
@@ -70,26 +68,13 @@ void Frame::SetElement(int n, Val* v)
void Frame::SetElement(int n, IntrusivePtr v)
{
ClearElement(n);
- frame[n] = std::move(v);
-
- if ( weak_refs )
- weak_refs[n] = false;
+ frame[n] = {std::move(v), false};
}
void Frame::SetElementWeak(int n, Val* v)
{
ClearElement(n);
- frame[n] = {AdoptRef{}, v};
-
- if ( ! weak_refs )
- {
- weak_refs = new bool[size];
-
- for ( auto i = 0; i < size; ++i )
- weak_refs[i] = false;
- }
-
- weak_refs[n] = true;
+ frame[n] = {{AdoptRef{}, v}, true};
}
void Frame::SetElement(const ID* id, IntrusivePtr v)
@@ -134,19 +119,16 @@ const IntrusivePtr& Frame::GetElementByID(const ID* id) const
{
auto where = offset_map->find(std::string(id->Name()));
if ( where != offset_map->end() )
- return frame[where->second];
+ return frame[where->second].val;
}
- return frame[id->Offset()];
+ return frame[id->Offset()].val;
}
void Frame::Reset(int startIdx)
{
for ( int i = startIdx; i < size; ++i )
- {
ClearElement(i);
- frame[i] = nullptr;
- }
}
void Frame::Describe(ODesc* d) const
@@ -160,14 +142,14 @@ void Frame::Describe(ODesc* d) const
for ( int i = 0; i < size; ++i )
{
- d->Add(frame[i] != nullptr);
+ d->Add(frame[i].val != nullptr);
d->SP();
}
}
for ( int i = 0; i < size; ++i )
- if ( frame[i] )
- frame[i]->Describe(d);
+ if ( frame[i].val )
+ frame[i].val->Describe(d);
else if ( d->IsReadable() )
d->Add("");
}
@@ -185,8 +167,8 @@ Frame* Frame::Clone() const
other->trigger = trigger;
for ( int i = 0; i < size; i++ )
- if ( frame[i] )
- other->frame[i] = frame[i]->Clone();
+ if ( frame[i].val )
+ other->frame[i].val = frame[i].val->Clone();
return other;
}
@@ -201,7 +183,7 @@ static bool val_is_func(const IntrusivePtr& v, BroFunc* func)
void Frame::CloneNonFuncElement(int offset, BroFunc* func, Frame* other) const
{
- const auto& v = frame[offset];
+ const auto& v = frame[offset].val;
if ( ! v )
return;
@@ -247,7 +229,7 @@ Frame* Frame::SelectiveClone(const id_list& selection, BroFunc* func) const
}
}
- if ( ! frame[id->Offset()] )
+ if ( ! frame[id->Offset()].val )
reporter->InternalError("Attempted to clone an id ('%s') with no associated value.", id->Name());
CloneNonFuncElement(id->Offset(), func, other);
@@ -349,7 +331,7 @@ broker::expected Frame::Serialize(const Frame* target, const id_li
if (where != new_map.end())
location = where->second;
- const auto& val = target->frame[location];
+ const auto& val = target->frame[location].val;
TypeTag tag = val->GetType()->Tag();
@@ -484,7 +466,7 @@ std::pair> Frame::Unserialize(const broker::vector& da
if ( ! val )
return std::make_pair(false, nullptr);
- rf->frame[i] = std::move(val);
+ rf->frame[i].val = std::move(val);
}
return std::make_pair(true, std::move(rf));
@@ -535,10 +517,10 @@ void Frame::ClearTrigger()
void Frame::ClearElement(int n)
{
- if ( weak_refs && weak_refs[n] )
- frame[n].release();
+ if ( frame[n].weak_ref )
+ frame[n].val.release();
else
- frame[n] = nullptr;
+ frame[n] = {nullptr, false};
}
bool Frame::IsOuterID(const ID* in) const
diff --git a/src/Frame.h b/src/Frame.h
index 9c517ff65c..6dc3a055c5 100644
--- a/src/Frame.h
+++ b/src/Frame.h
@@ -43,10 +43,10 @@ public:
* @return the value at index *n* of the underlying array.
*/
const IntrusivePtr& GetElement(int n) const
- { return frame[n]; }
+ { return frame[n].val; }
[[deprecated("Remove in v4.1. Use GetElement(int).")]]
- Val* NthElement(int n) const { return frame[n].get(); }
+ Val* NthElement(int n) const { return frame[n].val.get(); }
/**
* Sets the element at index *n* of the underlying array to *v*.
@@ -237,6 +237,13 @@ private:
using OffsetMap = std::unordered_map;
+ struct Element {
+ IntrusivePtr val;
+ // Weak reference is used to prevent circular reference memory leaks
+ // in lambdas/closures.
+ bool weak_ref;
+ };
+
const IntrusivePtr& GetElementByID(const ID* id) const;
/**
@@ -290,11 +297,7 @@ private:
bool delayed;
/** Associates ID's offsets with values. */
- std::unique_ptr[]> frame;
-
- /** Values that are weakly referenced by the frame. Used to
- * prevent circular reference memory leaks in lambda/closures */
- bool* weak_refs = nullptr;
+ std::unique_ptr frame;
/** The enclosing frame of this frame. */
Frame* closure;