Пример #1
0
TypedValue HHVM_FUNCTION(serialize_memoize_param, TypedValue param) {
  // Memoize throws in the emitter if any function parameters are references, so
  // we can just assert that the param is cell here
  assertx(param.m_type != KindOfRef);
  auto const type = param.m_type;

  if (isStringType(type)) {
    auto const str = param.m_data.pstr;
    if (str->empty()) {
      return make_tv<KindOfPersistentString>(s_emptyStrMemoKey.get());
    } else if ((unsigned char)str->data()[0] < '~') {
      // fb_compact_serialize always returns a string with the high-bit set in
      // the first character. Furthermore, we use ~ to begin all our special
      // constants, so anything less than ~ can't collide. There's no worry
      // about int-like strings because we use dicts (which don't perform key
      // coercion) to store the memoized values.
      str->incRefCount();
      return param;
    }
  } else if (isContainer(param) && getContainerSize(param) == 0) {
    return make_tv<KindOfPersistentString>(s_emptyArrMemoKey.get());
  } else if (type == KindOfUninit || type == KindOfNull) {
    return make_tv<KindOfPersistentString>(s_nullMemoKey.get());
  } else if (type == KindOfBoolean) {
    return make_tv<KindOfPersistentString>(
      param.m_data.num ? s_trueMemoKey.get() : s_falseMemoKey.get()
    );
  } else if (type == KindOfInt64) {
    return param;
  }

  return tvReturn(
    fb_compact_serialize(tvAsCVarRef(&param),
                         FBCompactSerializeBehavior::MemoizeParam));
}
Пример #2
0
Variant HHVM_FUNCTION(serialize_memoize_param, const Variant& param) {
  // Memoize throws in the emitter if any function parameters are references, so
  // we can just assert that the param is cell here
  const auto& cell_param = *tvAssertCell(param.asTypedValue());
  auto type = param.getType();

  if (type == KindOfInt64) {
    return param;
  } else if (type == KindOfUninit || type == KindOfNull) {
    return s_empty;
  } else if (type == KindOfBoolean) {
    return param.asBooleanVal() ? s_true : s_false;
  } else if (type == KindOfString) {
    auto str = param.asCStrRef();
    if (str.empty()) {
      return s_emptyStr;
    } else if (str.charAt(0) > '9') {
      // If it doesn't start with a number, then we know it can never collide
      // with an int or any of our constants, so it's fine as is
      return param;
    }
  } else if (isContainer(cell_param) && getContainerSize(cell_param) == 0) {
    return s_emptyArr;
  }

  return fb_compact_serialize(param, FBCompactSerializeBehavior::MemoizeParam);
}