StringData* tvCastToString(const TypedValue* tv) { assert(tvIsPlausible(*tv)); if (tv->m_type == KindOfRef) { tv = tv->m_data.pref->tv(); } StringData* s; switch (tv->m_type) { case KindOfUninit: case KindOfNull: return staticEmptyString(); case KindOfBoolean: return tv->m_data.num ? s_1.get() : staticEmptyString(); 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: 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->o_toString().detach(); default: not_reached(); } s->incRefCount(); return s; }
void tvCastToStringInPlace(TypedValue* tv) { assert(tvIsPlausible(*tv)); tvUnboxIfNeeded(tv); StringData* s; do { switch (tv->m_type) { case KindOfUninit: case KindOfNull: s = staticEmptyString(); goto static_string; case KindOfBoolean: s = tv->m_data.num ? s_1.get() : staticEmptyString(); goto static_string; case KindOfInt64: s = buildStringData(tv->m_data.num); continue; case KindOfDouble: s = buildStringData(tv->m_data.dbl); continue; case KindOfStaticString: case KindOfString: return; case KindOfArray: raise_notice("Array to string conversion"); s = array_string.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; case KindOfRef: case KindOfClass: break; } not_reached(); } while (0); s->incRefCount(); tv->m_data.pstr = s; tv->m_type = KindOfString; return; static_string: tv->m_data.pstr = s; tv->m_type = KindOfStaticString; }
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 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(); }
StringData* StringData::getChar(int offset) const { if (offset >= 0 && offset < size()) { return makeStaticString(m_data[offset]); } raise_notice("Uninitialized string offset: %d", offset); return staticEmptyString(); }
VarNR Variant::toKey() const { if (m_type == KindOfString || m_type == KindOfStaticString) { int64_t n; if (m_data.pstr->isStrictlyInteger(n)) { return VarNR(n); } else { return VarNR(m_data.pstr); } } switch (m_type) { case KindOfUninit: case KindOfNull: return VarNR(staticEmptyString()); case KindOfBoolean: case KindOfInt64: return VarNR(m_data.num); case KindOfObject: break; case KindOfDouble: case KindOfResource: return VarNR(toInt64()); case KindOfRef: return m_data.pref->var()->toKey(); default: break; } throw_bad_type_exception("Invalid type used as key"); return null_varNR; }
void UnitEmitter::initMain(int line1, int line2) { assertx(m_fes.size() == 0); StringData* name = staticEmptyString(); FuncEmitter* pseudomain = newFuncEmitter(name); Attr attrs = AttrMayUseVV; pseudomain->init(line1, line2, 0, attrs, false, name); }
VarNR String::toKey() const { if (!m_str) return VarNR(staticEmptyString()); int64_t n = 0; if (m_str->isStrictlyInteger(n)) { return VarNR(n); } else { return VarNR(m_str.get()); } }
static Variant HHVM_FUNCTION(xdebug_call_class) { // PHP5 xdebug returns false if the callee is top-level auto fp = get_call_fp(); if (fp == nullptr) { return false; } // PHP5 xdebug returns "" for no class auto cls = fp->m_func->cls(); if (!cls) { return Variant{staticEmptyString()}; } return String(const_cast<StringData*>(cls->name())); }
PreClass* PreClassEmitter::create(Unit& unit) const { Attr attrs = m_attrs; if (attrs & AttrPersistent && !RuntimeOption::RepoAuthoritative && SystemLib::s_inited) { attrs = Attr(attrs & ~AttrPersistent); } auto pc = folly::make_unique<PreClass>( &unit, m_line1, m_line2, m_offset, m_name, attrs, m_parent, m_docComment, m_id, m_hoistable); pc->m_instanceCtor = m_instanceCtor; pc->m_instanceDtor = m_instanceDtor; pc->m_builtinObjSize = m_builtinObjSize; pc->m_builtinODOffset = m_builtinODOffset; pc->m_interfaces = m_interfaces; pc->m_usedTraits = m_usedTraits; pc->m_requirements = m_requirements; pc->m_traitPrecRules = m_traitPrecRules; pc->m_traitAliasRules = m_traitAliasRules; pc->m_enumBaseTy = m_enumBaseTy; // Set user attributes. [&] { pc->m_userAttributes = m_userAttributes; pc->m_nativeDataInfo = nullptr; if (!m_userAttributes.size()) return; // Check for <<__NativeData("Type")>>. auto it = m_userAttributes.find(s_nativedata.get()); if (it == m_userAttributes.end()) return; TypedValue ndiInfo = it->second; if (ndiInfo.m_type != KindOfArray) return; // Use the first string label which references a registered type. In // practice, there should generally only be one item and it should be a // string, but maybe that'll be extended... for (ArrayIter it(ndiInfo.m_data.parr); it; ++it) { Variant val = it.second(); if (!val.isString()) continue; pc->m_nativeDataInfo = Native::getNativeDataInfo(val.toString().get()); if (pc->m_nativeDataInfo) break; } }(); PreClass::MethodMap::Builder methodBuild; for (MethodVec::const_iterator it = m_methods.begin(); it != m_methods.end(); ++it) { Func* f = (*it)->create(unit, pc.get()); methodBuild.add(f->name(), f); } pc->m_methods.create(methodBuild); PreClass::PropMap::Builder propBuild; for (unsigned i = 0; i < m_propMap.size(); ++i) { const Prop& prop = m_propMap[i]; propBuild.add(prop.name(), PreClass::Prop(pc.get(), prop.name(), prop.attrs(), prop.typeConstraint(), prop.docComment(), prop.val(), prop.repoAuthType())); } pc->m_properties.create(propBuild); PreClass::ConstMap::Builder constBuild; for (unsigned i = 0; i < m_constMap.size(); ++i) { const Const& const_ = m_constMap[i]; constBuild.add(const_.name(), PreClass::Const(pc.get(), const_.name(), const_.typeConstraint(), const_.val(), const_.phpCode())); } if (auto nativeConsts = Native::getClassConstants(m_name)) { for (auto cnsMap : *nativeConsts) { auto tv = cnsMap.second; constBuild.add(cnsMap.first, PreClass::Const(pc.get(), cnsMap.first, staticEmptyString(), tv, staticEmptyString())); } } pc->m_constants.create(constBuild); return pc.release(); }
static inline StrNR ctxClassName() { Class* ctx = g_context->getContextClass(); return ctx ? ctx->nameStr() : StrNR(staticEmptyString()); }
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(); }