mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
Switch FuncType capture-list storage to optional<vector<Capture>>
May help clarify overall mem-mgmt/ownership semantics.
This commit is contained in:
parent
ab15a98b28
commit
b08112b2e7
8 changed files with 44 additions and 41 deletions
10
src/Expr.cc
10
src/Expr.cc
|
@ -4421,7 +4421,7 @@ LambdaExpr::LambdaExpr(std::unique_ptr<function_ingredients> arg_ing,
|
||||||
void LambdaExpr::CheckCaptures()
|
void LambdaExpr::CheckCaptures()
|
||||||
{
|
{
|
||||||
auto ft = type->AsFuncType();
|
auto ft = type->AsFuncType();
|
||||||
auto captures = ft->GetCaptures();
|
const auto& captures = ft->GetCaptures();
|
||||||
|
|
||||||
capture_by_ref = false;
|
capture_by_ref = false;
|
||||||
|
|
||||||
|
@ -4441,9 +4441,9 @@ void LambdaExpr::CheckCaptures()
|
||||||
std::set<const ID*> outer_is_matched;
|
std::set<const ID*> outer_is_matched;
|
||||||
std::set<const ID*> capture_is_matched;
|
std::set<const ID*> capture_is_matched;
|
||||||
|
|
||||||
for ( auto c : *captures )
|
for ( const auto& c : *captures )
|
||||||
{
|
{
|
||||||
auto cid = c->id.get();
|
auto cid = c.id.get();
|
||||||
|
|
||||||
if ( ! cid )
|
if ( ! cid )
|
||||||
// This happens for undefined/inappropriate
|
// This happens for undefined/inappropriate
|
||||||
|
@ -4470,9 +4470,9 @@ void LambdaExpr::CheckCaptures()
|
||||||
if ( outer_is_matched.count(id) == 0 )
|
if ( outer_is_matched.count(id) == 0 )
|
||||||
ExprError(util::fmt("%s is used inside lambda but not captured", id->Name()));
|
ExprError(util::fmt("%s is used inside lambda but not captured", id->Name()));
|
||||||
|
|
||||||
for ( auto c : *captures )
|
for ( const auto& c : *captures )
|
||||||
{
|
{
|
||||||
auto cid = c->id.get();
|
auto cid = c.id.get();
|
||||||
if ( cid && capture_is_matched.count(cid) == 0 )
|
if ( cid && capture_is_matched.count(cid) == 0 )
|
||||||
ExprError(util::fmt("%s is captured but not used inside lambda", cid->Name()));
|
ExprError(util::fmt("%s is captured but not used inside lambda", cid->Name()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -419,7 +419,7 @@ broker::expected<broker::data> Frame::SerializeCopyFrame()
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<bool, FramePtr> Frame::Unserialize(const broker::vector& data,
|
std::pair<bool, FramePtr> Frame::Unserialize(const broker::vector& data,
|
||||||
const std::vector<FuncType::Capture*>* captures)
|
const std::optional<FuncType::CaptureList>& captures)
|
||||||
{
|
{
|
||||||
if ( data.size() == 0 )
|
if ( data.size() == 0 )
|
||||||
return std::make_pair(true, nullptr);
|
return std::make_pair(true, nullptr);
|
||||||
|
@ -505,7 +505,7 @@ std::pair<bool, FramePtr> Frame::Unserialize(const broker::vector& data,
|
||||||
|
|
||||||
std::advance(where, 1);
|
std::advance(where, 1);
|
||||||
|
|
||||||
auto closure_pair = Frame::Unserialize(*has_vec, nullptr);
|
auto closure_pair = Frame::Unserialize(*has_vec, {});
|
||||||
if ( ! closure_pair.first )
|
if ( ! closure_pair.first )
|
||||||
{
|
{
|
||||||
for ( auto& i : outer_ids )
|
for ( auto& i : outer_ids )
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include <broker/data.hh>
|
#include <broker/data.hh>
|
||||||
#include <broker/expected.hh>
|
#include <broker/expected.hh>
|
||||||
|
@ -242,7 +243,7 @@ public:
|
||||||
* reference semantics.
|
* reference semantics.
|
||||||
*/
|
*/
|
||||||
static std::pair<bool, FramePtr> Unserialize(const broker::vector& data,
|
static std::pair<bool, FramePtr> Unserialize(const broker::vector& data,
|
||||||
const std::vector<FuncType::Capture*>* captures);
|
const std::optional<FuncType::CaptureList>& captures);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the IDs that the frame knows offsets for. These offsets will
|
* Sets the IDs that the frame knows offsets for. These offsets will
|
||||||
|
|
20
src/Func.cc
20
src/Func.cc
|
@ -477,7 +477,7 @@ ValPtr ScriptFunc::Invoke(zeek::Args* args, Frame* parent) const
|
||||||
|
|
||||||
void ScriptFunc::CreateCaptures(Frame* f)
|
void ScriptFunc::CreateCaptures(Frame* f)
|
||||||
{
|
{
|
||||||
auto captures = type->GetCaptures();
|
const auto& captures = type->GetCaptures();
|
||||||
|
|
||||||
if ( ! captures )
|
if ( ! captures )
|
||||||
return;
|
return;
|
||||||
|
@ -490,27 +490,26 @@ void ScriptFunc::CreateCaptures(Frame* f)
|
||||||
captures_offset_mapping = new OffsetMap;
|
captures_offset_mapping = new OffsetMap;
|
||||||
|
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
for ( auto c : *captures )
|
for ( const auto& c : *captures )
|
||||||
{
|
{
|
||||||
auto cid = c->id;
|
auto v = f->GetElementByID(c.id);
|
||||||
auto v = f->GetElementByID(cid);
|
|
||||||
|
|
||||||
if ( v )
|
if ( v )
|
||||||
{
|
{
|
||||||
if ( c->deep_copy || ! v->Modifiable() )
|
if ( c.deep_copy || ! v->Modifiable() )
|
||||||
v = v->Clone();
|
v = v->Clone();
|
||||||
|
|
||||||
captures_frame->SetElement(offset, std::move(v));
|
captures_frame->SetElement(offset, std::move(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
(*captures_offset_mapping)[cid->Name()] = offset;
|
(*captures_offset_mapping)[c.id->Name()] = offset;
|
||||||
++offset;
|
++offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptFunc::SetCaptures(Frame* f)
|
void ScriptFunc::SetCaptures(Frame* f)
|
||||||
{
|
{
|
||||||
auto captures = type->GetCaptures();
|
const auto& captures = type->GetCaptures();
|
||||||
ASSERT(captures);
|
ASSERT(captures);
|
||||||
|
|
||||||
delete captures_frame;
|
delete captures_frame;
|
||||||
|
@ -519,10 +518,9 @@ void ScriptFunc::SetCaptures(Frame* f)
|
||||||
captures_offset_mapping = new OffsetMap;
|
captures_offset_mapping = new OffsetMap;
|
||||||
|
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
for ( auto c : *captures )
|
for ( const auto& c : *captures )
|
||||||
{
|
{
|
||||||
auto cid = c->id;
|
(*captures_offset_mapping)[c.id->Name()] = offset;
|
||||||
(*captures_offset_mapping)[cid->Name()] = offset;
|
|
||||||
++offset;
|
++offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -600,7 +598,7 @@ void ScriptFunc::SetClosureFrame(Frame* f)
|
||||||
|
|
||||||
bool ScriptFunc::UpdateClosure(const broker::vector& data)
|
bool ScriptFunc::UpdateClosure(const broker::vector& data)
|
||||||
{
|
{
|
||||||
auto result = Frame::Unserialize(data, nullptr);
|
auto result = Frame::Unserialize(data, {});
|
||||||
|
|
||||||
if ( ! result.first )
|
if ( ! result.first )
|
||||||
return false;
|
return false;
|
||||||
|
|
16
src/Type.cc
16
src/Type.cc
|
@ -622,8 +622,6 @@ FuncType::FuncType(RecordTypePtr arg_args,
|
||||||
}
|
}
|
||||||
|
|
||||||
prototypes.emplace_back(Prototype{false, "", args, std::move(offsets)});
|
prototypes.emplace_back(Prototype{false, "", args, std::move(offsets)});
|
||||||
|
|
||||||
captures = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TypePtr FuncType::ShallowClone()
|
TypePtr FuncType::ShallowClone()
|
||||||
|
@ -657,16 +655,6 @@ string FuncType::FlavorString() const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FuncType::~FuncType()
|
|
||||||
{
|
|
||||||
if ( captures )
|
|
||||||
{
|
|
||||||
for ( auto c : *captures )
|
|
||||||
delete c;
|
|
||||||
delete captures;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int FuncType::MatchesIndex(detail::ListExpr* const index) const
|
int FuncType::MatchesIndex(detail::ListExpr* const index) const
|
||||||
{
|
{
|
||||||
return check_and_promote_args(index, args.get()) ?
|
return check_and_promote_args(index, args.get()) ?
|
||||||
|
@ -709,9 +697,9 @@ bool FuncType::CheckArgs(const std::vector<TypePtr>& args,
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FuncType::SetCaptures(std::vector<Capture*>* _captures)
|
void FuncType::SetCaptures(std::optional<CaptureList> _captures)
|
||||||
{
|
{
|
||||||
captures = _captures;
|
captures = std::move(_captures);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FuncType::Describe(ODesc* d) const
|
void FuncType::Describe(ODesc* d) const
|
||||||
|
|
10
src/Type.h
10
src/Type.h
|
@ -492,8 +492,6 @@ public:
|
||||||
|
|
||||||
TypePtr ShallowClone() override;
|
TypePtr ShallowClone() override;
|
||||||
|
|
||||||
~FuncType() override;
|
|
||||||
|
|
||||||
[[deprecated("Remove in v4.1. Use Params().")]]
|
[[deprecated("Remove in v4.1. Use Params().")]]
|
||||||
RecordType* Args() const { return args.get(); }
|
RecordType* Args() const { return args.get(); }
|
||||||
|
|
||||||
|
@ -549,19 +547,21 @@ public:
|
||||||
bool deep_copy;
|
bool deep_copy;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using CaptureList = std::vector<Capture>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets this function's set of captures. Only valid for lambdas.
|
* Sets this function's set of captures. Only valid for lambdas.
|
||||||
*
|
*
|
||||||
* @param captures if non-nil, a list of the lambda's captures
|
* @param captures if non-nil, a list of the lambda's captures
|
||||||
*/
|
*/
|
||||||
void SetCaptures(std::vector<Capture*>* captures);
|
void SetCaptures(std::optional<CaptureList> captures);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the captures declared for this function, or nil if none.
|
* Returns the captures declared for this function, or nil if none.
|
||||||
*
|
*
|
||||||
* @return a vector giving the captures
|
* @return a vector giving the captures
|
||||||
*/
|
*/
|
||||||
const std::vector<Capture*>* GetCaptures() const
|
const std::optional<CaptureList>& GetCaptures() const
|
||||||
{ return captures; }
|
{ return captures; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -574,7 +574,7 @@ protected:
|
||||||
FunctionFlavor flavor;
|
FunctionFlavor flavor;
|
||||||
std::vector<Prototype> prototypes;
|
std::vector<Prototype> prototypes;
|
||||||
|
|
||||||
std::vector<Capture*>* captures; // if nil then no captures specified
|
std::optional<CaptureList> captures; // if nil then no captures specified
|
||||||
};
|
};
|
||||||
|
|
||||||
class TypeType final : public Type {
|
class TypeType final : public Type {
|
||||||
|
|
|
@ -405,8 +405,7 @@ struct val_converter {
|
||||||
if ( ! b )
|
if ( ! b )
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
auto copy_semantics =
|
auto copy_semantics = b->GetType()->GetCaptures().has_value();
|
||||||
b->GetType()->GetCaptures() != nullptr;
|
|
||||||
|
|
||||||
if ( copy_semantics )
|
if ( copy_semantics )
|
||||||
{
|
{
|
||||||
|
|
19
src/parse.y
19
src/parse.y
|
@ -1315,7 +1315,24 @@ begin_lambda:
|
||||||
{
|
{
|
||||||
auto id = zeek::detail::current_scope()->GenerateTemporary("anonymous-function");
|
auto id = zeek::detail::current_scope()->GenerateTemporary("anonymous-function");
|
||||||
zeek::detail::begin_func(id, zeek::detail::current_module.c_str(), zeek::FUNC_FLAVOR_FUNCTION, false, {zeek::AdoptRef{}, $2});
|
zeek::detail::begin_func(id, zeek::detail::current_module.c_str(), zeek::FUNC_FLAVOR_FUNCTION, false, {zeek::AdoptRef{}, $2});
|
||||||
$2->SetCaptures($1);
|
|
||||||
|
std::optional<zeek::FuncType::CaptureList> captures;
|
||||||
|
|
||||||
|
if ( $1 )
|
||||||
|
{
|
||||||
|
captures = zeek::FuncType::CaptureList{};
|
||||||
|
captures->reserve($1->size());
|
||||||
|
|
||||||
|
for ( auto c : *$1 )
|
||||||
|
{
|
||||||
|
captures->emplace_back(*c);
|
||||||
|
delete c;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete $1;
|
||||||
|
}
|
||||||
|
|
||||||
|
$2->SetCaptures(std::move(captures));
|
||||||
$$ = id.release();
|
$$ = id.release();
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue