diff --git a/src/Expr.cc b/src/Expr.cc index d5da1628de..d600ed0718 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -4421,7 +4421,7 @@ LambdaExpr::LambdaExpr(std::unique_ptr arg_ing, void LambdaExpr::CheckCaptures() { auto ft = type->AsFuncType(); - auto captures = ft->GetCaptures(); + const auto& captures = ft->GetCaptures(); capture_by_ref = false; @@ -4441,9 +4441,9 @@ void LambdaExpr::CheckCaptures() std::set outer_is_matched; std::set capture_is_matched; - for ( auto c : *captures ) + for ( const auto& c : *captures ) { - auto cid = c->id.get(); + auto cid = c.id.get(); if ( ! cid ) // This happens for undefined/inappropriate @@ -4470,9 +4470,9 @@ void LambdaExpr::CheckCaptures() if ( outer_is_matched.count(id) == 0 ) 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 ) ExprError(util::fmt("%s is captured but not used inside lambda", cid->Name())); } diff --git a/src/Frame.cc b/src/Frame.cc index 05b70c32a4..a444ad3906 100644 --- a/src/Frame.cc +++ b/src/Frame.cc @@ -419,7 +419,7 @@ broker::expected Frame::SerializeCopyFrame() } std::pair Frame::Unserialize(const broker::vector& data, - const std::vector* captures) + const std::optional& captures) { if ( data.size() == 0 ) return std::make_pair(true, nullptr); @@ -505,7 +505,7 @@ std::pair Frame::Unserialize(const broker::vector& data, std::advance(where, 1); - auto closure_pair = Frame::Unserialize(*has_vec, nullptr); + auto closure_pair = Frame::Unserialize(*has_vec, {}); if ( ! closure_pair.first ) { for ( auto& i : outer_ids ) diff --git a/src/Frame.h b/src/Frame.h index 3365c85a37..7413beacec 100644 --- a/src/Frame.h +++ b/src/Frame.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -242,7 +243,7 @@ public: * reference semantics. */ static std::pair Unserialize(const broker::vector& data, - const std::vector* captures); + const std::optional& captures); /** * Sets the IDs that the frame knows offsets for. These offsets will diff --git a/src/Func.cc b/src/Func.cc index 8ab24d5eef..0206fc7485 100644 --- a/src/Func.cc +++ b/src/Func.cc @@ -477,7 +477,7 @@ ValPtr ScriptFunc::Invoke(zeek::Args* args, Frame* parent) const void ScriptFunc::CreateCaptures(Frame* f) { - auto captures = type->GetCaptures(); + const auto& captures = type->GetCaptures(); if ( ! captures ) return; @@ -490,27 +490,26 @@ void ScriptFunc::CreateCaptures(Frame* f) captures_offset_mapping = new OffsetMap; int offset = 0; - for ( auto c : *captures ) + for ( const auto& c : *captures ) { - auto cid = c->id; - auto v = f->GetElementByID(cid); + auto v = f->GetElementByID(c.id); if ( v ) { - if ( c->deep_copy || ! v->Modifiable() ) + if ( c.deep_copy || ! v->Modifiable() ) v = v->Clone(); captures_frame->SetElement(offset, std::move(v)); } - (*captures_offset_mapping)[cid->Name()] = offset; + (*captures_offset_mapping)[c.id->Name()] = offset; ++offset; } } void ScriptFunc::SetCaptures(Frame* f) { - auto captures = type->GetCaptures(); + const auto& captures = type->GetCaptures(); ASSERT(captures); delete captures_frame; @@ -519,10 +518,9 @@ void ScriptFunc::SetCaptures(Frame* f) captures_offset_mapping = new OffsetMap; int offset = 0; - for ( auto c : *captures ) + for ( const auto& c : *captures ) { - auto cid = c->id; - (*captures_offset_mapping)[cid->Name()] = offset; + (*captures_offset_mapping)[c.id->Name()] = offset; ++offset; } } @@ -600,7 +598,7 @@ void ScriptFunc::SetClosureFrame(Frame* f) bool ScriptFunc::UpdateClosure(const broker::vector& data) { - auto result = Frame::Unserialize(data, nullptr); + auto result = Frame::Unserialize(data, {}); if ( ! result.first ) return false; diff --git a/src/Type.cc b/src/Type.cc index 8c48e0da97..7387368254 100644 --- a/src/Type.cc +++ b/src/Type.cc @@ -622,8 +622,6 @@ FuncType::FuncType(RecordTypePtr arg_args, } prototypes.emplace_back(Prototype{false, "", args, std::move(offsets)}); - - captures = nullptr; } 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 { return check_and_promote_args(index, args.get()) ? @@ -709,9 +697,9 @@ bool FuncType::CheckArgs(const std::vector& args, return success; } -void FuncType::SetCaptures(std::vector* _captures) +void FuncType::SetCaptures(std::optional _captures) { - captures = _captures; + captures = std::move(_captures); } void FuncType::Describe(ODesc* d) const diff --git a/src/Type.h b/src/Type.h index 31b50daa0f..cae2429719 100644 --- a/src/Type.h +++ b/src/Type.h @@ -492,8 +492,6 @@ public: TypePtr ShallowClone() override; - ~FuncType() override; - [[deprecated("Remove in v4.1. Use Params().")]] RecordType* Args() const { return args.get(); } @@ -549,19 +547,21 @@ public: bool deep_copy; }; + using CaptureList = std::vector; + /** * Sets this function's set of captures. Only valid for lambdas. * * @param captures if non-nil, a list of the lambda's captures */ - void SetCaptures(std::vector* captures); + void SetCaptures(std::optional captures); /** * Returns the captures declared for this function, or nil if none. * * @return a vector giving the captures */ - const std::vector* GetCaptures() const + const std::optional& GetCaptures() const { return captures; } protected: @@ -574,7 +574,7 @@ protected: FunctionFlavor flavor; std::vector prototypes; - std::vector* captures; // if nil then no captures specified + std::optional captures; // if nil then no captures specified }; class TypeType final : public Type { diff --git a/src/broker/Data.cc b/src/broker/Data.cc index 15c3ec5607..e5f459b952 100644 --- a/src/broker/Data.cc +++ b/src/broker/Data.cc @@ -405,8 +405,7 @@ struct val_converter { if ( ! b ) return nullptr; - auto copy_semantics = - b->GetType()->GetCaptures() != nullptr; + auto copy_semantics = b->GetType()->GetCaptures().has_value(); if ( copy_semantics ) { diff --git a/src/parse.y b/src/parse.y index b7f684007a..8b1bcbfbfe 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1315,7 +1315,24 @@ begin_lambda: { 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}); - $2->SetCaptures($1); + + std::optional 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(); } ;