Esempio n. 1
0
ArrayData *ZendArray::addLval(int64 k, Variant *&ret, bool copy) {
  ASSERT(!exists(k));
  if (UNLIKELY(copy)) {
    ZendArray *result = copyImpl();
    result->addLvalImpl(k, &ret, false);
    return result;
  }
  addLvalImpl(k, &ret, false);
  return NULL;
}
Esempio n. 2
0
ArrayData *ZendArray::addLval(CStrRef k, Variant *&ret, bool copy) {
  ASSERT(!exists(k));
  if (UNLIKELY(copy)) {
    ZendArray *result = copyImpl();
    result->addLvalImpl(k.get(), k->hash(), &ret, false);
    return result;
  }
  addLvalImpl(k.get(), k->hash(), &ret, false);
  return NULL;
}
Esempio n. 3
0
ArrayData* StructArray::LvalInt(
  ArrayData* ad,
  int64_t k,
  Variant*& ret,
  bool copy
) {
  auto structArray = asStructArray(ad);
  auto mixedArray = copy ? ToMixedCopy(structArray) : ToMixed(structArray);
  return mixedArray->addLvalImpl(k, ret);
}
Esempio n. 4
0
ArrayData* StructArray::LvalStr(
  ArrayData* ad,
  StringData* property,
  Variant*& ret,
  bool copy
) {
  auto structArray = asStructArray(ad);
  auto shape = structArray->shape();
  auto offset = shape->offsetFor(property);
  if (offset != PropertyTable::kInvalidOffset) {
    auto const result = asStructArray(
      copy ? Copy(structArray) : structArray);
    ret = &tvAsVariant(&result->data()[offset]);
    return result;
  }

  auto convertToMixedAndAdd = [&]() {
    auto mixed = copy ? ToMixedCopy(structArray) : ToMixed(structArray);
    return mixed->addLvalImpl(property, ret);
  };

  // We don't support adding non-static strings yet.
  StringData* staticKey;
  if (property->isStatic()) {
    staticKey = property;
  } else {
    staticKey = lookupStaticString(property);
    if (!staticKey) return convertToMixedAndAdd();
  }

  auto newShape = shape->transition(staticKey);
  if (!newShape) return convertToMixedAndAdd();
  auto result = copy ? CopyAndResizeIfNeeded(structArray, newShape)
                     : ResizeIfNeeded(structArray, newShape);

  assert(newShape->hasOffsetFor(staticKey));
  offset = newShape->offsetFor(staticKey);
  tvWriteNull(&result->data()[offset]);
  ret = &tvAsVariant(&result->data()[offset]);
  return result;
}
Esempio n. 5
0
ArrayData *ZendArray::lval(int64 k, Variant *&ret, bool copy,
                           bool checkExist /* = false */) {
  if (!copy) {
    addLvalImpl(k, &ret);
    return NULL;
  }
  if (!checkExist) {
    ZendArray *a = copyImpl();
    a->addLvalImpl(k, &ret);
    return a;
  }
  Bucket *p = find(k);
  if (p &&
      (p->data.isReferenced() || p->data.isObject())) {
    ret = &p->data;
    return NULL;
  }
  ZendArray *a = copyImpl();
  a->addLvalImpl(k, &ret, p);
  return a;
}
Esempio n. 6
0
ArrayData* PackedArray::LvalInt(ArrayData* adIn,
                                int64_t k,
                                Variant*& ret,
                                bool copy) {
  assert(checkInvariants(adIn));

  if (LIKELY(size_t(k) < adIn->m_size)) {
    auto const ad = copy ? Copy(adIn) : adIn;
    ret = &tvAsVariant(&packedData(ad)[k]);
    return ad;
  }

  // We can stay packed if the index is m_size, and the operation does
  // the same thing as LvalNew.
  if (size_t(k) == adIn->m_size) return LvalNew(adIn, ret, copy);

  // Promote-to-mixed path, we know the key is new and should be using
  // findForNewInsert but aren't yet TODO(#2606310).
  auto const mixed = copy ? ToMixedCopy(adIn) : ToMixed(adIn);
  return mixed->addLvalImpl(k, ret);
}
Esempio n. 7
0
ArrayData *ZendArray::lval(CStrRef k, Variant *&ret, bool copy,
                           bool checkExist /* = false */) {
  StringData *key = k.get();
  int64 prehash = key->hash();
  if (!copy) {
    addLvalImpl(key, prehash, &ret);
    return NULL;
  }
  if (!checkExist) {
    ZendArray *a = copyImpl();
    a->addLvalImpl(key, prehash, &ret);
    return a;
  }
  Bucket *p = find(key->data(), key->size(), prehash);
  if (p &&
      (p->data.isReferenced() || p->data.isObject())) {
    ret = &p->data;
    return NULL;
  }
  ZendArray *a = copyImpl();
  a->addLvalImpl(key, prehash, &ret, p);
  return a;
}
Variant &Array::addLval(CStrRef key, bool isKey /* = false */) {
    if (isKey) return addLvalImpl(key);
    return addLvalImpl(key.toKey());
}
Variant &Array::addLval(litstr  key, bool isKey /* = false */) {
    if (isKey) return addLvalImpl(String(key));
    return addLvalImpl(String(key).toKey());
}