mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
state-holding fix: track unique identifiers for Func's in CompHash's, not Func's themselves
This commit is contained in:
parent
0235541a95
commit
323b919eef
4 changed files with 45 additions and 31 deletions
|
@ -260,13 +260,16 @@ bool CompositeHash::RecoverOneVal(const HashKey& hk, Type* t, ValPtr* pval, bool
|
||||||
{
|
{
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
hk.Read("func", id);
|
hk.Read("func", id);
|
||||||
const auto& f = Func::GetFuncPtrByID(id);
|
|
||||||
|
|
||||||
if ( ! f )
|
ASSERT(func_id_to_func != nullptr);
|
||||||
|
|
||||||
|
if ( id >= func_id_to_func->size() )
|
||||||
reporter->InternalError("failed to look up unique function id %" PRIu32
|
reporter->InternalError("failed to look up unique function id %" PRIu32
|
||||||
" in CompositeHash::RecoverOneVal()",
|
" in CompositeHash::RecoverOneVal()",
|
||||||
id);
|
id);
|
||||||
|
|
||||||
|
const auto& f = func_id_to_func->at(id);
|
||||||
|
|
||||||
*pval = make_intrusive<FuncVal>(f);
|
*pval = make_intrusive<FuncVal>(f);
|
||||||
const auto& pvt = (*pval)->GetType();
|
const auto& pvt = (*pval)->GetType();
|
||||||
|
|
||||||
|
@ -547,7 +550,31 @@ bool CompositeHash::SingleValHash(HashKey& hk, const Val* v, Type* bt, bool type
|
||||||
switch ( v->GetType()->Tag() )
|
switch ( v->GetType()->Tag() )
|
||||||
{
|
{
|
||||||
case TYPE_FUNC:
|
case TYPE_FUNC:
|
||||||
hk.Write("func", v->AsFunc()->GetUniqueFuncID());
|
{
|
||||||
|
auto f = v->AsFunc();
|
||||||
|
|
||||||
|
if ( ! func_to_func_id )
|
||||||
|
const_cast<CompositeHash*>(this)->BuildFuncMappings();
|
||||||
|
|
||||||
|
auto id_mapping = func_to_func_id->find(f);
|
||||||
|
uint32_t id;
|
||||||
|
|
||||||
|
if ( id_mapping == func_to_func_id->end() )
|
||||||
|
{
|
||||||
|
// We need the pointer to stick around
|
||||||
|
// for our lifetime, so we have to get
|
||||||
|
// a non-const version we can ref.
|
||||||
|
FuncPtr fptr = {NewRef{}, const_cast<Func*>(f)};
|
||||||
|
|
||||||
|
id = func_id_to_func->size();
|
||||||
|
func_id_to_func->push_back(std::move(fptr));
|
||||||
|
func_to_func_id->insert_or_assign(f, id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
id = id_mapping->second;
|
||||||
|
|
||||||
|
hk.Write("func", id);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_PATTERN:
|
case TYPE_PATTERN:
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "zeek/IntrusivePtr.h"
|
#include "zeek/Func.h"
|
||||||
#include "zeek/Type.h"
|
#include "zeek/Type.h"
|
||||||
|
|
||||||
namespace zeek
|
namespace zeek
|
||||||
|
@ -61,6 +61,18 @@ protected:
|
||||||
|
|
||||||
bool EnsureTypeReserve(HashKey& hk, const Val* v, Type* bt, bool type_check) const;
|
bool EnsureTypeReserve(HashKey& hk, const Val* v, Type* bt, bool type_check) const;
|
||||||
|
|
||||||
|
// The following are for allowing hashing of function values.
|
||||||
|
// These can occur, for example, in sets of predicates that get
|
||||||
|
// iterated over. We use pointers in order to keep storage
|
||||||
|
// lower for the common case of these not being needed.
|
||||||
|
std::unique_ptr<std::unordered_map<const Func*, uint32_t>> func_to_func_id;
|
||||||
|
std::unique_ptr<std::vector<FuncPtr>> func_id_to_func;
|
||||||
|
void BuildFuncMappings()
|
||||||
|
{
|
||||||
|
func_to_func_id = std::make_unique<std::unordered_map<const Func*, uint32_t>>();
|
||||||
|
func_id_to_func = std::make_unique<std::vector<FuncPtr>>();
|
||||||
|
}
|
||||||
|
|
||||||
TypeListPtr type;
|
TypeListPtr type;
|
||||||
bool is_singleton = false; // if just one type in index
|
bool is_singleton = false; // if just one type in index
|
||||||
};
|
};
|
||||||
|
|
15
src/Func.cc
15
src/Func.cc
|
@ -133,20 +133,6 @@ std::string render_call_stack()
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
Func::Func()
|
|
||||||
{
|
|
||||||
unique_id = unique_ids.size();
|
|
||||||
unique_ids.push_back({NewRef{}, this});
|
|
||||||
}
|
|
||||||
|
|
||||||
Func::Func(Kind arg_kind) : kind(arg_kind)
|
|
||||||
{
|
|
||||||
unique_id = unique_ids.size();
|
|
||||||
unique_ids.push_back({NewRef{}, this});
|
|
||||||
}
|
|
||||||
|
|
||||||
Func::~Func() = default;
|
|
||||||
|
|
||||||
void Func::AddBody(detail::StmtPtr /* new_body */,
|
void Func::AddBody(detail::StmtPtr /* new_body */,
|
||||||
const std::vector<detail::IDPtr>& /* new_inits */, size_t /* new_frame_size */,
|
const std::vector<detail::IDPtr>& /* new_inits */, size_t /* new_frame_size */,
|
||||||
int /* priority */)
|
int /* priority */)
|
||||||
|
@ -238,7 +224,6 @@ void Func::CopyStateInto(Func* other) const
|
||||||
other->type = type;
|
other->type = type;
|
||||||
|
|
||||||
other->name = name;
|
other->name = name;
|
||||||
other->unique_id = unique_id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Func::CheckPluginResult(bool handled, const ValPtr& hook_result, FunctionFlavor flavor) const
|
void Func::CheckPluginResult(bool handled, const ValPtr& hook_result, FunctionFlavor flavor) const
|
||||||
|
|
14
src/Func.h
14
src/Func.h
|
@ -61,9 +61,7 @@ public:
|
||||||
BUILTIN_FUNC
|
BUILTIN_FUNC
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit Func(Kind arg_kind);
|
explicit Func(Kind arg_kind) : kind(arg_kind) { }
|
||||||
|
|
||||||
~Func() override;
|
|
||||||
|
|
||||||
virtual bool IsPure() const = 0;
|
virtual bool IsPure() const = 0;
|
||||||
FunctionFlavor Flavor() const { return GetType()->Flavor(); }
|
FunctionFlavor Flavor() const { return GetType()->Flavor(); }
|
||||||
|
@ -122,14 +120,8 @@ public:
|
||||||
|
|
||||||
virtual detail::TraversalCode Traverse(detail::TraversalCallback* cb) const;
|
virtual detail::TraversalCode Traverse(detail::TraversalCallback* cb) const;
|
||||||
|
|
||||||
uint32_t GetUniqueFuncID() const { return unique_id; }
|
|
||||||
static const FuncPtr& GetFuncPtrByID(uint32_t id)
|
|
||||||
{
|
|
||||||
return id >= unique_ids.size() ? Func::nil : unique_ids[id];
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Func();
|
Func() = default;
|
||||||
|
|
||||||
// Copies this function's state into other.
|
// Copies this function's state into other.
|
||||||
void CopyStateInto(Func* other) const;
|
void CopyStateInto(Func* other) const;
|
||||||
|
@ -140,10 +132,8 @@ protected:
|
||||||
std::vector<Body> bodies;
|
std::vector<Body> bodies;
|
||||||
detail::ScopePtr scope;
|
detail::ScopePtr scope;
|
||||||
Kind kind = SCRIPT_FUNC;
|
Kind kind = SCRIPT_FUNC;
|
||||||
uint32_t unique_id = 0;
|
|
||||||
FuncTypePtr type;
|
FuncTypePtr type;
|
||||||
std::string name;
|
std::string name;
|
||||||
static inline std::vector<FuncPtr> unique_ids;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue