Beispiel #1
0
String &String::operator+=(const String& str) {
  if (!str.empty()) {
    if (empty()) {
      StringBase::operator=(str.m_px);
    } else if (m_px->getCount() == 1) {
      auto tmp = m_px->append(str.slice());
      if (UNLIKELY(tmp != m_px)) StringBase::operator=(tmp);
    } else {
      StringData* px = StringData::Make(m_px, str.slice());
      decRefStr(m_px);
      px->setRefCount(1);
      m_px = px;
    }
  }
  return *this;
}
Beispiel #2
0
String &String::operator+=(litstr s) {
  if (s && *s) {
    if (empty()) {
      m_px = NEW(StringData)(s, AttachLiteral);
      m_px->setRefCount(1);
    } else if (m_px->getCount() == 1) {
      m_px->append(s, strlen(s));
    } else {
      StringData* px = NEW(StringData)(m_px, s);
      px->setRefCount(1);
      decRefStr(m_px);
      m_px = px;
    }
  }
  return *this;
}
Beispiel #3
0
String &String::operator+=(litstr s) {
    if (s && *s) {
        if (empty()) {
            m_px = StringData::Make(s, CopyString);
            m_px->setRefCount(1);
        } else if (m_px->getCount() == 1) {
            auto const tmp = m_px->append(StringSlice(s, strlen(s)));
            if (UNLIKELY(tmp != m_px)) StringBase::operator=(tmp);
        } else {
            StringData* px = StringData::Make(m_px, s);
            px->setRefCount(1);
            decRefStr(m_px);
            m_px = px;
        }
    }
    return *this;
}
Beispiel #4
0
void Variant::setEvalScalar() {
    switch (m_type) {
    case KindOfUninit:
    case KindOfNull:
    case KindOfBoolean:
    case KindOfInt64:
    case KindOfDouble:
    case KindOfStaticString:
        return;

    case KindOfString: {
        StringData *pstr = m_data.pstr;
        if (!pstr->isStatic()) {
            StringData *sd = makeStaticString(pstr);
            decRefStr(pstr);
            m_data.pstr = sd;
            assert(m_data.pstr->isStatic());
            m_type = KindOfStaticString;
        }
        return;
    }

    case KindOfPersistentArray:
    case KindOfArray: {
        auto parr = m_data.parr;
        if (!parr->isStatic()) {
            auto ad = ArrayData::GetScalarArray(parr);
            assert(ad->isStatic());
            m_data.parr = ad;
            m_type = KindOfPersistentArray;
            decRefArr(parr);
        }
        return;
    }

    case KindOfObject:
    case KindOfResource:
    case KindOfRef:
    case KindOfClass:
        break;
    }
    not_reached();
}
Beispiel #5
0
/**
 * postSort() runs after the sort has been performed. For MixedArray, postSort()
 * handles rebuilding the hash. Also, if resetKeys is true, postSort() will
 * renumber the keys 0 thru n-1.
 */
void MixedArray::postSort(bool resetKeys) {   // nothrow guarantee
  assert(m_size > 0);
  auto const ht = hashTab();
  initHash(ht, m_scale);
  if (resetKeys) {
    for (uint32_t pos = 0; pos < m_used; ++pos) {
      auto& e = data()[pos];
      if (e.hasStrKey()) decRefStr(e.skey);
      e.setIntKey(pos);
      ht[pos] = pos;
    }
    m_nextKI = m_size;
  } else {
    auto mask = this->mask();
    auto data = this->data();
    for (uint32_t pos = 0; pos < m_used; ++pos) {
      auto& e = data[pos];
      *findForNewInsert(ht, mask, e.probe()) = pos;
    }
  }
}
Beispiel #6
0
String &String::operator^=(CStrRef v) {
  const char *s1 = data();
  const char *s2 = v.data();
  int len1 = size();
  int len2 = v.size();
  int len;
  char *copy = NULL;
  if (len2 < len1) {
    len = len2;
    copy = string_duplicate(s2, len2);
    for (int i = 0; i < len2; i++) copy[i] ^= s1[i];
  } else {
    len = len1;
    copy = string_duplicate(s1, len1);
    for (int i = 0; i < len1; i++) copy[i] ^= s2[i];
  }
  if (m_px) decRefStr(m_px);
  m_px = NEW(StringData)(copy, len, AttachString);
  m_px->setRefCount(1);
  return *this;
}
int64_t switchStringHelper(StringData* s, int64_t base, int64_t nTargets) {
  int64_t ival;
  double dval;
  switch (s->isNumericWithVal(ival, dval, 1)) {
    case KindOfNull:
      ival = switchBoundsCheck(0, base, nTargets);
      break;

    case KindOfDouble:
      ival = switchBoundsCheck(dval, base, nTargets);
      break;

    case KindOfInt64:
      ival = switchBoundsCheck(ival, base, nTargets);
      break;

    default:
      not_reached();
  }
  decRefStr(s);
  return ival;
}
/**
 * postSort() runs after the sort has been performed. For HphpArray, postSort()
 * handles rebuilding the hash. Also, if resetKeys is true, postSort() will
 * renumber the keys 0 thru n-1.
 */
void HphpArray::postSort(bool resetKeys) {
  assert(m_size > 0);
  size_t tableSize = computeTableSize(m_tableMask);
  initHash(m_hash, tableSize);
  m_hLoad = 0;
  if (resetKeys) {
    for (uint32_t pos = 0; pos < m_used; ++pos) {
      Elm* e = &m_data[pos];
      if (e->hasStrKey()) decRefStr(e->key);
      e->setIntKey(pos);
      m_hash[pos] = pos;
    }
    m_nextKI = m_size;
  } else {
    for (uint32_t pos = 0; pos < m_used; ++pos) {
      Elm* e = &m_data[pos];
      ElmInd* ei = findForNewInsert(e->hasIntKey() ? e->ikey : e->hash());
      *ei = pos;
    }
  }
  m_hLoad = m_size;
}
Beispiel #9
0
/**
 * postSort() runs after the sort has been performed. For MixedArray, postSort()
 * handles rebuilding the hash. Also, if resetKeys is true, postSort() will
 * renumber the keys 0 thru n-1.
 */
