Ejemplo n.º 1
0
static int collator_numeric_compare_function(CVarRef v1, CVarRef v2,
                                             const void *data,
                                             bool ascending) {
  Variant num1;
  Variant num2;

  if (v1.isString()) {
    num1 = collator_convert_string_to_double(v1);
  } else {
    num1 = v1.toDouble();
  }
  if (v2.isString()) {
    num2 = collator_convert_string_to_double(v2);
  } else {
    num2 = v2.toDouble();
  }
  if (ascending) {
    if (num1.less(num2)) return -1;
    if (num1.equal(num2)) return 0;
    return 1;
  }
  if (num1.less(num2)) return 1;
  if (num1.equal(num2)) return 0;
  return -1;
}
Ejemplo n.º 2
0
int Array::SortNumericDescending(CVarRef v1, CVarRef v2, const void *data) {
  double d1 = v1.toDouble();
  double d2 = v2.toDouble();
  if (d1 < d2) return 1;
  if (d1 == d2) return 0;
  return -1;
}
Ejemplo n.º 3
0
double VariantToMilliseconds(CVarRef arg) {
  if (arg.isNumeric(true)) {
    return U_MILLIS_PER_SECOND * arg.toDouble();
  }
  // TODO: Handle object IntlCalendar and DateTime
  return NAN;
}
Ejemplo n.º 4
0
static bool HHVM_METHOD(IntlCalendar, setTime, CVarRef date) {
  CAL_FETCH(data, this_, false);
  UErrorCode error = U_ZERO_ERROR;
  data->calendar()->setTime((UDate)date.toDouble(), error);
  if (U_FAILURE(error)) {
    data->setError(error, "Call to underlying method failed");
    return false;
  }
  return true;
}
Ejemplo n.º 5
0
Variant f_range(CVarRef low, CVarRef high, CVarRef step /* = 1 */) {
  bool is_step_double = false;
  double dstep = 1.0;
  if (step.isDouble()) {
    dstep = step.toDouble();
    is_step_double = true;
  } else if (step.isString()) {
    int64_t sn;
    double sd;
    DataType stype = step.toString()->isNumericWithVal(sn, sd, 0);
    if (stype == KindOfDouble) {
      is_step_double = true;
      dstep = sd;
    } else if (stype == KindOfInt64) {
      dstep = (double)sn;
    } else {
      dstep = step.toDouble();
    }
  } else {
    dstep = step.toDouble();
  }
  /* We only want positive step values. */
  if (dstep < 0.0) dstep *= -1;
  if (low.isString() && high.isString()) {
    String slow = low.toString();
    String shigh = high.toString();
    if (slow.size() >= 1 && shigh.size() >=1) {
      int64_t n1, n2;
      double d1, d2;
      DataType type1 = slow->isNumericWithVal(n1, d1, 0);
      DataType type2 = shigh->isNumericWithVal(n2, d2, 0);
      if (type1 == KindOfDouble || type2 == KindOfDouble || is_step_double) {
        if (type1 != KindOfDouble) d1 = slow.toDouble();
        if (type2 != KindOfDouble) d2 = shigh.toDouble();
        return ArrayUtil::Range(d1, d2, dstep);
      }

      int64_t lstep = (int64_t) dstep;
      if (type1 == KindOfInt64 || type2 == KindOfInt64) {
        if (type1 != KindOfInt64) n1 = slow.toInt64();
        if (type2 != KindOfInt64) n2 = shigh.toInt64();
        return ArrayUtil::Range((double)n1, (double)n2, lstep);
      }

      return ArrayUtil::Range((unsigned char)slow.charAt(0),
                              (unsigned char)shigh.charAt(0), lstep);
    }
  }

  if (low.is(KindOfDouble) || high.is(KindOfDouble) || is_step_double) {
    return ArrayUtil::Range(low.toDouble(), high.toDouble(), dstep);
  }

  int64_t lstep = (int64_t) dstep;
  return ArrayUtil::Range(low.toDouble(), high.toDouble(), lstep);
}
Ejemplo n.º 6
0
static bool HHVM_METHOD(IntlCalendar, isWeekend, CVarRef date) {
  CAL_FETCH(data, this_, false);
  if (date.isNull()) {
    return data->calendar()->isWeekend();
  }
  UErrorCode error = U_ZERO_ERROR;
  bool ret = data->calendar()->isWeekend((UDate)date.toDouble(), error);
  if (U_FAILURE(error)) {
    data->setError(error, "intlcal_is_weekend: Error calling ICU method");
    return false;
  }
  return ret;
}
Ejemplo n.º 7
0
static Variant HHVM_METHOD(IntlCalendar, fieldDifference,
                           CVarRef when, int64_t field) {
  CAL_FETCH(data, this_, false);
  CAL_CHECK_FIELD(field, "intlcal_field_difference");
  UErrorCode error = U_ZERO_ERROR;
  int64_t ret = data->calendar()->fieldDifference(
    (UDate)when.toDouble(), (UCalendarDateFields)field, error);
  if (U_FAILURE(error)) {
    data->setError(error, "intlcal_field_difference: "
                          "Call to ICU method has failed");
    return false;
  }
  return ret;
}
Ejemplo n.º 8
0
Numeric f_pow(CVarRef base, CVarRef exp) {
  int64_t bint, eint;
  double bdbl, edbl;
  DataType bt = base.toNumeric(bint, bdbl, true);
  DataType et = exp.toNumeric(eint, edbl, true);
  if (bt == KindOfInt64 && et == KindOfInt64 && eint >= 0) {
    if (eint == 0) return 1LL;
    if (bint == 0) return 0LL;

    // calculate pow(long,long) in O(log exp) operations, bail if overflow
    int64_t l1 = 1;
    while (eint >= 1) {
      int overflow;
      double dval = 0.0;
      if (eint % 2) {
        --eint;
        ZEND_SIGNED_MULTIPLY_LONG(l1, bint, l1, dval, overflow);
        if (overflow) return dval * pow(bint, eint);
      } else {
        eint /= 2;
        ZEND_SIGNED_MULTIPLY_LONG(bint, bint, bint, dval, overflow);
        if (overflow) return (double)l1 * pow(dval, eint);
      }
      if (eint == 0) {
        return l1;
      }
    }
  }
  if (bt != KindOfDouble) {
    bdbl = base.toDouble();
  }
  if (et != KindOfDouble) {
    edbl = exp.toDouble();
  }
  return pow(bdbl, edbl);
}
Ejemplo n.º 9
0
double f_round(CVarRef val, int64 precision /* = 0 */) {
  int64 ival;
  double dval;
  DataType k = val.toNumeric(ival, dval, true);
 if (k == KindOfInt64) {
   if (precision >= 0) {
    return ival;
   } else {
     dval = ival;
   }
 } else if (k != KindOfDouble) {
   dval = val.toDouble();
 }
 PHP_ROUND_WITH_FUZZ(dval, precision);
 return dval;
}
Ejemplo n.º 10
0
double f_round(CVarRef val, int64_t precision /* = 0 */,
               int64_t mode /* = PHP_ROUND_HALF_UP */) {
  int64_t ival;
  double dval;
  DataType k = val.toNumeric(ival, dval, true);
  if (k == KindOfInt64) {
    if (precision >= 0) {
     return ival;
    } else {
      dval = ival;
    }
  } else if (k != KindOfDouble) {
    dval = val.toDouble();
  }
  dval = php_math_round(dval, precision, mode);
  return dval;
}
Ejemplo n.º 11
0
int hphp_ffi_exportVariant(CVarRef v, void** result) {
  switch (v.getType()) {
  case KindOfNull:    return 0;
  case KindOfBoolean: *result = (void*)v.toBoolean(); return 1;
  case KindOfByte:
  case KindOfInt16:
  case KindOfInt32:
  case KindOfInt64: {
    *result = (void*)v.toInt64();
    return 2;
  }
  case KindOfDouble: {
    union {
      double d;
      void* p;
    } u;
    u.d = v.toDouble();
    *result = u.p;
    return 3;
  }
  case LiteralString: *result = (void*)v.getLiteralString(); return 4;
  case KindOfString: {
    StringData *sd = v.getStringData();
    sd->incRefCount();
    *result = (void*)sd;
    return 5;
  }
  case KindOfArray: {
    ArrayData *ad = v.getArrayData();
    ad->incRefCount();
    *result = (void*)ad;
    return 6;
  }
  case KindOfObject: {
    ObjectData *od = v.getObjectData();
    od->incRefCount();
    *result = (void*)od;
    return 7;
  }
  default:
    ASSERT(false);
    return 0;
  }
}
Ejemplo n.º 12
0
ThreadSharedVariant::ThreadSharedVariant(CVarRef source, bool serialized,
                                         bool inner /* = false */) {
  ASSERT(!serialized || source.isString());

  setOwner();
  m_ref = 1;

  switch (source.getType()) {
  case KindOfBoolean:
    {
      m_type = KindOfBoolean;
      m_data.num = source.toBoolean();
      break;
    }
  case KindOfByte:
  case KindOfInt16:
  case KindOfInt32:
  case KindOfInt64:
    {
      m_type = KindOfInt64;
      m_data.num = source.toInt64();
      break;
    }
  case KindOfDouble:
    {
      m_type = KindOfDouble;
      m_data.dbl = source.toDouble();
      break;
    }
  case KindOfStaticString:
  case KindOfString:
    {
      String s = source.toString();
      m_type = serialized ? KindOfObject : KindOfString;
      if (serialized) {
        // It is priming, and there might not be the right class definitions
        // for unserialization.
        s = apc_reserialize(s);
      }
      m_data.str = s->copy(true);
      break;
    }
  case KindOfArray:
    {
      m_type = KindOfArray;

      ArrayData *arr = source.getArrayData();

      if (!inner) {
        // only need to call hasInternalReference() on the toplevel array
        PointerSet seen;
        if (arr->hasInternalReference(seen)) {
          setSerializedArray();
          setShouldCache();
          String s = apc_serialize(source);
          m_data.str = new StringData(s.data(), s.size(), CopyString);
          break;
        }
      }

      size_t size = arr->size();
      if (arr->isVectorData()) {
        setIsVector();
        m_data.vec = new VectorData(size);
        uint i = 0;
        for (ArrayIter it(arr); !it.end(); it.next(), i++) {
          ThreadSharedVariant* val = createAnother(it.second(), false, true);
          if (val->shouldCache()) setShouldCache();
          m_data.vec->vals[i] = val;
        }
      } else {
        m_data.map = new ImmutableMap(size);
        uint i = 0;
        for (ArrayIter it(arr); !it.end(); it.next(), i++) {
          ThreadSharedVariant* key = createAnother(it.first(), false);
          ThreadSharedVariant* val = createAnother(it.second(), false, true);
          if (val->shouldCache()) setShouldCache();
          m_data.map->add(key, val);
        }
      }
      break;
    }
  default:
    {
      m_type = KindOfObject;
      setShouldCache();
      String s = apc_serialize(source);
      m_data.str = new StringData(s.data(), s.size(), CopyString);
      break;
    }
  }
}
SharedVariant::SharedVariant(CVarRef source, bool serialized,
                             bool inner /* = false */,
                             bool unserializeObj /* = false */)
  : m_count (1), m_shouldCache(false), m_flags(0){
  ASSERT(!serialized || source.isString());

  m_type = source.getType();

  switch (m_type) {
  case KindOfBoolean:
    {
      m_data.num = source.toBoolean();
      break;
    }
  case KindOfByte:
  case KindOfInt16:
  case KindOfInt32:
  case KindOfInt64:
    {
      m_type = KindOfInt64;
      m_data.num = source.toInt64();
      break;
    }
  case KindOfDouble:
    {
      m_data.dbl = source.toDouble();
      break;
    }
  case KindOfStaticString:
  case KindOfString:
    {
      String s = source.toString();
      if (serialized) {
        m_type = KindOfObject;
        // It is priming, and there might not be the right class definitions
        // for unserialization.
        s = apc_reserialize(s);
      }
      m_data.str = s->copy(true);
      break;
    }
  case KindOfArray:
    {
      ArrayData *arr = source.getArrayData();

      if (!inner) {
        // only need to call hasInternalReference() on the toplevel array
        PointerSet seen;
        if (arr->hasInternalReference(seen)) {
          setSerializedArray();
          m_shouldCache = true;
          String s = apc_serialize(source);
          m_data.str = new StringData(s.data(), s.size(), CopyString);
          break;
        }
      }

      size_t size = arr->size();
      if (arr->isVectorData()) {
        setIsVector();
        m_data.vec = new VectorData(size);
        uint i = 0;
        for (ArrayIter it(arr); !it.end(); it.next(), i++) {
          SharedVariant* val = Create(it.secondRef(), false, true,
                                      unserializeObj);
          if (val->m_shouldCache) m_shouldCache = true;
          m_data.vec->vals[i] = val;
        }
      } else {
        m_data.map = new ImmutableMap(size);
        for (ArrayIter it(arr); !it.end(); it.next()) {
          SharedVariant* key = Create(it.first(), false, true,
                                      unserializeObj);
          SharedVariant* val = Create(it.secondRef(), false, true,
                                      unserializeObj);
          if (val->m_shouldCache) m_shouldCache = true;
          m_data.map->add(key, val);
        }
      }
      break;
    }
  case KindOfNull:
    {
      m_data.num = 0;
      break;
    }
  default:
    {
      ASSERT(source.isObject());
      m_shouldCache = true;
      if (unserializeObj) {
        // This assumes hasInternalReference(seen, true) is false
        ImmutableObj* obj = new ImmutableObj(source.getObjectData());
        m_data.obj = obj;
        setIsObj();
      } else {
        String s = apc_serialize(source);
        m_data.str = new StringData(s.data(), s.size(), CopyString);
      }
      break;
    }
  }
}
Ejemplo n.º 14
0
double f_floatval(CVarRef v) { return v.toDouble();}
Ejemplo n.º 15
0
double f_doubleval(CVarRef v) { return v.toDouble();}
Ejemplo n.º 16
0
void binary_serialize(int8_t thrift_typeID, PHPOutputTransport& transport,
                      CVarRef value, CArrRef fieldspec) {
  // At this point the typeID (and field num, if applicable) should've already
  // been written to the output so all we need to do is write the payload.
  switch (thrift_typeID) {
    case T_STOP:
    case T_VOID:
      return;
    case T_STRUCT: {
      if (!value.is(KindOfObject)) {
        throw_tprotocolexception("Attempt to send non-object "
                                 "type as a T_STRUCT", INVALID_DATA);
      }
      binary_serialize_spec(value.toObject(), transport,
                            f_hphp_get_static_property(value.toObject()->
                                                       o_getClassName(),
                                                       s_TSPEC,
                                                       false).toArray());
    } return;
    case T_BOOL:
      transport.writeI8(value.toBoolean() ? 1 : 0);
      return;
    case T_BYTE:
      transport.writeI8(value.toByte());
      return;
    case T_I16:
      transport.writeI16(value.toInt16());
      return;
    case T_I32:
      transport.writeI32(value.toInt32());
      return;
    case T_I64:
    case T_U64:
      transport.writeI64(value.toInt64());
      return;
    case T_DOUBLE: {
      union {
        int64_t c;
        double d;
      } a;
      a.d = value.toDouble();
      transport.writeI64(a.c);
    } return;
    case T_FLOAT: {
      union {
        int32_t c;
        float d;
      } a;
      a.d = (float)value.toDouble();
      transport.writeI32(a.c);
    } return;
    //case T_UTF7:
    case T_UTF8:
    case T_UTF16:
    case T_STRING: {
        String sv = value.toString();
        transport.writeString(sv.data(), sv.size());
    } return;
    case T_MAP: {
      Array ht = value.toArray();
      uint8_t keytype = fieldspec.rvalAt(PHPTransport::s_ktype,
                                         AccessFlags::Error_Key).toByte();
      transport.writeI8(keytype);
      uint8_t valtype = fieldspec.rvalAt(PHPTransport::s_vtype,
                                         AccessFlags::Error_Key).toByte();
      transport.writeI8(valtype);

      Array valspec = fieldspec.rvalAt(PHPTransport::s_val,
                                       AccessFlags::Error_Key).toArray();

      transport.writeI32(ht.size());
      for (ArrayIter key_ptr = ht.begin(); !key_ptr.end(); ++key_ptr) {
        binary_serialize_hashtable_key(keytype, transport, key_ptr.first());
        binary_serialize(valtype, transport, key_ptr.second(), valspec);
      }
    } return;
    case T_LIST: {
      Array ht = value.toArray();
      Variant val;

      uint8_t valtype = fieldspec.rvalAt(PHPTransport::s_etype,
                                         AccessFlags::Error_Key).toInt64();
      transport.writeI8(valtype);
      Array valspec = fieldspec.rvalAt(PHPTransport::s_elem,
                                       AccessFlags::Error_Key).toArray();
      transport.writeI32(ht.size());
      for (ArrayIter key_ptr = ht.begin(); !key_ptr.end(); ++key_ptr) {
        binary_serialize(valtype, transport, key_ptr.second(), valspec);
      }
    } return;
    case T_SET: {
      Array ht = value.toArray();

      uint8_t keytype = fieldspec.rvalAt(PHPTransport::s_etype,
                                         AccessFlags::Error_Key).toByte();
      transport.writeI8(keytype);

      transport.writeI32(ht.size());
      for (ArrayIter key_ptr = ht.begin(); !key_ptr.end(); ++key_ptr) {
        binary_serialize_hashtable_key(keytype, transport, key_ptr.first());
      }
    } return;
  };
  char errbuf[128];
  sprintf(errbuf, "Unknown thrift typeID %d", thrift_typeID);
  throw_tprotocolexception(String(errbuf, CopyString), INVALID_DATA);
}
Ejemplo n.º 17
0
ProcessSharedVariant::ProcessSharedVariant(CVarRef source,
                                           ProcessSharedVariantLock* lock)
  : m_lock(putPtr(lock)) {
  switch (source.getType()) {
  case KindOfBoolean:
    {
      m_type = KindOfBoolean;
      m_data.num = source.toBoolean();
      break;
    }
  case KindOfByte:
  case KindOfInt16:
  case KindOfInt32:
  case KindOfInt64:
    {
      m_type = KindOfInt64;
      m_data.num = source.toInt64();
      break;
    }
  case KindOfDouble:
    {
      m_type = KindOfDouble;
      m_data.dbl = source.toDouble();
      break;
    }
  case LiteralString:
  case KindOfStaticString:
  case KindOfString:
    {
      String s = source.toString();
      m_type = KindOfString;
      if (lock) {
        m_data.str = putPtr(SharedMemoryManager::GetSegment()
                            ->construct<SharedMemoryString>
                            (boost::interprocess::anonymous_instance)
                            (s.data(), s.size()));
      } else {
        // Just need this string to live long enough for the key lookup so
        // don't store in shared memory.
        m_data.str = putPtr(new SharedMemoryString(s.data(), s.size()));
      }
      break;
    }
  case KindOfArray:
    {
      ASSERT(lock);
      m_type = KindOfArray;
      uint i = 0;
      ProcessSharedVariantMapData* mapData = SharedMemoryManager::GetSegment()
        ->construct<ProcessSharedVariantMapData>
        (boost::interprocess::anonymous_instance)();
      m_data.map = putPtr(mapData);
      ProcessSharedVariantToIntMap* map = SharedMemoryManager::GetSegment()
        ->construct<ProcessSharedVariantToIntMap>
        (boost::interprocess::anonymous_instance)();
      mapData->map = putPtr(map);
      SharedMemoryVector<SharedVariant*>* keys =
        SharedMemoryManager::GetSegment()
        ->construct<SharedMemoryVector<SharedVariant*> >
        (boost::interprocess::anonymous_instance)();
      mapData->keys = putPtr(keys);
      SharedMemoryVector<SharedVariant*>* vals =
        SharedMemoryManager::GetSegment()
        ->construct<SharedMemoryVector<SharedVariant*> >
        (boost::interprocess::anonymous_instance)();
      mapData->vals = putPtr(vals);
      for (ArrayIterPtr it = source.begin(); !it->end(); it->next()) {
        ProcessSharedVariant* key = SharedMemoryManager::GetSegment()
          ->construct<ProcessSharedVariant>
          (boost::interprocess::anonymous_instance)
          (it->first(), getLock());
        ProcessSharedVariant* val = SharedMemoryManager::GetSegment()
          ->construct<ProcessSharedVariant>
          (boost::interprocess::anonymous_instance)
          (it->second(), getLock());
        (*map)[key] = i++;
        keys->push_back(putPtr(key));
        vals->push_back(putPtr(val));
      }
      break;
    }
  default:
    {
      m_type = KindOfObject;
      String s = f_serialize(source);
      m_data.str = putPtr(SharedMemoryManager::GetSegment()
                          ->construct<SharedMemoryString>
                          (boost::interprocess::anonymous_instance)
                          (s.data(), s.size()));
      break;
    }
  }
}
Ejemplo n.º 18
0
SharedVariant::SharedVariant(CVarRef source, bool serialized,
                             bool inner /* = false */,
                             bool unserializeObj /* = false */)
  : m_shouldCache(false), m_flags(0) {
  assert(!serialized || source.isString());
  m_count = 1;
  m_type = source.getType();
  switch (m_type) {
  case KindOfBoolean:
    {
      m_data.num = source.toBoolean();
      break;
    }
  case KindOfInt64:
    {
      m_type = KindOfInt64;
      m_data.num = source.toInt64();
      break;
    }
  case KindOfDouble:
    {
      m_data.dbl = source.toDouble();
      break;
    }
  case KindOfStaticString:
    {
      if (serialized) goto StringCase;
      m_data.str = source.getStringData();
      break;
    }
StringCase:
  case KindOfString:
    {
      String s = source.toString();
      if (serialized) {
        m_type = KindOfObject;
        // It is priming, and there might not be the right class definitions
        // for unserialization.
        s = apc_reserialize(s);
      }
      StringData* st = StringData::LookupStaticString(s.get());
      if (st) {
        m_data.str = st;
        m_type = KindOfStaticString;
        break;
      }
      m_data.str = s->copy(true);
      break;
    }
  case KindOfArray:
    {
      ArrayData *arr = source.getArrayData();

      if (!inner) {
        // only need to call hasInternalReference() on the toplevel array
        PointerSet seen;
        if (arr->hasInternalReference(seen)) {
          setSerializedArray();
          m_shouldCache = true;
          String s = apc_serialize(source);
          m_data.str = StringData::MakeMalloced(s.data(), s.size());
          break;
        }
      }

      if (arr->isVectorData()) {
        setIsVector();
        m_data.vec = new (arr->size()) VectorData();
        for (ArrayIter it(arr); !it.end(); it.next()) {
          SharedVariant* val = Create(it.secondRef(), false, true,
                                      unserializeObj);
          if (val->m_shouldCache) m_shouldCache = true;
          m_data.vec->vals()[m_data.vec->m_size++] = val;
        }
      } else {
        m_data.map = ImmutableMap::Create(arr, unserializeObj, m_shouldCache);
      }
      break;
    }
  case KindOfUninit:
  case KindOfNull:
    {
      break;
    }
  case KindOfResource:
    {
      // TODO Task #2661075: Here and elsewhere in the runtime, we convert
      // Resources to the empty array during various serialization operations,
      // which does not match Zend behavior. We should fix this.
      m_type = KindOfArray;
      setIsVector();
      m_data.vec = new (0) VectorData();
      break;
    }
  default:
    {
      assert(source.isObject());
      m_shouldCache = true;
      if (unserializeObj) {
        // This assumes hasInternalReference(seen, true) is false
        ImmutableObj* obj = new ImmutableObj(source.getObjectData());
        m_data.obj = obj;
        setIsObj();
      } else {
        String s = apc_serialize(source);
        m_data.str = StringData::MakeMalloced(s.data(), s.size());
      }
      break;
    }
  }
  assert(m_type != KindOfResource);
}