/** * concat_si will decRef the string passed in as appropriate, and it will * incRef the output string */ StringData* concat_si(StringData* v1, int64 v2) { int len2; char intbuf[21]; char* intstart; // Convert the int to a string { int is_negative; intstart = conv_10(v2, &is_negative, intbuf + sizeof(intbuf), &len2); } StringSlice s1 = v1->slice(); StringSlice s2(intstart, len2); StringData* ret = NEW(StringData)(s1, s2); ret->incRefCount(); decRefStr(v1); return ret; }
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; } }
/** * concat will decRef the values passed in as appropriate, and it will * incRef the output string */ StringData* concat_tv(DataType t1, uint64_t v1, DataType t2, uint64_t v2) { const char *s1, *s2; size_t s1len, s2len; bool free1, free2; tvPairToCString(t1, v1, &s1, &s1len, &free1); tvPairToCString(t2, v2, &s2, &s2len, &free2); StringSlice r1(s1, s1len); StringSlice r2(s2, s2len); StringData* retval = StringData::Make(r1, r2); retval->incRefCount(); // If tvPairToCString allocated temporary buffers, free them now if (free1) free((void*)s1); if (free2) free((void*)s2); // decRef the parameters as appropriate tvRefcountedDecRefHelper(t2, v2); tvRefcountedDecRefHelper(t1, v1); return retval; }
/* * Wraps calling an (autoload) PHP function from a CufIter. */ static Variant vm_call_user_func_cufiter(const CufIter& cufIter, const Array& params) { ObjectData* obj = nullptr; HPHP::Class* cls = nullptr; StringData* invName = cufIter.name(); const HPHP::Func* f = cufIter.func(); if (cufIter.ctx()) { if (uintptr_t(cufIter.ctx()) & 1) { cls = (Class*)(uintptr_t(cufIter.ctx()) & ~1); } else { obj = (ObjectData*)cufIter.ctx(); } } assert(!obj || !cls); if (invName) { invName->incRefCount(); } Variant ret; g_context->invokeFunc((TypedValue*)&ret, f, params, obj, cls, nullptr, invName, ExecutionContext::InvokeCuf); return ret; }
void tvCastToStringInPlace(TypedValue* tv) { assert(tvIsPlausible(*tv)); tvUnboxIfNeeded(tv); StringData * s; switch (tv->m_type) { case KindOfUninit: case KindOfNull: s = empty_string.get(); goto static_string; case KindOfBoolean: s = tv->m_data.num ? s_1.get() : empty_string.get(); goto static_string; case KindOfInt64: s = buildStringData(tv->m_data.num); break; case KindOfDouble: s = buildStringData(tv->m_data.dbl); break; case KindOfStaticString: case KindOfString: return; case KindOfArray: raise_notice("Array to string conversion"); s = s_Array.get(); tvDecRefArr(tv); goto static_string; 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->o_toString(); return; default: not_reached(); } s->incRefCount(); tv->m_data.pstr = s; tv->m_type = KindOfString; return; static_string: tv->m_data.pstr = s; tv->m_type = KindOfStaticString; }
StringData* tvCastToString(TypedValue* tv) { if (tv->m_type == KindOfRef) { tv = tv->m_data.pref->tv(); } StringData* s; switch (tv->m_type) { case KindOfUninit: case KindOfNull: return empty_string.get(); case KindOfBoolean: return tv->m_data.num ? s_1.get() : empty_string.get(); case KindOfInt64: s = buildStringData(tv->m_data.num); break; case KindOfDouble: s = buildStringData(tv->m_data.dbl); break; case KindOfStaticString: return tv->m_data.pstr; case KindOfString: s = tv->m_data.pstr; break; case KindOfArray: return s_Array.get(); case KindOfObject: return tv->m_data.pobj->t___tostring().detach(); default: not_reached(); } s->incRefCount(); return s; }