mirror of
https://github.com/zeek/zeek.git
synced 2025-10-03 15:18:20 +00:00
Switch Frame::SetElement() to use IntrusivePtr
This commit is contained in:
parent
1c617c4f7a
commit
e9e2e388f8
5 changed files with 78 additions and 60 deletions
|
@ -273,7 +273,7 @@ void NameExpr::Assign(Frame* f, IntrusivePtr<Val> v)
|
||||||
if ( id->IsGlobal() )
|
if ( id->IsGlobal() )
|
||||||
id->SetVal(std::move(v));
|
id->SetVal(std::move(v));
|
||||||
else
|
else
|
||||||
f->SetElement(id.get(), v.release());
|
f->SetElement(id.get(), std::move(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NameExpr::IsPure() const
|
bool NameExpr::IsPure() const
|
||||||
|
|
50
src/Frame.cc
50
src/Frame.cc
|
@ -49,7 +49,7 @@ Frame::~Frame()
|
||||||
Unref(i);
|
Unref(i);
|
||||||
|
|
||||||
for ( int i = 0; i < size; ++i )
|
for ( int i = 0; i < size; ++i )
|
||||||
UnrefElement(i);
|
ClearElement(i);
|
||||||
|
|
||||||
delete [] weak_refs;
|
delete [] weak_refs;
|
||||||
}
|
}
|
||||||
|
@ -64,13 +64,23 @@ void Frame::AddFunctionWithClosureRef(BroFunc* func)
|
||||||
functions_with_closure_frame_reference->emplace_back(func);
|
functions_with_closure_frame_reference->emplace_back(func);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Frame::SetElement(int n, Val* v, bool weak_ref)
|
void Frame::SetElement(int n, Val* v)
|
||||||
|
{ SetElement(n, {AdoptRef{}, v}); }
|
||||||
|
|
||||||
|
void Frame::SetElement(int n, IntrusivePtr<Val> v)
|
||||||
{
|
{
|
||||||
UnrefElement(n);
|
ClearElement(n);
|
||||||
|
frame[n] = std::move(v);
|
||||||
|
|
||||||
|
if ( weak_refs )
|
||||||
|
weak_refs[n] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Frame::SetElementWeak(int n, Val* v)
|
||||||
|
{
|
||||||
|
ClearElement(n);
|
||||||
frame[n] = {AdoptRef{}, v};
|
frame[n] = {AdoptRef{}, v};
|
||||||
|
|
||||||
if ( weak_ref )
|
|
||||||
{
|
|
||||||
if ( ! weak_refs )
|
if ( ! weak_refs )
|
||||||
{
|
{
|
||||||
weak_refs = new bool[size];
|
weak_refs = new bool[size];
|
||||||
|
@ -81,20 +91,14 @@ void Frame::SetElement(int n, Val* v, bool weak_ref)
|
||||||
|
|
||||||
weak_refs[n] = true;
|
weak_refs[n] = true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
if ( weak_refs )
|
|
||||||
weak_refs[n] = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Frame::SetElement(const ID* id, Val* v)
|
void Frame::SetElement(const ID* id, IntrusivePtr<Val> v)
|
||||||
{
|
{
|
||||||
if ( closure )
|
if ( closure )
|
||||||
{
|
{
|
||||||
if ( IsOuterID(id) )
|
if ( IsOuterID(id) )
|
||||||
{
|
{
|
||||||
closure->SetElement(id, v);
|
closure->SetElement(id, std::move(v));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,11 +114,11 @@ void Frame::SetElement(const ID* id, Val* v)
|
||||||
// id->Offset() below is otherwise responsible for keeping track
|
// id->Offset() below is otherwise responsible for keeping track
|
||||||
// of the implied reference count of the passed-in 'v' argument.
|
// of the implied reference count of the passed-in 'v' argument.
|
||||||
// i.e. if we end up storing it twice, we need an addition Ref.
|
// i.e. if we end up storing it twice, we need an addition Ref.
|
||||||
SetElement(where->second, v->Ref());
|
SetElement(where->second, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetElement(id->Offset(), v);
|
SetElement(id->Offset(), std::move(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
Val* Frame::GetElement(const ID* id) const
|
Val* Frame::GetElement(const ID* id) const
|
||||||
|
@ -140,7 +144,7 @@ void Frame::Reset(int startIdx)
|
||||||
{
|
{
|
||||||
for ( int i = startIdx; i < size; ++i )
|
for ( int i = startIdx; i < size; ++i )
|
||||||
{
|
{
|
||||||
UnrefElement(i);
|
ClearElement(i);
|
||||||
frame[i] = nullptr;
|
frame[i] = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -195,9 +199,7 @@ static bool val_is_func(const IntrusivePtr<Val>& v, BroFunc* func)
|
||||||
return v->AsFunc() == func;
|
return v->AsFunc() == func;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clone_if_not_func(const std::unique_ptr<IntrusivePtr<Val>[]>& frame,
|
void Frame::CloneNonFuncElement(int offset, BroFunc* func, Frame* other) const
|
||||||
int offset, BroFunc* func,
|
|
||||||
Frame* other)
|
|
||||||
{
|
{
|
||||||
const auto& v = frame[offset];
|
const auto& v = frame[offset];
|
||||||
|
|
||||||
|
@ -206,12 +208,12 @@ static void clone_if_not_func(const std::unique_ptr<IntrusivePtr<Val>[]>& frame,
|
||||||
|
|
||||||
if ( val_is_func(v, func) )
|
if ( val_is_func(v, func) )
|
||||||
{
|
{
|
||||||
other->SetElement(offset, v.get(), true);
|
other->SetElementWeak(offset, v.get());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto rval = v->Clone();
|
auto rval = v->Clone();
|
||||||
other->SetElement(offset, rval.release());
|
other->SetElement(offset, std::move(rval));
|
||||||
}
|
}
|
||||||
|
|
||||||
Frame* Frame::SelectiveClone(const id_list& selection, BroFunc* func) const
|
Frame* Frame::SelectiveClone(const id_list& selection, BroFunc* func) const
|
||||||
|
@ -240,7 +242,7 @@ Frame* Frame::SelectiveClone(const id_list& selection, BroFunc* func) const
|
||||||
auto where = offset_map->find(std::string(id->Name()));
|
auto where = offset_map->find(std::string(id->Name()));
|
||||||
if ( where != offset_map->end() )
|
if ( where != offset_map->end() )
|
||||||
{
|
{
|
||||||
clone_if_not_func(frame, where->second, func, other);
|
CloneNonFuncElement(where->second, func, other);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -248,7 +250,7 @@ Frame* Frame::SelectiveClone(const id_list& selection, BroFunc* func) const
|
||||||
if ( ! frame[id->Offset()] )
|
if ( ! frame[id->Offset()] )
|
||||||
reporter->InternalError("Attempted to clone an id ('%s') with no associated value.", id->Name());
|
reporter->InternalError("Attempted to clone an id ('%s') with no associated value.", id->Name());
|
||||||
|
|
||||||
clone_if_not_func(frame, id->Offset(), func, other);
|
CloneNonFuncElement(id->Offset(), func, other);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -531,7 +533,7 @@ void Frame::ClearTrigger()
|
||||||
trigger = nullptr;
|
trigger = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Frame::UnrefElement(int n)
|
void Frame::ClearElement(int n)
|
||||||
{
|
{
|
||||||
if ( weak_refs && weak_refs[n] )
|
if ( weak_refs && weak_refs[n] )
|
||||||
frame[n].release();
|
frame[n].release();
|
||||||
|
|
39
src/Frame.h
39
src/Frame.h
|
@ -45,16 +45,14 @@ public:
|
||||||
Val* NthElement(int n) const { return frame[n].get(); }
|
Val* NthElement(int n) const { return frame[n].get(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the element at index *n* of the underlying array
|
* Sets the element at index *n* of the underlying array to *v*.
|
||||||
* to *v*.
|
|
||||||
*
|
|
||||||
* @param n the index to set
|
* @param n the index to set
|
||||||
* @param v the value to set it to
|
* @param v the value to set it to
|
||||||
* @param weak_ref whether the frame owns the value and should unref
|
|
||||||
* it upon destruction. Used to break circular references between
|
|
||||||
* lambda functions and closure frames.
|
|
||||||
*/
|
*/
|
||||||
void SetElement(int n, Val* v, bool weak_ref = false);
|
void SetElement(int n, IntrusivePtr<Val> v);
|
||||||
|
|
||||||
|
[[deprecated("Remove in v4.1. Pass IntrusivePtr instead.")]]
|
||||||
|
void SetElement(int n, Val* v);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Associates *id* and *v* in the frame. Future lookups of
|
* Associates *id* and *v* in the frame. Future lookups of
|
||||||
|
@ -63,7 +61,7 @@ public:
|
||||||
* @param id the ID to associate
|
* @param id the ID to associate
|
||||||
* @param v the value to associate it with
|
* @param v the value to associate it with
|
||||||
*/
|
*/
|
||||||
void SetElement(const ID* id, Val* v);
|
void SetElement(const ID* id, IntrusivePtr<Val> v);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the value associated with *id* and returns it. Returns
|
* Gets the value associated with *id* and returns it. Returns
|
||||||
|
@ -76,8 +74,7 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets all of the indexes from [*startIdx, frame_size) in
|
* Resets all of the indexes from [*startIdx, frame_size) in
|
||||||
* the Frame. Unrefs all of the values in reset indexes.
|
* the Frame.
|
||||||
*
|
|
||||||
* @param the first index to unref.
|
* @param the first index to unref.
|
||||||
*/
|
*/
|
||||||
void Reset(int startIdx);
|
void Reset(int startIdx);
|
||||||
|
@ -232,9 +229,27 @@ private:
|
||||||
using OffsetMap = std::unordered_map<std::string, int>;
|
using OffsetMap = std::unordered_map<std::string, int>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unrefs the value at offset 'n' frame unless it's a weak reference.
|
* Sets the element at index *n* of the underlying array to *v*, but does
|
||||||
|
* not take ownership of a reference count to it. This method is used to
|
||||||
|
* break circular references between lambda functions and closure frames.
|
||||||
|
* @param n the index to set
|
||||||
|
* @param v the value to set it to (caller has not Ref'd and Frame will
|
||||||
|
* not Unref it)
|
||||||
*/
|
*/
|
||||||
void UnrefElement(int n);
|
void SetElementWeak(int n, Val* v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clone an element at an offset into other frame if not equal to a given
|
||||||
|
* function (in that case just assigna weak reference). Used to break
|
||||||
|
* circular references between lambda functions and closure frames.
|
||||||
|
*/
|
||||||
|
void CloneNonFuncElement(int offset, BroFunc* func, Frame* other) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the value at offset 'n' frame (by decrementing reference
|
||||||
|
* count if not a weak reference).
|
||||||
|
*/
|
||||||
|
void ClearElement(int n);
|
||||||
|
|
||||||
/** Have we captured this id? */
|
/** Have we captured this id? */
|
||||||
bool IsOuterID(const ID* in) const;
|
bool IsOuterID(const ID* in) const;
|
||||||
|
|
|
@ -365,11 +365,11 @@ IntrusivePtr<Val> BroFunc::operator()(zeek::Args* args, Frame* parent) const
|
||||||
// Fill in the rest of the frame with the function's arguments.
|
// Fill in the rest of the frame with the function's arguments.
|
||||||
for ( auto j = 0u; j < args->size(); ++j )
|
for ( auto j = 0u; j < args->size(); ++j )
|
||||||
{
|
{
|
||||||
Val* arg = (*args)[j].get();
|
const auto& arg = (*args)[j];
|
||||||
|
|
||||||
if ( f->NthElement(j) != arg )
|
if ( f->NthElement(j) != arg )
|
||||||
// Either not yet set, or somebody reassigned the frame slot.
|
// Either not yet set, or somebody reassigned the frame slot.
|
||||||
f->SetElement(j, arg->Ref());
|
f->SetElement(j, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
f->Reset(args->size());
|
f->Reset(args->size());
|
||||||
|
|
23
src/Stmt.cc
23
src/Stmt.cc
|
@ -811,7 +811,7 @@ IntrusivePtr<Val> SwitchStmt::DoExec(Frame* f, Val* v, stmt_flow_type& flow) con
|
||||||
if ( matching_id )
|
if ( matching_id )
|
||||||
{
|
{
|
||||||
auto cv = cast_value_to_type(v, matching_id->GetType().get());
|
auto cv = cast_value_to_type(v, matching_id->GetType().get());
|
||||||
f->SetElement(matching_id, cv.release());
|
f->SetElement(matching_id, std::move(cv));
|
||||||
}
|
}
|
||||||
|
|
||||||
flow = FLOW_NEXT;
|
flow = FLOW_NEXT;
|
||||||
|
@ -1191,10 +1191,10 @@ IntrusivePtr<Val> ForStmt::DoExec(Frame* f, Val* v, stmt_flow_type& flow) const
|
||||||
delete k;
|
delete k;
|
||||||
|
|
||||||
if ( value_var )
|
if ( value_var )
|
||||||
f->SetElement(value_var.get(), current_tev->GetVal()->Ref());
|
f->SetElement(value_var.get(), current_tev->GetVal());
|
||||||
|
|
||||||
for ( int i = 0; i < ind_lv->Length(); i++ )
|
for ( int i = 0; i < ind_lv->Length(); i++ )
|
||||||
f->SetElement((*loop_vars)[i], ind_lv->Idx(i)->Ref());
|
f->SetElement((*loop_vars)[i], ind_lv->Idx(i));
|
||||||
|
|
||||||
flow = FLOW_NEXT;
|
flow = FLOW_NEXT;
|
||||||
|
|
||||||
|
@ -1230,7 +1230,7 @@ IntrusivePtr<Val> ForStmt::DoExec(Frame* f, Val* v, stmt_flow_type& flow) const
|
||||||
|
|
||||||
// Set the loop variable to the current index, and make
|
// Set the loop variable to the current index, and make
|
||||||
// another pass over the loop body.
|
// another pass over the loop body.
|
||||||
f->SetElement((*loop_vars)[0], val_mgr->Count(i).release());
|
f->SetElement((*loop_vars)[0], val_mgr->Count(i));
|
||||||
flow = FLOW_NEXT;
|
flow = FLOW_NEXT;
|
||||||
ret = body->Exec(f, flow);
|
ret = body->Exec(f, flow);
|
||||||
|
|
||||||
|
@ -1244,8 +1244,8 @@ IntrusivePtr<Val> ForStmt::DoExec(Frame* f, Val* v, stmt_flow_type& flow) const
|
||||||
|
|
||||||
for ( int i = 0; i < sval->Len(); ++i )
|
for ( int i = 0; i < sval->Len(); ++i )
|
||||||
{
|
{
|
||||||
f->SetElement((*loop_vars)[0],
|
auto sv = make_intrusive<StringVal>(1, (const char*) sval->Bytes() + i);
|
||||||
new StringVal(1, (const char*) sval->Bytes() + i));
|
f->SetElement((*loop_vars)[0], std::move(sv));
|
||||||
flow = FLOW_NEXT;
|
flow = FLOW_NEXT;
|
||||||
ret = body->Exec(f, flow);
|
ret = body->Exec(f, flow);
|
||||||
|
|
||||||
|
@ -1653,23 +1653,24 @@ IntrusivePtr<Val> InitStmt::Exec(Frame* f, stmt_flow_type& flow) const
|
||||||
{
|
{
|
||||||
const auto& t = aggr->GetType();
|
const auto& t = aggr->GetType();
|
||||||
|
|
||||||
Val* v = nullptr;
|
IntrusivePtr<Val> v;
|
||||||
|
|
||||||
switch ( t->Tag() ) {
|
switch ( t->Tag() ) {
|
||||||
case TYPE_RECORD:
|
case TYPE_RECORD:
|
||||||
v = new RecordVal(cast_intrusive<RecordType>(t));
|
v = make_intrusive<RecordVal>(cast_intrusive<RecordType>(t));
|
||||||
break;
|
break;
|
||||||
case TYPE_VECTOR:
|
case TYPE_VECTOR:
|
||||||
v = new VectorVal(cast_intrusive<VectorType>(t));
|
v = make_intrusive<VectorVal>(cast_intrusive<VectorType>(t));
|
||||||
break;
|
break;
|
||||||
case TYPE_TABLE:
|
case TYPE_TABLE:
|
||||||
v = new TableVal(cast_intrusive<TableType>(t), {NewRef{}, aggr->Attrs()});
|
v = make_intrusive<TableVal>(cast_intrusive<TableType>(t),
|
||||||
|
IntrusivePtr{NewRef{}, aggr->Attrs()});
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
f->SetElement(aggr, v);
|
f->SetElement(aggr, std::move(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue