Ejemplo n.º 1
0
void tvCastToArrayInPlace(TypedValue* tv) {
  assert(tvIsPlausible(*tv));
  tvUnboxIfNeeded(tv);
  ArrayData* a;

  do {
    switch (tv->m_type) {
      case KindOfUninit:
      case KindOfNull:
        a = ArrayData::Create();
        continue;

      case KindOfBoolean:
      case KindOfInt64:
      case KindOfDouble:
      case KindOfPersistentString:
        a = ArrayData::Create(tvAsVariant(tv));
        continue;

      case KindOfString:
        a = ArrayData::Create(tvAsVariant(tv));
        tvDecRefStr(tv);
        continue;

      case KindOfPersistentArray:
      case KindOfArray: {
        ArrayData* adIn = tv->m_data.parr;
        if (adIn->isVecArray()) {
          tv->m_data.parr = PackedArray::MakeFromVec(adIn, adIn->cowCheck());
          tv->m_type = KindOfArray;
        } else if (adIn->isDict()) {
          tv->m_data.parr = MixedArray::MakeFromDict(adIn, adIn->cowCheck());
          tv->m_type = KindOfArray;
        }
        return;
      }

      case KindOfObject:
        // For objects, we fall back on the Variant machinery
        tvAsVariant(tv) = tv->m_data.pobj->toArray();
        return;

      case KindOfResource:
        a = ArrayData::Create(tvAsVariant(tv));
        tvDecRefRes(tv);
        continue;

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

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

  tv->m_data.parr = a;
  tv->m_type = KindOfArray;
}