Пример #1
0
bool tvSame(const TypedValue* tv1, const TypedValue* tv2) {
  bool const null1 = IS_NULL_TYPE(tv1->m_type);
  bool const null2 = IS_NULL_TYPE(tv2->m_type);
  if (null1 && null2) return true;
  if (null1 || null2) return false;

  if (tv1->m_type == KindOfRef) tv1 = tv1->m_data.pref->tv();
  if (tv2->m_type == KindOfRef) tv2 = tv2->m_data.pref->tv();

  switch (tv1->m_type) {
  case KindOfInt64:
  case KindOfBoolean:
    if (tv2->m_type != tv1->m_type) return false;
    return tv1->m_data.num == tv2->m_data.num;
  case KindOfDouble:
    if (tv2->m_type != tv1->m_type) return false;
    return tv1->m_data.dbl == tv2->m_data.dbl;

  case KindOfStaticString:
  case KindOfString:
    if (!IS_STRING_TYPE(tv2->m_type)) return false;
    return tv1->m_data.pstr->same(tv2->m_data.pstr);

  case KindOfArray:
    if (tv2->m_type != KindOfArray) return false;
    return tv1->m_data.parr->equal(tv2->m_data.parr, true);

  case KindOfObject:
    return tv2->m_type == KindOfObject &&
      tv1->m_data.pobj == tv2->m_data.pobj;

  default:
    break;
  }
  not_reached();
}
Пример #2
0
Resource Variant::toResourceHelper() const {
  switch (m_type) {
    case KindOfUninit:
    case KindOfNull:
    case KindOfBoolean:
    case KindOfInt64:
    case KindOfDouble:
    case KindOfStaticString:
    case KindOfString:
    case KindOfArray:
    case KindOfObject:
      return Resource(makeSmartPtr<DummyResource>());

    case KindOfResource:
      return m_data.pres;

    case KindOfRef:
      return m_data.pref->var()->toResource();

    case KindOfClass:
      break;
  }
  not_reached();
}
Пример #3
0
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();
}
Пример #4
0
bool cellSame(Cell c1, Cell c2) {
  assert(cellIsPlausible(c1));
  assert(cellIsPlausible(c2));

  bool const null1 = IS_NULL_TYPE(c1.m_type);
  bool const null2 = IS_NULL_TYPE(c2.m_type);
  if (null1 && null2) return true;
  if (null1 || null2) return false;

  switch (c1.m_type) {
  case KindOfInt64:
  case KindOfBoolean:
    if (c2.m_type != c1.m_type) return false;
    return c1.m_data.num == c2.m_data.num;
  case KindOfDouble:
    if (c2.m_type != c1.m_type) return false;
    return c1.m_data.dbl == c2.m_data.dbl;

  case KindOfStaticString:
  case KindOfString:
    if (!IS_STRING_TYPE(c2.m_type)) return false;
    return c1.m_data.pstr->same(c2.m_data.pstr);

  case KindOfArray:
    if (c2.m_type != KindOfArray) return false;
    return c1.m_data.parr->equal(c2.m_data.parr, true);

  case KindOfObject:
    return c2.m_type == KindOfObject &&
      c1.m_data.pobj == c2.m_data.pobj;

  default:
    break;
  }
  not_reached();
}
Пример #5
0
bool Variant::isScalar() const noexcept {
  switch (getType()) {
    case KindOfUninit:
    case KindOfNull:
    case KindOfArray:
    case KindOfObject:
    case KindOfResource:
      return false;

    case KindOfBoolean:
    case KindOfInt64:
    case KindOfDouble:
    case KindOfStaticString:
    case KindOfString:
      return true;

    case KindOfRef:
      always_assert(false && "isScalar() called on a boxed value");

    case KindOfClass:
      break;
  }
  not_reached();
}
Пример #6
0
void
IRTranslator::translateSetOpL(const NormalizedInstruction& i) {
  auto const opc = [&] {
    switch (static_cast<SetOpOp>(i.imm[1].u_OA)) {
    case SetOpOp::PlusEqual:   return Op::Add;
    case SetOpOp::MinusEqual:  return Op::Sub;
    case SetOpOp::MulEqual:    return Op::Mul;
    case SetOpOp::PlusEqualO:  return Op::AddO;
    case SetOpOp::MinusEqualO: return Op::SubO;
    case SetOpOp::MulEqualO:   return Op::MulO;
    case SetOpOp::DivEqual:    HHIR_UNIMPLEMENTED(SetOpL_Div);
    case SetOpOp::ConcatEqual: return Op::Concat;
    case SetOpOp::ModEqual:    HHIR_UNIMPLEMENTED(SetOpL_Mod);
    case SetOpOp::PowEqual:    HHIR_UNIMPLEMENTED(SetOpL_Pow);;
    case SetOpOp::AndEqual:    return Op::BitAnd;
    case SetOpOp::OrEqual:     return Op::BitOr;
    case SetOpOp::XorEqual:    return Op::BitXor;
    case SetOpOp::SlEqual:     HHIR_UNIMPLEMENTED(SetOpL_Shl);
    case SetOpOp::SrEqual:     HHIR_UNIMPLEMENTED(SetOpL_Shr);
    }
    not_reached();
  }();
  HHIR_EMIT(SetOpL, opc, i.imm[0].u_LA);
}
Пример #7
0
DataType Type::toDataType() const {
  assert(!isPtr());
  if (isBoxed()) {
    return KindOfRef;
  }

  // Order is important here: types must progress from more specific
  // to less specific to return the most specific DataType.
  if (subtypeOf(Uninit))        return KindOfUninit;
  if (subtypeOf(Null))          return KindOfNull;
  if (subtypeOf(Bool))          return KindOfBoolean;
  if (subtypeOf(Int))           return KindOfInt64;
  if (subtypeOf(Dbl))           return KindOfDouble;
  if (subtypeOf(StaticStr))     return KindOfStaticString;
  if (subtypeOf(Str))           return KindOfString;
  if (subtypeOf(Arr))           return KindOfArray;
  if (subtypeOf(Obj))           return KindOfObject;
  if (subtypeOf(Res))           return KindOfResource;
  if (subtypeOf(Cls))           return KindOfClass;
  if (subtypeOf(UncountedInit)) return KindOfUncountedInit;
  if (subtypeOf(Uncounted))     return KindOfUncounted;
  if (subtypeOf(Gen))           return KindOfAny;
  not_reached();
}
Пример #8
0
RegionDescPtr selectRegion(const RegionContext& context,
                           TransKind kind) {
  auto const mode = regionMode();

  FTRACE(1,
    "Select region: mode={} context:\n{}",
    static_cast<int>(mode), show(context)
  );

  auto region = [&]{
    try {
      switch (mode) {
        case RegionMode::None:
          return RegionDescPtr{nullptr};
        case RegionMode::Method:
          return selectMethod(context);
        case RegionMode::Tracelet:
          return selectTracelet(context, RuntimeOption::EvalJitMaxRegionInstrs,
                                kind == TransKind::Profile);
      }
      not_reached();
    } catch (const std::exception& e) {
      FTRACE(1, "region selector threw: {}\n", e.what());
      return RegionDescPtr{nullptr};
    }
  }();

  if (region) {
    FTRACE(3, "{}", show(*region));
    always_assert(region->instrSize() <= RuntimeOption::EvalJitMaxRegionInstrs);
  } else {
    FTRACE(1, "no region selectable; using tracelet compiler\n");
  }

  return region;
}
Пример #9
0
/**
 * Returns the expected input flavor of stack slot idx.
 */
FlavorDesc instrInputFlavor(PC op, uint32_t idx) {
#define NOV always_assert(0 && "Opcode has no stack inputs");
#define ONE(f1) return doFlavor(idx, f1);
#define TWO(f1, f2) return doFlavor(idx, f1, f2);
#define THREE(f1, f2, f3) return doFlavor(idx, f1, f2, f3);
#define FOUR(f1, f2, f3, f4) return doFlavor(idx, f1, f2, f3, f4);
#define MFINAL return manyFlavor(op, idx, CRV);
#define F_MFINAL MFINAL
#define C_MFINAL return idx == 0 ? CV : CRV;
#define V_MFINAL return idx == 0 ? VV : CRV;
#define FMANY return manyFlavor(op, idx, FV);
#define CVUMANY return manyFlavor(op, idx, CVUV);
#define CMANY return manyFlavor(op, idx, CV);
#define SMANY return manyFlavor(op, idx, CV);
#define IDX_A return baseSFlavor(op, idx);
#define O(name, imm, pop, push, flags) case Op::name: pop
  switch (peek_op(op)) {
    OPCODES
  }
  not_reached();
#undef NOV
#undef ONE
#undef TWO
#undef THREE
#undef FOUR
#undef MFINAL
#undef F_MFINAL
#undef C_MFINAL
#undef V_MFINAL
#undef FMANY
#undef CVUMANY
#undef CMANY
#undef SMANY
#undef IDX_A
#undef O
}
Пример #10
0
DataType DataTypeProfiler::operator()(DataType type) {
  switch (type) {
    case KindOfUninit:        m_uninit.count(); break;
    case KindOfNull:          m_null.count(); break;
    case KindOfBoolean:       m_boolean.count(); break;
    case KindOfInt64:         m_int.count(); break;
    case KindOfDouble:        m_double.count(); break;
    case KindOfPersistentString:  m_persistent_string.count(); break;
    case KindOfString:        m_string.count(); break;
    case KindOfPersistentVec:   m_persistent_vec.count(); break;
    case KindOfVec:           m_vec.count(); break;
    case KindOfPersistentDict:   m_persistent_dict.count(); break;
    case KindOfDict:          m_dict.count(); break;
    case KindOfPersistentKeyset: m_persistent_keyset.count(); break;
    case KindOfKeyset:        m_keyset.count(); break;
    case KindOfPersistentArray:  m_persistent_array.count(); break;
    case KindOfArray:         m_array.count(); break;
    case KindOfObject:        m_object.count(); break;
    case KindOfResource:      m_resource.count(); break;
    case KindOfRef:           m_ref.count(); break;
    case KindOfClass:         not_reached();
  }
  return type;
}
Пример #11
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 empty_string.get();
  case KindOfBoolean: return tv->m_data.num ? s_1.get() : empty_string.get();
  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:   return s_Array.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;
}
Пример #12
0
/*
 * Returns true iff t is specific enough to fit tc, meaning a consumer
 * constraining a value with tc would be satisfied with t as the value's type
 * after relaxation.
 */
bool typeFitsConstraint(Type t, TypeConstraint tc) {
  assert(t != Type::Bottom);

  if (tc.innerCat > DataTypeGeneric) {
    // First check the outer constraint.
    if (!typeFitsConstraint(t, tc.category)) return false;

    // Then, if t might be boxed, check the inner type.
    return t.notBoxed() ||
      typeFitsConstraint((t & Type::BoxedCell).innerType(), tc.innerCat);
  }

  switch (tc.category) {
    case DataTypeGeneric:
      return true;

    case DataTypeCountness:
      // Consumers using this constraint are probably going to decref the
      // value, so it's ok if we know whether t is counted or not. Arr and Str
      // are special cased because we don't guard on staticness for them.
      return t.notCounted() ||
             t <= (Type::Counted | Type::StaticArr | Type::StaticStr);

    case DataTypeCountnessInit:
      return typeFitsConstraint(t, DataTypeCountness) &&
             (t <= Type::Uninit || t.not(Type::Uninit));

    case DataTypeSpecific:
      return t.isKnownDataType();

    case DataTypeSpecialized:
      return t.isSpecialized();
  }

  not_reached();
}
Пример #13
0
MemberKey decode_member_key(PC& pc, Either<const Unit*, const UnitEmitter*> u) {
  auto const mcode = static_cast<MemberCode>(decode_byte(pc));

  switch (mcode) {
    case MEC: case MEL: case MPC: case MPL:
      return MemberKey{mcode, decode_iva(pc)};

    case MEI:
      return MemberKey{mcode, decode_raw<int64_t>(pc)};

    case MET: case MPT: case MQT: {
      auto const id = decode_raw<Id>(pc);
      auto const str = u.match(
        [id](const Unit* u) { return u->lookupLitstrId(id); },
        [id](const UnitEmitter* ue) { return ue->lookupLitstr(id); }
      );
      return MemberKey{mcode, str};
    }

    case MW:
      return MemberKey{};
  }
  not_reached();
}
Пример #14
0
/*
 * Returns the least specific supertype of t that maintains the properties
 * required by cat.
 */
Type relaxType(Type t, DataTypeCategory cat) {
  always_assert(t <= Type::Gen);

  switch (cat) {
    case DataTypeGeneric:
      return Type::Gen;

    case DataTypeCountness:
      return t.notCounted() ? Type::Uncounted : t.unspecialize();

    case DataTypeCountnessInit:
      if (t <= Type::Uninit) return Type::Uninit;
      return t.notCounted() ? Type::UncountedInit : t.unspecialize();

    case DataTypeSpecific:
      return t.unspecialize();

    case DataTypeSpecialized:
      assert(t.isSpecialized());
      return t;
  }

  not_reached();
}
Пример #15
0
Type typeSetOp(SetOpOp op, Type lhs, Type rhs) {
  switch (op) {
  case SetOpOp::PlusEqual:   return typeAdd(lhs, rhs);
  case SetOpOp::MinusEqual:  return typeSub(lhs, rhs);
  case SetOpOp::MulEqual:    return typeMul(lhs, rhs);

  case SetOpOp::DivEqual:    return typeDiv(lhs, rhs);
  case SetOpOp::ModEqual:    return typeMod(lhs, rhs);
  case SetOpOp::PowEqual:    return typePow(lhs, rhs);

  case SetOpOp::AndEqual:    return typeBitAnd(lhs, rhs);
  case SetOpOp::OrEqual:     return typeBitOr(lhs, rhs);
  case SetOpOp::XorEqual:    return typeBitXor(lhs, rhs);

  case SetOpOp::PlusEqualO:  return typeAddO(lhs, rhs);
  case SetOpOp::MinusEqualO: return typeSubO(lhs, rhs);
  case SetOpOp::MulEqualO:   return typeMulO(lhs, rhs);

  case SetOpOp::ConcatEqual: return TStr;
  case SetOpOp::SlEqual:     return typeShl(lhs, rhs);
  case SetOpOp::SrEqual:     return typeShr(lhs, rhs);
  }
  not_reached();
}
Пример #16
0
void CodeGenerator::cgLdRaw(IRInstruction* inst) {
  auto* addr   = inst->src(0);
  auto* offset = inst->src(1);

  auto destReg = x2a(curOpd(inst->dst()).reg());
  auto addrReg = x2a(curOpd(addr).reg());

  if (addr->isConst()) {
    not_implemented();
  }

  if (offset->isConst()) {
    auto kind   = offset->getValInt();
    auto& slot  = RawMemSlot::Get(RawMemSlot::Kind(kind));
    auto ldSize = slot.size();
    auto offs   = slot.offset();

    switch (ldSize) {
      case sz::qword:
        m_as.  Ldr  (destReg, addrReg[offs]);
        break;
      case sz::dword:
        m_as.  Ldr  (destReg.W(), addrReg[offs]);
        break;
      case sz::byte:
        // Ldrb zero-extends
        m_as.  Ldrb (destReg.W(), addrReg[offs]);
        break;
      default: not_reached();
    }
  } else {
    auto offsetReg = x2a(curOpd(offset).reg());
    assert(inst->dst()->type().nativeSize() == sz::qword);
    m_as.  Ldr  (destReg, addrReg[offsetReg]);
  }
}
Пример #17
0
double Variant::toDoubleHelper() const {
  switch (m_type) {
    case KindOfUninit:
    case KindOfNull:          return 0.0;
    case KindOfBoolean:
    case KindOfInt64:         return (double)toInt64();
    case KindOfDouble:        return m_data.dbl;
    case KindOfPersistentString:
    case KindOfString:        return m_data.pstr->toDouble();
    case KindOfPersistentVec:
    case KindOfVec:
    case KindOfPersistentDict:
    case KindOfDict:
    case KindOfPersistentKeyset:
    case KindOfKeyset:
    case KindOfPersistentArray:
    case KindOfArray:         return (double)toInt64();
    case KindOfObject:        return m_data.pobj->toDouble();
    case KindOfResource:      return m_data.pres->data()->o_toDouble();
    case KindOfRef:           return m_data.pref->var()->toDouble();
    case KindOfClass:         break;
  }
  not_reached();
}
Пример #18
0
void GlobalsArray::OnSetEvalScalar(ArrayData*) {
  not_reached();
}
void c_AsyncGeneratorWaitHandle::t___construct() {
  // gen-ext-hhvm requires at least one declared method in the class to work
  not_reached();
}
Пример #20
0
std::string Scanner::escape(const char *str, int len, char quote_type) const {
  std::string output;
  output.reserve(len);

  if (quote_type == '\'') {
    for (int i = 0; i < len; i++) {
      unsigned char ch = str[i];
      if (ch == '\\') {
        if (++i < len) {
          switch (str[i]) {
            case '\\': output += "\\"; break;
            case '\'': output += '\''; break;
            default: {
              output += ch;
              output += str[i];
              break;
            }
          }
        } else {
          assert(false);
          output += ch;
        }
      } else {
        output += ch;
      }
    }
  } else {
    for (int i = 0; i < len; i++) {
      unsigned char ch = str[i];
      if (ch == '\\') {
        if (++i < len) {
          switch (str[i]) {
            case 'n':  output += '\n'; break;
            case 't':  output += '\t'; break;
            case 'r':  output += '\r'; break;
            case 'v':  output += '\v'; break;
            case 'f':  output += '\f'; break;
            case 'e':  output += '\033'; break;
            case '\\': output += '\\'; break;
            case '$':  output += '$';  break;
            case '"':
            case '`':
              if (str[i] != quote_type) {
                output += '\\';
              }
              output += str[i];
              break;
            case 'x':
            case 'X': {
              if (isxdigit(str[i+1])) {
                std::string shex;
                shex += str[++i]; // 0th hex digit
                if (isxdigit(str[i+1])) {
                  shex += str[++i]; // 1st hex digit
                }
                output += strtol(shex.c_str(), nullptr, 16);
              } else {
                output += ch;
                output += str[i];
              }
              break;
            }
            case 'u': {
              // Unicode escape sequence
              //   "\u{123456}"
              if (str[i+1] != '{') {
                // BC for "\u1234" passthrough
                output += ch;
                output += str[i];
                break;
              }

              bool valid = true;
              auto start = str + i + 2;
              auto closebrace = strchr(start, '}');
              if (closebrace > start) {
                for (auto p = start; p < closebrace; ++p) {
                  if (!isxdigit(*p)) {
                    valid = false;
                    break;
                  }
                }
              } else {
                valid = false;
              }

              auto fatal = [this](const char *msg) {
                auto loc = getLocation();
                return ParseTimeFatalException(
                  loc->file,
                  loc->r.line0,
                  "%s", msg);
              };
              if (!valid) {
                throw fatal("Invalid UTF-8 codepoint escape sequence");
              }

              std::string codepoint(start, closebrace - start);
              char *end = nullptr;
              int32_t uchar = strtol(codepoint.c_str(), &end, 16);
              if ((end && *end) || (uchar > 0x10FFFF)) {
                throw fatal(
                  "Invalid UTF-8 codepoint escape sequence: "
                  "Codepoint too large");
              }
              if (uchar <= 0x0007F) {
                output += (char)uchar;
              } else if (uchar <= 0x007FF) {
                output += (char)(0xC0 | ( uchar >> 6         ));
                output += (char)(0x80 | ( uchar        & 0x3F));
              } else if (uchar <= 0x00FFFF) {
                output += (char)(0xE0 | ( uchar >> 12        ));
                output += (char)(0x80 | ((uchar >>  6) & 0x3F));
                output += (char)(0x80 | ( uchar        & 0x3F));
              } else if (uchar <= 0x10FFFF) {
                output += (char)(0xF0 | ( uchar >> 18        ));
                output += (char)(0x80 | ((uchar >> 12) & 0x3F));
                output += (char)(0x80 | ((uchar >>  6) & 0x3F));
                output += (char)(0x80 | ( uchar        & 0x3F));
              } else {
                not_reached();
                assert(false);
              }
              i += codepoint.size() + 2 /* strlen("{}") */;
              break;
            }
Пример #21
0
void staticArrayStreamer(ArrayData* ad, std::ostream& out) {
  out << "array(";
  if (!ad->empty()) {
    bool comma = false;
    for (ArrayIter it(ad); !it.end(); it.next()) {
      if (comma) {
        out << ",";
      } else {
        comma = true;
      }
      Variant key = it.first();

      // Key.
      if (IS_INT_TYPE(key.getType())) {
        out << *key.getInt64Data();
      } else if (IS_STRING_TYPE(key.getType())) {
        out << "\""
            << escapeStringForCPP(key.getStringData()->data(),
                                  key.getStringData()->size())
            << "\"";
      } else {
        assert(false);
      }

      out << "=>";

      Variant val = it.second();

      // Value.
      [&] {
        switch (val.getType()) {
          case KindOfUninit:
          case KindOfNull:
            out << "null";
            return;
          case KindOfBoolean:
            out << (val.toBoolean() ? "true" : "false");
            return;
          case KindOfInt64:
            out << *val.getInt64Data();
            return;
          case KindOfDouble:
            out << *val.getDoubleData();
            return;
          case KindOfStaticString:
          case KindOfString:
            out << "\""
                << escapeStringForCPP(val.getStringData()->data(),
                                      val.getStringData()->size())
                << "\"";
            return;
          case KindOfArray:
            staticArrayStreamer(val.getArrayData(), out);
            return;
          case KindOfObject:
          case KindOfResource:
          case KindOfRef:
          case KindOfClass:
            not_reached();
        }
      }();
    }
  }
  out << ")";
}
Пример #22
0
size_t APCLocalArray::Vsize(const ArrayData*) { not_reached(); }
Пример #23
0
int immSize(PC origPC, int idx) {
  auto pc = origPC;
  auto const op = decode_op(pc);
  assert(idx >= 0 && idx < numImmediates(op));
  always_assert(idx < 4); // No origPCs have more than four immediates
  static const int8_t argTypeToSizes[] = {
#define ARGTYPE(nm, type) sizeof(type),
#define ARGTYPEVEC(nm, type) 0,
    ARGTYPES
#undef ARGTYPE
#undef ARGTYPEVEC
  };

  if (immType(op, idx) == IVA ||
      immType(op, idx) == LA ||
      immType(op, idx) == IA) {
    if (idx >= 1) pc += immSize(origPC, 0);
    if (idx >= 2) pc += immSize(origPC, 1);
    if (idx >= 3) pc += immSize(origPC, 2);
    return encoded_iva_size(decode_raw<uint8_t>(pc));
  }

  if (immType(op, idx) == KA) {
    if (idx >= 1) pc += immSize(origPC, 0);
    if (idx >= 2) pc += immSize(origPC, 1);
    if (idx >= 3) pc += immSize(origPC, 2);

    switch (decode_raw<MemberCode>(pc)) {
      case MW:
        return 1;
      case MEL: case MPL: case MEC: case MPC:
        return 1 + encoded_iva_size(decode_raw<uint8_t>(pc));
      case MEI:
        return 1 + sizeof(int64_t);
      case MET: case MPT: case MQT:
        return 1 + sizeof(Id);
    }
    not_reached();
  }

  if (immType(op, idx) == RATA) {
    if (idx >= 1) pc += immSize(origPC, 0);
    if (idx >= 2) pc += immSize(origPC, 1);
    if (idx >= 3) pc += immSize(origPC, 2);
    return encodedRATSize(pc);
  }

  if (immIsVector(op, idx)) {
    if (idx >= 1) pc += immSize(origPC, 0);
    if (idx >= 2) pc += immSize(origPC, 1);
    if (idx >= 3) pc += immSize(origPC, 2);
    int vecElemSz;
    auto itype = immType(op, idx);
    if (itype == BLA) {
      vecElemSz = sizeof(Offset);
    } else if (itype == ILA) {
      vecElemSz = 2 * sizeof(uint32_t);
    } else if (itype == VSA) {
      vecElemSz = sizeof(Id);
    } else {
      assert(itype == SLA);
      vecElemSz = sizeof(StrVecItem);
    }
    return sizeof(int32_t) + vecElemSz * decode_raw<int32_t>(pc);
  }

  ArgType type = immType(op, idx);
  return (type >= 0) ? argTypeToSizes[type] : 0;
}
Пример #24
0
bool APCLocalArray::AdvanceMArrayIter(ArrayData* ad, MArrayIter& fp) {
  not_reached();  // we should've escalated
}
Пример #25
0
void APCLocalArray::OnSetEvalScalar(ArrayData*) {
  not_reached();
}
Пример #26
0
bool APCLocalArray::ValidMArrayIter(const ArrayData* ad,
                                    const MArrayIter& fp) {
  assert(fp.getContainer() == ad);
  not_reached();  // we should've escalated
}
Пример #27
0
bool APCLocalArray::Uasort(ArrayData*, const Variant& cmp_function) {
  not_reached();
}
Пример #28
0
void APCLocalArray::Asort(ArrayData*, int sort_flags, bool ascending) {
  not_reached();
}
Пример #29
0
static Variant get_icu_display_value(const String &locale,
                                     const String &disp_locale,
                                     LocaleTag tag) {
  String locname(locale);
  if (tag != LOC_DISPLAY) {
    int ofs = getGrandfatheredOffset(locale);
    if (ofs >= 0) {
      if (tag == LOC_LANG) {
        locname = getGrandfatheredPreferred(ofs);
      } else {
        return false;
      }
    }
  }

  int32_t (*ulocfunc)(const char *loc, const char *dloc,
                      UChar *dest, int32_t destcap, UErrorCode *err);
  switch (tag) {
    case LOC_LANG:     ulocfunc = uloc_getDisplayLanguage; break;
    case LOC_SCRIPT:   ulocfunc = uloc_getDisplayScript;   break;
    case LOC_REGION:   ulocfunc = uloc_getDisplayCountry;  break;
    case LOC_VARIANT:  ulocfunc = uloc_getDisplayVariant;  break;
    case LOC_DISPLAY:  ulocfunc = uloc_getDisplayName;     break;
    default:
      assert(false);
      return false;
  }

  icu::UnicodeString buf;
  auto ubuf = buf.getBuffer(64);
  do {
    UErrorCode error = U_ZERO_ERROR;
    int32_t len = ulocfunc(locname.c_str(), disp_locale.c_str(),
                           ubuf, buf.getCapacity(), &error);
    if (error != U_BUFFER_OVERFLOW_ERROR &&
        error != U_STRING_NOT_TERMINATED_WARNING) {
      if (U_FAILURE(error)) {
        s_intl_error->setError(error, "locale_get_display_%s : unable to "
                                      "get locale %s",
                                      LocaleName(tag).c_str(),
                                      LocaleName(tag).c_str());
        return false;
      }
      buf.releaseBuffer(len);

      error = U_ZERO_ERROR;
      String out(u8(buf, error));
      if (U_FAILURE(error)) {
        s_intl_error->setError(error, "Unable to convert result from "
                                      "locale_get_display_%s to UTF-8",
                                      LocaleName(tag).c_str());
        return false;
      }
      return out;
    }
    if (len <= buf.getCapacity()) {
      // Avoid infinite loop
      buf.releaseBuffer(0);
      s_intl_error->setError(U_INTERNAL_PROGRAM_ERROR,
                             "Got invalid response from ICU");
      return false;
    }

    // Grow the buffer to sufficient size
    buf.releaseBuffer(0);
    ubuf = buf.getBuffer(len);
  } while (true);

  not_reached();
  return false;
}
Пример #30
0
static Variant get_icu_value(const String &locale, LocaleTag tag,
                             bool fromParseLocale = false) {
  String locale_name(locale);
  if (tag != LOC_CANONICALIZE) {
    if (getGrandfatheredOffset(locale) >= 0) {
      if (tag == LOC_LANG) {
        return locale;
      }
      return false;
    }
    if (fromParseLocale) {
      auto localecstr = locale.c_str();
      if (tag == LOC_LANG && locale.size() > 1 && isIDPrefix(localecstr)) {
        return locale;
      }
      int pos = singleton_pos(locale);
      if (pos == 0) {
        return null_string;
      } else if (pos > 0) {
        locale_name = f_substr(locale, 0, pos - 1);
      }
    }
  }

  int32_t (*ulocfunc)(const char *loc, char *val, int32_t len, UErrorCode *err);
  switch (tag) {
    case LOC_SCRIPT:       ulocfunc = uloc_getScript;    break;
    case LOC_LANG:         ulocfunc = uloc_getLanguage;  break;
    case LOC_REGION:       ulocfunc = uloc_getCountry;   break;
    case LOC_VARIANT:      ulocfunc = uloc_getVariant;   break;
    case LOC_CANONICALIZE: ulocfunc = uloc_canonicalize; break;
    default:
      assert(false);
      return false;
  }

  String buf(64, ReserveString);
  do {
    UErrorCode error = U_ZERO_ERROR;
    int32_t len = ulocfunc(locale_name.c_str(),
                           buf->mutableData(), buf->capacity(), &error);
    if (error != U_BUFFER_OVERFLOW_ERROR &&
        error != U_STRING_NOT_TERMINATED_WARNING) {
      if (U_FAILURE(error)) {
        s_intl_error->setError(error, "unable to get locale info");
        return false;
      }
      buf.setSize(len);
      return buf;
    }
    if (len <= buf->capacity()) {
      // Avoid infinite loop
      s_intl_error->setError(U_INTERNAL_PROGRAM_ERROR,
                             "Got invalid response from ICU");
      return false;
    }
    buf = String(len, ReserveString);
  } while (true);

  not_reached();
  return false;
}