diff --git a/src/Val.cc b/src/Val.cc index bf86360b70..e82f0e9c1b 100644 --- a/src/Val.cc +++ b/src/Val.cc @@ -3241,10 +3241,11 @@ bool VectorVal::Assign(unsigned int index, ValPtr element) { if ( yield_types ) { const auto& t = element->GetType(); - (*yield_types)[index] = t; + auto& yt_i = (*yield_types)[index]; auto& elem = vector_val[index]; if ( elem ) - ZVal::DeleteIfManaged(*elem, t); + ZVal::DeleteIfManaged(*elem, yt_i); + yt_i = t; elem = ZVal(std::move(element), t); } else { diff --git a/src/script_opt/Expr.cc b/src/script_opt/Expr.cc index 1ad24c5277..8516224106 100644 --- a/src/script_opt/Expr.cc +++ b/src/script_opt/Expr.cc @@ -1629,6 +1629,9 @@ ExprPtr AssignExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { StmtPtr lhs_stmt; StmtPtr rhs_stmt; + if ( GetType()->Tag() == TYPE_ANY && op2->GetType()->Tag() != TYPE_ANY ) + op2 = with_location_of(make_intrusive(op2), op2); + auto lhs_e = field_e->Op()->Reduce(c, lhs_stmt); auto rhs_e = op2->ReduceToFieldAssignment(c, rhs_stmt); diff --git a/src/script_opt/ZAM/OPs/ZAM.op b/src/script_opt/ZAM/OPs/ZAM.op index 36f8beddd9..bd78716459 100644 --- a/src/script_opt/ZAM/OPs/ZAM.op +++ b/src/script_opt/ZAM/OPs/ZAM.op @@ -934,13 +934,13 @@ eval auto& vsel = frame[z.v2].vector_val->RawVec(); auto& v1 = frame[z.v3].vector_val->RawVec(); auto& v2 = frame[z.v4].vector_val->RawVec(); auto n = v1.size(); - auto res = new vector>(n); + vector> res(n); for ( auto i = 0U; i < n; ++i ) if ( vsel[i] ) - (*res)[i] = vsel[i]->int_val ? v1[i] : v2[i]; + res[i] = vsel[i]->int_val ? v1[i] : v2[i]; auto& full_res = frame[z.v1].vector_val; Unref(full_res); - full_res = new VectorVal(cast_intrusive(z.t), res); + full_res = new VectorVal(cast_intrusive(z.t), &res); # Our instruction format doesn't accommodate two constants, so for # the singular case of a V ? C1 : C2 conditional, we split it into @@ -1254,9 +1254,14 @@ macro AssignFromRec() 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()); - init_vals[lhs_map[i]] = rhs_i; + if ( init_i ) + ZVal::DeleteManagedType(*init_i); + } + init_i = rhs_i; } op Construct-Known-Record-From @@ -1606,7 +1611,19 @@ op Any-Vector-Elem-Assign op1-read set-type $1 type VVV -eval EvalVectorElemAssign(, vv->Assign(ind, frame[z.v3].ToVal(z.t))) +eval auto ind = frame[z.v2].AsCount(); + auto vv = frame[z.v1].AsVector(); + auto yt = vv->RawYieldTypes(); + if ( ind < vv->Size() && yt && (*yt)[ind] && ZVal::IsManagedType((*yt)[ind]) ) + { + auto orig_elem = vv->RawVec()[ind]; + if ( ! vv->Assign(ind, frame[z.v3].ToVal(z.t)) ) + ZAM_run_time_error(z.loc, "value used but not set"); + if ( orig_elem ) + ZVal::DeleteManagedType(*orig_elem); + } + else if ( ! vv->Assign(ind, frame[z.v3].ToVal(z.t)) ) + ZAM_run_time_error(z.loc, "value used but not set"); op Vector-Elem-Assign-Any op1-read diff --git a/src/script_opt/ZAM/ZBody.cc b/src/script_opt/ZAM/ZBody.cc index 0eb283284a..77bb11b93b 100644 --- a/src/script_opt/ZAM/ZBody.cc +++ b/src/script_opt/ZAM/ZBody.cc @@ -214,8 +214,9 @@ static void vec_exec(ZOp op, TypePtr t, VectorVal*& v1, const VectorVal* v2, con std::string err = "overflow promoting from "; \ err += ov_err; \ err += " arithmetic value"; \ + /* The run-time error will throw an exception, so recover intermediary memory. */ \ + delete res_zv; \ ZAM_run_time_error(z.loc, err.c_str()); \ - res[i] = std::nullopt; \ } \ else \ res[i] = ZVal(cast(vi)); \ @@ -604,8 +605,7 @@ static void vec_exec(ZOp op, TypePtr t, VectorVal*& v1, const VectorVal* v2, con auto& vec2 = v2->RawVec(); auto n = vec2.size(); - auto vec1_ptr = new vector>(n); - auto& vec1 = *vec1_ptr; + vector> vec1(n); for ( auto i = 0U; i < n; ++i ) { if ( vec2[i] ) @@ -620,7 +620,7 @@ static void vec_exec(ZOp op, TypePtr t, VectorVal*& v1, const VectorVal* v2, con auto vt = cast_intrusive(std::move(t)); auto old_v1 = v1; - v1 = new VectorVal(std::move(vt), vec1_ptr); + v1 = new VectorVal(std::move(vt), &vec1); Unref(old_v1); } @@ -631,8 +631,13 @@ static void vec_exec(ZOp op, TypePtr t, VectorVal*& v1, const VectorVal* v2, con auto& vec2 = v2->RawVec(); auto& vec3 = v3->RawVec(); auto n = vec2.size(); - auto vec1_ptr = new vector>(n); - auto& vec1 = *vec1_ptr; + + if ( vec3.size() != n ) { + ZAM_run_time_error(util::fmt("vector operands are of different sizes (%d vs. %d)", int(n), int(vec3.size()))); + return; + } + + vector> vec1(n); for ( auto i = 0U; i < vec2.size(); ++i ) { if ( vec2[i] && vec3[i] ) @@ -647,7 +652,7 @@ static void vec_exec(ZOp op, TypePtr t, VectorVal*& v1, const VectorVal* v2, con auto vt = cast_intrusive(std::move(t)); auto old_v1 = v1; - v1 = new VectorVal(std::move(vt), vec1_ptr); + v1 = new VectorVal(std::move(vt), &vec1); Unref(old_v1); }