Example #1
0
ArrayData *VectorArray::lval(int64 k, Variant *&ret, bool copy,
                             bool checkExist /* = false */) {
  ret = inRange(k, m_size) ? &tvAsVariant(&m_elems[k]) : nullptr;
  if (ret == nullptr && k != m_size) {
    ZendArray *a = escalateToZendArray();
    a->addLvalImpl(k, &ret, false);
    return a;
  }
  if (LIKELY(!copy)) {
    if (ret) return nullptr;
    assert(m_size == k);
    checkSize();
    Variant& v = tvAsUninitializedVariant(&m_elems[k]);
    v.setUninitNull();
    ret = &v;
    checkInsertIterator((ssize_t)k);
    m_size++;
    return nullptr;
  }
  if (checkExist && ret && (ret->isReferenced() || ret->isObject())) {
    return nullptr;
  }
  VectorArray *a = NEW(VectorArray)(this);
  if (ret) {
    Variant& v = tvAsVariant(&a->m_elems[k]);
    ret = &v;
    assert(ret);
    return a;
  }
  assert(m_size == k);
  a->VectorArray::lvalNew(ret, false);
  return a;
}
Example #2
0
ArrayData *VectorArray::prepend(CVarRef v, bool copy) {
  if (UNLIKELY(m_size == m_capacity)) {
    ZendArray *a = escalateToNonEmptyZendArray();
    ArrayData *aa UNUSED = a->prepend(v, false);
    assert(!aa);
    return a;
  }
  if (UNLIKELY(copy)) {
    ArrayData *a = UNLIKELY(m_size >= FixedSize && Util::isPowerOfTwo(m_size)) ?
      // in this case, we would escalate in the capacity check anyway
      static_cast<ArrayData*>(escalateToNonEmptyZendArray()) :
      static_cast<ArrayData*>(NEW(VectorArray)(this));
    ArrayData *aa UNUSED = a->prepend(v, false);
    assert(!aa);
    return a;
  }
  checkSize();
  for (uint i = m_size; i > 0; i--) {
    // copying TV's by value, intentionally not refcounting.
    m_elems[i] = m_elems[i-1];
  }
  tvAsUninitializedVariant(&m_elems[0]).constructValHelper(v);
  m_size++;
  // To match PHP-like semantics, the prepend operation resets the array's
  // internal iterator
  m_pos = (ssize_t)0;
  return nullptr;
}
Example #3
0
HOT_FUNC_HPHP
ArrayData *VectorArray::append(CVarRef v, bool copy) {
  uint index = m_size;
  if (copy) {
    VectorArray *a = NEW(VectorArray)(this);
    a->checkSize();
    tvAsUninitializedVariant(&a->m_elems[index]).constructValHelper(v);
    a->checkInsertIterator((ssize_t)index);
    a->m_size++;
    return a;
  }
  checkSize();
  tvAsUninitializedVariant(&m_elems[index]).constructValHelper(v);
  checkInsertIterator((ssize_t)index);
  m_size++;
  return nullptr;
}
Example #4
0
HOT_FUNC_HPHP
VectorArray::VectorArray(uint size, const Variant *values[]) {
  assert(size > 0);
  m_size = size;
  alloc(size);
  for (uint i = 0; i < size; i++) {
    Variant& to = tvAsUninitializedVariant(&m_elems[i]);
    to.constructValHelper(*values[i]);
  }
  assert(m_pos == 0);
}
Example #5
0
HOT_FUNC_HPHP
ArrayData *VectorArray::append(const ArrayData *elems, ArrayOp op, bool copy) {
  if (UNLIKELY(!elems->isVectorArray())) {
    ZendArray *a = escalateToZendArray();
    a->append(elems, op, false);
    return a;
  }
  if (UNLIKELY(copy)) {
    VectorArray *a = NEW(VectorArray)(this);
    a->VectorArray::append(elems, op, false);
    return a;
  }
  assert(dynamic_cast<const VectorArray *>(elems));
  const VectorArray *velems = static_cast<const VectorArray *>(elems);
  if (op == Plus) {
    if (velems->m_size > m_size) {
      checkSize(velems->m_size - m_size);
      for (uint i = m_size; i < velems->m_size; i++) {
        Variant& to = tvAsUninitializedVariant(&m_elems[i]);
        CVarRef fm = tvAsCVarRef(&velems->m_elems[i]);
        to.constructWithRefHelper(fm, 0);
      }
      checkInsertIterator((ssize_t)m_size);
      m_size = velems->m_size;
    }
  } else {
    assert(op == Merge);
    if (velems->m_size > 0) {
      checkSize(velems->m_size);
      for (uint i = m_size; i < m_size + velems->m_size; i++) {
        Variant& to = tvAsUninitializedVariant(&m_elems[i]);
        CVarRef fm = tvAsCVarRef(&velems->m_elems[i - m_size]);
        to.constructWithRefHelper(fm, 0);
      }
      checkInsertIterator((ssize_t)m_size);
      m_size += velems->m_size;
    }
  }
  return nullptr;
}
Example #6
0
ArrayData *VectorArray::appendRef(CVarRef v, bool copy) {
  if (UNLIKELY(copy)) {
    VectorArray *a = NEW(VectorArray)(this);
    a->VectorArray::appendRef(v, false);
    return a;
  }
  uint index = m_size;
  checkSize();
  tvAsUninitializedVariant(&m_elems[index]).constructRefHelper(v);
  checkInsertIterator((ssize_t)index);
  m_size++;
  return nullptr;
}
Example #7
0
ArrayData *VectorArray::lvalNew(Variant *&ret, bool copy) {
  if (UNLIKELY(copy)) {
    VectorArray *a = NEW(VectorArray)(this);
    a->VectorArray::lvalNew(ret, false);
    return a;
  }
  uint index = m_size;
  checkSize();
  Variant& v = tvAsUninitializedVariant(&m_elems[index]);
  v.setUninitNull();
  ret = &v;
  checkInsertIterator((ssize_t)index);
  m_size++;
  return nullptr;
}
Example #8
0
HOT_FUNC_HPHP
VectorArray::VectorArray(const VectorArray *src, uint start /* = 0 */,
  uint size /* = 0 */) : ArrayData(src) {
  assert(src);
  assert(size == 0 || (size == src->m_size - 1L && size > 0));
  assert(!src->strongIterators());
  assert(m_pos == src->m_pos);
  m_size = size ? size : src->m_size;
  alloc(m_size);
  for (uint i = 0; i < m_size; i++) {
    Variant& to = tvAsUninitializedVariant(&m_elems[i]);
    CVarRef fm = tvAsCVarRef(&src->m_elems[i + start]);
    to.constructWithRefHelper(fm, src);
  }
}
Example #9
0
ArrayData *VectorArray::appendWithRef(CVarRef v, bool copy) {
  if (UNLIKELY(copy)) {
    VectorArray *a = NEW(VectorArray)(this);
    a->VectorArray::appendWithRef(v, false);
    return a;
  }
  uint index = m_size;
  checkSize();
  Variant& to = tvAsUninitializedVariant(&m_elems[index]);
  to.setUninitNull();
  to.setWithRef(v);
  checkInsertIterator((ssize_t)index);
  m_size++;
  return NULL;
}
Example #10
0
ArrayData *VectorArray::addLval(int64 k, Variant *&ret, bool copy) {
  assert(!exists(k));
  if (k != m_size) {
    ZendArray *a = escalateToZendArray();
    a->addLval(k, ret, false);
    return a;
  }
  uint index = m_size;
  if (UNLIKELY(copy)) {
    VectorArray *a = NEW(VectorArray)(this);
    a->VectorArray::addLval(k, ret, false);
    return a;
  }
  checkSize();
  Variant& v = tvAsUninitializedVariant(&m_elems[index]);
  v.setUninitNull();
  ret = &v;
  checkInsertIterator((ssize_t)index);
  m_size++;
  return nullptr;
}
Example #11
0
ArrayData* PackedArray::Prepend(ArrayData* adIn,
                                const Variant& v,
                                bool copy) {
  assert(checkInvariants(adIn));

  auto const ad = adIn->hasMultipleRefs() ? CopyAndResizeIfNeeded(adIn)
                                          : ResizeIfNeeded(adIn);
  // To conform to PHP behavior, we invalidate all strong iterators when an
  // element is added to the beginning of the array.
  if (UNLIKELY(strong_iterators_exist())) {
    free_strong_iterators(ad);
  }

  auto const size = ad->m_size;
  auto const data = packedData(ad);
  std::memmove(data + 1, data, sizeof *data * size);
  // TODO(#3888164): constructValHelper is making KindOfUninit checks.
  tvAsUninitializedVariant(&data[0]).constructValHelper(v);
  ad->m_size = size + 1;
  ad->m_pos = 0;
  return ad;
}
Example #12
0
ArrayData *VectorArray::setRef(int64 k, CVarRef v, bool copy) {
  if (UNLIKELY(copy)) {
    if (inRange(k, m_size) || k == m_size) {
      VectorArray *a = NEW(VectorArray)(this);
      a->VectorArray::setRef(k, v, false);
      return a;
    }
  } else {
    if (inRange(k, m_size)) {
      tvAsVariant(&m_elems[k]).assignRef(v);
      return nullptr;
    } else if (k == m_size) {
      checkSize();
      tvAsUninitializedVariant(&m_elems[k]).constructRefHelper(v);
      checkInsertIterator((ssize_t)k);
      m_size++;
      return nullptr;
    }
  }
  ZendArray *a = escalateToZendArray();
  a->updateRef(k, v);
  return a;
}
Example #13
0
// This constructor is for nonSmartCopy()
VectorArray::VectorArray(const VectorArray *src, bool sma /* ignored */) :
    ArrayData(src, kArrayData, /*nonsmart*/true) {
  assert(src);
  assert(!src->strongIterators());
  m_size = src->m_size;
  if (m_size <= FixedSize) {
    m_capacity = FixedSize;
    m_elems = m_fixed;
    m_allocMode = kInline;
  } else {
    m_capacity = Util::nextPower2(m_size);
    m_elems = (TypedValue*) malloc(m_capacity * sizeof(TypedValue));
    m_allocMode = kMalloc;
  }
  for (uint i = 0, n = m_size; i < n; i++) {
    assert(src->m_elems[i].m_type != KindOfRef &&
           src->m_elems[i].m_type != KindOfObject);
    Variant& to = tvAsUninitializedVariant(&m_elems[i]);
    CVarRef fm = tvAsCVarRef(&src->m_elems[i]);
    to.constructWithRefHelper(fm, src);
  }
  assert(src->m_pos == 0 && m_pos == 0);
}