示例#1
0
文件: tv-helpers.cpp 项目: c9s/hhvm
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* convCellToStrHelper(TypedValue tv) {
  switch (tv.m_type) {
    case KindOfUninit:
    case KindOfNull:    return buildStringData("");
    case KindOfBoolean: return buildStringData(tv.m_data.num ? "1" : "");
    case KindOfInt64:   return convIntToStrHelper(tv.m_data.num);
    case KindOfDouble:  return convDblToStrHelper(tv.m_data.num);
    case KindOfStaticString:
    case KindOfString:  return tv.m_data.pstr;
    case KindOfArray:   tvDecRefArr(&tv); return buildStringData("Array");
    case KindOfObject:  return convObjToStrHelper(tv.m_data.pobj);
    default:            not_reached();
  }
}
示例#3
0
StringData* convCellToStrHelper(TypedValue tv) {
  switch (tv.m_type) {
  case KindOfUninit:
  case KindOfNull:     return s_empty.get();
  case KindOfBoolean:  return tv.m_data.num ? s_1.get() : s_empty.get();
  case KindOfInt64:    return convIntToStrHelper(tv.m_data.num);
  case KindOfDouble:   return convDblToStrHelper(tv.m_data.num);
  case KindOfStaticString:
  case KindOfString:   // No incref, since there is also a logical decref of
                       // our argument.
                       return tv.m_data.pstr;
  case KindOfArray:    tvDecRefArr(&tv); return s_Array.get();
  case KindOfObject:   return convObjToStrHelper(tv.m_data.pobj);
  case KindOfResource: return convResToStrHelper(tv.m_data.pres);
  default:             not_reached();
  }
}
示例#4
0
void tvCastToBooleanInPlace(TypedValue* tv) {
  tvUnboxIfNeeded(tv);
  bool b;
  switch (tv->m_type) {
  case KindOfUninit:
  case KindOfNull:    b = false; break;
  case KindOfBoolean: return;
  case KindOfInt64:   b = (tv->m_data.num != 0LL); break;
  case KindOfDouble:  b = (tv->m_data.dbl != 0); break;
  case KindOfStaticString: b = tv->m_data.pstr->toBoolean(); break;
  case KindOfString:  b = tv->m_data.pstr->toBoolean(); tvDecRefStr(tv); break;
  case KindOfArray:   b = (!tv->m_data.parr->empty()); tvDecRefArr(tv); break;
  case KindOfObject:  b = (tv->m_data.pobj != nullptr); tvDecRefObj(tv); break;
  default:            assert(false); b = false; break;
  }
  tv->m_data.num = b;
  tv->m_type = KindOfBoolean;
}
示例#5
0
void cellCastToInt64InPlace(Cell* cell) {
  assert(cellIsPlausible(*cell));

  int64_t i;
  switch (cell->m_type) {
  case KindOfUninit:
  case KindOfNull:
    cell->m_data.num = 0LL;
    // Fall through
  case KindOfBoolean:
    assert(cell->m_data.num == 0LL || cell->m_data.num == 1LL);
    cell->m_type = KindOfInt64;
    // Fall through
  case KindOfInt64:
    return;
  case KindOfDouble:  {
    i = toInt64(cell->m_data.dbl);
    break;
  }
  case KindOfStaticString: i = (cell->m_data.pstr->toInt64()); break;
  case KindOfString:  {
    i = cell->m_data.pstr->toInt64();
    tvDecRefStr(cell);
    break;
  }
  case KindOfArray:
    i = cell->m_data.parr->empty() ? 0 : 1;
    tvDecRefArr(cell);
    break;
  case KindOfObject:
    i = cell->m_data.pobj->o_toInt64();
    tvDecRefObj(cell);
    break;
  case KindOfResource:
    i = cell->m_data.pres->o_toInt64();
    tvDecRefRes(cell);
    break;
  default:
    not_reached();
  }
  cell->m_data.num = i;
  cell->m_type = KindOfInt64;
}
示例#6
0
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;
}
示例#7
0
void tvCastToInt64InPlace(TypedValue* tv, int base /* = 10 */) {
  tvUnboxIfNeeded(tv);
  int64_t i;
  switch (tv->m_type) {
  case KindOfUninit:
  case KindOfNull:
    tv->m_data.num = 0LL;
    // Fall through
  case KindOfBoolean:
    assert(tv->m_data.num == 0LL || tv->m_data.num == 1LL);
    tv->m_type = KindOfInt64;
    // Fall through
  case KindOfInt64:
    return;
  case KindOfDouble:  {
    i = toInt64(tv->m_data.dbl);
    break;
  }
  case KindOfStaticString: i = (tv->m_data.pstr->toInt64(base)); break;
  case KindOfString:  {
    i = (tv->m_data.pstr->toInt64(base));
    tvDecRefStr(tv);
    break;
  }
  case KindOfArray:   {
    i = (tv->m_data.parr->empty() ? 0LL : 1LL);
    tvDecRefArr(tv);
    break;
  }
  case KindOfObject:  {
    i = (tv->m_data.pobj ? tv->m_data.pobj->o_toInt64() : 0LL);
    tvDecRefObj(tv);
    break;
  }
  default:            assert(false); i = 0LL; break;
  }
  tv->m_data.num = i;
  tv->m_type = KindOfInt64;
}
示例#8
0
void tvCastToBooleanInPlace(TypedValue* tv) {
  assert(tvIsPlausible(*tv));
  tvUnboxIfNeeded(tv);
  bool b;

  do {
    switch (tv->m_type) {
      case KindOfUninit:
      case KindOfNull:
        b = false;
        continue;

      case KindOfBoolean:
        return;

      case KindOfInt64:
        b = (tv->m_data.num != 0LL);
        continue;

      case KindOfDouble:
        b = (tv->m_data.dbl != 0);
        continue;

      case KindOfPersistentString:
        b = tv->m_data.pstr->toBoolean();
        continue;

      case KindOfString:
        b = tv->m_data.pstr->toBoolean();
        tvDecRefStr(tv);
        continue;

      case KindOfPersistentArray:
        b = !tv->m_data.parr->empty();
        continue;

      case KindOfArray:
        b = !tv->m_data.parr->empty();
        tvDecRefArr(tv);
        continue;

      case KindOfObject:
        b = tv->m_data.pobj->toBoolean();
        tvDecRefObj(tv);
        continue;

      case KindOfResource:
        b = tv->m_data.pres->data()->o_toBoolean();
        tvDecRefRes(tv);
        continue;

      case KindOfRef:
      case KindOfClass:
        break;
    }
    not_reached();
  } while (0);

  tv->m_data.num = b;
  tv->m_type = KindOfBoolean;
}
示例#9
0
void tvCastToArrayInPlace(TypedValue* tv) {
  assert(tvIsPlausible(*tv));
  tvUnboxIfNeeded(tv);
  ArrayData* a;

  do {
    switch (tv->m_type) {
      case KindOfUninit:
      case KindOfNull:
        a = ArrayData::Create();
        continue;

      case KindOfBoolean:
      case KindOfInt64:
      case KindOfDouble:
      case KindOfPersistentString:
        a = ArrayData::Create(tvAsVariant(tv));
        continue;

      case KindOfString:
        a = ArrayData::Create(tvAsVariant(tv));
        tvDecRefStr(tv);
        continue;

      case KindOfPersistentVec: {
        auto* adIn = tv->m_data.parr;
        assert(adIn->isVecArray());
        a = PackedArray::ToPHPArrayVec(adIn, true);
        assert(a != adIn);
        continue;
      }

      case KindOfVec: {
        auto* adIn = tv->m_data.parr;
        assert(adIn->isVecArray());
        a = PackedArray::ToPHPArrayVec(adIn, adIn->cowCheck());
        if (a != adIn) tvDecRefArr(tv);
        continue;
      }

      case KindOfPersistentDict: {
        auto* adIn = tv->m_data.parr;
        assert(adIn->isDict());
        a = MixedArray::ToPHPArrayDict(adIn, true);
        assert(a != adIn);
        continue;
      }

      case KindOfDict: {
        auto* adIn = tv->m_data.parr;
        assert(adIn->isDict());
        a = MixedArray::ToPHPArrayDict(adIn, adIn->cowCheck());
        if (a != adIn) tvDecRefArr(tv);
        continue;
      }

      case KindOfPersistentKeyset: {
        auto* adIn = tv->m_data.parr;
        assert(adIn->isKeyset());
        a = MixedArray::ToPHPArrayKeyset(adIn, true);
        assert(a != adIn);
        continue;
      }

      case KindOfKeyset: {
        auto* adIn = tv->m_data.parr;
        assert(adIn->isKeyset());
        a = MixedArray::ToPHPArrayKeyset(adIn, adIn->cowCheck());
        if (a != adIn) tvDecRefArr(tv);
        continue;
      }

      case KindOfPersistentArray:
      case KindOfArray:
        assert(tv->m_data.parr->isPHPArray());
        return;

      case KindOfObject:
        // For objects, we fall back on the Variant machinery
        tvAsVariant(tv) = tv->m_data.pobj->toArray();
        return;

      case KindOfResource:
        a = ArrayData::Create(tvAsVariant(tv));
        tvDecRefRes(tv);
        continue;

      case KindOfRef:
      case KindOfClass:
        break;
    }
    not_reached();
  } while (0);

  assert(!a->isRefCounted() || a->hasExactlyOneRef());

  tv->m_data.parr = a;
  tv->m_type = KindOfArray;
  assert(cellIsPlausible(*tv));
}
示例#10
0
void cellCastToInt64InPlace(Cell* cell) {
  assert(cellIsPlausible(*cell));
  int64_t i;

  do {
    switch (cell->m_type) {
      case KindOfUninit:
      case KindOfNull:
        cell->m_data.num = 0LL;
        // fallthru
      case KindOfBoolean:
        assert(cell->m_data.num == 0LL || cell->m_data.num == 1LL);
        cell->m_type = KindOfInt64;
        // fallthru
      case KindOfInt64:
        return;

      case KindOfDouble:
        i = toInt64(cell->m_data.dbl);
        continue;

      case KindOfPersistentString:
        i = cell->m_data.pstr->toInt64();
        continue;

      case KindOfString:
        i = cell->m_data.pstr->toInt64();
        tvDecRefStr(cell);
        continue;

      case KindOfPersistentVec:
      case KindOfPersistentDict:
      case KindOfPersistentKeyset:
      case KindOfPersistentArray:
        i = cell->m_data.parr->empty() ? 0 : 1;
        continue;

      case KindOfVec:
      case KindOfDict:
      case KindOfKeyset:
      case KindOfArray:
        i = cell->m_data.parr->empty() ? 0 : 1;
        tvDecRefArr(cell);
        continue;

      case KindOfObject:
        i = cell->m_data.pobj->toInt64();
        tvDecRefObj(cell);
        continue;

      case KindOfResource:
        i = cell->m_data.pres->data()->o_toInt64();
        tvDecRefRes(cell);
        continue;

      case KindOfRef:
      case KindOfClass:
        break;
    }
    not_reached();
  } while (0);

  cell->m_data.num = i;
  cell->m_type = KindOfInt64;
}
示例#11
0
void tvCastToDoubleInPlace(TypedValue* tv) {
  assert(tvIsPlausible(*tv));
  tvUnboxIfNeeded(tv);
  double d;

  do {
    switch (tv->m_type) {
      case KindOfUninit:
      case KindOfNull:
        d = 0.0;
        continue;

      case KindOfBoolean:
        assert(tv->m_data.num == 0LL || tv->m_data.num == 1LL);
        // fallthru
      case KindOfInt64:
        d = (double)(tv->m_data.num);
        continue;

      case KindOfDouble:
        return;

      case KindOfPersistentString:
        d = tv->m_data.pstr->toDouble();
        continue;

      case KindOfString:
        d = tv->m_data.pstr->toDouble();
        tvDecRefStr(tv);
        continue;

      case KindOfPersistentVec:
      case KindOfPersistentDict:
      case KindOfPersistentKeyset:
      case KindOfPersistentArray:
        d = tv->m_data.parr->empty() ? 0 : 1;
        continue;

      case KindOfVec:
      case KindOfDict:
      case KindOfKeyset:
      case KindOfArray:
        d = tv->m_data.parr->empty() ? 0 : 1;
        tvDecRefArr(tv);
        continue;

      case KindOfObject:
        d = tv->m_data.pobj->toDouble();
        tvDecRefObj(tv);
        continue;

      case KindOfResource:
        d = tv->m_data.pres->data()->o_toDouble();
        tvDecRefRes(tv);
        continue;

      case KindOfRef:
      case KindOfClass:
        break;
    }
    not_reached();
  } while (0);

  tv->m_data.dbl = d;
  tv->m_type = KindOfDouble;
}