ArrayData *ZendArray::append(const ArrayData *elems, ArrayOp op, bool copy) { if (UNLIKELY(copy)) { ZendArray *a = copyImpl(); a->append(elems, op, false); return a; } if (op == Plus) { for (ArrayIter it(elems); !it.end(); it.next()) { Variant key = it.first(); CVarRef value = it.secondRef(); if (key.isNumeric()) { addValWithRef(key.toInt64(), value); } else { addValWithRef(key.getStringData(), value); } } } else { ASSERT(op == Merge); for (ArrayIter it(elems); !it.end(); it.next()) { Variant key = it.first(); CVarRef value = it.secondRef(); if (key.isNumeric()) { nextInsertWithRef(value); } else { Variant *p; StringData *sd = key.getStringData(); addLvalImpl(sd, sd->hash(), &p, true); p->setWithRef(value); } } } return NULL; }
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; }