Deprecate Func::Call(val_list*, ...)

The version taking a vector of intrusive pointers should be used
instead.  A variadic version is also added that forwards all arguments.
This commit is contained in:
Jon Siwek 2020-03-24 20:38:26 -07:00
parent 4e1ac4e124
commit b667c637df
12 changed files with 114 additions and 90 deletions

5
NEWS
View file

@ -47,6 +47,11 @@ Removed Functionality
Deprecated Functionality
------------------------
- The ``Func::Call(val_list*, ...)`` method is now deprecated. The alternate
overload taking a ``zeek::Args`` (``std::vector<IntrusivePtr<Val>>``) should
be used instead. There's also now a variadic template that forwards all
arguments.
Zeek 3.1.0
==========

View file

@ -39,11 +39,11 @@ int Discarder::NextPacket(const IP_Hdr* ip, int len, int caplen)
if ( check_ip )
{
val_list args{ip->BuildPktHdrVal()};
zeek::Args args{{AdoptRef{}, ip->BuildPktHdrVal()}};
try
{
discard_packet = check_ip->Call(&args)->AsBool();
discard_packet = check_ip->Call(args)->AsBool();
}
catch ( InterpreterException& e )
@ -91,14 +91,14 @@ int Discarder::NextPacket(const IP_Hdr* ip, int len, int caplen)
const struct tcphdr* tp = (const struct tcphdr*) data;
int th_len = tp->th_off * 4;
val_list args{
ip->BuildPktHdrVal(),
BuildData(data, th_len, len, caplen),
zeek::Args args{
{AdoptRef{}, ip->BuildPktHdrVal()},
{AdoptRef{}, BuildData(data, th_len, len, caplen)},
};
try
{
discard_packet = check_tcp->Call(&args)->AsBool();
discard_packet = check_tcp->Call(args)->AsBool();
}
catch ( InterpreterException& e )
@ -115,14 +115,14 @@ int Discarder::NextPacket(const IP_Hdr* ip, int len, int caplen)
const struct udphdr* up = (const struct udphdr*) data;
int uh_len = sizeof (struct udphdr);
val_list args{
ip->BuildPktHdrVal(),
BuildData(data, uh_len, len, caplen),
zeek::Args args{
{AdoptRef{}, ip->BuildPktHdrVal()},
{AdoptRef{}, BuildData(data, uh_len, len, caplen)},
};
try
{
discard_packet = check_udp->Call(&args)->AsBool();
discard_packet = check_udp->Call(args)->AsBool();
}
catch ( InterpreterException& e )
@ -138,11 +138,11 @@ int Discarder::NextPacket(const IP_Hdr* ip, int len, int caplen)
{
const struct icmp* ih = (const struct icmp*) data;
val_list args{ip->BuildPktHdrVal()};
zeek::Args args{{AdoptRef{}, ip->BuildPktHdrVal()}};
try
{
discard_packet = check_icmp->Call(&args)->AsBool();
discard_packet = check_icmp->Call(args)->AsBool();
}
catch ( InterpreterException& e )

View file

@ -13,6 +13,8 @@
#include <memory>
#include <string>
#include <vector>
#include <tuple>
#include <type_traits>
#include <broker/data.hh>
#include <broker/expected.hh>
@ -50,10 +52,28 @@ public:
const vector<Body>& GetBodies() const { return bodies; }
bool HasBodies() const { return bodies.size(); }
// TODO: deprecate
[[deprecated("Remove in v4.1. Use zeek::Args overload instead.")]]
virtual IntrusivePtr<Val> Call(val_list* args, Frame* parent = nullptr) const;
/**
* Calls a Zeek function.
* @param args the list of arguments to the function call.
* @param parent the frame from which the function is being called.
* @return the return value of the function call.
*/
virtual IntrusivePtr<Val> Call(const zeek::Args& args, Frame* parent = nullptr) const = 0;
/**
* A version of Call() taking a variable number of individual arguments.
*/
template <class... Args>
std::enable_if_t<
std::is_convertible_v<std::tuple_element_t<0, std::tuple<Args...>>,
IntrusivePtr<Val>>,
IntrusivePtr<Val>>
Call(Args&&... args) const
{ return Call(zeek::Args{std::forward<Args>(args)...}); }
// Add a new event handler to an existing function (event).
virtual void AddBody(IntrusivePtr<Stmt> new_body, id_list* new_inits,
size_t new_frame_size, int priority = 0);

View file

@ -167,19 +167,20 @@ bool RuleConditionEval::DoMatch(Rule* rule, RuleEndpointState* state,
return id->ID_Val()->AsBool();
// Call function with a signature_state value as argument.
val_list args(2);
args.push_back(rule_matcher->BuildRuleStateValue(rule, state));
zeek::Args args;
args.reserve(2);
args.emplace_back(AdoptRef{}, rule_matcher->BuildRuleStateValue(rule, state));
if ( data )
args.push_back(new StringVal(len, (const char*) data));
args.emplace_back(make_intrusive<StringVal>(len, (const char*) data));
else
args.push_back(val_mgr->GetEmptyString());
args.emplace_back(AdoptRef{}, val_mgr->GetEmptyString());
bool result = false;
try
{
auto val = id->ID_Val()->AsFunc()->Call(&args);
auto val = id->ID_Val()->AsFunc()->Call(args);
result = val && val->AsBool();
}

View file

@ -1835,25 +1835,24 @@ IntrusivePtr<Val> TableVal::Default(Val* index)
}
const Func* f = def_val->AsFunc();
val_list vl;
zeek::Args vl;
if ( index->Type()->Tag() == TYPE_LIST )
{
const val_list* vl0 = index->AsListVal()->Vals();
vl = val_list(vl0->length());
vl.reserve(vl0->length());
for ( const auto& v : *vl0 )
vl.push_back(v->Ref());
vl.emplace_back(NewRef{}, v);
}
else
{
vl = val_list{index->Ref()};
}
vl.emplace_back(NewRef{}, index);
IntrusivePtr<Val> result;
try
{
result = f->Call(&vl);
result = f->Call(vl);
}
catch ( InterpreterException& e )
@ -2011,34 +2010,35 @@ void TableVal::CallChangeFunc(const Val* index, Val* old_value, OnChangeType tpe
}
const Func* f = thefunc->AsFunc();
val_list vl { Ref() };
IntrusivePtr<EnumVal> type;
const auto& index_list = *index->AsListVal()->Vals();
zeek::Args vl;
vl.reserve(2 + index_list.length() + table_type->IsTable());
vl.emplace_back(NewRef{}, this);
switch ( tpe )
{
case ELEMENT_NEW:
type = BifType::Enum::TableChange->GetVal(BifEnum::TableChange::TABLE_ELEMENT_NEW);
vl.emplace_back(BifType::Enum::TableChange->GetVal(BifEnum::TableChange::TABLE_ELEMENT_NEW));
break;
case ELEMENT_CHANGED:
type = BifType::Enum::TableChange->GetVal(BifEnum::TableChange::TABLE_ELEMENT_CHANGED);
vl.emplace_back(BifType::Enum::TableChange->GetVal(BifEnum::TableChange::TABLE_ELEMENT_CHANGED));
break;
case ELEMENT_REMOVED:
type = BifType::Enum::TableChange->GetVal(BifEnum::TableChange::TABLE_ELEMENT_REMOVED);
vl.emplace_back(BifType::Enum::TableChange->GetVal(BifEnum::TableChange::TABLE_ELEMENT_REMOVED));
break;
case ELEMENT_EXPIRED:
type = BifType::Enum::TableChange->GetVal(BifEnum::TableChange::TABLE_ELEMENT_EXPIRED);
vl.emplace_back(BifType::Enum::TableChange->GetVal(BifEnum::TableChange::TABLE_ELEMENT_EXPIRED));
}
vl.append(type.release());
for ( const auto& v : *index->AsListVal()->Vals() )
vl.append(v->Ref());
vl.emplace_back(NewRef{}, v);
if ( ! table_type->IsSet() )
vl.append(old_value->Ref());
if ( table_type->IsTable() )
vl.emplace_back(NewRef{}, old_value);
in_change_func = true;
f->Call(&vl);
f->Call(vl);
}
catch ( InterpreterException& e )
{
@ -2451,7 +2451,7 @@ double TableVal::CallExpireFunc(IntrusivePtr<ListVal> idx)
}
const Func* f = vf->AsFunc();
val_list vl { Ref() };
zeek::Args vl;
const auto func_args = f->FType()->ArgTypes()->Types();
@ -2460,20 +2460,27 @@ double TableVal::CallExpireFunc(IntrusivePtr<ListVal> idx)
if ( ! any_idiom )
{
for ( const auto& v : *idx->AsListVal()->Vals() )
vl.append(v->Ref());
const auto& index_list = *idx->AsListVal()->Vals();
vl.reserve(1 + index_list.length());
vl.emplace_back(NewRef{}, this);
for ( const auto& v : index_list )
vl.emplace_back(NewRef{}, v);
}
else
{
vl.reserve(2);
vl.emplace_back(NewRef{}, this);
ListVal* idx_list = idx->AsListVal();
// Flatten if only one element
if ( idx_list->Length() == 1 )
vl.append(idx_list->Index(0)->Ref());
vl.emplace_back(NewRef{}, idx_list->Index(0));
else
vl.append(idx.release());
vl.emplace_back(std::move(idx));
}
auto result = f->Call(&vl);
auto result = f->Call(vl);
if ( result )
secs = result->AsInterval();

View file

@ -545,12 +545,8 @@ bool Manager::PublishLogWrite(EnumVal* stream, EnumVal* writer, string path, int
std::string serial_data(data, len);
free(data);
val_list vl{
stream->Ref(),
new StringVal(path),
};
auto v = log_topic_func->Call(&vl);
auto v = log_topic_func->Call(IntrusivePtr{NewRef{}, stream},
make_intrusive<StringVal>(path));
if ( ! v )
{

View file

@ -188,8 +188,8 @@ function Cluster::publish_rr%(pool: Pool, key: string, ...%): bool
if ( ! topic_func )
topic_func = global_scope()->Lookup("Cluster::rr_topic")->ID_Val()->AsFunc();
val_list vl{pool->Ref(), key->Ref()};
auto topic = topic_func->Call(&vl);
zeek::Args vl{{NewRef{}, pool}, {NewRef{}, key}};
auto topic = topic_func->Call(vl);
if ( ! topic->AsString()->Len() )
return val_mgr->GetFalse();
@ -225,8 +225,8 @@ function Cluster::publish_hrw%(pool: Pool, key: any, ...%): bool
if ( ! topic_func )
topic_func = global_scope()->Lookup("Cluster::hrw_topic")->ID_Val()->AsFunc();
val_list vl{pool->Ref(), key->Ref()};
auto topic = topic_func->Call(&vl);
zeek::Args vl{{NewRef{}, pool}, {NewRef{}, key}};
auto topic = topic_func->Call(vl);
if ( ! topic->AsString()->Len() )
return val_mgr->GetFalse();

View file

@ -60,11 +60,9 @@ bool file_analysis::X509::EndOfFile()
return false;
// yup, let's call the callback.
val_list vl(3);
vl.push_back(GetFile()->GetVal()->Ref());
vl.push_back(entry.release());
vl.push_back(new StringVal(cert_sha256));
cache_hit_callback->Call(&vl);
cache_hit_callback->Call(IntrusivePtr{NewRef{}, GetFile()->GetVal()},
std::move(entry),
make_intrusive<StringVal>(cert_sha256));
return false;
}
}

View file

@ -1782,16 +1782,18 @@ bool Manager::Delete(ReaderFrontend* reader, Value* *vals)
bool Manager::CallPred(Func* pred_func, const int numvals, ...) const
{
bool result = false;
val_list vl(numvals);
zeek::Args vl;
vl.reserve(numvals);
va_list lP;
va_start(lP, numvals);
for ( int i = 0; i < numvals; i++ )
vl.push_back( va_arg(lP, Val*) );
vl.emplace_back(AdoptRef{}, va_arg(lP, Val*));
va_end(lP);
auto v = pred_func->Call(&vl);
auto v = pred_func->Call(vl);
if ( v )
result = v->AsBool();

View file

@ -723,11 +723,9 @@ bool Manager::Write(EnumVal* id, RecordVal* columns_arg)
{
// See whether the predicates indicates that we want
// to log this record.
val_list vl{columns->Ref()};
int result = 1;
auto v = filter->pred->Call(columns);
auto v = filter->pred->Call(&vl);
if ( v )
result = v->AsBool();
@ -737,23 +735,25 @@ bool Manager::Write(EnumVal* id, RecordVal* columns_arg)
if ( filter->path_func )
{
Val* path_arg;
if ( filter->path_val )
path_arg = filter->path_val->Ref();
else
path_arg = val_mgr->GetEmptyString();
IntrusivePtr<Val> path_arg;
Val* rec_arg;
if ( filter->path_val )
path_arg = {NewRef{}, filter->path_val};
else
path_arg = {AdoptRef{}, val_mgr->GetEmptyString()};
IntrusivePtr<Val> rec_arg;
BroType* rt = filter->path_func->FType()->Args()->FieldType("rec");
if ( rt->Tag() == TYPE_RECORD )
rec_arg = columns->CoerceTo(rt->AsRecordType(), true).release();
rec_arg = columns->CoerceTo(rt->AsRecordType(), true);
else
// Can be TYPE_ANY here.
rec_arg = columns->Ref();
rec_arg = columns;
val_list vl{id->Ref(), path_arg, rec_arg};
auto v = filter->path_func->Call(&vl);
auto v = filter->path_func->Call(IntrusivePtr{NewRef{}, id},
std::move(path_arg),
std::move(rec_arg));
if ( ! v )
return false;
@ -1058,8 +1058,7 @@ threading::Value** Manager::RecordToFilterVals(Stream* stream, Filter* filter,
if ( filter->num_ext_fields > 0 )
{
val_list vl{filter->path_val->Ref()};
auto res = filter->ext_func->Call(&vl);
auto res = filter->ext_func->Call(IntrusivePtr{NewRef{}, filter->path_val});
if ( res )
ext_rec = {AdoptRef{}, res.release()->AsRecordVal()};
@ -1515,7 +1514,7 @@ bool Manager::FinishedRotation(WriterFrontend* writer, const char* new_name, con
return true;
// Create the RotationInfo record.
RecordVal* info = new RecordVal(BifType::Record::Log::RotationInfo);
auto info = make_intrusive<RecordVal>(BifType::Record::Log::RotationInfo);
info->Assign(0, winfo->type->Ref());
info->Assign(1, make_intrusive<StringVal>(new_name));
info->Assign(2, make_intrusive<StringVal>(winfo->writer->Info().path));
@ -1534,11 +1533,9 @@ bool Manager::FinishedRotation(WriterFrontend* writer, const char* new_name, con
assert(func);
// Call the postprocessor function.
val_list vl{info};
int result = 0;
auto v = func->Call(&vl);
auto v = func->Call(std::move(info));
if ( v )
result = v->AsBool();

View file

@ -16,14 +16,15 @@ static bool call_option_handlers_and_set_value(StringVal* name, ID* i,
for ( auto handler_function : i->GetOptionHandlers() )
{
bool add_loc = handler_function->FType()->AsFuncType()->ArgTypes()->Types()->length() == 3;
val_list vl(2 + add_loc);
vl.push_back(name->Ref());
vl.push_back(val->Ref());
zeek::Args vl;
vl.reserve(2 + add_loc);
vl.emplace_back(NewRef{}, name);
vl.emplace_back(val);
if ( add_loc )
vl.push_back(location->Ref());
vl.emplace_back(NewRef{}, location);
val = handler_function->Call(&vl); // consumed by next call.
val = handler_function->Call(vl); // consumed by next call.
if ( ! val )
{

View file

@ -1335,11 +1335,8 @@ bool sort_function(Val* a, Val* b)
if ( ! b )
return 1;
val_list sort_func_args;
sort_func_args.push_back(a->Ref());
sort_func_args.push_back(b->Ref());
auto result = sort_function_comp->Call(&sort_func_args);
auto result = sort_function_comp->Call(IntrusivePtr{NewRef{}, a},
IntrusivePtr{NewRef{}, b});
int int_result = result->CoerceToInt();
return int_result < 0;