support for ensuring that a vector can be treated as having a homogeneous type

This commit is contained in:
Vern Paxson 2021-05-30 17:55:03 -07:00
parent 65be1b5d76
commit fb01f6fdef
2 changed files with 60 additions and 0 deletions

View file

@ -3653,6 +3653,50 @@ VectorValPtr VectorVal::Order(Func* cmp_func)
return result_v; return result_v;
} }
bool VectorVal::Concretize(const TypePtr& t)
{
if ( ! any_yield )
// Could do a same_type() call here, but really this case
// shouldn't happen in any case.
return yield_type->Tag() == t->Tag();
if ( ! vector_val )
// Trivially concretized.
return true;
auto n = vector_val->size();
for ( auto i = 0U; i < n; ++i )
{
auto& v = (*vector_val)[i];
if ( ! v )
// Vector hole does not require concretization.
continue;
auto& vt_i = yield_types ? (*yield_types)[i] : yield_type;
if ( vt_i->Tag() == TYPE_ANY )
{ // Do the concretization.
ValPtr any_v = {NewRef{}, v->AsAny()};
auto& vt = any_v->GetType();
if ( vt->Tag() != t->Tag() )
return false;
v = ZVal(any_v, t);
}
else if ( vt_i->Tag() != t->Tag() )
return false;
}
// Require that this vector be treated consistently in the future.
yield_type = t;
managed_yield = ZVal::IsManagedType(yield_type);
delete yield_types;
yield_types = nullptr;
any_yield = false;
return true;
}
unsigned int VectorVal::Resize(unsigned int new_num_elements) unsigned int VectorVal::Resize(unsigned int new_num_elements)
{ {
unsigned int oldsize = vector_val->size(); unsigned int oldsize = vector_val->size();

View file

@ -1553,6 +1553,22 @@ public:
*/ */
VectorValPtr Order(Func* cmp_func = nullptr); VectorValPtr Order(Func* cmp_func = nullptr);
/**
* Ensures that the vector can be used as a "vector of t". In
* general, this is only relevant for objects that are typed as
* "vector of any", making sure that each element is in fact
* of type "t", and is internally represented as such so that
* this object can be used directly without any special-casing.
*
* Returns true if the object is compatible with "vector of t"
* (including if it's not a vector-of-any but instead already a
* vector-of-t), false if not compatible.
* @param t The yield type to concretize to.
* @return True if the object is compatible with vector-of-t, false
* if not.
*/
bool Concretize(const TypePtr& t);
ValPtr ValAt(unsigned int index) const { return At(index); } ValPtr ValAt(unsigned int index) const { return At(index); }
bool Has(unsigned int index) const bool Has(unsigned int index) const