# Operations corresponding to aggregated constructors. # Table construction requires atypical evaluation of list elements # using information from their expression specifics. direct-unary-op Table-Constructor ConstructTable macro ConstructTableOrSetPre(width) auto tt = cast_intrusive(Z_TYPE); auto new_t = new TableVal(tt, Z_AUX_ATTRS); auto aux = Z_AUX; auto n = aux->n; auto ind_width = width; macro ConstructTableOrSetPost(lhs) auto& t = lhs.AsTableRef(); Unref(t); t = new_t; internal-op Construct-Table class Vi eval ConstructTableOrSetPre($1) for ( auto i = 0; i < n; ++i ) { auto indices = aux->ToIndices(frame, i, ind_width); auto v = aux->ToVal(frame, i + ind_width); new_t->Assign(indices, v); i += ind_width; } ConstructTableOrSetPost($$) # When tables are constructed, if their &default is a lambda with captures # then we need to explicitly set up the default. internal-op Set-Table-Default-Lambda op1-read class VV op-types T X eval auto tbl = $1; auto lambda = $2.ToVal(Z_TYPE); tbl->InitDefaultVal(std::move(lambda)); direct-unary-op Set-Constructor ConstructSet internal-op Construct-Set class Vi eval ConstructTableOrSetPre($1) for ( auto i = 0; i < n; i += ind_width ) { auto indices = aux->ToIndices(frame, i, ind_width); new_t->Assign(indices, nullptr); } ConstructTableOrSetPost($$) direct-unary-op Record-Constructor ConstructRecord direct-unary-op Rec-Construct-With-Rec ConstructRecordFromRecord macro ConstructRecordPost(lhs) Unref(lhs); lhs = new RecordVal(cast_intrusive(Z_TYPE), std::move(init_vals)); op Construct-Direct-Record class V op-types R eval auto init_vals = Z_AUX->ToZValVec(frame); ConstructRecordPost($$) op Construct-Known-Record class V op-types R eval auto init_vals = Z_AUX->ToZValVecWithMap(frame); ConstructRecordPost($$) macro AssignFromRec(rhs) /* The following is defined below, for use by Rec-Assign-Fields */ SetUpRecFieldOps(lhs_map) auto is_managed = Z_AUX->is_managed; for ( size_t i = 0U; i < n; ++i ) { auto rhs_i = rhs->RawField(rhs_map[i]); auto& init_i = init_vals[lhs_map[i]]; if ( is_managed[i] ) { zeek::Ref(rhs_i.ManagedVal()); if ( init_i ) ZVal::DeleteManagedType(*init_i); } init_i = rhs_i; } op Construct-Known-Record-From class VV op-types R R eval auto init_vals = Z_AUX->ToZValVecWithMap(frame); AssignFromRec($1) ConstructRecordPost($$) macro DoNetworkTimeInit(slot) init_vals[slot] = ZVal(run_state::network_time); op Construct-Known-Record-With-NT class Vi op-types R I eval auto init_vals = Z_AUX->ToZValVecWithMap(frame); DoNetworkTimeInit($1) ConstructRecordPost($$) op Construct-Known-Record-With-NT-From class VVi op-types R R I eval auto init_vals = Z_AUX->ToZValVecWithMap(frame); DoNetworkTimeInit($2) AssignFromRec($1) ConstructRecordPost($$) macro GenInits() auto init_vals = Z_AUX->ToZValVecWithMap(frame); for ( auto& fi : *Z_AUX->field_inits ) init_vals[fi.first] = fi.second->Generate(); op Construct-Known-Record-With-Inits class V op-types R eval GenInits() ConstructRecordPost($$) op Construct-Known-Record-With-Inits-From class VV op-types R R eval GenInits() AssignFromRec($1) ConstructRecordPost($$) op Construct-Known-Record-With-Inits-And-NT class Vi op-types R I eval GenInits() DoNetworkTimeInit($1) ConstructRecordPost($$) op Construct-Known-Record-With-Inits-And-NT-From class VVi op-types R R I eval GenInits() DoNetworkTimeInit($2) AssignFromRec($1) ConstructRecordPost($$) macro SetUpRecFieldOps(which_lhs_map) auto& lhs_map = Z_AUX->which_lhs_map; auto& rhs_map = Z_AUX->rhs_map; auto n = rhs_map.size(); op Rec-Assign-Fields op1-read class VV op-types R R eval SetUpRecFieldOps(map) for ( size_t i = 0U; i < n; ++i ) $1->RawOptField(lhs_map[i]).Set($2->RawField(rhs_map[i])); macro DoManagedRecAssign(lhs, rhs) auto is_managed = Z_AUX->is_managed; for ( size_t i = 0U; i < n; ++i ) { auto& lhs_i = lhs->RawOptField(lhs_map[i]); auto rhs_i = rhs->RawField(rhs_map[i]); if ( is_managed[i] ) zeek::Ref(rhs_i.ManagedVal()); lhs_i.Set(rhs_i); } op Rec-Assign-Fields-Managed op1-read class VV op-types R R eval SetUpRecFieldOps(map) DoManagedRecAssign($1, $2) op Rec-Assign-Fields-All-Managed op1-read class VV op-types R R eval SetUpRecFieldOps(map) for ( size_t i = 0U; i < n; ++i ) { auto& lhs_i = $1->RawOptField(lhs_map[i]); auto rhs_i = $2->RawField(rhs_map[i]); zeek::Ref(rhs_i.ManagedVal()); lhs_i.Set(rhs_i); } op Rec-Add-Int-Fields op1-read class VV op-types R R eval SetUpRecFieldOps(map) for ( size_t i = 0U; i < n; ++i ) $1->RawFieldRef(lhs_map[i]).AsIntRef() += $2->RawField(rhs_map[i]).AsInt(); op Rec-Add-Double-Fields op1-read class VV op-types R R eval SetUpRecFieldOps(map) for ( size_t i = 0U; i < n; ++i ) $1->RawFieldRef(lhs_map[i]).AsDoubleRef() += $2->RawField(rhs_map[i]).AsDouble(); op Rec-Add-Fields op1-read class VV op-types R R eval SetUpRecFieldOps(map) auto& types = Z_AUX->types; for ( size_t i = 0U; i < n; ++i ) { auto& lhs_i = $1->RawFieldRef(lhs_map[i]); auto rhs_i = $2->RawField(rhs_map[i]); auto tag = types[i]->Tag(); if ( tag == TYPE_INT ) lhs_i.AsIntRef() += rhs_i.AsInt(); else if ( tag == TYPE_COUNT ) lhs_i.AsCountRef() += rhs_i.AsCount(); else lhs_i.AsDoubleRef() += rhs_i.AsDouble(); } # Special instruction for concretizing vectors that are fields in a # newly-constructed record. "aux" holds which fields in the record to # inspect. op Concretize-Vector-Fields op1-read class V op-types R eval auto rt = cast_intrusive(Z_TYPE); auto r = $1; auto aux = Z_AUX; auto n = aux->n; for ( auto i = 0; i < n; ++i ) { auto ind = aux->elems[i].IntVal(); auto v_i = r->GetField(ind); ASSERT(v_i); if ( v_i->GetType()->IsUnspecifiedVector() ) { const auto& t_i = rt->GetFieldType(ind); v_i->AsVectorVal()->Concretize(t_i->Yield()); } } direct-unary-op Vector-Constructor ConstructVector internal-op Construct-Vector class V op-types V eval auto new_vv = new VectorVal(cast_intrusive(Z_TYPE)); auto aux = Z_AUX; auto n = aux->n; for ( auto i = 0; i < n; ++i ) new_vv->Assign(i, aux->ToVal(frame, i)); auto& vv = $$; Unref(vv); vv = new_vv;