ZEND_API int _zend_list_delete(int id TSRMLS_DC) { zend_rsrc_list_entry* le = zend_list_id_to_entry(id TSRMLS_CC); if (le) { int refcount = le->getCount(); decRefRes(le); if (refcount <= 1) { RL()[id] = nullptr; return SUCCESS; } else { return SUCCESS; } } else { return FAILURE; } }
StringData* convResToStrHelper(ResourceData* o) { try { auto s = o->o_toString(); auto r = s.get(); decRefRes(o); if (!r->isStatic()) r->incRefCount(); return r; } catch (...) { // spill object back to stack. unwinder // will take care of decreffing it. VMRegAnchor _; TypedValue* spillSlot = (TypedValue *)vmsp(); spillSlot->m_data.pres = o; spillSlot->m_type = KindOfResource; throw; } }
void tvCastToKeysetInPlace(TypedValue* tv) { assert(tvIsPlausible(*tv)); tvUnboxIfNeeded(tv); ArrayData* a; do { switch (tv->m_type) { case KindOfUninit: case KindOfNull: raise_warning("Null to keyset conversion"); a = staticEmptyKeysetArray(); continue; case KindOfBoolean: raise_warning("Bool to keyset conversion"); a = staticEmptyKeysetArray(); continue; case KindOfInt64: raise_warning("Int to keyset conversion"); a = staticEmptyKeysetArray(); continue; case KindOfDouble: raise_warning("Double to keyset conversion"); a = staticEmptyKeysetArray(); continue; case KindOfPersistentString: case KindOfString: raise_warning("String to keyset conversion"); a = staticEmptyKeysetArray(); decRefStr(tv->m_data.pstr); continue; case KindOfResource: raise_warning("Resource to keyset conversion"); a = staticEmptyKeysetArray(); decRefRes(tv->m_data.pres); continue; case KindOfPersistentVec: case KindOfVec: { auto* adIn = tv->m_data.parr; assert(adIn->isVecArray()); a = PackedArray::ToKeysetVec(adIn, adIn->cowCheck()); assert(a != adIn); decRefArr(adIn); continue; } case KindOfPersistentDict: case KindOfDict: { auto* adIn = tv->m_data.parr; assert(adIn->isDict()); a = MixedArray::ToKeysetDict(adIn, adIn->cowCheck()); if (a != adIn) decRefArr(adIn); continue; } case KindOfPersistentArray: case KindOfArray: { auto* adIn = tv->m_data.parr; assert(adIn->isPHPArray()); a = adIn->toKeyset(adIn->cowCheck()); if (a != adIn) decRefArr(adIn); continue; } case KindOfPersistentKeyset: case KindOfKeyset: assert(tv->m_data.parr->isKeyset()); return; case KindOfObject: { auto* obj = tv->m_data.pobj; if (!obj->isCollection()) { raise_warning("Non-collection object conversion to keyset"); a = staticEmptyKeysetArray(); } else { auto keyset = collections::toArray(obj).toKeyset(); decRefObj(obj); a = keyset.detach(); } continue; } case KindOfRef: case KindOfClass: break; } not_reached(); } while (0); assert(!a->isRefCounted() || a->hasExactlyOneRef()); tv->m_data.parr = a; tv->m_type = KindOfKeyset; assert(cellIsPlausible(*tv)); }