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 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 Zeek 3.1.0
========== ==========

View file

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

View file

@ -13,6 +13,8 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include <vector> #include <vector>
#include <tuple>
#include <type_traits>
#include <broker/data.hh> #include <broker/data.hh>
#include <broker/expected.hh> #include <broker/expected.hh>
@ -50,10 +52,28 @@ 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(); }
// TODO: deprecate [[deprecated("Remove in v4.1. Use zeek::Args overload instead.")]]
virtual IntrusivePtr<Val> Call(val_list* args, Frame* parent = nullptr) const; 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; 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). // 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,
size_t new_frame_size, int priority = 0); 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(); return id->ID_Val()->AsBool();
// Call function with a signature_state value as argument. // Call function with a signature_state value as argument.
val_list args(2); zeek::Args args;
args.push_back(rule_matcher->BuildRuleStateValue(rule, state)); args.reserve(2);
args.emplace_back(AdoptRef{}, rule_matcher->BuildRuleStateValue(rule, state));
if ( data ) if ( data )
args.push_back(new StringVal(len, (const char*) data)); args.emplace_back(make_intrusive<StringVal>(len, (const char*) data));
else else
args.push_back(val_mgr->GetEmptyString()); args.emplace_back(AdoptRef{}, val_mgr->GetEmptyString());
bool result = false; bool result = false;
try try
{ {
auto val = id->ID_Val()->AsFunc()->Call(&args); auto val = id->ID_Val()->AsFunc()->Call(args);
result = val && val->AsBool(); result = val && val->AsBool();
} }

View file

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

View file

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

View file

@ -60,11 +60,9 @@ bool file_analysis::X509::EndOfFile()
return false; return false;
// yup, let's call the callback. // yup, let's call the callback.
val_list vl(3); cache_hit_callback->Call(IntrusivePtr{NewRef{}, GetFile()->GetVal()},
vl.push_back(GetFile()->GetVal()->Ref()); std::move(entry),
vl.push_back(entry.release()); make_intrusive<StringVal>(cert_sha256));
vl.push_back(new StringVal(cert_sha256));
cache_hit_callback->Call(&vl);
return false; 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 Manager::CallPred(Func* pred_func, const int numvals, ...) const
{ {
bool result = false; bool result = false;
val_list vl(numvals); zeek::Args vl;
vl.reserve(numvals);
va_list lP; va_list lP;
va_start(lP, numvals); va_start(lP, numvals);
for ( int i = 0; i < numvals; i++ ) 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); va_end(lP);
auto v = pred_func->Call(&vl); auto v = pred_func->Call(vl);
if ( v ) if ( v )
result = v->AsBool(); 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 // See whether the predicates indicates that we want
// to log this record. // to log this record.
val_list vl{columns->Ref()};
int result = 1; int result = 1;
auto v = filter->pred->Call(columns);
auto v = filter->pred->Call(&vl);
if ( v ) if ( v )
result = v->AsBool(); result = v->AsBool();
@ -737,23 +735,25 @@ bool Manager::Write(EnumVal* id, RecordVal* columns_arg)
if ( filter->path_func ) if ( filter->path_func )
{ {
Val* path_arg; IntrusivePtr<Val> path_arg;
if ( filter->path_val )
path_arg = filter->path_val->Ref();
else
path_arg = val_mgr->GetEmptyString();
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"); BroType* rt = filter->path_func->FType()->Args()->FieldType("rec");
if ( rt->Tag() == TYPE_RECORD ) if ( rt->Tag() == TYPE_RECORD )
rec_arg = columns->CoerceTo(rt->AsRecordType(), true).release(); rec_arg = columns->CoerceTo(rt->AsRecordType(), true);
else else
// Can be TYPE_ANY here. // 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(IntrusivePtr{NewRef{}, id},
auto v = filter->path_func->Call(&vl); std::move(path_arg),
std::move(rec_arg));
if ( ! v ) if ( ! v )
return false; return false;
@ -1058,8 +1058,7 @@ threading::Value** Manager::RecordToFilterVals(Stream* stream, Filter* filter,
if ( filter->num_ext_fields > 0 ) if ( filter->num_ext_fields > 0 )
{ {
val_list vl{filter->path_val->Ref()}; auto res = filter->ext_func->Call(IntrusivePtr{NewRef{}, filter->path_val});
auto res = filter->ext_func->Call(&vl);
if ( res ) if ( res )
ext_rec = {AdoptRef{}, res.release()->AsRecordVal()}; ext_rec = {AdoptRef{}, res.release()->AsRecordVal()};
@ -1515,7 +1514,7 @@ bool Manager::FinishedRotation(WriterFrontend* writer, const char* new_name, con
return true; return true;
// Create the RotationInfo record. // 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(0, winfo->type->Ref());
info->Assign(1, make_intrusive<StringVal>(new_name)); info->Assign(1, make_intrusive<StringVal>(new_name));
info->Assign(2, make_intrusive<StringVal>(winfo->writer->Info().path)); 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); assert(func);
// Call the postprocessor function. // Call the postprocessor function.
val_list vl{info};
int result = 0; int result = 0;
auto v = func->Call(&vl); auto v = func->Call(std::move(info));
if ( v ) if ( v )
result = v->AsBool(); 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() ) for ( auto handler_function : i->GetOptionHandlers() )
{ {
bool add_loc = handler_function->FType()->AsFuncType()->ArgTypes()->Types()->length() == 3; bool add_loc = handler_function->FType()->AsFuncType()->ArgTypes()->Types()->length() == 3;
val_list vl(2 + add_loc); zeek::Args vl;
vl.push_back(name->Ref()); vl.reserve(2 + add_loc);
vl.push_back(val->Ref()); vl.emplace_back(NewRef{}, name);
vl.emplace_back(val);
if ( add_loc ) 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 ) if ( ! val )
{ {

View file

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