Changeset 6025 in webkit for trunk/JavaScriptCore/kjs/value.cpp


Ignore:
Timestamp:
Feb 2, 2004, 1:23:17 PM (21 years ago)
Author:
darin
Message:

Reviewed by Maciej.

  • fixed <rdar://problem/3519285>: integer operations on large negative numbers yield bad results (discovered with "HTMLCrypt")
  • fixed other related overflow issues
  • kjs/value.h: Changed return types of toInteger, toInt32, toUInt32, and toUInt16.
  • kjs/value.cpp: (ValueImp::toInteger): Change to return a double, since this operation, from the ECMA specification, must not restrict values to the range of a particular integer type. (ValueImp::toInt32): Used a sized integer type for the result of this function, and also added proper handling for negative results from fmod. (ValueImp::toUInt32): Ditto. (ValueImp::toUInt16): Ditto. (ValueImp::dispatchToUInt32): Changed result type from unsigned to uint32_t.
  • kjs/array_object.cpp: (ArrayProtoFuncImp::call): Use a double instead of an int to handle out-of-integer-range values better in the slice function.
  • kjs/internal.cpp: (KJS::roundValue): Streamline the function, handling NAN and infinity properly.
  • kjs/number_object.cpp: (NumberProtoFuncImp::call): Use a double instead of an int to handle out-of-integer-range values better in the toString function.
  • kjs/string_object.cpp: (StringProtoFuncImp::call): Use a double instead of an int to handle out-of-integer-range values better in the charAt, charCodeAt, indexOf, lastIndexOf, slice, and substr functions.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/value.cpp

    r3373 r6025  
    9494
    9595// ECMA 9.4
    96 int ValueImp::toInteger(ExecState *exec) const
    97 {
    98   unsigned i;
     96double ValueImp::toInteger(ExecState *exec) const
     97{
     98  uint32_t i;
    9999  if (dispatchToUInt32(i))
    100     return (int)i;
    101   return int(roundValue(exec, Value(const_cast<ValueImp*>(this))));
    102 }
    103 
    104 int ValueImp::toInt32(ExecState *exec) const
    105 {
    106   unsigned i;
     100    return i;
     101  return roundValue(exec, Value(const_cast<ValueImp*>(this)));
     102}
     103
     104int32_t ValueImp::toInt32(ExecState *exec) const
     105{
     106  uint32_t i;
    107107  if (dispatchToUInt32(i))
    108     return (int)i;
     108    return i;
    109109
    110110  double d = roundValue(exec, Value(const_cast<ValueImp*>(this)));
     111  if (isNaN(d) || isInf(d))
     112    return 0;
    111113  double d32 = fmod(d, D32);
    112114
    113115  if (d32 >= D32 / 2.0)
    114116    d32 -= D32;
    115 
    116   return static_cast<int>(d32);
    117 }
    118 
    119 unsigned int ValueImp::toUInt32(ExecState *exec) const
    120 {
    121   unsigned i;
     117  else if (d32 < -D32 / 2.0)
     118    d32 += D32;
     119
     120  return static_cast<int32_t>(d32);
     121}
     122
     123uint32_t ValueImp::toUInt32(ExecState *exec) const
     124{
     125  uint32_t i;
    122126  if (dispatchToUInt32(i))
    123127    return i;
    124128
    125129  double d = roundValue(exec, Value(const_cast<ValueImp*>(this)));
     130  if (isNaN(d) || isInf(d))
     131    return 0;
    126132  double d32 = fmod(d, D32);
    127133
    128   return static_cast<unsigned int>(d32);
    129 }
    130 
    131 unsigned short ValueImp::toUInt16(ExecState *exec) const
    132 {
    133   unsigned i;
     134  if (d32 < 0)
     135    d32 += D32;
     136
     137  return static_cast<uint32_t>(d32);
     138}
     139
     140uint16_t ValueImp::toUInt16(ExecState *exec) const
     141{
     142  uint32_t i;
    134143  if (dispatchToUInt32(i))
    135     return (unsigned short)i;
     144    return i;
    136145
    137146  double d = roundValue(exec, Value(const_cast<ValueImp*>(this)));
     147  if (isNaN(d) || isInf(d))
     148    return 0;
    138149  double d16 = fmod(d, D16);
    139150
    140   return static_cast<unsigned short>(d16);
     151  if (d16 < 0)
     152    d16 += D16;
     153
     154  return static_cast<uint16_t>(d16);
    141155}
    142156
     
    186200}
    187201
    188 bool ValueImp::dispatchToUInt32(unsigned& result) const
     202bool ValueImp::dispatchToUInt32(uint32_t& result) const
    189203{
    190204  if (SimpleNumber::is(this)) {
     
    192206    if (i < 0)
    193207      return false;
    194     result = (unsigned)i;
     208    result = i;
    195209    return true;
    196210  }
Note: See TracChangeset for help on using the changeset viewer.