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;
}
Ejemplo n.º 2
0
ArrayData* APCLocalArray::EscalateForSort(ArrayData* ad, SortFunction sf) {
  auto a = asApcArray(ad);
  ArrayData* elems = a->loadElems();
  ArrayData* ret = elems->escalateForSort(sf);
  if (ret != elems) {
    elems->release();
  }
  assert(ret->hasExactlyOneRef());
  assert(!ret->isStatic());
  return ret;
}
Ejemplo n.º 3
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 KindOfStaticString:
        a = ArrayData::Create(tvAsVariant(tv));
        continue;

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

      case 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->isStatic() || a->hasExactlyOneRef());

  tv->m_data.parr = a;
  tv->m_type = KindOfArray;
}
Ejemplo n.º 4
0
ArrayData* APCLocalArray::loadElems() const {
  auto count = m_arr->size();
  ArrayData* elems;
  if (m_arr->isPacked()) {
    PackedArrayInit ai(count);
    for (uint32_t i = 0; i < count; i++) {
      ai.append(RvalAtPos(this, i).tv());
    }
    elems = ai.create();
  } else {
    ArrayInit ai(count, ArrayInit::Mixed{});
    for (uint32_t i = 0; i < count; i++) {
      ai.add(getKey(i), RvalAtPos(this, i).tv(), true);
    }
    elems = ai.create();
  }
  if (elems->isStatic()) {
    elems = elems->copy();
  }
  assert(elems->hasExactlyOneRef());
  return elems;
}
Ejemplo n.º 5
0
void tvCastToKeysetInPlace(TypedValue* tv) {
  assert(tvIsPlausible(*tv));
  tvUnboxIfNeeded(tv);
  ArrayData* a;

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

      case KindOfBoolean:
        raise_warning("Bool to keyset conversion");
        a = staticEmptyKeysetArray();
        continue;

      case KindOfInt64:
        raise_warning("Int to keyset conversion");
        a = staticEmptyKeysetArray();
        continue;

      case KindOfDouble:
        raise_warning("Double to keyset conversion");
        a = staticEmptyKeysetArray();
        continue;

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

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

      case KindOfPersistentVec:
      case KindOfVec: {
        auto* adIn = tv->m_data.parr;
        assert(adIn->isVecArray());
        a = PackedArray::ToKeysetVec(adIn, adIn->cowCheck());
        assert(a != adIn);
        decRefArr(adIn);
        continue;
      }

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

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

      case KindOfPersistentKeyset:
      case KindOfKeyset:
        assert(tv->m_data.parr->isKeyset());
        return;

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

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

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

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