void MixedArray::postSort(bool resetKeys) {
  assert(m_size > 0);
  auto const ht = hashTab();
  initHash(ht, hashSize());
  if (resetKeys) {
    for (uint32_t pos = 0; pos < m_used; ++pos) {
      auto& e = data()[pos];
      if (e.hasStrKey()) decRefStr(e.skey);
      e.setIntKey(pos);
      ht[pos] = pos;
    }
    m_nextKI = m_size;
  } else {
    auto mask = m_tableMask;
    auto data = this->data();
    for (uint32_t pos = 0; pos < m_used; ++pos) {
      auto& e = data[pos];
      auto ei = findForNewInsert(ht, mask,
                                 e.hasIntKey() ? e.ikey : e.hash());
      *ei = pos;
    }
  }
}
void Variant::setEvalScalar() {
  switch (m_type) {
    DT_UNCOUNTED_CASE:
      return;

    case KindOfString: {
      StringData *pstr = m_data.pstr;
      if (!pstr->isStatic()) {
        StringData *sd = makeStaticString(pstr);
        decRefStr(pstr);
        m_data.pstr = sd;
        assert(m_data.pstr->isStatic());
        m_type = KindOfStaticString;
      }
      return;
    }

    case KindOfArray: {
      ArrayData *parr = m_data.parr;
      if (!parr->isStatic()) {
        ArrayData *ad = ArrayData::GetScalarArray(parr);
        decRefArr(parr);
        m_data.parr = ad;
        assert(m_data.parr->isStatic());
      }
      return;
    }

    case KindOfObject:
    case KindOfResource:
    case KindOfRef:
    case KindOfClass:
      break;
  }
  not_reached();
}
Beispiel #11
0
void String::unserialize(VariableUnserializer *uns,
                         char delimiter0 /* = '"' */,
                         char delimiter1 /* = '"' */) {
  int64 size = uns->readInt();
  if (size >= RuntimeOption::MaxSerializedStringSize) {
    throw Exception("Size of serialized string (%d) exceeds max", int(size));
  }
  if (size < 0) {
    throw Exception("Size of serialized string (%d) must not be negative",
                    int(size));
  }

  char ch = uns->readChar();
  if (ch != ':') {
    throw Exception("Expected ':' but got '%c'", ch);
  }
  ch = uns->readChar();
  if (ch != delimiter0) {
    throw Exception("Expected '%c' but got '%c'", delimiter0, ch);
  }
  StringData *px = NEW(StringData)(int(size));
  MutableSlice buf = px->mutableSlice();
  assert(size <= buf.len);
  uns->read(buf.ptr, size);
  px->setSize(size);
  if (m_px) decRefStr(m_px);
  m_px = px;
  px->setRefCount(1);

  ch = uns->readChar();
  if (ch != delimiter1) {
    throw Exception("Expected '%c' but got '%c'", delimiter1, ch);
  }

  checkStatic();
}
Beispiel #12
0
String &String::operator=(const std::string & s) {
  if (m_px) decRefStr(m_px);
  m_px = NEW(StringData)(s.c_str(), s.size(), CopyString);
  m_px->setRefCount(1);
  return *this;
}
Beispiel #13
0
void Variant::setEvalScalar() {
  assertx(cellIsPlausible(*this));

  auto const do_array = [this]{
    auto parr = m_data.parr;
    if (!parr->isStatic()) {
      auto ad = ArrayData::GetScalarArray(parr);
      assert(ad->isStatic());
      m_data.parr = ad;
      decRefArr(parr);
    }
  };

  switch (m_type) {
    case KindOfUninit:
    case KindOfNull:
    case KindOfBoolean:
    case KindOfInt64:
    case KindOfDouble:
      return;

    case KindOfString:
      m_type = KindOfPersistentString;
    case KindOfPersistentString: {
      auto pstr = m_data.pstr;
      if (!pstr->isStatic()) {
        StringData *sd = makeStaticString(pstr);
        decRefStr(pstr);
        m_data.pstr = sd;
        assert(m_data.pstr->isStatic());
      }
      return;
    }

    case KindOfVec:
      m_type = KindOfPersistentVec;
    case KindOfPersistentVec:
      do_array();
      return;

    case KindOfDict:
      m_type = KindOfPersistentDict;
    case KindOfPersistentDict:
      do_array();
      return;

    case KindOfKeyset:
      m_type = KindOfPersistentKeyset;
    case KindOfPersistentKeyset:
      do_array();
      return;

    case KindOfArray:
      m_type = KindOfPersistentArray;
    case KindOfPersistentArray:
      do_array();
      return;

    case KindOfObject:
    case KindOfResource:
    case KindOfRef:
    case KindOfClass:
      break;
  }
  not_reached();
}
Beispiel #14
0
/**
 * print_string will decRef the string
 */
void print_string(StringData* s) {
  g_context->write(s->data(), s->size());
  TRACE(1, "t-x64 output(str): (%p) %43s\n", s->data(),
        escapeStringForCPP(s->data(), s->size()).data());
  decRefStr(s);
}
HOT_FUNC_VM
TypedValue* ldGblAddrDefHelper(StringData* name) {
  TypedValue* r = g_vmContext->m_globalVarEnv->lookupAdd(name);
  decRefStr(name);
  return r;
}
Beispiel #16
0
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));
}
Beispiel #17
0
void String::checkStaticHelper() {
  if (StringData* t = StringData::FindStaticString(m_px)) {
    decRefStr(m_px);
    m_px = t;
  }
}
Beispiel #18
0
String &String::operator=(const StaticString& str) {
  if (m_px) decRefStr(m_px);
  m_px = str.m_px;
  return *this;
}