mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
Use vector<IntrusivePtr<Val>> for Func::Call and Event queuing args
This change may break BIFs that use @ARGS@, @ARG@, or @ARGC@ since their types have changed.
This commit is contained in:
parent
94656c2308
commit
4e1ac4e124
29 changed files with 367 additions and 305 deletions
6
NEWS
6
NEWS
|
@ -27,10 +27,14 @@ Changed Functionality
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
- Several C++ functions have been changed to pass smart pointers
|
- Several C++ functions have been changed to pass smart pointers
|
||||||
(`class IntrusivePtr<>`) instead of raw pointers. This makes the
|
(``class IntrusivePtr<>``) instead of raw pointers. This makes the
|
||||||
code more robust. External plugins may need to be updated to this
|
code more robust. External plugins may need to be updated to this
|
||||||
API change.
|
API change.
|
||||||
|
|
||||||
|
- BIFs that use @ARG@, @ARGS@, or @ARGC@ may break since their type has
|
||||||
|
changed: BIF arguments are now passed as a ``std::vector<IntrusivePtr<Val>>``
|
||||||
|
rather than a ``val_list`` (i.e. ``List<Val*>``).
|
||||||
|
|
||||||
Removed Functionality
|
Removed Functionality
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit b3a5d01c041b78a9e50544ac891c5e0d35c116f7
|
Subproject commit 75f645ac9bdfd141f549b7e1a197459f2ad518be
|
|
@ -282,6 +282,7 @@ set(MAIN_SRCS
|
||||||
Val.cc
|
Val.cc
|
||||||
Var.cc
|
Var.cc
|
||||||
WeirdState.cc
|
WeirdState.cc
|
||||||
|
ZeekArgs.cc
|
||||||
bsd-getopt-long.c
|
bsd-getopt-long.c
|
||||||
bro_inet_ntop.c
|
bro_inet_ntop.c
|
||||||
cq.c
|
cq.c
|
||||||
|
|
50
src/Event.cc
50
src/Event.cc
|
@ -18,7 +18,7 @@ EventMgr mgr;
|
||||||
uint64_t num_events_queued = 0;
|
uint64_t num_events_queued = 0;
|
||||||
uint64_t num_events_dispatched = 0;
|
uint64_t num_events_dispatched = 0;
|
||||||
|
|
||||||
Event::Event(EventHandlerPtr arg_handler, val_list arg_args,
|
Event::Event(EventHandlerPtr arg_handler, zeek::Args arg_args,
|
||||||
SourceID arg_src, analyzer::ID arg_aid, TimerMgr* arg_mgr,
|
SourceID arg_src, analyzer::ID arg_aid, TimerMgr* arg_mgr,
|
||||||
BroObj* arg_obj)
|
BroObj* arg_obj)
|
||||||
: handler(arg_handler),
|
: handler(arg_handler),
|
||||||
|
@ -33,14 +33,6 @@ Event::Event(EventHandlerPtr arg_handler, val_list arg_args,
|
||||||
Ref(obj);
|
Ref(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
Event::Event(EventHandlerPtr arg_handler, val_list* arg_args,
|
|
||||||
SourceID arg_src, analyzer::ID arg_aid, TimerMgr* arg_mgr,
|
|
||||||
BroObj* arg_obj)
|
|
||||||
: Event(arg_handler, std::move(*arg_args), arg_src, arg_aid, arg_mgr, arg_obj)
|
|
||||||
{
|
|
||||||
delete arg_args;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Event::Describe(ODesc* d) const
|
void Event::Describe(ODesc* d) const
|
||||||
{
|
{
|
||||||
if ( d->IsReadable() )
|
if ( d->IsReadable() )
|
||||||
|
@ -53,7 +45,7 @@ void Event::Describe(ODesc* d) const
|
||||||
|
|
||||||
if ( ! d->IsBinary() )
|
if ( ! d->IsBinary() )
|
||||||
d->Add("(");
|
d->Add("(");
|
||||||
describe_vals(&args, d);
|
describe_vals(args, d);
|
||||||
if ( ! d->IsBinary() )
|
if ( ! d->IsBinary() )
|
||||||
d->Add("(");
|
d->Add("(");
|
||||||
}
|
}
|
||||||
|
@ -68,7 +60,7 @@ void Event::Dispatch(bool no_remote)
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
handler->Call(&args, no_remote);
|
handler->Call(args, no_remote);
|
||||||
}
|
}
|
||||||
|
|
||||||
catch ( InterpreterException& e )
|
catch ( InterpreterException& e )
|
||||||
|
@ -106,12 +98,19 @@ EventMgr::~EventMgr()
|
||||||
Unref(src_val);
|
Unref(src_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EventMgr::QueueEventFast(const EventHandlerPtr &h, val_list vl,
|
||||||
|
SourceID src, analyzer::ID aid, TimerMgr* mgr,
|
||||||
|
BroObj* obj)
|
||||||
|
{
|
||||||
|
QueueEvent(new Event(h, zeek::val_list_to_args(&vl), src, aid, mgr, obj));
|
||||||
|
}
|
||||||
|
|
||||||
void EventMgr::QueueEvent(const EventHandlerPtr &h, val_list vl,
|
void EventMgr::QueueEvent(const EventHandlerPtr &h, val_list vl,
|
||||||
SourceID src, analyzer::ID aid,
|
SourceID src, analyzer::ID aid,
|
||||||
TimerMgr* mgr, BroObj* obj)
|
TimerMgr* mgr, BroObj* obj)
|
||||||
{
|
{
|
||||||
if ( h )
|
if ( h )
|
||||||
QueueEvent(new Event(h, std::move(vl), src, aid, mgr, obj));
|
QueueEvent(new Event(h, zeek::val_list_to_args(&vl), src, aid, mgr, obj));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for ( const auto& v : vl )
|
for ( const auto& v : vl )
|
||||||
|
@ -119,6 +118,29 @@ void EventMgr::QueueEvent(const EventHandlerPtr &h, val_list vl,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EventMgr::QueueEvent(const EventHandlerPtr &h, val_list* vl,
|
||||||
|
SourceID src, analyzer::ID aid,
|
||||||
|
TimerMgr* mgr, BroObj* obj)
|
||||||
|
{
|
||||||
|
QueueEvent(h, std::move(*vl), src, aid, mgr, obj);
|
||||||
|
delete vl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventMgr::QueueCheckedEvent(const EventHandlerPtr& h, zeek::Args vl,
|
||||||
|
SourceID src, analyzer::ID aid,
|
||||||
|
TimerMgr* mgr, BroObj* obj)
|
||||||
|
{
|
||||||
|
QueueEvent(new Event(h, std::move(vl), src, aid, mgr, obj));
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventMgr::QueueUncheckedEvent(const EventHandlerPtr& h, zeek::Args vl,
|
||||||
|
SourceID src, analyzer::ID aid,
|
||||||
|
TimerMgr* mgr, BroObj* obj)
|
||||||
|
{
|
||||||
|
if ( h )
|
||||||
|
QueueEvent(new Event(h, std::move(vl), src, aid, mgr, obj));
|
||||||
|
}
|
||||||
|
|
||||||
void EventMgr::QueueEvent(Event* event)
|
void EventMgr::QueueEvent(Event* event)
|
||||||
{
|
{
|
||||||
bool done = PLUGIN_HOOK_WITH_RESULT(HOOK_QUEUE_EVENT, HookQueueEvent(event), false);
|
bool done = PLUGIN_HOOK_WITH_RESULT(HOOK_QUEUE_EVENT, HookQueueEvent(event), false);
|
||||||
|
|
55
src/Event.h
55
src/Event.h
|
@ -6,20 +6,15 @@
|
||||||
#include "analyzer/Analyzer.h"
|
#include "analyzer/Analyzer.h"
|
||||||
#include "iosource/IOSource.h"
|
#include "iosource/IOSource.h"
|
||||||
#include "Flare.h"
|
#include "Flare.h"
|
||||||
|
#include "ZeekArgs.h"
|
||||||
|
|
||||||
class EventMgr;
|
class EventMgr;
|
||||||
|
|
||||||
// We don't Unref() the individual arguments by using delete_vals()
|
|
||||||
// in a dtor because Func::Call already does that.
|
|
||||||
class Event : public BroObj {
|
class Event : public BroObj {
|
||||||
public:
|
public:
|
||||||
Event(EventHandlerPtr handler, val_list args,
|
Event(EventHandlerPtr handler, zeek::Args args,
|
||||||
SourceID src = SOURCE_LOCAL, analyzer::ID aid = 0,
|
SourceID src = SOURCE_LOCAL, analyzer::ID aid = 0,
|
||||||
TimerMgr* mgr = 0, BroObj* obj = 0);
|
TimerMgr* mgr = nullptr, BroObj* obj = nullptr);
|
||||||
|
|
||||||
Event(EventHandlerPtr handler, val_list* args,
|
|
||||||
SourceID src = SOURCE_LOCAL, analyzer::ID aid = 0,
|
|
||||||
TimerMgr* mgr = 0, BroObj* obj = 0);
|
|
||||||
|
|
||||||
void SetNext(Event* n) { next_event = n; }
|
void SetNext(Event* n) { next_event = n; }
|
||||||
Event* NextEvent() const { return next_event; }
|
Event* NextEvent() const { return next_event; }
|
||||||
|
@ -28,7 +23,7 @@ public:
|
||||||
analyzer::ID Analyzer() const { return aid; }
|
analyzer::ID Analyzer() const { return aid; }
|
||||||
TimerMgr* Mgr() const { return mgr; }
|
TimerMgr* Mgr() const { return mgr; }
|
||||||
EventHandlerPtr Handler() const { return handler; }
|
EventHandlerPtr Handler() const { return handler; }
|
||||||
const val_list* Args() const { return &args; }
|
const zeek::Args& Args() const { return args; }
|
||||||
|
|
||||||
void Describe(ODesc* d) const override;
|
void Describe(ODesc* d) const override;
|
||||||
|
|
||||||
|
@ -40,7 +35,7 @@ protected:
|
||||||
void Dispatch(bool no_remote = false);
|
void Dispatch(bool no_remote = false);
|
||||||
|
|
||||||
EventHandlerPtr handler;
|
EventHandlerPtr handler;
|
||||||
val_list args;
|
zeek::Args args;
|
||||||
SourceID src;
|
SourceID src;
|
||||||
analyzer::ID aid;
|
analyzer::ID aid;
|
||||||
TimerMgr* mgr;
|
TimerMgr* mgr;
|
||||||
|
@ -64,12 +59,11 @@ public:
|
||||||
// against the case where there's no handlers (one usually also does that
|
// against the case where there's no handlers (one usually also does that
|
||||||
// because it would be a waste of effort to construct all the event
|
// because it would be a waste of effort to construct all the event
|
||||||
// arguments when there's no handlers to consume them).
|
// arguments when there's no handlers to consume them).
|
||||||
|
// TODO: deprecate
|
||||||
|
/* [[deprecated("Remove in v4.1. Use IntrusivePtr overload instead.")]] */
|
||||||
void QueueEventFast(const EventHandlerPtr &h, val_list vl,
|
void QueueEventFast(const EventHandlerPtr &h, val_list vl,
|
||||||
SourceID src = SOURCE_LOCAL, analyzer::ID aid = 0,
|
SourceID src = SOURCE_LOCAL, analyzer::ID aid = 0,
|
||||||
TimerMgr* mgr = 0, BroObj* obj = 0)
|
TimerMgr* mgr = 0, BroObj* obj = 0);
|
||||||
{
|
|
||||||
QueueEvent(new Event(h, std::move(vl), src, aid, mgr, obj));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Queues an event if there's an event handler (or remote consumer). This
|
// Queues an event if there's an event handler (or remote consumer). This
|
||||||
// function always takes ownership of decrementing the reference count of
|
// function always takes ownership of decrementing the reference count of
|
||||||
|
@ -77,6 +71,8 @@ public:
|
||||||
// checked for event handler existence, you may wish to call
|
// checked for event handler existence, you may wish to call
|
||||||
// QueueEventFast() instead of this function to prevent the redundant
|
// QueueEventFast() instead of this function to prevent the redundant
|
||||||
// existence check.
|
// existence check.
|
||||||
|
// TODO: deprecate
|
||||||
|
/* [[deprecated("Remove in v4.1. Use IntrusivePtr overload instead.")]] */
|
||||||
void QueueEvent(const EventHandlerPtr &h, val_list vl,
|
void QueueEvent(const EventHandlerPtr &h, val_list vl,
|
||||||
SourceID src = SOURCE_LOCAL, analyzer::ID aid = 0,
|
SourceID src = SOURCE_LOCAL, analyzer::ID aid = 0,
|
||||||
TimerMgr* mgr = 0, BroObj* obj = 0);
|
TimerMgr* mgr = 0, BroObj* obj = 0);
|
||||||
|
@ -85,13 +81,32 @@ public:
|
||||||
// pointer instead of by value. This function takes ownership of the
|
// pointer instead of by value. This function takes ownership of the
|
||||||
// memory pointed to by 'vl' as well as decrementing the reference count of
|
// memory pointed to by 'vl' as well as decrementing the reference count of
|
||||||
// each of its elements.
|
// each of its elements.
|
||||||
|
// TODO: deprecate
|
||||||
|
/* [[deprecated("Remove in v4.1. Use IntrusivePtr overload instead.")]] */
|
||||||
void QueueEvent(const EventHandlerPtr &h, val_list* vl,
|
void QueueEvent(const EventHandlerPtr &h, val_list* vl,
|
||||||
SourceID src = SOURCE_LOCAL, analyzer::ID aid = 0,
|
SourceID src = SOURCE_LOCAL, analyzer::ID aid = 0,
|
||||||
TimerMgr* mgr = 0, BroObj* obj = 0)
|
TimerMgr* mgr = 0, BroObj* obj = 0);
|
||||||
{
|
|
||||||
QueueEvent(h, std::move(*vl), src, aid, mgr, obj);
|
/**
|
||||||
delete vl;
|
* Queues an event without first checking if there's an event handler
|
||||||
}
|
* remote consumer. If there are actually no handlers/consumers upon
|
||||||
|
* dispatching the event, nothing happens besides having wasted a bit of
|
||||||
|
* time and resources. This method is mostly useful from a performance
|
||||||
|
* standpoint: usually callers have already checked that the event will
|
||||||
|
* consumed so they don't waste time creating an argument list that will
|
||||||
|
* only be discarded, so there's no need to do the same check again when
|
||||||
|
* going to queue the event.
|
||||||
|
*/
|
||||||
|
void QueueUncheckedEvent(const EventHandlerPtr& h, zeek::Args vl,
|
||||||
|
SourceID src = SOURCE_LOCAL, analyzer::ID aid = 0,
|
||||||
|
TimerMgr* mgr = nullptr, BroObj* obj = nullptr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queues an event if it has an event handler or remote consumer.
|
||||||
|
*/
|
||||||
|
void QueueCheckedEvent(const EventHandlerPtr& h, zeek::Args vl,
|
||||||
|
SourceID src = SOURCE_LOCAL, analyzer::ID aid = 0,
|
||||||
|
TimerMgr* mgr = nullptr, BroObj* obj = nullptr);
|
||||||
|
|
||||||
void Dispatch(Event* event, bool no_remote = false);
|
void Dispatch(Event* event, bool no_remote = false);
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@ void EventHandler::SetLocalHandler(Func* f)
|
||||||
local = f;
|
local = f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventHandler::Call(val_list* vl, bool no_remote)
|
void EventHandler::Call(const zeek::Args& vl, bool no_remote)
|
||||||
{
|
{
|
||||||
#ifdef PROFILE_BRO_FUNCTIONS
|
#ifdef PROFILE_BRO_FUNCTIONS
|
||||||
DEBUG_MSG("Event: %s\n", Name());
|
DEBUG_MSG("Event: %s\n", Name());
|
||||||
|
@ -75,12 +75,12 @@ void EventHandler::Call(val_list* vl, bool no_remote)
|
||||||
{
|
{
|
||||||
// Send event in form [name, xs...] where xs represent the arguments.
|
// Send event in form [name, xs...] where xs represent the arguments.
|
||||||
broker::vector xs;
|
broker::vector xs;
|
||||||
xs.reserve(vl->length());
|
xs.reserve(vl.size());
|
||||||
bool valid_args = true;
|
bool valid_args = true;
|
||||||
|
|
||||||
for ( auto i = 0; i < vl->length(); ++i )
|
for ( auto i = 0u; i < vl.size(); ++i )
|
||||||
{
|
{
|
||||||
auto opt_data = bro_broker::val_to_data((*vl)[i]);
|
auto opt_data = bro_broker::val_to_data(vl[i].get());
|
||||||
|
|
||||||
if ( opt_data )
|
if ( opt_data )
|
||||||
xs.emplace_back(move(*opt_data));
|
xs.emplace_back(move(*opt_data));
|
||||||
|
@ -115,14 +115,9 @@ void EventHandler::Call(val_list* vl, bool no_remote)
|
||||||
if ( local )
|
if ( local )
|
||||||
// No try/catch here; we pass exceptions upstream.
|
// No try/catch here; we pass exceptions upstream.
|
||||||
local->Call(vl);
|
local->Call(vl);
|
||||||
else
|
|
||||||
{
|
|
||||||
for ( auto v : *vl )
|
|
||||||
Unref(v);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventHandler::NewEvent(val_list* vl)
|
void EventHandler::NewEvent(const zeek::Args& vl)
|
||||||
{
|
{
|
||||||
if ( ! new_event )
|
if ( ! new_event )
|
||||||
return;
|
return;
|
||||||
|
@ -132,7 +127,7 @@ void EventHandler::NewEvent(val_list* vl)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
RecordType* args = FType()->Args();
|
RecordType* args = FType()->Args();
|
||||||
VectorVal* vargs = new VectorVal(call_argument_vector);
|
auto vargs = make_intrusive<VectorVal>(call_argument_vector);
|
||||||
|
|
||||||
for ( int i = 0; i < args->NumFields(); i++ )
|
for ( int i = 0; i < args->NumFields(); i++ )
|
||||||
{
|
{
|
||||||
|
@ -151,19 +146,15 @@ void EventHandler::NewEvent(val_list* vl)
|
||||||
if ( fdefault )
|
if ( fdefault )
|
||||||
rec->Assign(2, std::move(fdefault));
|
rec->Assign(2, std::move(fdefault));
|
||||||
|
|
||||||
if ( i < vl->length() && (*vl)[i] )
|
if ( i < static_cast<int>(vl.size()) && vl[i] )
|
||||||
{
|
rec->Assign(3, vl[i]);
|
||||||
Val* val = (*vl)[i];
|
|
||||||
Ref(val);
|
|
||||||
rec->Assign(3, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
vargs->Assign(i, std::move(rec));
|
vargs->Assign(i, std::move(rec));
|
||||||
}
|
}
|
||||||
|
|
||||||
Event* ev = new Event(new_event, {
|
Event* ev = new Event(new_event, {
|
||||||
new StringVal(name),
|
make_intrusive<StringVal>(name),
|
||||||
vargs,
|
std::move(vargs),
|
||||||
});
|
});
|
||||||
mgr.Dispatch(ev);
|
mgr.Dispatch(ev);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "BroList.h"
|
#include "BroList.h"
|
||||||
|
#include "ZeekArgs.h"
|
||||||
|
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -31,7 +32,7 @@ public:
|
||||||
auto_publish.erase(topic);
|
auto_publish.erase(topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Call(val_list* vl, bool no_remote = false);
|
void Call(const zeek::Args& vl, bool no_remote = false);
|
||||||
|
|
||||||
// Returns true if there is at least one local or remote handler.
|
// Returns true if there is at least one local or remote handler.
|
||||||
explicit operator bool() const;
|
explicit operator bool() const;
|
||||||
|
@ -52,7 +53,7 @@ public:
|
||||||
bool GenerateAlways() { return generate_always; }
|
bool GenerateAlways() { return generate_always; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void NewEvent(val_list* vl); // Raise new_event() meta event.
|
void NewEvent(const zeek::Args& vl); // Raise new_event() meta event.
|
||||||
|
|
||||||
const char* name;
|
const char* name;
|
||||||
Func* local;
|
Func* local;
|
||||||
|
|
51
src/Expr.cc
51
src/Expr.cc
|
@ -3884,12 +3884,11 @@ IntrusivePtr<Val> FlattenExpr::Fold(Val* v) const
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScheduleTimer::ScheduleTimer(EventHandlerPtr arg_event, val_list* arg_args,
|
ScheduleTimer::ScheduleTimer(EventHandlerPtr arg_event, zeek::Args arg_args,
|
||||||
double t, TimerMgr* arg_tmgr)
|
double t, TimerMgr* arg_tmgr)
|
||||||
: Timer(t, TIMER_SCHEDULE),
|
: Timer(t, TIMER_SCHEDULE),
|
||||||
event(arg_event), args(std::move(*arg_args)), tmgr(arg_tmgr)
|
event(arg_event), args(std::move(arg_args)), tmgr(arg_tmgr)
|
||||||
{
|
{
|
||||||
delete arg_args;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ScheduleTimer::~ScheduleTimer()
|
ScheduleTimer::~ScheduleTimer()
|
||||||
|
@ -3898,7 +3897,7 @@ ScheduleTimer::~ScheduleTimer()
|
||||||
|
|
||||||
void ScheduleTimer::Dispatch(double /* t */, int /* is_expire */)
|
void ScheduleTimer::Dispatch(double /* t */, int /* is_expire */)
|
||||||
{
|
{
|
||||||
mgr.QueueEvent(event, std::move(args), SOURCE_LOCAL, 0, tmgr);
|
mgr.QueueUncheckedEvent(event, std::move(args), SOURCE_LOCAL, 0, tmgr);
|
||||||
}
|
}
|
||||||
|
|
||||||
ScheduleExpr::ScheduleExpr(IntrusivePtr<Expr> arg_when,
|
ScheduleExpr::ScheduleExpr(IntrusivePtr<Expr> arg_when,
|
||||||
|
@ -3937,7 +3936,7 @@ IntrusivePtr<Val> ScheduleExpr::Eval(Frame* f) const
|
||||||
if ( when->Type()->Tag() == TYPE_INTERVAL )
|
if ( when->Type()->Tag() == TYPE_INTERVAL )
|
||||||
dt += network_time;
|
dt += network_time;
|
||||||
|
|
||||||
val_list* args = eval_list(f, event->Args());
|
auto args = eval_list(f, event->Args());
|
||||||
|
|
||||||
if ( args )
|
if ( args )
|
||||||
{
|
{
|
||||||
|
@ -3946,7 +3945,7 @@ IntrusivePtr<Val> ScheduleExpr::Eval(Frame* f) const
|
||||||
if ( ! tmgr )
|
if ( ! tmgr )
|
||||||
tmgr = timer_mgr;
|
tmgr = timer_mgr;
|
||||||
|
|
||||||
tmgr->Add(new ScheduleTimer(event->Handler(), args, dt, tmgr));
|
tmgr->Add(new ScheduleTimer(event->Handler(), std::move(*args), dt, tmgr));
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -4236,7 +4235,7 @@ IntrusivePtr<Val> CallExpr::Eval(Frame* f) const
|
||||||
|
|
||||||
IntrusivePtr<Val> ret;
|
IntrusivePtr<Val> ret;
|
||||||
auto func_val = func->Eval(f);
|
auto func_val = func->Eval(f);
|
||||||
val_list* v = eval_list(f, args.get());
|
auto v = eval_list(f, args.get());
|
||||||
|
|
||||||
if ( func_val && v )
|
if ( func_val && v )
|
||||||
{
|
{
|
||||||
|
@ -4246,16 +4245,11 @@ IntrusivePtr<Val> CallExpr::Eval(Frame* f) const
|
||||||
if ( f )
|
if ( f )
|
||||||
f->SetCall(this);
|
f->SetCall(this);
|
||||||
|
|
||||||
ret = func->Call(v, f);
|
ret = func->Call(*v, f);
|
||||||
|
|
||||||
if ( f )
|
if ( f )
|
||||||
f->SetCall(current_call);
|
f->SetCall(current_call);
|
||||||
|
|
||||||
// Don't Unref() the arguments, as Func::Call already did that.
|
|
||||||
delete v;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
delete_vals(v);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -4448,10 +4442,8 @@ IntrusivePtr<Val> EventExpr::Eval(Frame* f) const
|
||||||
if ( IsError() )
|
if ( IsError() )
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
val_list* v = eval_list(f, args.get());
|
auto v = eval_list(f, args.get());
|
||||||
mgr.QueueEvent(handler, std::move(*v));
|
mgr.QueueUncheckedEvent(handler, std::move(*v));
|
||||||
delete v;
|
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5176,36 +5168,23 @@ int check_and_promote_exprs_to_type(ListExpr* const elements, BroType* type)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
val_list* eval_list(Frame* f, const ListExpr* l)
|
std::optional<std::vector<IntrusivePtr<Val>>> eval_list(Frame* f, const ListExpr* l)
|
||||||
{
|
{
|
||||||
const expr_list& e = l->Exprs();
|
const expr_list& e = l->Exprs();
|
||||||
val_list* v = new val_list(e.length());
|
auto rval = std::make_optional<std::vector<IntrusivePtr<Val>>>();
|
||||||
bool success = true;
|
rval->reserve(e.length());
|
||||||
|
|
||||||
for ( const auto& expr : e )
|
for ( const auto& expr : e )
|
||||||
{
|
{
|
||||||
auto ev = expr->Eval(f);
|
auto ev = expr->Eval(f);
|
||||||
|
|
||||||
if ( ! ev )
|
if ( ! ev )
|
||||||
{
|
return {};
|
||||||
success = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
v->push_back(ev.release());
|
rval->emplace_back(std::move(ev));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! success )
|
return rval;
|
||||||
{
|
|
||||||
for ( const auto& val : *v )
|
|
||||||
Unref(val);
|
|
||||||
|
|
||||||
delete v;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
return v;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool expr_greater(const Expr* e1, const Expr* e2)
|
bool expr_greater(const Expr* e1, const Expr* e2)
|
||||||
|
|
15
src/Expr.h
15
src/Expr.h
|
@ -9,10 +9,13 @@
|
||||||
#include "EventHandler.h"
|
#include "EventHandler.h"
|
||||||
#include "TraverseTypes.h"
|
#include "TraverseTypes.h"
|
||||||
#include "Val.h"
|
#include "Val.h"
|
||||||
|
#include "ZeekArgs.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
|
@ -737,15 +740,15 @@ protected:
|
||||||
|
|
||||||
class ScheduleTimer : public Timer {
|
class ScheduleTimer : public Timer {
|
||||||
public:
|
public:
|
||||||
ScheduleTimer(EventHandlerPtr event, val_list* args, double t,
|
ScheduleTimer(EventHandlerPtr event, zeek::Args args,
|
||||||
TimerMgr* tmgr);
|
double t, TimerMgr* tmgr);
|
||||||
~ScheduleTimer() override;
|
~ScheduleTimer() override;
|
||||||
|
|
||||||
void Dispatch(double t, int is_expire) override;
|
void Dispatch(double t, int is_expire) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
EventHandlerPtr event;
|
EventHandlerPtr event;
|
||||||
val_list args;
|
zeek::Args args;
|
||||||
TimerMgr* tmgr;
|
TimerMgr* tmgr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -936,9 +939,9 @@ extern int check_and_promote_exprs(ListExpr* elements, TypeList* types);
|
||||||
extern int check_and_promote_args(ListExpr* args, RecordType* types);
|
extern int check_and_promote_args(ListExpr* args, RecordType* types);
|
||||||
extern int check_and_promote_exprs_to_type(ListExpr* elements, BroType* type);
|
extern int check_and_promote_exprs_to_type(ListExpr* elements, BroType* type);
|
||||||
|
|
||||||
// Returns a ListExpr simplified down to a list a values, or a nil
|
// Returns a ListExpr simplified down to a list a values, or nil
|
||||||
// pointer if they couldn't all be reduced.
|
// if they couldn't all be reduced.
|
||||||
val_list* eval_list(Frame* f, const ListExpr* l);
|
std::optional<std::vector<IntrusivePtr<Val>>> eval_list(Frame* f, const ListExpr* l);
|
||||||
|
|
||||||
// Returns true if e1 is "greater" than e2 - here "greater" is just
|
// Returns true if e1 is "greater" than e2 - here "greater" is just
|
||||||
// a heuristic, used with commutative operators to put them into
|
// a heuristic, used with commutative operators to put them into
|
||||||
|
|
|
@ -325,7 +325,7 @@ void BroFile::RaiseOpenEvent()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Ref(this);
|
Ref(this);
|
||||||
Event* event = new ::Event(::file_opened, {new Val(this)});
|
Event* event = new ::Event(::file_opened, {make_intrusive<Val>(this)});
|
||||||
mgr.Dispatch(event, true);
|
mgr.Dispatch(event, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
vector<Frame*> g_frame_stack;
|
vector<Frame*> g_frame_stack;
|
||||||
|
|
||||||
Frame::Frame(int arg_size, const BroFunc* func, const val_list* fn_args)
|
Frame::Frame(int arg_size, const BroFunc* func, const zeek::Args* fn_args)
|
||||||
{
|
{
|
||||||
size = arg_size;
|
size = arg_size;
|
||||||
frame = new Val*[size];
|
frame = new Val*[size];
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "BroList.h" // for typedef val_list
|
#include "BroList.h" // for typedef val_list
|
||||||
#include "Obj.h"
|
#include "Obj.h"
|
||||||
#include "IntrusivePtr.h"
|
#include "IntrusivePtr.h"
|
||||||
|
#include "ZeekArgs.h"
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -28,7 +29,7 @@ public:
|
||||||
* @param func the function that is creating this frame
|
* @param func the function that is creating this frame
|
||||||
* @param fn_args the arguments being passed to that function.
|
* @param fn_args the arguments being passed to that function.
|
||||||
*/
|
*/
|
||||||
Frame(int size, const BroFunc* func, const val_list *fn_args);
|
Frame(int size, const BroFunc* func, const zeek::Args* fn_args);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes the frame. Unrefs its trigger, the values that it
|
* Deletes the frame. Unrefs its trigger, the values that it
|
||||||
|
@ -100,7 +101,7 @@ public:
|
||||||
* @return the arguments passed to the function that this frame
|
* @return the arguments passed to the function that this frame
|
||||||
* is associated with.
|
* is associated with.
|
||||||
*/
|
*/
|
||||||
const val_list* GetFuncArgs() const { return func_args; }
|
const zeek::Args* GetFuncArgs() const { return func_args; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Change the function that the frame is associated with.
|
* Change the function that the frame is associated with.
|
||||||
|
@ -283,7 +284,7 @@ private:
|
||||||
/** The function this frame is associated with. */
|
/** The function this frame is associated with. */
|
||||||
const BroFunc* function;
|
const BroFunc* function;
|
||||||
/** The arguments to the function that this Frame is associated with. */
|
/** The arguments to the function that this Frame is associated with. */
|
||||||
const val_list* func_args;
|
const zeek::Args* func_args;
|
||||||
|
|
||||||
/** The next statement to be evaluted in the context of this frame. */
|
/** The next statement to be evaluted in the context of this frame. */
|
||||||
Stmt* next_stmt;
|
Stmt* next_stmt;
|
||||||
|
|
84
src/Func.cc
84
src/Func.cc
|
@ -79,19 +79,16 @@ std::string render_call_stack()
|
||||||
auto name = ci.func->Name();
|
auto name = ci.func->Name();
|
||||||
std::string arg_desc;
|
std::string arg_desc;
|
||||||
|
|
||||||
if ( ci.args )
|
for ( const auto& arg : ci.args )
|
||||||
{
|
{
|
||||||
for ( const auto& arg : *ci.args )
|
ODesc d;
|
||||||
{
|
d.SetShort();
|
||||||
ODesc d;
|
arg->Describe(&d);
|
||||||
d.SetShort();
|
|
||||||
arg->Describe(&d);
|
|
||||||
|
|
||||||
if ( ! arg_desc.empty() )
|
if ( ! arg_desc.empty() )
|
||||||
arg_desc += ", ";
|
arg_desc += ", ";
|
||||||
|
|
||||||
arg_desc += d.Description();
|
arg_desc += d.Description();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rval += fmt("#%d %s(%s)", lvl, name, arg_desc.data());
|
rval += fmt("#%d %s(%s)", lvl, name, arg_desc.data());
|
||||||
|
@ -143,7 +140,7 @@ IntrusivePtr<Func> Func::DoClone()
|
||||||
return {NewRef{}, this};
|
return {NewRef{}, this};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Func::DescribeDebug(ODesc* d, const val_list* args) const
|
void Func::DescribeDebug(ODesc* d, const zeek::Args* args) const
|
||||||
{
|
{
|
||||||
d->Add(Name());
|
d->Add(Name());
|
||||||
|
|
||||||
|
@ -153,10 +150,10 @@ void Func::DescribeDebug(ODesc* d, const val_list* args) const
|
||||||
{
|
{
|
||||||
d->Add("(");
|
d->Add("(");
|
||||||
|
|
||||||
for ( int i = 0; i < args->length(); ++i )
|
for ( auto i = 0u; i < args->size(); ++i )
|
||||||
{
|
{
|
||||||
// Handle varargs case (more args than formals).
|
// Handle varargs case (more args than formals).
|
||||||
if ( i >= func_args->NumFields() )
|
if ( i >= static_cast<size_t>(func_args->NumFields()) )
|
||||||
{
|
{
|
||||||
d->Add("vararg");
|
d->Add("vararg");
|
||||||
d->Add(i - func_args->NumFields());
|
d->Add(i - func_args->NumFields());
|
||||||
|
@ -167,7 +164,7 @@ void Func::DescribeDebug(ODesc* d, const val_list* args) const
|
||||||
d->Add(" = '");
|
d->Add(" = '");
|
||||||
(*args)[i]->Describe(d);
|
(*args)[i]->Describe(d);
|
||||||
|
|
||||||
if ( i < args->length() - 1 )
|
if ( i < args->size() - 1 )
|
||||||
d->Add("', ");
|
d->Add("', ");
|
||||||
else
|
else
|
||||||
d->Add("'");
|
d->Add("'");
|
||||||
|
@ -217,7 +214,7 @@ void Func::CopyStateInto(Func* other) const
|
||||||
other->unique_id = unique_id;
|
other->unique_id = unique_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<bool, Val*> Func::HandlePluginResult(std::pair<bool, Val*> plugin_result, val_list* args, function_flavor flavor) const
|
std::pair<bool, Val*> Func::HandlePluginResult(std::pair<bool, Val*> plugin_result, function_flavor flavor) const
|
||||||
{
|
{
|
||||||
// Helper function factoring out this code from BroFunc:Call() for
|
// Helper function factoring out this code from BroFunc:Call() for
|
||||||
// better readability.
|
// better readability.
|
||||||
|
@ -265,9 +262,6 @@ std::pair<bool, Val*> Func::HandlePluginResult(std::pair<bool, Val*> plugin_resu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( const auto& arg : *args )
|
|
||||||
Unref(arg);
|
|
||||||
|
|
||||||
return plugin_result;
|
return plugin_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,7 +294,12 @@ int BroFunc::IsPure() const
|
||||||
[](const Body& b) { return b.stmts->IsPure(); });
|
[](const Body& b) { return b.stmts->IsPure(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
IntrusivePtr<Val> BroFunc::Call(val_list* args, Frame* parent) const
|
IntrusivePtr<Val> Func::Call(val_list* args, Frame* parent) const
|
||||||
|
{
|
||||||
|
return Call(zeek::val_list_to_args(args), parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
IntrusivePtr<Val> BroFunc::Call(const zeek::Args& args, Frame* parent) const
|
||||||
{
|
{
|
||||||
#ifdef PROFILE_BRO_FUNCTIONS
|
#ifdef PROFILE_BRO_FUNCTIONS
|
||||||
DEBUG_MSG("Function: %s\n", Name());
|
DEBUG_MSG("Function: %s\n", Name());
|
||||||
|
@ -312,7 +311,7 @@ IntrusivePtr<Val> BroFunc::Call(val_list* args, Frame* parent) const
|
||||||
|
|
||||||
std::pair<bool, Val*> plugin_result = PLUGIN_HOOK_WITH_RESULT(HOOK_CALL_FUNCTION, HookCallFunction(this, parent, args), empty_hook_result);
|
std::pair<bool, Val*> plugin_result = PLUGIN_HOOK_WITH_RESULT(HOOK_CALL_FUNCTION, HookCallFunction(this, parent, args), empty_hook_result);
|
||||||
|
|
||||||
plugin_result = HandlePluginResult(plugin_result, args, Flavor());
|
plugin_result = HandlePluginResult(plugin_result, Flavor());
|
||||||
|
|
||||||
if( plugin_result.first )
|
if( plugin_result.first )
|
||||||
return {AdoptRef{}, plugin_result.second};
|
return {AdoptRef{}, plugin_result.second};
|
||||||
|
@ -321,13 +320,10 @@ IntrusivePtr<Val> BroFunc::Call(val_list* args, Frame* parent) const
|
||||||
{
|
{
|
||||||
// Can only happen for events and hooks.
|
// Can only happen for events and hooks.
|
||||||
assert(Flavor() == FUNC_FLAVOR_EVENT || Flavor() == FUNC_FLAVOR_HOOK);
|
assert(Flavor() == FUNC_FLAVOR_EVENT || Flavor() == FUNC_FLAVOR_HOOK);
|
||||||
for ( const auto& arg : *args )
|
|
||||||
Unref(arg);
|
|
||||||
|
|
||||||
return Flavor() == FUNC_FLAVOR_HOOK ? IntrusivePtr{AdoptRef{}, val_mgr->GetTrue()} : nullptr;
|
return Flavor() == FUNC_FLAVOR_HOOK ? IntrusivePtr{AdoptRef{}, val_mgr->GetTrue()} : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto f = make_intrusive<Frame>(frame_size, this, args);
|
auto f = make_intrusive<Frame>(frame_size, this, &args);
|
||||||
|
|
||||||
if ( closure )
|
if ( closure )
|
||||||
f->CaptureClosure(closure, outer_ids);
|
f->CaptureClosure(closure, outer_ids);
|
||||||
|
@ -346,7 +342,7 @@ IntrusivePtr<Val> BroFunc::Call(val_list* args, Frame* parent) const
|
||||||
if ( g_trace_state.DoTrace() )
|
if ( g_trace_state.DoTrace() )
|
||||||
{
|
{
|
||||||
ODesc d;
|
ODesc d;
|
||||||
DescribeDebug(&d, args);
|
DescribeDebug(&d, &args);
|
||||||
|
|
||||||
g_trace_state.LogTrace("%s called: %s\n",
|
g_trace_state.LogTrace("%s called: %s\n",
|
||||||
FType()->FlavorString().c_str(), d.Description());
|
FType()->FlavorString().c_str(), d.Description());
|
||||||
|
@ -362,19 +358,16 @@ IntrusivePtr<Val> BroFunc::Call(val_list* args, Frame* parent) const
|
||||||
body.stmts->GetLocationInfo());
|
body.stmts->GetLocationInfo());
|
||||||
|
|
||||||
// Fill in the rest of the frame with the function's arguments.
|
// Fill in the rest of the frame with the function's arguments.
|
||||||
loop_over_list(*args, j)
|
for ( auto j = 0u; j < args.size(); ++j )
|
||||||
{
|
{
|
||||||
Val* arg = (*args)[j];
|
Val* arg = args[j].get();
|
||||||
|
|
||||||
if ( f->NthElement(j) != arg )
|
if ( f->NthElement(j) != arg )
|
||||||
{
|
|
||||||
// Either not yet set, or somebody reassigned the frame slot.
|
// Either not yet set, or somebody reassigned the frame slot.
|
||||||
Ref(arg);
|
f->SetElement(j, arg->Ref());
|
||||||
f->SetElement(j, arg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
f->Reset(args->length());
|
f->Reset(args.size());
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -421,11 +414,6 @@ IntrusivePtr<Val> BroFunc::Call(val_list* args, Frame* parent) const
|
||||||
|
|
||||||
call_stack.pop_back();
|
call_stack.pop_back();
|
||||||
|
|
||||||
// We have an extra Ref for each argument (so that they don't get
|
|
||||||
// deleted between bodies), release that.
|
|
||||||
for ( const auto& arg : *args )
|
|
||||||
Unref(arg);
|
|
||||||
|
|
||||||
if ( Flavor() == FUNC_FLAVOR_HOOK )
|
if ( Flavor() == FUNC_FLAVOR_HOOK )
|
||||||
{
|
{
|
||||||
if ( ! result )
|
if ( ! result )
|
||||||
|
@ -612,7 +600,7 @@ int BuiltinFunc::IsPure() const
|
||||||
return is_pure;
|
return is_pure;
|
||||||
}
|
}
|
||||||
|
|
||||||
IntrusivePtr<Val> BuiltinFunc::Call(val_list* args, Frame* parent) const
|
IntrusivePtr<Val> BuiltinFunc::Call(const zeek::Args& args, Frame* parent) const
|
||||||
{
|
{
|
||||||
#ifdef PROFILE_BRO_FUNCTIONS
|
#ifdef PROFILE_BRO_FUNCTIONS
|
||||||
DEBUG_MSG("Function: %s\n", Name());
|
DEBUG_MSG("Function: %s\n", Name());
|
||||||
|
@ -624,7 +612,7 @@ IntrusivePtr<Val> BuiltinFunc::Call(val_list* args, Frame* parent) const
|
||||||
|
|
||||||
std::pair<bool, Val*> plugin_result = PLUGIN_HOOK_WITH_RESULT(HOOK_CALL_FUNCTION, HookCallFunction(this, parent, args), empty_hook_result);
|
std::pair<bool, Val*> plugin_result = PLUGIN_HOOK_WITH_RESULT(HOOK_CALL_FUNCTION, HookCallFunction(this, parent, args), empty_hook_result);
|
||||||
|
|
||||||
plugin_result = HandlePluginResult(plugin_result, args, FUNC_FLAVOR_FUNCTION);
|
plugin_result = HandlePluginResult(plugin_result, FUNC_FLAVOR_FUNCTION);
|
||||||
|
|
||||||
if ( plugin_result.first )
|
if ( plugin_result.first )
|
||||||
return {AdoptRef{}, plugin_result.second};
|
return {AdoptRef{}, plugin_result.second};
|
||||||
|
@ -632,20 +620,16 @@ IntrusivePtr<Val> BuiltinFunc::Call(val_list* args, Frame* parent) const
|
||||||
if ( g_trace_state.DoTrace() )
|
if ( g_trace_state.DoTrace() )
|
||||||
{
|
{
|
||||||
ODesc d;
|
ODesc d;
|
||||||
DescribeDebug(&d, args);
|
DescribeDebug(&d, &args);
|
||||||
|
|
||||||
g_trace_state.LogTrace("\tBuiltin Function called: %s\n", d.Description());
|
g_trace_state.LogTrace("\tBuiltin Function called: %s\n", d.Description());
|
||||||
}
|
}
|
||||||
|
|
||||||
const CallExpr* call_expr = parent ? parent->GetCall() : nullptr;
|
const CallExpr* call_expr = parent ? parent->GetCall() : nullptr;
|
||||||
call_stack.emplace_back(CallInfo{call_expr, this, args});
|
call_stack.emplace_back(CallInfo{call_expr, this, args});
|
||||||
IntrusivePtr<Val> result{AdoptRef{}, func(parent, args)};
|
IntrusivePtr<Val> result{AdoptRef{}, func(parent, &args)};
|
||||||
call_stack.pop_back();
|
call_stack.pop_back();
|
||||||
|
|
||||||
for ( const auto& arg : *args )
|
|
||||||
Unref(arg);
|
|
||||||
|
|
||||||
// Don't Unref() args, that's the caller's responsibility.
|
|
||||||
if ( result && g_trace_state.DoTrace() )
|
if ( result && g_trace_state.DoTrace() )
|
||||||
{
|
{
|
||||||
ODesc d;
|
ODesc d;
|
||||||
|
@ -663,6 +647,16 @@ void BuiltinFunc::Describe(ODesc* d) const
|
||||||
d->AddCount(is_pure);
|
d->AddCount(is_pure);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void builtin_error(const char* msg)
|
||||||
|
{
|
||||||
|
builtin_error(msg, IntrusivePtr<Val>{});
|
||||||
|
}
|
||||||
|
|
||||||
|
void builtin_error(const char* msg, IntrusivePtr<Val> arg)
|
||||||
|
{
|
||||||
|
builtin_error(msg, arg.get());
|
||||||
|
}
|
||||||
|
|
||||||
void builtin_error(const char* msg, BroObj* arg)
|
void builtin_error(const char* msg, BroObj* arg)
|
||||||
{
|
{
|
||||||
auto emit = [=](const CallExpr* ce)
|
auto emit = [=](const CallExpr* ce)
|
||||||
|
|
22
src/Func.h
22
src/Func.h
|
@ -7,6 +7,7 @@
|
||||||
#include "IntrusivePtr.h"
|
#include "IntrusivePtr.h"
|
||||||
#include "Type.h" /* for function_flavor */
|
#include "Type.h" /* for function_flavor */
|
||||||
#include "TraverseTypes.h"
|
#include "TraverseTypes.h"
|
||||||
|
#include "ZeekArgs.h"
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
@ -30,7 +31,6 @@ class Scope;
|
||||||
|
|
||||||
class Func : public BroObj {
|
class Func : public BroObj {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum Kind { BRO_FUNC, BUILTIN_FUNC };
|
enum Kind { BRO_FUNC, BUILTIN_FUNC };
|
||||||
|
|
||||||
explicit Func(Kind arg_kind);
|
explicit Func(Kind arg_kind);
|
||||||
|
@ -50,7 +50,9 @@ public:
|
||||||
const vector<Body>& GetBodies() const { return bodies; }
|
const vector<Body>& GetBodies() const { return bodies; }
|
||||||
bool HasBodies() const { return bodies.size(); }
|
bool HasBodies() const { return bodies.size(); }
|
||||||
|
|
||||||
virtual IntrusivePtr<Val> Call(val_list* args, Frame* parent = 0) const = 0;
|
// TODO: deprecate
|
||||||
|
virtual IntrusivePtr<Val> Call(val_list* args, Frame* parent = nullptr) const;
|
||||||
|
virtual IntrusivePtr<Val> Call(const zeek::Args& args, Frame* parent = nullptr) const = 0;
|
||||||
|
|
||||||
// Add a new event handler to an existing function (event).
|
// Add a new event handler to an existing function (event).
|
||||||
virtual void AddBody(IntrusivePtr<Stmt> new_body, id_list* new_inits,
|
virtual void AddBody(IntrusivePtr<Stmt> new_body, id_list* new_inits,
|
||||||
|
@ -67,7 +69,7 @@ public:
|
||||||
void SetName(const char* arg_name) { name = arg_name; }
|
void SetName(const char* arg_name) { name = arg_name; }
|
||||||
|
|
||||||
void Describe(ODesc* d) const override = 0;
|
void Describe(ODesc* d) const override = 0;
|
||||||
virtual void DescribeDebug(ODesc* d, const val_list* args) const;
|
virtual void DescribeDebug(ODesc* d, const zeek::Args* args) const;
|
||||||
|
|
||||||
virtual IntrusivePtr<Func> DoClone();
|
virtual IntrusivePtr<Func> DoClone();
|
||||||
|
|
||||||
|
@ -84,7 +86,7 @@ protected:
|
||||||
void CopyStateInto(Func* other) const;
|
void CopyStateInto(Func* other) const;
|
||||||
|
|
||||||
// Helper function for handling result of plugin hook.
|
// Helper function for handling result of plugin hook.
|
||||||
std::pair<bool, Val*> HandlePluginResult(std::pair<bool, Val*> plugin_result, val_list* args, function_flavor flavor) const;
|
std::pair<bool, Val*> HandlePluginResult(std::pair<bool, Val*> plugin_result, function_flavor flavor) const;
|
||||||
|
|
||||||
vector<Body> bodies;
|
vector<Body> bodies;
|
||||||
IntrusivePtr<Scope> scope;
|
IntrusivePtr<Scope> scope;
|
||||||
|
@ -102,7 +104,7 @@ public:
|
||||||
~BroFunc() override;
|
~BroFunc() override;
|
||||||
|
|
||||||
int IsPure() const override;
|
int IsPure() const override;
|
||||||
IntrusivePtr<Val> Call(val_list* args, Frame* parent) const override;
|
IntrusivePtr<Val> Call(const zeek::Args& args, Frame* parent) const override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds adds a closure to the function. Closures are cloned and
|
* Adds adds a closure to the function. Closures are cloned and
|
||||||
|
@ -169,7 +171,7 @@ private:
|
||||||
bool weak_closure_ref = false;
|
bool weak_closure_ref = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef Val* (*built_in_func)(Frame* frame, val_list* args);
|
using built_in_func = Val* (*)(Frame* frame, const zeek::Args* args);
|
||||||
|
|
||||||
class BuiltinFunc : public Func {
|
class BuiltinFunc : public Func {
|
||||||
public:
|
public:
|
||||||
|
@ -177,7 +179,7 @@ public:
|
||||||
~BuiltinFunc() override;
|
~BuiltinFunc() override;
|
||||||
|
|
||||||
int IsPure() const override;
|
int IsPure() const override;
|
||||||
IntrusivePtr<Val> Call(val_list* args, Frame* parent) const override;
|
IntrusivePtr<Val> Call(const zeek::Args& args, Frame* parent) const override;
|
||||||
built_in_func TheFunc() const { return func; }
|
built_in_func TheFunc() const { return func; }
|
||||||
|
|
||||||
void Describe(ODesc* d) const override;
|
void Describe(ODesc* d) const override;
|
||||||
|
@ -190,7 +192,9 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
extern void builtin_error(const char* msg, BroObj* arg = 0);
|
extern void builtin_error(const char* msg);
|
||||||
|
extern void builtin_error(const char* msg, IntrusivePtr<Val>);
|
||||||
|
extern void builtin_error(const char* msg, BroObj* arg);
|
||||||
extern void init_builtin_funcs();
|
extern void init_builtin_funcs();
|
||||||
extern void init_builtin_funcs_subdirs();
|
extern void init_builtin_funcs_subdirs();
|
||||||
|
|
||||||
|
@ -199,7 +203,7 @@ extern bool check_built_in_call(BuiltinFunc* f, CallExpr* call);
|
||||||
struct CallInfo {
|
struct CallInfo {
|
||||||
const CallExpr* call;
|
const CallExpr* call;
|
||||||
const Func* func;
|
const Func* func;
|
||||||
const val_list* args;
|
const zeek::Args& args;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Struct that collects all the specifics defining a Func. Used for BroFuncs
|
// Struct that collects all the specifics defining a Func. Used for BroFuncs
|
||||||
|
|
|
@ -221,6 +221,26 @@ MD5Val::~MD5Val()
|
||||||
EVP_MD_CTX_free(ctx);
|
EVP_MD_CTX_free(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HashVal::digest_one(EVP_MD_CTX* h, const Val* v)
|
||||||
|
{
|
||||||
|
if ( v->Type()->Tag() == TYPE_STRING )
|
||||||
|
{
|
||||||
|
const BroString* str = v->AsString();
|
||||||
|
hash_update(h, str->Bytes(), str->Len());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ODesc d(DESC_BINARY);
|
||||||
|
v->Describe(&d);
|
||||||
|
hash_update(h, (const u_char *) d.Bytes(), d.Len());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HashVal::digest_one(EVP_MD_CTX* h, const IntrusivePtr<Val>& v)
|
||||||
|
{
|
||||||
|
digest_one(h, v.get());
|
||||||
|
}
|
||||||
|
|
||||||
IntrusivePtr<Val> MD5Val::DoClone(CloneState* state)
|
IntrusivePtr<Val> MD5Val::DoClone(CloneState* state)
|
||||||
{
|
{
|
||||||
auto out = make_intrusive<MD5Val>();
|
auto out = make_intrusive<MD5Val>();
|
||||||
|
@ -236,39 +256,6 @@ IntrusivePtr<Val> MD5Val::DoClone(CloneState* state)
|
||||||
return state->NewClone(this, std::move(out));
|
return state->NewClone(this, std::move(out));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MD5Val::digest(val_list& vlist, u_char result[MD5_DIGEST_LENGTH])
|
|
||||||
{
|
|
||||||
EVP_MD_CTX* h = hash_init(Hash_MD5);
|
|
||||||
|
|
||||||
for ( const auto& v : vlist )
|
|
||||||
{
|
|
||||||
if ( v->Type()->Tag() == TYPE_STRING )
|
|
||||||
{
|
|
||||||
const BroString* str = v->AsString();
|
|
||||||
hash_update(h, str->Bytes(), str->Len());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ODesc d(DESC_BINARY);
|
|
||||||
v->Describe(&d);
|
|
||||||
hash_update(h, (const u_char *) d.Bytes(), d.Len());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hash_final(h, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MD5Val::hmac(val_list& vlist,
|
|
||||||
u_char key[MD5_DIGEST_LENGTH],
|
|
||||||
u_char result[MD5_DIGEST_LENGTH])
|
|
||||||
{
|
|
||||||
digest(vlist, result);
|
|
||||||
for ( int i = 0; i < MD5_DIGEST_LENGTH; ++i )
|
|
||||||
result[i] ^= key[i];
|
|
||||||
|
|
||||||
internal_md5(result, MD5_DIGEST_LENGTH, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MD5Val::DoInit()
|
bool MD5Val::DoInit()
|
||||||
{
|
{
|
||||||
assert(! IsValid());
|
assert(! IsValid());
|
||||||
|
@ -389,28 +376,6 @@ IntrusivePtr<Val> SHA1Val::DoClone(CloneState* state)
|
||||||
return state->NewClone(this, std::move(out));
|
return state->NewClone(this, std::move(out));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHA1Val::digest(val_list& vlist, u_char result[SHA_DIGEST_LENGTH])
|
|
||||||
{
|
|
||||||
EVP_MD_CTX* h = hash_init(Hash_SHA1);
|
|
||||||
|
|
||||||
for ( const auto& v : vlist )
|
|
||||||
{
|
|
||||||
if ( v->Type()->Tag() == TYPE_STRING )
|
|
||||||
{
|
|
||||||
const BroString* str = v->AsString();
|
|
||||||
hash_update(h, str->Bytes(), str->Len());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ODesc d(DESC_BINARY);
|
|
||||||
v->Describe(&d);
|
|
||||||
hash_update(h, (const u_char *) d.Bytes(), d.Len());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hash_final(h, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SHA1Val::DoInit()
|
bool SHA1Val::DoInit()
|
||||||
{
|
{
|
||||||
assert(! IsValid());
|
assert(! IsValid());
|
||||||
|
@ -535,28 +500,6 @@ IntrusivePtr<Val> SHA256Val::DoClone(CloneState* state)
|
||||||
return state->NewClone(this, std::move(out));
|
return state->NewClone(this, std::move(out));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHA256Val::digest(val_list& vlist, u_char result[SHA256_DIGEST_LENGTH])
|
|
||||||
{
|
|
||||||
EVP_MD_CTX* h = hash_init(Hash_SHA256);
|
|
||||||
|
|
||||||
for ( const auto& v : vlist )
|
|
||||||
{
|
|
||||||
if ( v->Type()->Tag() == TYPE_STRING )
|
|
||||||
{
|
|
||||||
const BroString* str = v->AsString();
|
|
||||||
hash_update(h, str->Bytes(), str->Len());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ODesc d(DESC_BINARY);
|
|
||||||
v->Describe(&d);
|
|
||||||
hash_update(h, (const u_char *) d.Bytes(), d.Len());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hash_final(h, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SHA256Val::DoInit()
|
bool SHA256Val::DoInit()
|
||||||
{
|
{
|
||||||
assert( ! IsValid() );
|
assert( ! IsValid() );
|
||||||
|
|
|
@ -162,12 +162,26 @@ namespace probabilistic {
|
||||||
|
|
||||||
class HashVal : public OpaqueVal {
|
class HashVal : public OpaqueVal {
|
||||||
public:
|
public:
|
||||||
|
template <class T>
|
||||||
|
static void digest_all(HashAlgorithm alg, const T& vlist, u_char* result)
|
||||||
|
{
|
||||||
|
auto h = hash_init(alg);
|
||||||
|
|
||||||
|
for ( const auto& v : vlist )
|
||||||
|
digest_one(h, v);
|
||||||
|
|
||||||
|
hash_final(h, result);
|
||||||
|
}
|
||||||
|
|
||||||
bool IsValid() const;
|
bool IsValid() const;
|
||||||
bool Init();
|
bool Init();
|
||||||
bool Feed(const void* data, size_t size);
|
bool Feed(const void* data, size_t size);
|
||||||
IntrusivePtr<StringVal> Get();
|
IntrusivePtr<StringVal> Get();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
static void digest_one(EVP_MD_CTX* h, const Val* v);
|
||||||
|
static void digest_one(EVP_MD_CTX* h, const IntrusivePtr<Val>& v);
|
||||||
|
|
||||||
HashVal() { valid = false; }
|
HashVal() { valid = false; }
|
||||||
explicit HashVal(OpaqueType* t);
|
explicit HashVal(OpaqueType* t);
|
||||||
|
|
||||||
|
@ -182,11 +196,22 @@ private:
|
||||||
|
|
||||||
class MD5Val : public HashVal {
|
class MD5Val : public HashVal {
|
||||||
public:
|
public:
|
||||||
static void digest(val_list& vlist, u_char result[MD5_DIGEST_LENGTH]);
|
template <class T>
|
||||||
|
static void digest(const T& vlist, u_char result[MD5_DIGEST_LENGTH])
|
||||||
|
{ digest_all(Hash_MD5, vlist, result); }
|
||||||
|
|
||||||
static void hmac(val_list& vlist,
|
template <class T>
|
||||||
u_char key[MD5_DIGEST_LENGTH],
|
static void hmac(const T& vlist,
|
||||||
u_char result[MD5_DIGEST_LENGTH]);
|
u_char key[MD5_DIGEST_LENGTH],
|
||||||
|
u_char result[MD5_DIGEST_LENGTH])
|
||||||
|
{
|
||||||
|
digest(vlist, result);
|
||||||
|
|
||||||
|
for ( int i = 0; i < MD5_DIGEST_LENGTH; ++i )
|
||||||
|
result[i] ^= key[i];
|
||||||
|
|
||||||
|
internal_md5(result, MD5_DIGEST_LENGTH, result);
|
||||||
|
}
|
||||||
|
|
||||||
MD5Val();
|
MD5Val();
|
||||||
~MD5Val();
|
~MD5Val();
|
||||||
|
@ -207,7 +232,9 @@ private:
|
||||||
|
|
||||||
class SHA1Val : public HashVal {
|
class SHA1Val : public HashVal {
|
||||||
public:
|
public:
|
||||||
static void digest(val_list& vlist, u_char result[SHA_DIGEST_LENGTH]);
|
template <class T>
|
||||||
|
static void digest(const T& vlist, u_char result[SHA_DIGEST_LENGTH])
|
||||||
|
{ digest_all(Hash_SHA1, vlist, result); }
|
||||||
|
|
||||||
SHA1Val();
|
SHA1Val();
|
||||||
~SHA1Val();
|
~SHA1Val();
|
||||||
|
@ -228,7 +255,9 @@ private:
|
||||||
|
|
||||||
class SHA256Val : public HashVal {
|
class SHA256Val : public HashVal {
|
||||||
public:
|
public:
|
||||||
static void digest(val_list& vlist, u_char result[SHA256_DIGEST_LENGTH]);
|
template <class T>
|
||||||
|
static void digest(const T& vlist, u_char result[SHA256_DIGEST_LENGTH])
|
||||||
|
{ digest_all(Hash_SHA256, vlist, result); }
|
||||||
|
|
||||||
SHA256Val();
|
SHA256Val();
|
||||||
~SHA256Val();
|
~SHA256Val();
|
||||||
|
|
|
@ -314,8 +314,8 @@ void ProfileLogger::Log()
|
||||||
{
|
{
|
||||||
Ref(file);
|
Ref(file);
|
||||||
mgr.Dispatch(new Event(profiling_update, {
|
mgr.Dispatch(new Event(profiling_update, {
|
||||||
new Val(file),
|
make_intrusive<Val>(file),
|
||||||
val_mgr->GetBool(expensive),
|
{AdoptRef{}, val_mgr->GetBool(expensive)},
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
40
src/Stmt.cc
40
src/Stmt.cc
|
@ -151,15 +151,12 @@ IntrusivePtr<Val> ExprListStmt::Exec(Frame* f, stmt_flow_type& flow) const
|
||||||
last_access = network_time;
|
last_access = network_time;
|
||||||
flow = FLOW_NEXT;
|
flow = FLOW_NEXT;
|
||||||
|
|
||||||
val_list* vals = eval_list(f, l.get());
|
auto vals = eval_list(f, l.get());
|
||||||
|
|
||||||
if ( vals )
|
if ( vals )
|
||||||
{
|
return DoExec(std::move(*vals), flow);
|
||||||
auto result = DoExec(vals, flow);
|
|
||||||
delete_vals(vals);
|
return nullptr;
|
||||||
return result;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprListStmt::Describe(ODesc* d) const
|
void ExprListStmt::Describe(ODesc* d) const
|
||||||
|
@ -169,11 +166,6 @@ void ExprListStmt::Describe(ODesc* d) const
|
||||||
DescribeDone(d);
|
DescribeDone(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprListStmt::PrintVals(ODesc* d, val_list* vals, int offset) const
|
|
||||||
{
|
|
||||||
describe_vals(vals, d, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
TraversalCode ExprListStmt::Traverse(TraversalCallback* cb) const
|
TraversalCode ExprListStmt::Traverse(TraversalCallback* cb) const
|
||||||
{
|
{
|
||||||
TraversalCode tc = cb->PreStmt(this);
|
TraversalCode tc = cb->PreStmt(this);
|
||||||
|
@ -206,13 +198,13 @@ static IntrusivePtr<EnumVal> lookup_enum_val(const char* module_name, const char
|
||||||
return et->GetVal(index);
|
return et->GetVal(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_log(val_list* vals)
|
static void print_log(const std::vector<IntrusivePtr<Val>>& vals)
|
||||||
{
|
{
|
||||||
auto plval = lookup_enum_val("Log", "PRINTLOG");
|
auto plval = lookup_enum_val("Log", "PRINTLOG");
|
||||||
auto record = make_intrusive<RecordVal>(internal_type("Log::PrintLogInfo")->AsRecordType());
|
auto record = make_intrusive<RecordVal>(internal_type("Log::PrintLogInfo")->AsRecordType());
|
||||||
auto vec = make_intrusive<VectorVal>(internal_type("string_vec")->AsVectorType());
|
auto vec = make_intrusive<VectorVal>(internal_type("string_vec")->AsVectorType());
|
||||||
|
|
||||||
for ( const auto& val : *vals )
|
for ( const auto& val : vals )
|
||||||
{
|
{
|
||||||
ODesc d(DESC_READABLE);
|
ODesc d(DESC_READABLE);
|
||||||
val->Describe(&d);
|
val->Describe(&d);
|
||||||
|
@ -224,7 +216,8 @@ static void print_log(val_list* vals)
|
||||||
log_mgr->Write(plval.get(), record.get());
|
log_mgr->Write(plval.get(), record.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
IntrusivePtr<Val> PrintStmt::DoExec(val_list* vals, stmt_flow_type& /* flow */) const
|
IntrusivePtr<Val> PrintStmt::DoExec(std::vector<IntrusivePtr<Val>> vals,
|
||||||
|
stmt_flow_type& /* flow */) const
|
||||||
{
|
{
|
||||||
RegisterAccess();
|
RegisterAccess();
|
||||||
|
|
||||||
|
@ -234,9 +227,9 @@ IntrusivePtr<Val> PrintStmt::DoExec(val_list* vals, stmt_flow_type& /* flow */)
|
||||||
BroFile* f = print_stdout;
|
BroFile* f = print_stdout;
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
|
||||||
if ( vals->length() > 0 && (*vals)[0]->Type()->Tag() == TYPE_FILE )
|
if ( vals.size() > 0 && (vals)[0]->Type()->Tag() == TYPE_FILE )
|
||||||
{
|
{
|
||||||
f = (*vals)[0]->AsFile();
|
f = (vals)[0]->AsFile();
|
||||||
if ( ! f->IsOpen() )
|
if ( ! f->IsOpen() )
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
@ -277,7 +270,7 @@ IntrusivePtr<Val> PrintStmt::DoExec(val_list* vals, stmt_flow_type& /* flow */)
|
||||||
d.SetFlush(0);
|
d.SetFlush(0);
|
||||||
d.SetStyle(style);
|
d.SetStyle(style);
|
||||||
|
|
||||||
PrintVals(&d, vals, offset);
|
describe_vals(vals, &d, offset);
|
||||||
f->Write(d.Description(), d.Len());
|
f->Write(d.Description(), d.Len());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -286,7 +279,7 @@ IntrusivePtr<Val> PrintStmt::DoExec(val_list* vals, stmt_flow_type& /* flow */)
|
||||||
d.SetFlush(0);
|
d.SetFlush(0);
|
||||||
d.SetStyle(style);
|
d.SetStyle(style);
|
||||||
|
|
||||||
PrintVals(&d, vals, offset);
|
describe_vals(vals, &d, offset);
|
||||||
f->Write("\n", 1);
|
f->Write("\n", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -966,13 +959,10 @@ EventStmt::EventStmt(IntrusivePtr<EventExpr> arg_e)
|
||||||
IntrusivePtr<Val> EventStmt::Exec(Frame* f, stmt_flow_type& flow) const
|
IntrusivePtr<Val> EventStmt::Exec(Frame* f, stmt_flow_type& flow) const
|
||||||
{
|
{
|
||||||
RegisterAccess();
|
RegisterAccess();
|
||||||
val_list* args = eval_list(f, event_expr->Args());
|
auto args = eval_list(f, event_expr->Args());
|
||||||
|
|
||||||
if ( args )
|
if ( args )
|
||||||
{
|
mgr.QueueUncheckedEvent(event_expr->Handler(), std::move(*args));
|
||||||
mgr.QueueEvent(event_expr->Handler(), std::move(*args));
|
|
||||||
delete args;
|
|
||||||
}
|
|
||||||
|
|
||||||
flow = FLOW_NEXT;
|
flow = FLOW_NEXT;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -95,10 +95,10 @@ protected:
|
||||||
~ExprListStmt() override;
|
~ExprListStmt() override;
|
||||||
|
|
||||||
IntrusivePtr<Val> Exec(Frame* f, stmt_flow_type& flow) const override;
|
IntrusivePtr<Val> Exec(Frame* f, stmt_flow_type& flow) const override;
|
||||||
virtual IntrusivePtr<Val> DoExec(val_list* vals, stmt_flow_type& flow) const = 0;
|
virtual IntrusivePtr<Val> DoExec(std::vector<IntrusivePtr<Val>> vals,
|
||||||
|
stmt_flow_type& flow) const = 0;
|
||||||
|
|
||||||
void Describe(ODesc* d) const override;
|
void Describe(ODesc* d) const override;
|
||||||
void PrintVals(ODesc* d, val_list* vals, int offset) const;
|
|
||||||
|
|
||||||
IntrusivePtr<ListExpr> l;
|
IntrusivePtr<ListExpr> l;
|
||||||
};
|
};
|
||||||
|
@ -109,7 +109,8 @@ public:
|
||||||
explicit PrintStmt(L&& l) : ExprListStmt(STMT_PRINT, std::forward<L>(l)) { }
|
explicit PrintStmt(L&& l) : ExprListStmt(STMT_PRINT, std::forward<L>(l)) { }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
IntrusivePtr<Val> DoExec(val_list* vals, stmt_flow_type& flow) const override;
|
IntrusivePtr<Val> DoExec(std::vector<IntrusivePtr<Val>> vals,
|
||||||
|
stmt_flow_type& flow) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ExprStmt : public Stmt {
|
class ExprStmt : public Stmt {
|
||||||
|
|
18
src/Val.cc
18
src/Val.cc
|
@ -3292,6 +3292,24 @@ void describe_vals(const val_list* vals, ODesc* d, int offset)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void describe_vals(const std::vector<IntrusivePtr<Val>>& vals,
|
||||||
|
ODesc* d, size_t offset)
|
||||||
|
{
|
||||||
|
if ( ! d->IsReadable() )
|
||||||
|
{
|
||||||
|
d->Add(vals.size());
|
||||||
|
d->SP();
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( auto i = offset; i < vals.size(); ++i )
|
||||||
|
{
|
||||||
|
if ( i > offset && d->IsReadable() && d->Style() != RAW_STYLE )
|
||||||
|
d->Add(", ");
|
||||||
|
|
||||||
|
vals[i]->Describe(d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void delete_vals(val_list* vals)
|
void delete_vals(val_list* vals)
|
||||||
{
|
{
|
||||||
if ( vals )
|
if ( vals )
|
||||||
|
|
|
@ -1042,6 +1042,8 @@ extern int same_val(const Val* v1, const Val* v2);
|
||||||
extern int same_atomic_val(const Val* v1, const Val* v2);
|
extern int same_atomic_val(const Val* v1, const Val* v2);
|
||||||
extern bool is_atomic_val(const Val* v);
|
extern bool is_atomic_val(const Val* v);
|
||||||
extern void describe_vals(const val_list* vals, ODesc* d, int offset=0);
|
extern void describe_vals(const val_list* vals, ODesc* d, int offset=0);
|
||||||
|
extern void describe_vals(const std::vector<IntrusivePtr<Val>>& vals,
|
||||||
|
ODesc* d, size_t offset = 0);
|
||||||
extern void delete_vals(val_list* vals);
|
extern void delete_vals(val_list* vals);
|
||||||
|
|
||||||
// True if the given Val* has a vector type.
|
// True if the given Val* has a vector type.
|
||||||
|
|
15
src/ZeekArgs.cc
Normal file
15
src/ZeekArgs.cc
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#include "ZeekArgs.h"
|
||||||
|
#include "IntrusivePtr.h"
|
||||||
|
#include "Val.h"
|
||||||
|
|
||||||
|
zeek::Args zeek::val_list_to_args(const val_list* vl)
|
||||||
|
{
|
||||||
|
zeek::Args rval;
|
||||||
|
rval.reserve(vl->length());
|
||||||
|
|
||||||
|
for ( auto& v : *vl )
|
||||||
|
rval.emplace_back(AdoptRef{}, v);
|
||||||
|
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
27
src/ZeekArgs.h
Normal file
27
src/ZeekArgs.h
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
// See the file "COPYING" in the main distribution directory for copyright.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "BroList.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class Val;
|
||||||
|
template <class T> class IntrusivePtr;
|
||||||
|
|
||||||
|
namespace zeek {
|
||||||
|
|
||||||
|
using Args = std::vector<IntrusivePtr<Val>>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a legacy-style argument list for use in modern Zeek function
|
||||||
|
* calling or event queueing APIs.
|
||||||
|
* @param vl the argument list to convert, the returned value takes ownership
|
||||||
|
* of a reference to each element in the list, but not ownership of the list
|
||||||
|
* itself.
|
||||||
|
* @return the converted argument list
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Args val_list_to_args(const val_list* vl);
|
||||||
|
|
||||||
|
} // namespace zeek
|
|
@ -83,7 +83,13 @@ type Broker::Event: record;
|
||||||
function Broker::make_event%(...%): Broker::Event
|
function Broker::make_event%(...%): Broker::Event
|
||||||
%{
|
%{
|
||||||
bro_broker::Manager::ScriptScopeGuard ssg;
|
bro_broker::Manager::ScriptScopeGuard ssg;
|
||||||
auto rval = broker_mgr->MakeEvent(@ARGS@, frame);
|
const auto& bif_args = @ARGS@;
|
||||||
|
val_list args(bif_args->size());
|
||||||
|
|
||||||
|
for ( auto i = 0u; i < bif_args->size(); ++i )
|
||||||
|
args.push_back((*bif_args)[i].get());
|
||||||
|
|
||||||
|
auto rval = broker_mgr->MakeEvent(&args, frame);
|
||||||
return rval;
|
return rval;
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
@ -98,11 +104,11 @@ function Broker::make_event%(...%): Broker::Event
|
||||||
## Returns: true if the message is sent.
|
## Returns: true if the message is sent.
|
||||||
function Broker::publish%(topic: string, ...%): bool
|
function Broker::publish%(topic: string, ...%): bool
|
||||||
%{
|
%{
|
||||||
val_list* bif_args = @ARGS@;
|
const auto& bif_args = @ARGS@;
|
||||||
val_list args(bif_args->length() - 1);
|
val_list args(bif_args->size() - 1);
|
||||||
|
|
||||||
for ( auto i = 1; i < bif_args->length(); ++i )
|
for ( auto i = 1u; i < bif_args->size(); ++i )
|
||||||
args.push_back((*bif_args)[i]);
|
args.push_back((*bif_args)[i].get());
|
||||||
|
|
||||||
auto rval = publish_event_args(args, topic->AsString(), frame);
|
auto rval = publish_event_args(args, topic->AsString(), frame);
|
||||||
return val_mgr->GetBool(rval);
|
return val_mgr->GetBool(rval);
|
||||||
|
@ -188,11 +194,11 @@ function Cluster::publish_rr%(pool: Pool, key: string, ...%): bool
|
||||||
if ( ! topic->AsString()->Len() )
|
if ( ! topic->AsString()->Len() )
|
||||||
return val_mgr->GetFalse();
|
return val_mgr->GetFalse();
|
||||||
|
|
||||||
val_list* bif_args = @ARGS@;
|
const auto& bif_args = @ARGS@;
|
||||||
val_list args(bif_args->length() - 2);
|
val_list args(bif_args->size() - 2);
|
||||||
|
|
||||||
for ( auto i = 2; i < bif_args->length(); ++i )
|
for ( auto i = 2u; i < bif_args->size(); ++i )
|
||||||
args.push_back((*bif_args)[i]);
|
args.push_back((*bif_args)[i].get());
|
||||||
|
|
||||||
auto rval = publish_event_args(args, topic->AsString(), frame);
|
auto rval = publish_event_args(args, topic->AsString(), frame);
|
||||||
return val_mgr->GetBool(rval);
|
return val_mgr->GetBool(rval);
|
||||||
|
@ -225,11 +231,11 @@ function Cluster::publish_hrw%(pool: Pool, key: any, ...%): bool
|
||||||
if ( ! topic->AsString()->Len() )
|
if ( ! topic->AsString()->Len() )
|
||||||
return val_mgr->GetFalse();
|
return val_mgr->GetFalse();
|
||||||
|
|
||||||
val_list* bif_args = @ARGS@;
|
const auto& bif_args = @ARGS@;
|
||||||
val_list args(bif_args->length() - 2);
|
val_list args(bif_args->size() - 2);
|
||||||
|
|
||||||
for ( auto i = 2; i < bif_args->length(); ++i )
|
for ( auto i = 2u; i < bif_args->size(); ++i )
|
||||||
args.push_back((*bif_args)[i]);
|
args.push_back((*bif_args)[i].get());
|
||||||
|
|
||||||
auto rval = publish_event_args(args, topic->AsString(), frame);
|
auto rval = publish_event_args(args, topic->AsString(), frame);
|
||||||
return val_mgr->GetBool(rval);
|
return val_mgr->GetBool(rval);
|
||||||
|
|
|
@ -218,7 +218,7 @@ void done_with_network()
|
||||||
mgr.Drain();
|
mgr.Drain();
|
||||||
// Don't propagate this event to remote clients.
|
// Don't propagate this event to remote clients.
|
||||||
mgr.Dispatch(new Event(net_done,
|
mgr.Dispatch(new Event(net_done,
|
||||||
{new Val(timer_mgr->Time(), TYPE_TIME)}),
|
{make_intrusive<Val>(timer_mgr->Time(), TYPE_TIME)}),
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
// See the file "COPYING" in the main distribution directory for copyright.
|
// See the file "COPYING" in the main distribution directory for copyright.
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
@ -619,15 +620,21 @@ int Manager::HookLoadFile(const Plugin::LoadType type, const string& file, const
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<bool, Val*> Manager::HookCallFunction(const Func* func, Frame* parent, val_list* vargs) const
|
std::pair<bool, Val*> Manager::HookCallFunction(const Func* func, Frame* parent, const zeek::Args& vecargs) const
|
||||||
{
|
{
|
||||||
HookArgumentList args;
|
HookArgumentList args;
|
||||||
|
std::optional<val_list> vargs;
|
||||||
|
|
||||||
if ( HavePluginForHook(META_HOOK_PRE) )
|
if ( HavePluginForHook(META_HOOK_PRE) )
|
||||||
{
|
{
|
||||||
|
vargs = val_list(vecargs.size());
|
||||||
|
|
||||||
|
for ( const auto& v : vecargs )
|
||||||
|
vargs->push_back(v.get());
|
||||||
|
|
||||||
args.push_back(HookArgument(func));
|
args.push_back(HookArgument(func));
|
||||||
args.push_back(HookArgument(parent));
|
args.push_back(HookArgument(parent));
|
||||||
args.push_back(HookArgument(vargs));
|
args.push_back(HookArgument(&vargs.value()));
|
||||||
MetaHookPre(HOOK_CALL_FUNCTION, args);
|
MetaHookPre(HOOK_CALL_FUNCTION, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -637,11 +644,19 @@ std::pair<bool, Val*> Manager::HookCallFunction(const Func* func, Frame* parent,
|
||||||
|
|
||||||
if ( l )
|
if ( l )
|
||||||
{
|
{
|
||||||
|
if ( ! vargs )
|
||||||
|
{
|
||||||
|
vargs = val_list(vecargs.size());
|
||||||
|
|
||||||
|
for ( const auto& v : vecargs )
|
||||||
|
vargs->push_back(v.get());
|
||||||
|
}
|
||||||
|
|
||||||
for ( hook_list::iterator i = l->begin(); i != l->end(); ++i )
|
for ( hook_list::iterator i = l->begin(); i != l->end(); ++i )
|
||||||
{
|
{
|
||||||
Plugin* p = (*i).second;
|
Plugin* p = (*i).second;
|
||||||
|
|
||||||
v = p->HookCallFunction(func, parent, vargs);
|
v = p->HookCallFunction(func, parent, &vargs.value());
|
||||||
|
|
||||||
if ( v.first )
|
if ( v.first )
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -6,11 +6,11 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
|
||||||
|
|
||||||
#include "Plugin.h"
|
#include "Plugin.h"
|
||||||
#include "Component.h"
|
#include "Component.h"
|
||||||
|
|
||||||
#include "../Reporter.h"
|
#include "../Reporter.h"
|
||||||
|
#include "../ZeekArgs.h"
|
||||||
|
|
||||||
namespace plugin {
|
namespace plugin {
|
||||||
|
|
||||||
|
@ -253,7 +253,7 @@ public:
|
||||||
* functions and events, it may be any Val and must be ignored). If no
|
* functions and events, it may be any Val and must be ignored). If no
|
||||||
* plugin handled the call, the method returns null.
|
* plugin handled the call, the method returns null.
|
||||||
*/
|
*/
|
||||||
std::pair<bool, Val*> HookCallFunction(const Func* func, Frame *parent, val_list* args) const;
|
std::pair<bool, Val*> HookCallFunction(const Func* func, Frame* parent, const zeek::Args& args) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook that filters the queuing of an event.
|
* Hook that filters the queuing of an event.
|
||||||
|
|
|
@ -19,6 +19,7 @@ class ODesc;
|
||||||
class Frame;
|
class Frame;
|
||||||
class Func;
|
class Func;
|
||||||
class Event;
|
class Event;
|
||||||
|
template <class T> class IntrusivePtr;
|
||||||
|
|
||||||
namespace threading {
|
namespace threading {
|
||||||
struct Field;
|
struct Field;
|
||||||
|
|
30
src/zeek.bif
30
src/zeek.bif
|
@ -267,7 +267,7 @@ static void do_fmt(const char*& fmt, Val* v, ODesc* d)
|
||||||
++fmt;
|
++fmt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int next_fmt(const char*& fmt, val_list* args, ODesc* d, int& n)
|
static int next_fmt(const char*& fmt, const zeek::Args* args, ODesc* d, int& n)
|
||||||
{
|
{
|
||||||
const char* fp = fmt;
|
const char* fp = fmt;
|
||||||
|
|
||||||
|
@ -290,10 +290,10 @@ static int next_fmt(const char*& fmt, val_list* args, ODesc* d, int& n)
|
||||||
return next_fmt(fmt, args, d, n);
|
return next_fmt(fmt, args, d, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ++n >= args->length() )
|
if ( ++n >= static_cast<int>(args->size()) )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
do_fmt(fmt, (*args)[n], d);
|
do_fmt(fmt, (*args)[n].get(), d);
|
||||||
|
|
||||||
return *fmt != '\0';
|
return *fmt != '\0';
|
||||||
}
|
}
|
||||||
|
@ -1413,12 +1413,12 @@ function sort%(v: any, ...%) : any
|
||||||
BroType* elt_type = v->Type()->YieldType();
|
BroType* elt_type = v->Type()->YieldType();
|
||||||
Func* comp = 0;
|
Func* comp = 0;
|
||||||
|
|
||||||
if ( @ARG@.length() > 2 )
|
if ( @ARG@.size() > 2 )
|
||||||
builtin_error("sort() called with extraneous argument");
|
builtin_error("sort() called with extraneous argument");
|
||||||
|
|
||||||
if ( @ARG@.length() == 2 )
|
if ( @ARG@.size() == 2 )
|
||||||
{
|
{
|
||||||
Val* comp_val = @ARG@[1];
|
Val* comp_val = @ARG@[1].get();
|
||||||
if ( ! IsFunc(comp_val->Type()->Tag()) )
|
if ( ! IsFunc(comp_val->Type()->Tag()) )
|
||||||
{
|
{
|
||||||
builtin_error("second argument to sort() needs to be comparison function");
|
builtin_error("second argument to sort() needs to be comparison function");
|
||||||
|
@ -1483,12 +1483,12 @@ function order%(v: any, ...%) : index_vec
|
||||||
BroType* elt_type = v->Type()->YieldType();
|
BroType* elt_type = v->Type()->YieldType();
|
||||||
Func* comp = 0;
|
Func* comp = 0;
|
||||||
|
|
||||||
if ( @ARG@.length() > 2 )
|
if ( @ARG@.size() > 2 )
|
||||||
builtin_error("order() called with extraneous argument");
|
builtin_error("order() called with extraneous argument");
|
||||||
|
|
||||||
if ( @ARG@.length() == 2 )
|
if ( @ARG@.size() == 2 )
|
||||||
{
|
{
|
||||||
Val* comp_val = @ARG@[1];
|
Val* comp_val = @ARG@[1].get();
|
||||||
if ( ! IsFunc(comp_val->Type()->Tag()) )
|
if ( ! IsFunc(comp_val->Type()->Tag()) )
|
||||||
{
|
{
|
||||||
builtin_error("second argument to order() needs to be comparison function");
|
builtin_error("second argument to order() needs to be comparison function");
|
||||||
|
@ -1595,7 +1595,7 @@ function cat_sep%(sep: string, def: string, ...%): string
|
||||||
|
|
||||||
int pre_size = 0;
|
int pre_size = 0;
|
||||||
|
|
||||||
loop_over_list(@ARG@, i)
|
for ( auto i = 0u; i < @ARG@.size(); ++i )
|
||||||
{
|
{
|
||||||
// Skip named parameters.
|
// Skip named parameters.
|
||||||
if ( i < 2 )
|
if ( i < 2 )
|
||||||
|
@ -1604,7 +1604,7 @@ function cat_sep%(sep: string, def: string, ...%): string
|
||||||
if ( i > 2 )
|
if ( i > 2 )
|
||||||
d.Add(sep->CheckString(), 0);
|
d.Add(sep->CheckString(), 0);
|
||||||
|
|
||||||
Val* v = @ARG@[i];
|
Val* v = @ARG@[i].get();
|
||||||
if ( v->Type()->Tag() == TYPE_STRING && ! v->AsString()->Len() )
|
if ( v->Type()->Tag() == TYPE_STRING && ! v->AsString()->Len() )
|
||||||
v = def;
|
v = def;
|
||||||
|
|
||||||
|
@ -1660,7 +1660,7 @@ function fmt%(...%): string
|
||||||
if ( @ARGC@ == 0 )
|
if ( @ARGC@ == 0 )
|
||||||
return val_mgr->GetEmptyString();
|
return val_mgr->GetEmptyString();
|
||||||
|
|
||||||
Val* fmt_v = @ARG@[0];
|
Val* fmt_v = @ARG@[0].get();
|
||||||
|
|
||||||
// Type of fmt_v will be string here, check_built_in_call() in Func.cc
|
// Type of fmt_v will be string here, check_built_in_call() in Func.cc
|
||||||
// checks that.
|
// checks that.
|
||||||
|
@ -1674,13 +1674,13 @@ function fmt%(...%): string
|
||||||
while ( next_fmt(fmt, @ARGS@, &d, n) )
|
while ( next_fmt(fmt, @ARGS@, &d, n) )
|
||||||
;
|
;
|
||||||
|
|
||||||
if ( n < @ARGC@ - 1 )
|
if ( n < static_cast<int>(@ARGC@) - 1 )
|
||||||
{
|
{
|
||||||
builtin_error("too many arguments for format", fmt_v);
|
builtin_error("too many arguments for format", fmt_v);
|
||||||
return val_mgr->GetEmptyString();
|
return val_mgr->GetEmptyString();
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ( n >= @ARGC@ )
|
else if ( n >= static_cast<int>(@ARGC@) )
|
||||||
{
|
{
|
||||||
builtin_error("too few arguments for format", fmt_v);
|
builtin_error("too few arguments for format", fmt_v);
|
||||||
return val_mgr->GetEmptyString();
|
return val_mgr->GetEmptyString();
|
||||||
|
@ -1703,7 +1703,7 @@ function print_raw%(...%): bool
|
||||||
%{
|
%{
|
||||||
ODesc d(DESC_READABLE);
|
ODesc d(DESC_READABLE);
|
||||||
d.SetStyle(RAW_STYLE);
|
d.SetStyle(RAW_STYLE);
|
||||||
describe_vals(&@ARG@, &d, 0);
|
describe_vals(@ARG@, &d, 0);
|
||||||
printf("%.*s", d.Len(), d.Description());
|
printf("%.*s", d.Len(), d.Description());
|
||||||
return val_mgr->GetBool(true);
|
return val_mgr->GetBool(true);
|
||||||
%}
|
%}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue