mirror of
https://github.com/zeek/zeek.git
synced 2025-10-07 00:58:19 +00:00
Allow iterating over bif functions with result type vector of any.
This changes the internal type that is used to signal that a vector is unspecified from any to void. I tried to verify that the behavior of Bro is still the same. After a lot of playing around, I think everything still should worl as before. However, it might be good for someone to take a look at this. addresses BIT-1144
This commit is contained in:
parent
58eb9bbf28
commit
b3bd509b3f
11 changed files with 66 additions and 7 deletions
|
@ -39,6 +39,13 @@ type count_set: set[count];
|
||||||
## directly and then remove this alias.
|
## directly and then remove this alias.
|
||||||
type index_vec: vector of count;
|
type index_vec: vector of count;
|
||||||
|
|
||||||
|
## A vector of any, used by some builtin functions to store a list of varying types.
|
||||||
|
##
|
||||||
|
## .. todo:: We need this type definition only for declaring builtin functions
|
||||||
|
## via ``bifcl``. We should extend ``bifcl`` to understand composite types
|
||||||
|
## directly and then remove this alias.
|
||||||
|
type any_vec: vector of any;
|
||||||
|
|
||||||
## A vector of strings.
|
## A vector of strings.
|
||||||
##
|
##
|
||||||
## .. todo:: We need this type definition only for declaring builtin functions
|
## .. todo:: We need this type definition only for declaring builtin functions
|
||||||
|
|
|
@ -3819,7 +3819,9 @@ VectorConstructorExpr::VectorConstructorExpr(ListExpr* constructor_list,
|
||||||
if ( constructor_list->Exprs().length() == 0 )
|
if ( constructor_list->Exprs().length() == 0 )
|
||||||
{
|
{
|
||||||
// vector().
|
// vector().
|
||||||
SetType(new ::VectorType(base_type(TYPE_ANY)));
|
// By default, assign VOID type here. A vector with
|
||||||
|
// void type set is seen as an unspecified vector.
|
||||||
|
SetType(new ::VectorType(base_type(TYPE_VOID)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
17
src/Type.cc
17
src/Type.cc
|
@ -1626,6 +1626,21 @@ VectorType::~VectorType()
|
||||||
Unref(yield_type);
|
Unref(yield_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BroType* VectorType::YieldType()
|
||||||
|
{
|
||||||
|
// cheat around the fact that we use void internally to
|
||||||
|
// mark a vector as being unspecified
|
||||||
|
if ( IsUnspecifiedVector() )
|
||||||
|
{
|
||||||
|
BroType* ret = ::base_type(TYPE_ANY);
|
||||||
|
Unref(ret); // unref, because this won't be held by anyone.
|
||||||
|
assert(ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return yield_type;
|
||||||
|
}
|
||||||
|
|
||||||
int VectorType::MatchesIndex(ListExpr*& index) const
|
int VectorType::MatchesIndex(ListExpr*& index) const
|
||||||
{
|
{
|
||||||
expr_list& el = index->Exprs();
|
expr_list& el = index->Exprs();
|
||||||
|
@ -1645,7 +1660,7 @@ int VectorType::MatchesIndex(ListExpr*& index) const
|
||||||
|
|
||||||
bool VectorType::IsUnspecifiedVector() const
|
bool VectorType::IsUnspecifiedVector() const
|
||||||
{
|
{
|
||||||
return yield_type->Tag() == TYPE_ANY;
|
return yield_type->Tag() == TYPE_VOID;
|
||||||
}
|
}
|
||||||
|
|
||||||
IMPLEMENT_SERIAL(VectorType, SER_VECTOR_TYPE);
|
IMPLEMENT_SERIAL(VectorType, SER_VECTOR_TYPE);
|
||||||
|
|
|
@ -572,7 +572,7 @@ class VectorType : public BroType {
|
||||||
public:
|
public:
|
||||||
VectorType(BroType* t);
|
VectorType(BroType* t);
|
||||||
virtual ~VectorType();
|
virtual ~VectorType();
|
||||||
BroType* YieldType() { return yield_type; }
|
BroType* YieldType();
|
||||||
|
|
||||||
int MatchesIndex(ListExpr*& index) const;
|
int MatchesIndex(ListExpr*& index) const;
|
||||||
|
|
||||||
|
|
|
@ -2976,7 +2976,9 @@ VectorVal::~VectorVal()
|
||||||
bool VectorVal::Assign(unsigned int index, Val* element, Opcode op)
|
bool VectorVal::Assign(unsigned int index, Val* element, Opcode op)
|
||||||
{
|
{
|
||||||
if ( element &&
|
if ( element &&
|
||||||
! same_type(element->Type(), vector_type->YieldType(), 0) )
|
! same_type(element->Type(), vector_type->YieldType(), 0) &&
|
||||||
|
// if we are unspecified, you can assign anything to us.
|
||||||
|
! vector_type->IsUnspecifiedVector() )
|
||||||
{
|
{
|
||||||
Unref(element);
|
Unref(element);
|
||||||
return false;
|
return false;
|
||||||
|
@ -3139,7 +3141,7 @@ bool VectorVal::DoUnserialize(UnserialInfo* info)
|
||||||
for ( int i = 0; i < len; ++i )
|
for ( int i = 0; i < len; ++i )
|
||||||
{
|
{
|
||||||
Val* v;
|
Val* v;
|
||||||
UNSERIALIZE_OPTIONAL(v, Val::Unserialize(info, TYPE_ANY));
|
UNSERIALIZE_OPTIONAL(v, Val::Unserialize(info, TYPE_ANY)); // accept any type
|
||||||
Assign(i, v);
|
Assign(i, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -656,6 +656,8 @@ protected:
|
||||||
DECLARE_SERIAL(PatternVal);
|
DECLARE_SERIAL(PatternVal);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ListVals are mainly used to index tables that have more than one
|
||||||
|
// element in their index.
|
||||||
class ListVal : public Val {
|
class ListVal : public Val {
|
||||||
public:
|
public:
|
||||||
ListVal(TypeTag t);
|
ListVal(TypeTag t);
|
||||||
|
|
|
@ -49,7 +49,7 @@ function topk_add%(handle: opaque of topk, value: any%): any
|
||||||
##
|
##
|
||||||
## .. bro:see:: topk_init topk_add topk_count topk_epsilon
|
## .. bro:see:: topk_init topk_add topk_count topk_epsilon
|
||||||
## topk_size topk_sum topk_merge topk_merge_prune
|
## topk_size topk_sum topk_merge topk_merge_prune
|
||||||
function topk_get_top%(handle: opaque of topk, k: count%): any
|
function topk_get_top%(handle: opaque of topk, k: count%): any_vec
|
||||||
%{
|
%{
|
||||||
assert(handle);
|
assert(handle);
|
||||||
probabilistic::TopkVal* h = (probabilistic::TopkVal*) handle;
|
probabilistic::TopkVal* h = (probabilistic::TopkVal*) handle;
|
||||||
|
|
|
@ -79,3 +79,12 @@
|
||||||
0
|
0
|
||||||
8
|
8
|
||||||
0
|
0
|
||||||
|
0, c
|
||||||
|
1, e
|
||||||
|
2, d
|
||||||
|
0, c
|
||||||
|
1, e
|
||||||
|
2, d
|
||||||
|
0, c
|
||||||
|
1, e
|
||||||
|
2, d
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
[5, Hi, 127.0.0.1]
|
|
@ -148,7 +148,17 @@ event bro_init()
|
||||||
print topk_count(k3, "d");
|
print topk_count(k3, "d");
|
||||||
print topk_epsilon(k3, "d");
|
print topk_epsilon(k3, "d");
|
||||||
|
|
||||||
|
local styped: vector of count;
|
||||||
|
styped = topk_get_top(k3, 3);
|
||||||
|
for ( i in styped )
|
||||||
|
print i, styped[i];
|
||||||
|
|
||||||
|
local anytyped: vector of any;
|
||||||
|
anytyped = topk_get_top(k3, 3);
|
||||||
|
for ( i in anytyped )
|
||||||
|
print i, anytyped[i];
|
||||||
|
|
||||||
|
local suntyped = topk_get_top(k3, 3);
|
||||||
|
for ( i in suntyped )
|
||||||
|
print i, suntyped[i];
|
||||||
}
|
}
|
||||||
|
|
11
testing/btest/language/vector-unspecified.bro
Normal file
11
testing/btest/language/vector-unspecified.bro
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# @TEST-EXEC: bro -b %INPUT >output 2>&1
|
||||||
|
# @TEST-EXEC: btest-diff output
|
||||||
|
|
||||||
|
# Test assignment behavior of unspecified vectors
|
||||||
|
local a = vector();
|
||||||
|
|
||||||
|
a[0] = 5;
|
||||||
|
a[1] = "Hi";
|
||||||
|
a[2] = 127.0.0.1;
|
||||||
|
|
||||||
|
print a;
|
Loading…
Add table
Add a link
Reference in a new issue