Merge remote-tracking branch 'origin/master' into topic/johanna/remove-serializer

This commit is contained in:
Johanna Amann 2019-05-23 07:05:23 -07:00
commit da9bf96242
28 changed files with 991 additions and 39 deletions

View file

@ -70,12 +70,67 @@ Val::~Val()
#endif
}
Val* Val::Clone() const
Val* Val::Clone()
{
// Fixme: Johanna
return nullptr;
Val::CloneState state;
return Clone(&state);
}
Val* Val::Clone(CloneState* state)
{
auto i = state->clones.find(this);
if ( i != state->clones.end() )
return i->second->Ref();
auto c = DoClone(state);
assert(c);
state->clones.insert(std::make_pair(this, c));
return c;
}
Val* Val::DoClone(CloneState* state)
{
switch ( type->InternalType() ) {
case TYPE_INTERNAL_INT:
case TYPE_INTERNAL_UNSIGNED:
case TYPE_INTERNAL_DOUBLE:
// Immutable.
return Ref();
case TYPE_INTERNAL_OTHER:
// Derived classes are responsible for this. Exception:
// Functions and files. There aren't any derived classes.
if ( type->Tag() == TYPE_FUNC )
// Immutable.
return Ref();
if ( type->Tag() == TYPE_FILE )
{
// I think we can just ref the file here - it is unclear what else
// to do. In the case of cached files, I think this is equivalent
// to what happened before - serialization + unserialization just
// have you the same pointer that you already had. In the case of
// non-cached files, the behavior now is different; in the past,
// serialize + unserialize gave you a new file object because the
// old one was not in the list anymore. This object was
// automatically opened. This does not happen anymore - instead you
// get the non-cached pointer back which is brought back into the
// cache when written too.
return Ref();
}
// Fall-through.
default:
reporter->InternalError("cloning illegal base type");
}
reporter->InternalError("cannot be reached");
return nullptr;
}
int Val::IsZero() const
{
switch ( type->InternalType() ) {
@ -556,6 +611,12 @@ void PortVal::ValDescribe(ODesc* d) const
d->Add("/unknown");
}
Val* PortVal::DoClone(CloneState* state)
{
// Immutable.
return Ref();
}
AddrVal::AddrVal(const char* text) : Val(TYPE_ADDR)
{
val.addr_val = new IPAddr(text);
@ -600,6 +661,12 @@ Val* AddrVal::SizeVal() const
return val_mgr->GetCount(128);
}
Val* AddrVal::DoClone(CloneState* state)
{
// Immutable.
return Ref();
}
SubNetVal::SubNetVal(const char* text) : Val(TYPE_SUBNET)
{
string s(text);
@ -710,6 +777,12 @@ bool SubNetVal::Contains(const IPAddr& addr) const
return val.subnet_val->Contains(a);
}
Val* SubNetVal::DoClone(CloneState* state)
{
// Immutable.
return Ref();
}
StringVal::StringVal(BroString* s) : Val(TYPE_STRING)
{
val.string_val = s;
@ -752,6 +825,12 @@ unsigned int StringVal::MemoryAllocation() const
return padded_sizeof(*this) + val.string_val->MemoryAllocation();
}
Val* StringVal::DoClone(CloneState* state)
{
return new StringVal(new BroString((u_char*) val.string_val->Bytes(),
val.string_val->Len(), 1));
}
PatternVal::PatternVal(RE_Matcher* re) : Val(base_type(TYPE_PATTERN))
{
val.re_val = re;
@ -800,6 +879,14 @@ unsigned int PatternVal::MemoryAllocation() const
return padded_sizeof(*this) + val.re_val->MemoryAllocation();
}
Val* PatternVal::DoClone(CloneState* state)
{
auto re = new RE_Matcher(val.re_val->PatternText(),
val.re_val->AnywherePatternText());
re->Compile();
return new PatternVal(re);
}
ListVal::ListVal(TypeTag t)
: Val(new TypeList(t == TYPE_ANY ? 0 : base_type_no_ref(t)))
{
@ -882,6 +969,17 @@ void ListVal::Describe(ODesc* d) const
}
}
Val* ListVal::DoClone(CloneState* state)
{
auto lv = new ListVal(tag);
lv->vals.resize(vals.length());
loop_over_list(vals, i)
lv->Append(vals[i]->Clone(state));
return lv;
}
unsigned int ListVal::MemoryAllocation() const
{
unsigned int size = 0;
@ -2032,6 +2130,55 @@ void TableVal::ReadOperation(Val* index, TableEntryVal* v)
}
}
Val* TableVal::DoClone(CloneState* state)
{
auto tv = new TableVal(table_type);
const PDict(TableEntryVal)* tbl = AsTable();
IterCookie* cookie = tbl->InitForIteration();
HashKey* key;
TableEntryVal* val;
while ( (val = tbl->NextEntry(key, cookie)) )
{
TableEntryVal* nval = val->Clone();
tv->AsNonConstTable()->Insert(key, nval);
if ( subnets )
{
Val* idx = RecoverIndex(key);
tv->subnets->Insert(idx, nval);
Unref(idx);
}
delete key;
}
if ( attrs )
{
::Ref(attrs);
tv->attrs = attrs;
}
if ( expire_time )
{
tv->expire_time = expire_time->Ref();
// As network_time is not necessarily initialized yet, we set
// a timer which fires immediately.
timer = new TableValTimer(this, 1);
timer_mgr->Add(timer);
}
if ( expire_func )
tv->expire_func = expire_func->Ref();
if ( def_val )
tv->def_val = def_val->Ref();
return tv;
}
bool TableVal::AddProperties(Properties arg_props)
{
if ( ! MutableVal::AddProperties(arg_props) )
@ -2095,13 +2242,16 @@ unsigned int TableVal::MemoryAllocation() const
vector<RecordVal*> RecordVal::parse_time_records;
RecordVal::RecordVal(RecordType* t) : MutableVal(t)
RecordVal::RecordVal(RecordType* t, bool init_fields) : MutableVal(t)
{
origin = 0;
record_type = t;
int n = record_type->NumFields();
val_list* vl = val.val_list_val = new val_list(n);
if ( ! init_fields )
return;
// Initialize to default values from RecordType (which are nil
// by default).
for ( int i = 0; i < n; ++i )
@ -2334,7 +2484,7 @@ void RecordVal::Describe(ODesc* d) const
void RecordVal::DescribeReST(ODesc* d) const
{
const val_list* vl = AsRecord();
int n = vl->length();
int n = vl->length();
d->Add("{");
d->PushIndent();
@ -2359,6 +2509,25 @@ void RecordVal::DescribeReST(ODesc* d) const
d->Add("}");
}
Val* RecordVal::DoClone(CloneState* state)
{
// We set origin to 0 here. Origin only seems to be used for exactly one
// purpose - to find the connection record that is associated with a
// record. As we cannot guarantee that it will ber zeroed out at the
// approproate time (as it seems to be guaranteed for the original record)
// we don't touch it.
auto rv = new RecordVal(record_type, false);
rv->origin = nullptr;
loop_over_list(*val.val_list_val, i)
{
Val* v = (*val.val_list_val)[i] ? (*val.val_list_val)[i]->Clone(state) : nullptr;
rv->val.val_list_val->append(v);
}
return rv;
}
bool RecordVal::AddProperties(Properties arg_props)
{
if ( ! MutableVal::AddProperties(arg_props) )
@ -2420,6 +2589,12 @@ void EnumVal::ValDescribe(ODesc* d) const
d->Add(ename);
}
Val* EnumVal::DoClone(CloneState* state)
{
// Immutable.
return Ref();
}
VectorVal::VectorVal(VectorType* t) : MutableVal(t)
{
vector_type = t->Ref()->AsVectorType();
@ -2566,6 +2741,21 @@ bool VectorVal::RemoveProperties(Properties arg_props)
return true;
}
Val* VectorVal::DoClone(CloneState* state)
{
auto vv = new VectorVal(vector_type);
vv->val.vector_val->reserve(val.vector_val->size());
for ( unsigned int i = 0; i < val.vector_val->size(); ++i )
{
auto v = (*val.vector_val)[i]->Clone(state);
vv->val.vector_val->push_back(v);
}
return vv;
}
void VectorVal::ValDescribe(ODesc* d) const
{
d->Add("[");
@ -2593,6 +2783,12 @@ OpaqueVal::~OpaqueVal()
{
}
Val* OpaqueVal::DoClone(CloneState* state)
{
reporter->InternalError("cloning opaque type without clone implementation");
return nullptr;
}
Val* check_and_promote(Val* v, const BroType* t, int is_init)
{
if ( ! v )