HOT_FUNC_VM ArrayData* new_array(int capacity) { ArrayData *a = NEW(HphpArray)(capacity); a->incRefCount(); TRACE(2, "newArrayHelper: capacity %d\n", capacity); return a; }
void c_MutableArrayIterator::t___construct(VRefParam array) { INSTANCE_METHOD_INJECTION_BUILTIN(MutableArrayIterator, MutableArrayIterator::__construct); if (m_valid) { MIterCtx& mi = marr(); mi.~MIterCtx(); m_valid = false; } Variant var(strongBind(array)); TypedValue* tv = (TypedValue*)(&var); ASSERT(tv->m_type == KindOfRef); if (tv->m_data.ptv->m_type == KindOfArray) { ArrayData* ad = tv->m_data.ptv->m_data.parr; if (ad->getCount() > 1) { ArrayData* copy = ad->copy(); copy->incRefCount(); ad->decRefCount(); // count > 1 to begin with; don't need release ad = tv->m_data.ptv->m_data.parr = copy; } MIterCtx& mi = marr(); (void) new (&mi) MIterCtx(tv->m_data.pref); m_valid = mi.m_mArray->advance(); if (!m_valid) mi.~MIterCtx(); } else if (tv->m_data.ptv->m_type == KindOfObject) { CStrRef ctxStr = hhvm ? g_vmContext->getContextClassName(true) : FrameInjection::GetClassName(true); bool isIterator; Object obj = tv->m_data.ptv->m_data.pobj->iterableObject(isIterator); if (isIterator) { raise_error("An iterator cannot be used with foreach by reference"); } Array iterArray = obj->o_toIterArray(ctxStr, true); ArrayData* ad = iterArray.getArrayData(); if (ad->getCount() > 1) { ArrayData* copy = ad->copy(); copy->incRefCount(); ad->decRefCount(); // count > 1 to begin with; don't need release ad = copy; } MIterCtx& mi = marr(); (void) new (&mi) MIterCtx(ad); m_valid = mi.m_mArray->advance(); if (!m_valid) mi.~MIterCtx(); } else { raise_warning("Invalid argument supplied for foreach()"); } }
Variant::Variant(const Array& v) { m_type = KindOfArray; ArrayData *a = v.get(); if (a) { m_data.parr = a; a->incRefCount(); } else { m_type = KindOfNull; } }
/* * Cold path helper for AddNewElemC delegates to the ArrayData::append * virtual method. */ static NEVER_INLINE ArrayData* genericAddNewElemC(ArrayData* a, TypedValue value) { ArrayData* r = a->append(tvAsCVarRef(&value), a->getCount() != 1); if (UNLIKELY(r != a)) { r->incRefCount(); decRefArr(a); } tvRefcountedDecRef(value); return r; }
void zBoxAndProxy(TypedValue* arg) { if (arg->m_type != KindOfRef) { tvBox(arg); } auto inner = arg->m_data.pref->tv(); if (inner->m_type == KindOfArray && !inner->m_data.parr->isProxyArray()) { ArrayData * inner_arr = inner->m_data.parr; if (inner_arr->isStatic() || inner_arr->hasMultipleRefs()) { ArrayData * tmp = inner_arr->copy(); tmp->incRefCount(); inner_arr->decRefAndRelease(); inner_arr = tmp; } inner->m_data.parr = ProxyArray::Make(inner_arr); } }
int hphp_ffi_exportVariant(CVarRef v, void** result) { switch (v.getType()) { case KindOfNull: return 0; case KindOfBoolean: *result = (void*)v.toBoolean(); return 1; case KindOfByte: case KindOfInt16: case KindOfInt32: case KindOfInt64: { *result = (void*)v.toInt64(); return 2; } case KindOfDouble: { union { double d; void* p; } u; u.d = v.toDouble(); *result = u.p; return 3; } case LiteralString: *result = (void*)v.getLiteralString(); return 4; case KindOfString: { StringData *sd = v.getStringData(); sd->incRefCount(); *result = (void*)sd; return 5; } case KindOfArray: { ArrayData *ad = v.getArrayData(); ad->incRefCount(); *result = (void*)ad; return 6; } case KindOfObject: { ObjectData *od = v.getObjectData(); od->incRefCount(); *result = (void*)od; return 7; } default: ASSERT(false); return 0; } }
ArrayData* array_add(ArrayData* a1, ArrayData* a2) { if (!a2->empty()) { if (a1->empty()) { decRefArr(a1); return a2; } if (a1 != a2) { ArrayData *escalated = a1->plus(a2, a1->getCount() > 1); if (escalated != a1) { escalated->incRefCount(); decRefArr(a2); decRefArr(a1); return escalated; } } } decRefArr(a2); return a1; }
ArrayData* MutableArrayIter::cowCheck() { ArrayData* data; if (m_var) { data = getData(); if (!data) return NULL; if (data->getCount() > 1 && !data->noCopyOnWrite()) { *const_cast<Variant*>(m_var) = (data = data->copyWithStrongIterators()); } } else { assert(m_data); data = m_data; if (data->getCount() > 1 && !data->noCopyOnWrite()) { ArrayData* copied = data->copyWithStrongIterators(); copied->incRefCount(); decRefArr(data); m_data = data = copied; } } return data; }
void MutableArrayIter::escalateCheck() { ArrayData* data; if (m_var) { data = getData(); if (!data) return; ArrayData* esc = data->escalate(true); if (data != esc) { *const_cast<Variant*>(m_var) = esc; } } else { assert(m_data); data = m_data; ArrayData* esc = data->escalate(true); if (data != esc) { esc->incRefCount(); decRefArr(data); m_data = esc; } } }