mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
changes to Frames to support access to captured-by-copy-semantics variables
This commit is contained in:
parent
627fb8616e
commit
8f4b616d65
2 changed files with 51 additions and 9 deletions
35
src/Frame.cc
35
src/Frame.cc
|
@ -30,6 +30,15 @@ Frame::Frame(int arg_size, const ScriptFunc* func, const zeek::Args* fn_args)
|
||||||
delayed = false;
|
delayed = false;
|
||||||
|
|
||||||
closure = nullptr;
|
closure = nullptr;
|
||||||
|
|
||||||
|
// We could Ref()/Unref() the captures frame, but there's really
|
||||||
|
// no need because by definition this current frame exists to
|
||||||
|
// enable execution of the function, and its captures frame won't
|
||||||
|
// go away until the function itself goes away, which can only be
|
||||||
|
// after this frame does.
|
||||||
|
captures = function ? function->GetCapturesFrame() : nullptr;
|
||||||
|
captures_offset_map =
|
||||||
|
function ? function->GetCapturesOffsetMap() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Frame::~Frame()
|
Frame::~Frame()
|
||||||
|
@ -80,13 +89,20 @@ void Frame::SetElementWeak(int n, Val* v)
|
||||||
|
|
||||||
void Frame::SetElement(const ID* id, ValPtr v)
|
void Frame::SetElement(const ID* id, ValPtr v)
|
||||||
{
|
{
|
||||||
if ( closure )
|
if ( closure && IsOuterID(id) )
|
||||||
{
|
|
||||||
if ( IsOuterID(id) )
|
|
||||||
{
|
{
|
||||||
closure->SetElement(id, std::move(v));
|
closure->SetElement(id, std::move(v));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( captures )
|
||||||
|
{
|
||||||
|
auto cap_off = captures_offset_map->find(id->Name());
|
||||||
|
if ( cap_off != captures_offset_map->end() )
|
||||||
|
{
|
||||||
|
captures->SetElement(cap_off->second, std::move(v));
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// do we have an offset for it?
|
// do we have an offset for it?
|
||||||
|
@ -109,10 +125,14 @@ void Frame::SetElement(const ID* id, ValPtr v)
|
||||||
|
|
||||||
const ValPtr& Frame::GetElementByID(const ID* id) const
|
const ValPtr& Frame::GetElementByID(const ID* id) const
|
||||||
{
|
{
|
||||||
if ( closure )
|
if ( closure && IsOuterID(id) )
|
||||||
{
|
|
||||||
if ( IsOuterID(id) )
|
|
||||||
return closure->GetElementByID(id);
|
return closure->GetElementByID(id);
|
||||||
|
|
||||||
|
if ( captures )
|
||||||
|
{
|
||||||
|
auto cap_off = captures_offset_map->find(id->Name());
|
||||||
|
if ( cap_off != captures_offset_map->end() )
|
||||||
|
return captures->GetElement(cap_off->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
// do we have an offset for it?
|
// do we have an offset for it?
|
||||||
|
@ -185,6 +205,9 @@ Frame* Frame::Clone() const
|
||||||
if ( frame[i].val )
|
if ( frame[i].val )
|
||||||
other->frame[i].val = frame[i].val->Clone();
|
other->frame[i].val = frame[i].val->Clone();
|
||||||
|
|
||||||
|
// Note, there's no need to clone "captures" or "captures_offset_map"
|
||||||
|
// since those get created fresh when constructing "other".
|
||||||
|
|
||||||
return other;
|
return other;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
25
src/Frame.h
25
src/Frame.h
|
@ -286,9 +286,12 @@ private:
|
||||||
*/
|
*/
|
||||||
void ClearElement(int n);
|
void ClearElement(int n);
|
||||||
|
|
||||||
/** Have we captured this id? */
|
/** Have we captured this id? Version for deprecated semantics. */
|
||||||
bool IsOuterID(const ID* in) const;
|
bool IsOuterID(const ID* in) const;
|
||||||
|
|
||||||
|
/** Have we captured this id? Version for current semantics. */
|
||||||
|
bool IsCaptureID(const ID* in) const;
|
||||||
|
|
||||||
/** Serializes an offset_map */
|
/** Serializes an offset_map */
|
||||||
static broker::expected<broker::data>
|
static broker::expected<broker::data>
|
||||||
SerializeOffsetMap(const OffsetMap& in);
|
SerializeOffsetMap(const OffsetMap& in);
|
||||||
|
@ -316,10 +319,12 @@ private:
|
||||||
/** Associates ID's offsets with values. */
|
/** Associates ID's offsets with values. */
|
||||||
std::unique_ptr<Element[]> frame;
|
std::unique_ptr<Element[]> frame;
|
||||||
|
|
||||||
/** The enclosing frame of this frame. */
|
/** The enclosing frame of this frame. Used for reference semantics. */
|
||||||
Frame* closure;
|
Frame* closure;
|
||||||
|
|
||||||
/** ID's used in this frame from the enclosing frame. */
|
/** ID's used in this frame from the enclosing frame, when using
|
||||||
|
* reference semantics (closure != nullptr).
|
||||||
|
*/
|
||||||
IDPList outer_ids;
|
IDPList outer_ids;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -328,8 +333,22 @@ private:
|
||||||
*/
|
*/
|
||||||
std::unique_ptr<OffsetMap> offset_map;
|
std::unique_ptr<OffsetMap> offset_map;
|
||||||
|
|
||||||
|
/** Frame used for captures (if any) with copy semantics. */
|
||||||
|
Frame* captures;
|
||||||
|
|
||||||
|
/** Maps IDs to offsets into the "captures" frame. If the ID
|
||||||
|
* isn't present, then it's not a capture.
|
||||||
|
*
|
||||||
|
* We keep this separate from offset_map to help ensure we don't
|
||||||
|
* confuse code from the deprecated semantics with the current
|
||||||
|
* semantics.
|
||||||
|
*/
|
||||||
|
const OffsetMap* captures_offset_map;
|
||||||
|
|
||||||
/** The function this frame is associated with. */
|
/** The function this frame is associated with. */
|
||||||
const ScriptFunc* function;
|
const ScriptFunc* function;
|
||||||
|
|
||||||
|
// The following is only needed for the debugger.
|
||||||
/** The arguments to the function that this Frame is associated with. */
|
/** The arguments to the function that this Frame is associated with. */
|
||||||
const zeek::Args* func_args;
|
const zeek::Args* func_args;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue