StringData* convDblToStrHelper(int64_t i) { double d = reinterpretIntAsDbl(i); auto r = buildStringData(d); r->incRefCount(); return r; }
StringData* tvCastToString(const TypedValue* tv) { assert(tvIsPlausible(*tv)); if (tv->m_type == KindOfRef) { tv = tv->m_data.pref->tv(); } switch (tv->m_type) { case KindOfUninit: case KindOfNull: return staticEmptyString(); case KindOfBoolean: return tv->m_data.num ? s_1.get() : staticEmptyString(); case KindOfInt64: return buildStringData(tv->m_data.num); case KindOfDouble: return buildStringData(tv->m_data.dbl); case KindOfPersistentString: return tv->m_data.pstr; case KindOfString: { auto s = tv->m_data.pstr; s->incRefCount(); return s; } case KindOfPersistentVec: case KindOfVec: raise_notice("Vec to string conversion"); return vec_string.get(); case KindOfPersistentDict: case KindOfDict: raise_notice("Dict to string conversion"); return dict_string.get(); case KindOfPersistentKeyset: case KindOfKeyset: raise_notice("Keyset to string conversion"); return keyset_string.get(); case KindOfPersistentArray: case KindOfArray: raise_notice("Array to string conversion"); return array_string.get(); case KindOfObject: return tv->m_data.pobj->invokeToString().detach(); case KindOfResource: return tv->m_data.pres->data()->o_toString().detach(); case KindOfRef: case KindOfClass: not_reached(); } not_reached(); }
void tvCastToStringInPlace(TypedValue* tv) { assert(tvIsPlausible(*tv)); tvUnboxIfNeeded(tv); auto string = [&](StringData* s) { tv->m_type = KindOfString; tv->m_data.pstr = s; }; auto persistentString = [&](StringData* s) { assert(!s->isRefCounted()); tv->m_type = KindOfPersistentString; tv->m_data.pstr = s; }; switch (tv->m_type) { case KindOfUninit: case KindOfNull: return persistentString(staticEmptyString()); case KindOfBoolean: return persistentString(tv->m_data.num ? s_1.get() : staticEmptyString()); case KindOfInt64: return string(buildStringData(tv->m_data.num)); case KindOfDouble: return string(buildStringData(tv->m_data.dbl)); case KindOfPersistentString: case KindOfString: return; case KindOfVec: case KindOfPersistentVec: raise_notice("Vec to string conversion"); if (tv->m_type == KindOfVec) tvDecRefArr(tv); return persistentString(vec_string.get()); case KindOfDict: case KindOfPersistentDict: raise_notice("Dict to string conversion"); if (tv->m_type == KindOfDict) tvDecRefArr(tv); return persistentString(dict_string.get()); case KindOfKeyset: case KindOfPersistentKeyset: raise_notice("Keyset to string conversion"); if (tv->m_type == KindOfKeyset) tvDecRefArr(tv); return persistentString(keyset_string.get()); case KindOfArray: case KindOfPersistentArray: raise_notice("Array to string conversion"); if (tv->m_type == KindOfArray) tvDecRefArr(tv); return persistentString(array_string.get()); case KindOfObject: // For objects, we fall back on the Variant machinery tvAsVariant(tv) = tv->m_data.pobj->invokeToString(); return; case KindOfResource: // For resources, we fall back on the Variant machinery tvAsVariant(tv) = tv->m_data.pres->data()->o_toString(); return; case KindOfRef: case KindOfClass: break; } not_reached(); }
String::String(double n) : m_str(buildStringData(n), NoIncRef{}) { }
String::String(double n) { m_px = buildStringData(n); m_px->setRefCount(1); }
StringData* convIntToStrHelper(int64_t i) { auto r = buildStringData(i); r->incRefCount(); return r; }