switch cached Trigger values to be opaque-and-generic, rather than assuming CallExpr's

This commit is contained in:
Vern Paxson 2022-05-12 13:54:46 -07:00
parent 9ada7ac4e7
commit 5eb37e4c78
9 changed files with 50 additions and 40 deletions

View file

@ -4605,7 +4605,7 @@ ValPtr CallExpr::Eval(Frame* f) const
if ( func_val && v ) if ( func_val && v )
{ {
const zeek::Func* funcv = func_val->AsFunc(); const zeek::Func* funcv = func_val->AsFunc();
const CallExpr* current_call = f ? f->GetCall() : nullptr; auto current_assoc = f ? f->GetTriggerAssoc() : nullptr;
if ( f ) if ( f )
f->SetCall(this); f->SetCall(this);
@ -4614,7 +4614,7 @@ ValPtr CallExpr::Eval(Frame* f) const
ret = funcv->Invoke(&args, f); ret = funcv->Invoke(&args, f);
if ( f ) if ( f )
f->SetCall(current_call); f->SetTriggerAssoc(current_assoc);
} }
return ret; return ret;

View file

@ -201,6 +201,7 @@ Frame* Frame::Clone() const
other->CaptureClosure(closure, outer_ids); other->CaptureClosure(closure, outer_ids);
other->call = call; other->call = call;
other->assoc = assoc;
other->trigger = trigger; other->trigger = trigger;
for ( int i = 0; i < size; i++ ) for ( int i = 0; i < size; i++ )

View file

@ -258,10 +258,16 @@ public:
void ClearTrigger(); void ClearTrigger();
trigger::Trigger* GetTrigger() const { return trigger.get(); } trigger::Trigger* GetTrigger() const { return trigger.get(); }
void SetCall(const CallExpr* arg_call) { call = arg_call; } void SetCall(const CallExpr* arg_call)
void ClearCall() { call = nullptr; } {
call = arg_call;
SetTriggerAssoc((void*)call);
}
const CallExpr* GetCall() const { return call; } const CallExpr* GetCall() const { return call; }
void SetTriggerAssoc(const void* arg_assoc) { assoc = arg_assoc; }
const void* GetTriggerAssoc() const { return assoc; }
void SetCallLoc(const Location* loc) { call_loc = loc; } void SetCallLoc(const Location* loc) { call_loc = loc; }
const detail::Location* GetCallLocation() const; const detail::Location* GetCallLocation() const;
@ -388,6 +394,7 @@ private:
trigger::TriggerPtr trigger; trigger::TriggerPtr trigger;
const CallExpr* call = nullptr; const CallExpr* call = nullptr;
const void* assoc = nullptr;
const Location* call_loc = nullptr; // only needed if call is nil const Location* call_loc = nullptr; // only needed if call is nil
std::unique_ptr<std::vector<ScriptFunc*>> functions_with_closure_frame_reference; std::unique_ptr<std::vector<ScriptFunc*>> functions_with_closure_frame_reference;

View file

@ -365,7 +365,7 @@ ValPtr ScriptFunc::Invoke(zeek::Args* args, Frame* parent) const
if ( parent ) if ( parent )
{ {
f->SetTrigger({NewRef{}, parent->GetTrigger()}); f->SetTrigger({NewRef{}, parent->GetTrigger()});
f->SetCall(parent->GetCall()); f->SetTriggerAssoc(parent->GetTriggerAssoc());
} }
g_frame_stack.push_back(f.get()); // used for backtracing g_frame_stack.push_back(f.get()); // used for backtracing

View file

@ -350,7 +350,7 @@ bool Trigger::Eval()
{ {
Trigger* trigger = frame->GetTrigger(); Trigger* trigger = frame->GetTrigger();
assert(trigger); assert(trigger);
assert(frame->GetCall()); assert(frame->GetTriggerAssoc());
assert(trigger->attached == this); assert(trigger->attached == this);
#ifdef DEBUG #ifdef DEBUG
@ -359,7 +359,7 @@ bool Trigger::Eval()
delete[] pname; delete[] pname;
#endif #endif
auto queued = trigger->Cache(frame->GetCall(), v.get()); auto queued = trigger->Cache(frame->GetTriggerAssoc(), v.get());
trigger->Release(); trigger->Release();
frame->ClearTrigger(); frame->ClearTrigger();
@ -404,7 +404,7 @@ void Trigger::Timeout()
{ {
Trigger* trigger = frame->GetTrigger(); Trigger* trigger = frame->GetTrigger();
assert(trigger); assert(trigger);
assert(frame->GetCall()); assert(frame->GetTriggerAssoc());
assert(trigger->attached == this); assert(trigger->attached == this);
#ifdef DEBUG #ifdef DEBUG
@ -413,7 +413,7 @@ void Trigger::Timeout()
pname); pname);
delete[] pname; delete[] pname;
#endif #endif
auto queued = trigger->Cache(frame->GetCall(), v.get()); auto queued = trigger->Cache(frame->GetTriggerAssoc(), v.get());
trigger->Release(); trigger->Release();
frame->ClearTrigger(); frame->ClearTrigger();
@ -480,12 +480,12 @@ void Trigger::Attach(Trigger* trigger)
Hold(); Hold();
} }
bool Trigger::Cache(const CallExpr* expr, Val* v) bool Trigger::Cache(const void* obj, Val* v)
{ {
if ( disabled || ! v ) if ( disabled || ! v )
return false; return false;
ValCache::iterator i = cache.find(expr); ValCache::iterator i = cache.find(obj);
if ( i != cache.end() ) if ( i != cache.end() )
{ {
@ -494,7 +494,7 @@ bool Trigger::Cache(const CallExpr* expr, Val* v)
} }
else else
cache.insert(ValCache::value_type(expr, v)); cache.insert(ValCache::value_type(obj, v));
Ref(v); Ref(v);
@ -502,11 +502,11 @@ bool Trigger::Cache(const CallExpr* expr, Val* v)
return true; return true;
} }
Val* Trigger::Lookup(const CallExpr* expr) Val* Trigger::Lookup(const void* obj)
{ {
assert(! disabled); assert(! disabled);
ValCache::iterator i = cache.find(expr); ValCache::iterator i = cache.find(obj);
return (i != cache.end()) ? i->second : 0; return (i != cache.end()) ? i->second : 0;
} }

View file

@ -25,7 +25,6 @@ namespace detail
class Frame; class Frame;
class Stmt; class Stmt;
class Expr; class Expr;
class CallExpr;
class ID; class ID;
class WhenInfo; class WhenInfo;
@ -86,9 +85,11 @@ public:
// Cache for return values of delayed function calls. Returns whether // Cache for return values of delayed function calls. Returns whether
// the trigger is queued for later evaluation -- it may not be queued // the trigger is queued for later evaluation -- it may not be queued
// if the Val is null or it's disabled. // if the Val is null or it's disabled. The cache is managed using
bool Cache(const CallExpr* expr, Val* val); // void*'s so that the value can be associated with either a CallExpr
Val* Lookup(const CallExpr*); // (for interpreted execution) or a C++ function (for compiled-to-C++).
bool Cache(const void* obj, Val* val);
Val* Lookup(const void*);
// Disable this trigger completely. Needed because Unref'ing the trigger // Disable this trigger completely. Needed because Unref'ing the trigger
// may not immediately delete it as other references may still exist. // may not immediately delete it as other references may still exist.
@ -153,7 +154,7 @@ private:
std::vector<std::pair<Obj*, notifier::detail::Modifiable*>> objs; std::vector<std::pair<Obj*, notifier::detail::Modifiable*>> objs;
using ValCache = std::map<const CallExpr*, Val*>; using ValCache = std::map<const void*, Val*>;
ValCache cache; ValCache cache;
}; };

View file

@ -5,6 +5,7 @@
#include <broker/store.hh> #include <broker/store.hh>
#include <broker/store_event.hh> #include <broker/store_event.hh>
#include "zeek/Expr.h"
#include "zeek/OpaqueVal.h" #include "zeek/OpaqueVal.h"
#include "zeek/Trigger.h" #include "zeek/Trigger.h"
#include "zeek/broker/data.bif.h" #include "zeek/broker/data.bif.h"
@ -72,9 +73,9 @@ static std::optional<broker::timespan> convert_expiry(double e)
class StoreQueryCallback class StoreQueryCallback
{ {
public: public:
StoreQueryCallback(zeek::detail::trigger::Trigger* arg_trigger, StoreQueryCallback(zeek::detail::trigger::Trigger* arg_trigger, const void* arg_assoc,
const zeek::detail::CallExpr* arg_call, broker::store store) broker::store store)
: trigger(arg_trigger), call(arg_call), store(std::move(store)) : trigger(arg_trigger), assoc(arg_assoc), store(std::move(store))
{ {
Ref(trigger); Ref(trigger);
} }
@ -83,14 +84,14 @@ public:
void Result(const RecordValPtr& result) void Result(const RecordValPtr& result)
{ {
trigger->Cache(call, result.get()); trigger->Cache(assoc, result.get());
trigger->Release(); trigger->Release();
} }
void Abort() void Abort()
{ {
auto result = query_result(); auto result = query_result();
trigger->Cache(call, result.get()); trigger->Cache(assoc, result.get());
trigger->Release(); trigger->Release();
} }
@ -100,7 +101,7 @@ public:
private: private:
zeek::detail::trigger::Trigger* trigger; zeek::detail::trigger::Trigger* trigger;
const zeek::detail::CallExpr* call; const void* assoc;
broker::store store; broker::store store;
}; };

View file

