Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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();
}
Ejemplo n.º 4
0
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();
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
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());
  }
}
Ejemplo n.º 8
0
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()));
}
Ejemplo n.º 9
0
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());
}
Ejemplo n.º 11
0
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();
}