Beispiel #1
0
ArrayData* ArrayCommon::ToVec(const ArrayData* a) {
  auto const size = a->size();
  if (!size) return staticEmptyVecArray();
  VecArrayInit init{size};
  for (ArrayIter it{a}; it; ++it) {
    auto const& value = it.secondRef();
    if (UNLIKELY(value.isReferenced())) {
      throwRefInvalidArrayValueException(init.toArray());
    }
    init.append(value);
  }
  return init.create();
}
Beispiel #2
0
ArrayData* ArrayCommon::ToVec(ArrayData* a, bool) {
  auto const size = a->size();
  if (!size) return staticEmptyVecArray();
  VecArrayInit init{size};
  IterateV(
    a,
    [&](const TypedValue* v) {
      if (UNLIKELY(v->m_type == KindOfRef)) {
        if (v->m_data.pref->isReferenced()) {
          throwRefInvalidArrayValueException(init.toArray());
        }
      }
      init.append(tvAsCVarRef(v));
    }
  );
  return init.create();
}
Beispiel #3
0
ArrayData* EmptyArray::ToVec(ArrayData*, bool) {
  return staticEmptyVecArray();
}
Beispiel #4
0
void tvCastToVecInPlace(TypedValue* tv) {
  assert(tvIsPlausible(*tv));
  tvUnboxIfNeeded(tv);
  ArrayData* a;

  do {
    switch (tv->m_type) {
      case KindOfUninit:
      case KindOfNull:
        raise_warning("Null to vec conversion");
        a = staticEmptyVecArray();
        continue;

      case KindOfBoolean:
        raise_warning("Bool to vec conversion");
        a = staticEmptyVecArray();
        continue;

      case KindOfInt64:
        raise_warning("Int to vec conversion");
        a = staticEmptyVecArray();
        continue;

      case KindOfDouble:
        raise_warning("Double to vec conversion");
        a = staticEmptyVecArray();
        continue;

      case KindOfPersistentString:
      case KindOfString:
        raise_warning("String to vec conversion");
        a = staticEmptyVecArray();
        decRefStr(tv->m_data.pstr);
        continue;

      case KindOfResource:
        raise_warning("Resource to vec conversion");
        a = staticEmptyVecArray();
        decRefRes(tv->m_data.pres);
        continue;

      case KindOfPersistentDict:
      case KindOfDict: {
        auto* adIn = tv->m_data.parr;
        assert(adIn->isDict());
        a = MixedArray::ToVecDict(adIn, adIn->cowCheck());
        assert(a != adIn);
        decRefArr(adIn);
        continue;
      }

      case KindOfPersistentKeyset:
      case KindOfKeyset: {
        auto* adIn = tv->m_data.parr;
        assert(adIn->isKeyset());
        a = MixedArray::ToVecKeyset(adIn, adIn->cowCheck());
        assert(a != adIn);
        decRefArr(adIn);
        continue;
      }

      case KindOfPersistentArray:
      case KindOfArray: {
        auto* adIn = tv->m_data.parr;
        assert(adIn->isPHPArray());
        a = adIn->toVec(adIn->cowCheck());
        if (a != adIn) decRefArr(adIn);
        continue;
      }

      case KindOfPersistentVec:
      case KindOfVec:
        assert(tv->m_data.parr->isVecArray());
        return;

      case KindOfObject: {
        auto* obj = tv->m_data.pobj;
        if (!obj->isCollection()) {
          raise_warning("Non-collection object conversion to vec");
          a = staticEmptyVecArray();
        } else {
          auto vec = collections::toArray(obj).toVec();
          decRefObj(obj);
          a = vec.detach();
        }
        continue;
      }

      case KindOfRef:
      case KindOfClass:
        break;
    }
    not_reached();
  } while (0);

  assert(!a->isRefCounted() || a->hasExactlyOneRef());

  tv->m_data.parr = a;
  tv->m_type = KindOfVec;
  assert(cellIsPlausible(*tv));
}