@ -156,7 +156,7 @@ function Broker::__exists%(h: opaque of Broker::Store,
frame->SetDelayed(); frame->SetDelayed();
trigger->Hold(); trigger->Hold();
auto cb = new zeek::Broker::detail::StoreQueryCallback(trigger, frame->GetCall(), auto cb = new zeek::Broker::detail::StoreQueryCallback(trigger, frame->GetTriggerAssoc(),
handle->store); handle->store);
auto req_id = handle->proxy.exists(std::move(*key)); auto req_id = handle->proxy.exists(std::move(*key));
broker_mgr->TrackStoreQuery(handle, req_id, cb); broker_mgr->TrackStoreQuery(handle, req_id, cb);
@ -202,7 +202,7 @@ function Broker::__get%(h: opaque of Broker::Store,
frame->SetDelayed(); frame->SetDelayed();
trigger->Hold(); trigger->Hold();
auto cb = new zeek::Broker::detail::StoreQueryCallback(trigger, frame->GetCall(), auto cb = new zeek::Broker::detail::StoreQueryCallback(trigger, frame->GetTriggerAssoc(),
handle->store); handle->store);
auto req_id = handle->proxy.get(std::move(*key)); auto req_id = handle->proxy.get(std::move(*key));
broker_mgr->TrackStoreQuery(handle, req_id, cb); broker_mgr->TrackStoreQuery(handle, req_id, cb);
@ -255,7 +255,7 @@ function Broker::__put_unique%(h: opaque of Broker::Store,
frame->SetDelayed(); frame->SetDelayed();
trigger->Hold(); trigger->Hold();
auto cb = new zeek::Broker::detail::StoreQueryCallback(trigger, frame->GetCall(), auto cb = new zeek::Broker::detail::StoreQueryCallback(trigger, frame->GetTriggerAssoc(),
handle->store); handle->store);
auto req_id = handle->proxy.put_unique(std::move(*key), std::move(*val), auto req_id = handle->proxy.put_unique(std::move(*key), std::move(*val),
@ -311,7 +311,7 @@ function Broker::__get_index_from_value%(h: opaque of Broker::Store,
frame->SetDelayed(); frame->SetDelayed();
trigger->Hold(); trigger->Hold();
auto cb = new zeek::Broker::detail::StoreQueryCallback(trigger, frame->GetCall(), auto cb = new zeek::Broker::detail::StoreQueryCallback(trigger, frame->GetTriggerAssoc(),
handle->store); handle->store);
auto req_id = handle->proxy.get_index_from_value(std::move(*key), auto req_id = handle->proxy.get_index_from_value(std::move(*key),
std::move(*index)); std::move(*index));
@ -355,7 +355,7 @@ function Broker::__keys%(h: opaque of Broker::Store%): Broker::QueryResult
frame->SetDelayed(); frame->SetDelayed();
trigger->Hold(); trigger->Hold();
auto cb = new zeek::Broker::detail::StoreQueryCallback(trigger, frame->GetCall(), auto cb = new zeek::Broker::detail::StoreQueryCallback(trigger, frame->GetTriggerAssoc(),
handle->store); handle->store);
auto req_id = handle->proxy.keys(); auto req_id = handle->proxy.keys();
broker_mgr->TrackStoreQuery(handle, req_id, cb); broker_mgr->TrackStoreQuery(handle, req_id, cb);

View file

@ -3704,11 +3704,11 @@ function dump_packet%(pkt: pcap_packet, file_name: string%) : bool
class LookupHostCallback : public zeek::detail::DNS_Mgr::LookupCallback { class LookupHostCallback : public zeek::detail::DNS_Mgr::LookupCallback {
public: public:
LookupHostCallback(zeek::detail::trigger::Trigger* arg_trigger, LookupHostCallback(zeek::detail::trigger::Trigger* arg_trigger,
const zeek::detail::CallExpr* arg_call, bool arg_lookup_name) const void* arg_assoc, bool arg_lookup_name)
{ {
Ref(arg_trigger); Ref(arg_trigger);
trigger = arg_trigger; trigger = arg_trigger;
call = arg_call; assoc = arg_assoc;
lookup_name = arg_lookup_name; lookup_name = arg_lookup_name;
} }
@ -3721,7 +3721,7 @@ public:
void Resolved(const std::string& name) override void Resolved(const std::string& name) override
{ {
zeek::Val* result = new zeek::StringVal(name); zeek::Val* result = new zeek::StringVal(name);
trigger->Cache(call, result); trigger->Cache(assoc, result);
Unref(result); Unref(result);
trigger->Release(); trigger->Release();
} }
@ -3729,7 +3729,7 @@ public:
void Resolved(zeek::TableValPtr addrs) override void Resolved(zeek::TableValPtr addrs) override
{ {
// No Ref() for addrs. // No Ref() for addrs.
trigger->Cache(call, addrs.get()); trigger->Cache(assoc, addrs.get());
trigger->Release(); trigger->Release();
} }
@ -3738,7 +3738,7 @@ public:
if ( lookup_name ) if ( lookup_name )
{ {
zeek::Val* result = new zeek::StringVal("<\?\?\?>"); zeek::Val* result = new zeek::StringVal("<\?\?\?>");
trigger->Cache(call, result); trigger->Cache(assoc, result);
Unref(result); Unref(result);
} }
@ -3747,7 +3747,7 @@ public:
auto* lv = new zeek::ListVal(zeek::TYPE_ADDR); auto* lv = new zeek::ListVal(zeek::TYPE_ADDR);
lv->Append(zeek::make_intrusive<zeek::AddrVal>("0.0.0.0")); lv->Append(zeek::make_intrusive<zeek::AddrVal>("0.0.0.0"));
auto result = lv->ToSetVal(); auto result = lv->ToSetVal();
trigger->Cache(call, result.get()); trigger->Cache(assoc, result.get());
Unref(lv); Unref(lv);
} }
@ -3756,7 +3756,7 @@ public:
private: private:
zeek::detail::trigger::Trigger* trigger; zeek::detail::trigger::Trigger* trigger;
const zeek::detail::CallExpr* call; const void* assoc;
bool lookup_name; bool lookup_name;
}; };
%%} %%}
@ -3786,7 +3786,7 @@ function lookup_addr%(host: addr%) : string
trigger->Hold(); trigger->Hold();
zeek::detail::dns_mgr->LookupAddr(host->AsAddr(), zeek::detail::dns_mgr->LookupAddr(host->AsAddr(),
new LookupHostCallback(trigger, frame->GetCall(), true)); new LookupHostCallback(trigger, frame->GetTriggerAssoc(), true));
return nullptr; return nullptr;
%} %}
@ -3815,7 +3815,7 @@ function lookup_hostname_txt%(host: string%) : string
trigger->Hold(); trigger->Hold();
zeek::detail::dns_mgr->Lookup(host->CheckString(), T_TXT, zeek::detail::dns_mgr->Lookup(host->CheckString(), T_TXT,
new LookupHostCallback(trigger, frame->GetCall(), true)); new LookupHostCallback(trigger, frame->GetTriggerAssoc(), true));
return nullptr; return nullptr;
%} %}
@ -3844,7 +3844,7 @@ function lookup_hostname%(host: string%) : addr_set
trigger->Hold(); trigger->Hold();
zeek::detail::dns_mgr->LookupHost(host->CheckString(), zeek::detail::dns_mgr->LookupHost(host->CheckString(),
new LookupHostCallback(trigger, frame->GetCall(), false)); new LookupHostCallback(trigger, frame->GetTriggerAssoc(), false));
return nullptr; return nullptr;
%} %}