mirror of
https://github.com/zeek/zeek.git
synced 2025-10-05 16:18:19 +00:00
Merge remote branch 'origin/topic/robin/logging-internals'
Includes some additional cleanup.
This commit is contained in:
commit
13a492091f
119 changed files with 5266 additions and 183 deletions
216
src/Expr.cc
216
src/Expr.cc
|
@ -284,7 +284,7 @@ Val* NameExpr::Eval(Frame* f) const
|
|||
Val* v;
|
||||
|
||||
if ( id->AsType() )
|
||||
RunTime("cannot evaluate type name");
|
||||
return new Val(id->AsType(), true);
|
||||
|
||||
if ( id->IsGlobal() )
|
||||
v = id->ID_Val();
|
||||
|
@ -2497,12 +2497,7 @@ AssignExpr::AssignExpr(Expr* arg_op1, Expr* arg_op2, int arg_is_init,
|
|||
bool AssignExpr::TypeCheck()
|
||||
{
|
||||
TypeTag bt1 = op1->Type()->Tag();
|
||||
if ( IsVector(bt1) )
|
||||
bt1 = op1->Type()->AsVectorType()->YieldType()->Tag();
|
||||
|
||||
TypeTag bt2 = op2->Type()->Tag();
|
||||
if ( IsVector(bt2) )
|
||||
bt2 = op2->Type()->AsVectorType()->YieldType()->Tag();
|
||||
|
||||
if ( bt1 == TYPE_LIST && bt2 == TYPE_ANY )
|
||||
// This is ok because we cannot explicitly declare lists on
|
||||
|
@ -2531,16 +2526,42 @@ bool AssignExpr::TypeCheck()
|
|||
return true;
|
||||
}
|
||||
|
||||
if ( bt1 == TYPE_VECTOR && bt2 == bt1 &&
|
||||
op2->Type()->AsVectorType()->IsUnspecifiedVector() )
|
||||
{
|
||||
op2 = new VectorCoerceExpr(op2, op1->Type()->AsVectorType());
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( op1->Type()->Tag() == TYPE_RECORD &&
|
||||
op2->Type()->Tag() == TYPE_RECORD )
|
||||
{
|
||||
if ( same_type(op1->Type(), op2->Type()) )
|
||||
{
|
||||
RecordType* rt1 = op1->Type()->AsRecordType();
|
||||
RecordType* rt2 = op2->Type()->AsRecordType();
|
||||
|
||||
// Make sure the attributes match as well.
|
||||
for ( int i = 0; i < rt1->NumFields(); ++i )
|
||||
{
|
||||
const TypeDecl* td1 = rt1->FieldDecl(i);
|
||||
const TypeDecl* td2 = rt2->FieldDecl(i);
|
||||
|
||||
if ( same_attrs(td1->attrs, td2->attrs) )
|
||||
// Everything matches.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Need to coerce.
|
||||
op2 = new RecordCoerceExpr(op2, op1->Type()->AsRecordType());
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( ! same_type(op1->Type(), op2->Type()) )
|
||||
{
|
||||
if ( op1->Type()->Tag() == TYPE_RECORD &&
|
||||
op2->Type()->Tag() == TYPE_RECORD )
|
||||
op2 = new RecordCoerceExpr(op2, op1->Type()->AsRecordType());
|
||||
else
|
||||
{
|
||||
ExprError("type clash in assignment");
|
||||
return false;
|
||||
}
|
||||
ExprError("type clash in assignment");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -3290,48 +3311,12 @@ RecordConstructorExpr::RecordConstructorExpr(ListExpr* constructor_list)
|
|||
|
||||
Val* RecordConstructorExpr::InitVal(const BroType* t, Val* aggr) const
|
||||
{
|
||||
if ( ! aggr )
|
||||
aggr = new RecordVal(const_cast<RecordType*>(t->AsRecordType()));
|
||||
RecordVal* rv = Eval(0)->AsRecordVal();
|
||||
RecordVal* ar = rv->CoerceTo(t->AsRecordType(), aggr);
|
||||
|
||||
if ( record_promotion_compatible(t->AsRecordType(), Type()->AsRecordType()) )
|
||||
if ( ar )
|
||||
{
|
||||
RecordVal* ar = aggr->AsRecordVal();
|
||||
RecordType* ar_t = aggr->Type()->AsRecordType();
|
||||
|
||||
RecordVal* rv = Eval(0)->AsRecordVal();
|
||||
RecordType* rv_t = rv->Type()->AsRecordType();
|
||||
|
||||
int i;
|
||||
for ( i = 0; i < rv_t->NumFields(); ++i )
|
||||
{
|
||||
int t_i = ar_t->FieldOffset(rv_t->FieldName(i));
|
||||
|
||||
if ( t_i < 0 )
|
||||
{
|
||||
char buf[512];
|
||||
safe_snprintf(buf, sizeof(buf),
|
||||
"orphan field \"%s\" in initialization",
|
||||
rv_t->FieldName(i));
|
||||
Error(buf);
|
||||
break;
|
||||
}
|
||||
|
||||
else
|
||||
ar->Assign(t_i, rv->Lookup(i)->Ref());
|
||||
}
|
||||
|
||||
for ( i = 0; i < ar_t->NumFields(); ++i )
|
||||
if ( ! ar->Lookup(i) &&
|
||||
! ar_t->FieldDecl(i)->FindAttr(ATTR_OPTIONAL) )
|
||||
{
|
||||
char buf[512];
|
||||
safe_snprintf(buf, sizeof(buf),
|
||||
"non-optional field \"%s\" missing in initialization", ar_t->FieldName(i));
|
||||
Error(buf);
|
||||
}
|
||||
|
||||
Unref(rv);
|
||||
|
||||
return ar;
|
||||
}
|
||||
|
||||
|
@ -3400,7 +3385,7 @@ TableConstructorExpr::TableConstructorExpr(ListExpr* constructor_list,
|
|||
SetError("values in table(...) constructor do not specify a table");
|
||||
}
|
||||
|
||||
attrs = arg_attrs ? new Attributes(arg_attrs, type) : 0;
|
||||
attrs = arg_attrs ? new Attributes(arg_attrs, type, false) : 0;
|
||||
}
|
||||
|
||||
Val* TableConstructorExpr::Eval(Frame* f) const
|
||||
|
@ -3466,7 +3451,7 @@ SetConstructorExpr::SetConstructorExpr(ListExpr* constructor_list,
|
|||
else if ( type->Tag() != TYPE_TABLE || ! type->AsTableType()->IsSet() )
|
||||
SetError("values in set(...) constructor do not specify a set");
|
||||
|
||||
attrs = arg_attrs ? new Attributes(arg_attrs, type) : 0;
|
||||
attrs = arg_attrs ? new Attributes(arg_attrs, type, false) : 0;
|
||||
}
|
||||
|
||||
Val* SetConstructorExpr::Eval(Frame* f) const
|
||||
|
@ -3523,6 +3508,13 @@ VectorConstructorExpr::VectorConstructorExpr(ListExpr* constructor_list)
|
|||
if ( IsError() )
|
||||
return;
|
||||
|
||||
if ( constructor_list->Exprs().length() == 0 )
|
||||
{
|
||||
// vector().
|
||||
SetType(new ::VectorType(base_type(TYPE_ANY)));
|
||||
return;
|
||||
}
|
||||
|
||||
BroType* t = merge_type_list(constructor_list);
|
||||
if ( t )
|
||||
{
|
||||
|
@ -3994,15 +3986,8 @@ RecordCoerceExpr::RecordCoerceExpr(Expr* op, RecordType* r)
|
|||
{
|
||||
int t_i = t_r->FieldOffset(sub_r->FieldName(i));
|
||||
if ( t_i < 0 )
|
||||
{
|
||||
// Same as in RecordConstructorExpr::InitVal.
|
||||
char buf[512];
|
||||
safe_snprintf(buf, sizeof(buf),
|
||||
"orphan record field \"%s\"",
|
||||
sub_r->FieldName(i));
|
||||
Error(buf);
|
||||
// Orphane field in rhs, that's ok.
|
||||
continue;
|
||||
}
|
||||
|
||||
BroType* sub_t_i = sub_r->FieldType(i);
|
||||
BroType* sup_t_i = t_r->FieldType(t_i);
|
||||
|
@ -4047,7 +4032,23 @@ Val* RecordCoerceExpr::Fold(Val* v) const
|
|||
for ( int i = 0; i < map_size; ++i )
|
||||
{
|
||||
if ( map[i] >= 0 )
|
||||
val->Assign(i, rv->Lookup(map[i])->Ref());
|
||||
{
|
||||
Val* rhs = rv->Lookup(map[i]);
|
||||
if ( ! rhs )
|
||||
{
|
||||
const Attr* def = rv->Type()->AsRecordType()->FieldDecl(
|
||||
map[i])->FindAttr(ATTR_DEFAULT);
|
||||
|
||||
if ( def )
|
||||
rhs = def->AttrExpr()->Eval(0);
|
||||
}
|
||||
|
||||
if ( rhs )
|
||||
rhs = rhs->Ref();
|
||||
|
||||
assert(rhs || Type()->AsRecordType()->FieldDecl(i)->FindAttr(ATTR_OPTIONAL));
|
||||
val->Assign(i, rhs);
|
||||
}
|
||||
else
|
||||
val->Assign(i, 0);
|
||||
}
|
||||
|
@ -4132,6 +4133,50 @@ bool TableCoerceExpr::DoUnserialize(UnserialInfo* info)
|
|||
return true;
|
||||
}
|
||||
|
||||
VectorCoerceExpr::VectorCoerceExpr(Expr* op, VectorType* v)
|
||||
: UnaryExpr(EXPR_VECTOR_COERCE, op)
|
||||
{
|
||||
if ( IsError() )
|
||||
return;
|
||||
|
||||
SetType(v->Ref());
|
||||
|
||||
if ( Type()->Tag() != TYPE_VECTOR )
|
||||
ExprError("coercion to non-vector");
|
||||
|
||||
else if ( op->Type()->Tag() != TYPE_VECTOR )
|
||||
ExprError("coercion of non-vector to vector");
|
||||
}
|
||||
|
||||
|
||||
VectorCoerceExpr::~VectorCoerceExpr()
|
||||
{
|
||||
}
|
||||
|
||||
Val* VectorCoerceExpr::Fold(Val* v) const
|
||||
{
|
||||
VectorVal* vv = v->AsVectorVal();
|
||||
|
||||
if ( vv->Size() > 0 )
|
||||
Internal("coercion of non-empty vector");
|
||||
|
||||
return new VectorVal(Type()->Ref()->AsVectorType());
|
||||
}
|
||||
|
||||
IMPLEMENT_SERIAL(VectorCoerceExpr, SER_VECTOR_COERCE_EXPR);
|
||||
|
||||
bool VectorCoerceExpr::DoSerialize(SerialInfo* info) const
|
||||
{
|
||||
DO_SERIALIZE(SER_VECTOR_COERCE_EXPR, UnaryExpr);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VectorCoerceExpr::DoUnserialize(UnserialInfo* info)
|
||||
{
|
||||
DO_UNSERIALIZE(UnaryExpr);
|
||||
return true;
|
||||
}
|
||||
|
||||
FlattenExpr::FlattenExpr(Expr* arg_op)
|
||||
: UnaryExpr(EXPR_FLATTEN, arg_op)
|
||||
{
|
||||
|
@ -5308,27 +5353,52 @@ int check_and_promote_expr(Expr*& e, BroType* t)
|
|||
return 1;
|
||||
}
|
||||
|
||||
else if ( ! same_type(t, et) )
|
||||
if ( t->Tag() == TYPE_RECORD && et->Tag() == TYPE_RECORD )
|
||||
{
|
||||
if ( t->Tag() == TYPE_RECORD && et->Tag() == TYPE_RECORD )
|
||||
{
|
||||
RecordType* t_r = t->AsRecordType();
|
||||
RecordType* et_r = et->AsRecordType();
|
||||
RecordType* t_r = t->AsRecordType();
|
||||
RecordType* et_r = et->AsRecordType();
|
||||
|
||||
if ( record_promotion_compatible(t_r, et_r) )
|
||||
if ( same_type(t, et) )
|
||||
{
|
||||
// Make sure the attributes match as well.
|
||||
for ( int i = 0; i < t_r->NumFields(); ++i )
|
||||
{
|
||||
e = new RecordCoerceExpr(e, t_r);
|
||||
return 1;
|
||||
const TypeDecl* td1 = t_r->FieldDecl(i);
|
||||
const TypeDecl* td2 = et_r->FieldDecl(i);
|
||||
|
||||
if ( same_attrs(td1->attrs, td2->attrs) )
|
||||
// Everything matches perfectly.
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
else if ( t->Tag() == TYPE_TABLE && et->Tag() == TYPE_TABLE &&
|
||||
if ( record_promotion_compatible(t_r, et_r) )
|
||||
{
|
||||
e = new RecordCoerceExpr(e, t_r);
|
||||
return 1;
|
||||
}
|
||||
|
||||
t->Error("incompatible record types", e);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if ( ! same_type(t, et) )
|
||||
{
|
||||
if ( t->Tag() == TYPE_TABLE && et->Tag() == TYPE_TABLE &&
|
||||
et->AsTableType()->IsUnspecifiedTable() )
|
||||
{
|
||||
e = new TableCoerceExpr(e, t->AsTableType());
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( t->Tag() == TYPE_VECTOR && et->Tag() == TYPE_VECTOR &&
|
||||
et->AsVectorType()->IsUnspecifiedVector() )
|
||||
{
|
||||
e = new VectorCoerceExpr(e, t->AsVectorType());
|
||||
return 1;
|
||||
}
|
||||
|
||||
t->Error("type clash", e);
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue