/* * Helper for creating a single-element mixed array with a string key. * * Note: the key is not already incref'd, but the value must be. */ NEVER_INLINE std::pair<ArrayData*,TypedValue*> EmptyArray::MakeMixed(StringData* key, TypedValue val) { auto const ad = reqAllocArray(MixedArray::SmallScale); MixedArray::InitSmall(ad, 1/*count*/, 1/*size*/, 0/*nextIntKey*/); auto const data = ad->data(); auto const hash = reinterpret_cast<int32_t*>(data + MixedArray::SmallSize); auto const khash = key->hash(); auto const mask = MixedArray::SmallMask; hash[khash & mask] = 0; data[0].setStrKey(key, khash); auto& lval = data[0].data; lval.m_data = val.m_data; lval.m_type = val.m_type; assert(ad->m_size == 1); assert(ad->m_pos == 0); assert(ad->m_scale == MixedArray::SmallScale); assert(ad->kind() == ArrayData::kMixedKind); assert(ad->hasExactlyOneRef()); assert(ad->m_used == 1); assert(ad->checkInvariants()); return { ad, &lval }; }
MixedArray* StructArray::ToMixedHeader(size_t neededSize) { auto const scale = computeScaleFromSize(neededSize); auto const ad = reqAllocArray(scale); ad->m_sizeAndPos = 0; // We'll set size and pos later. ad->m_hdr.init(HeaderKind::Mixed, 1); ad->m_scale_used = scale; // used=0 ad->m_nextKI = 0; // There were never any numeric indices. assert(ad->kind() == ArrayData::kMixedKind); assert(ad->m_size == 0); assert(ad->m_pos == 0); assert(ad->hasExactlyOneRef()); assert(ad->m_used == 0); assert(ad->m_scale == scale); return ad; }
/* * Creating a single-element mixed array with a integer key. The * value is already incref'd. */ ArrayLval EmptyArray::MakeMixed(int64_t key, TypedValue val) { auto const ad = reqAllocArray(MixedArray::SmallScale); MixedArray::InitSmall(ad, 1/*count*/, 1/*size*/, (key >= 0) ? key + 1 : 0); auto const data = ad->data(); auto const hash = reinterpret_cast<int32_t*>(data + MixedArray::SmallSize); auto const mask = MixedArray::SmallMask; auto h = hash_int64(key); hash[h & mask] = 0; data[0].setIntKey(key, h); auto& lval = data[0].data; lval.m_data = val.m_data; lval.m_type = val.m_type; assert(ad->kind() == ArrayData::kMixedKind); assert(ad->m_size == 1); assert(ad->m_pos == 0); assert(ad->hasExactlyOneRef()); assert(ad->m_scale == MixedArray::SmallScale); assert(ad->m_used == 1); assert(ad->checkInvariants()); return { ad, &tvAsVariant(&lval) }; }