[webkit-changes] cvs commit: JavaScriptCore/kjs internal.h math_object.cpp nodes.cpp number_object.cpp operations.cpp operations.h simple_number.h string_object.cpp ustring.cpp value.cpp value.h

Geoffrey ggaren at opensource.apple.com
Wed Oct 5 18:13:20 PDT 2005


ggaren      05/10/05 18:13:19

  Modified:    .        ChangeLog
               kjs      internal.h math_object.cpp nodes.cpp
                        number_object.cpp operations.cpp operations.h
                        simple_number.h string_object.cpp ustring.cpp
                        value.cpp value.h
  Log:
          - Darin and I rewrote our implementation of the SimpleNumber class
            to store number bit patterns in their floating point formats.
  
          My tweaks reviewed by Darin.
  
          ~1% speedup on JS iBench.
  
          * kjs/internal.h: removed obsolete jsNumber declarations.
          * kjs/math_object.cpp:
          (MathFuncImp::callAsFunction): changed KJS::isNaN to isNaN
          * kjs/nodes.cpp:
          (PostfixResolveNode::evaluate): removed obsolete knownToBeInteger
          (PostfixBracketNode::evaluate): ditto
          (PostfixDotNode::evaluate): ditto
          (PrefixResolveNode::evaluate): ditto
          (PrefixBracketNode::evaluate): ditto
          (PrefixDotNode::evaluate): ditto
          (NegateNode::evaluate): ditto
          (valueForReadModifyAssignment): ditto
          * kjs/number_object.cpp: removed obsolete comment
          * kjs/operations.cpp:
          (KJS::equal): removed unnecessary isNaN checks
          (KJS::strictEqual): ditto
          (KJS::add): removed obsolete knownToBeInteger
          (KJS::mult): ditto
          * kjs/operations.h: removed include of "value.h" to prevent circular reference
          * kjs/simple_number.h: removed unnecessary #includes
          (KJS::SimpleNumber::make): see above
          (KJS::SimpleNumber::is): ditto
          (KJS::SimpleNumber::value): ditto
          * kjs/string_object.cpp:
          (StringProtoFuncImp::callAsFunction): changed KJS::isNaN to isNaN
          * kjs/ustring.cpp: removed unnecessary isNaN check
          (KJS::UString::toUInt32): ditto
          * kjs/value.cpp:
          (KJS::jsNumber): removed obsolete jsNumber definitions
          (KJS::ConstantValues::init): NaN is no longer a ConstantValue
          (KJS::ConstantValues::clear): ditto
          (KJS::ConstantValues::mark): ditto
          * kjs/value.h: removed obsolete knownToBeInteger
          (KJS::jsNaN): now returns a SimpleNumber
          (KJS::ValueImp::getUInt32): changed to account for NaN being a SimpleNumber
          (KJS::ValueImp::toBoolean): ditto
          (KJS::ValueImp::toString): changed to account for +/- 0.0
          (KJS::jsZero): changed to reflect that SimpleNumber::make takes a double
          (KJS::jsOne): ditto
          (KJS::jsTwo): ditto
          (KJS::Number): removed obsolete non-double constructor declarations
  
  Revision  Changes    Path
  1.855     +51 -0     JavaScriptCore/ChangeLog
  
  Index: ChangeLog
  ===================================================================
  RCS file: /cvs/root/JavaScriptCore/ChangeLog,v
  retrieving revision 1.854
  retrieving revision 1.855
  diff -u -r1.854 -r1.855
  --- ChangeLog	5 Oct 2005 08:05:33 -0000	1.854
  +++ ChangeLog	6 Oct 2005 01:13:17 -0000	1.855
  @@ -1,3 +1,54 @@
  +2005-10-05  Geoffrey Garen  <ggaren at apple.com>
  + 
  +        - Darin and I rewrote our implementation of the SimpleNumber class
  +          to store number bit patterns in their floating point formats.
  + 
  +        My tweaks reviewed by Darin.
  +        
  +        ~1% speedup on JS iBench.
  +        
  +        * kjs/internal.h: removed obsolete jsNumber declarations.
  +        * kjs/math_object.cpp:
  +        (MathFuncImp::callAsFunction): changed KJS::isNaN to isNaN
  +        * kjs/nodes.cpp:
  +        (PostfixResolveNode::evaluate): removed obsolete knownToBeInteger
  +        (PostfixBracketNode::evaluate): ditto
  +        (PostfixDotNode::evaluate): ditto
  +        (PrefixResolveNode::evaluate): ditto
  +        (PrefixBracketNode::evaluate): ditto
  +        (PrefixDotNode::evaluate): ditto
  +        (NegateNode::evaluate): ditto
  +        (valueForReadModifyAssignment): ditto
  +        * kjs/number_object.cpp: removed obsolete comment
  +        * kjs/operations.cpp:
  +        (KJS::equal): removed unnecessary isNaN checks
  +        (KJS::strictEqual): ditto
  +        (KJS::add): removed obsolete knownToBeInteger
  +        (KJS::mult): ditto
  +        * kjs/operations.h: removed include of "value.h" to prevent circular reference
  +        * kjs/simple_number.h: removed unnecessary #includes
  +        (KJS::SimpleNumber::make): see above
  +        (KJS::SimpleNumber::is): ditto
  +        (KJS::SimpleNumber::value): ditto
  +        * kjs/string_object.cpp:
  +        (StringProtoFuncImp::callAsFunction): changed KJS::isNaN to isNaN
  +        * kjs/ustring.cpp: removed unnecessary isNaN check
  +        (KJS::UString::toUInt32): ditto
  +        * kjs/value.cpp:
  +        (KJS::jsNumber): removed obsolete jsNumber definitions
  +        (KJS::ConstantValues::init): NaN is no longer a ConstantValue
  +        (KJS::ConstantValues::clear): ditto
  +        (KJS::ConstantValues::mark): ditto
  +        * kjs/value.h: removed obsolete knownToBeInteger
  +        (KJS::jsNaN): now returns a SimpleNumber
  +        (KJS::ValueImp::getUInt32): changed to account for NaN being a SimpleNumber
  +        (KJS::ValueImp::toBoolean): ditto
  +        (KJS::ValueImp::toString): changed to account for +/- 0.0
  +        (KJS::jsZero): changed to reflect that SimpleNumber::make takes a double
  +        (KJS::jsOne): ditto
  +        (KJS::jsTwo): ditto
  +        (KJS::Number): removed obsolete non-double constructor declarations
  +
   2005-10-05  Maciej Stachowiak  <mjs at apple.com>
   
           Reviewed by Eric.
  
  
  
  1.43      +1 -8      JavaScriptCore/kjs/internal.h
  
  Index: internal.h
  ===================================================================
  RCS file: /cvs/root/JavaScriptCore/kjs/internal.h,v
  retrieving revision 1.42
  retrieving revision 1.43
  diff -u -r1.42 -r1.43
  --- internal.h	4 Oct 2005 01:43:58 -0000	1.42
  +++ internal.h	6 Oct 2005 01:13:17 -0000	1.43
  @@ -26,7 +26,6 @@
   #define INTERNAL_H
   
   #include "ustring.h"
  -#include "value.h"
   #include "object.h"
   #include "protect.h"
   #include "types.h"
  @@ -112,14 +111,7 @@
     class NumberImp : public AllocatedValueImp {
       friend class ConstantValues;
       friend class InterpreterImp;
  -    friend ValueImp *jsNumber(int);
  -    friend ValueImp *jsNumber(unsigned);
  -    friend ValueImp *jsNumber(long);
  -    friend ValueImp *jsNumber(unsigned long);
  -    friend ValueImp *jsNumber(long long);
  -    friend ValueImp *jsNumber(unsigned long long);
       friend ValueImp *jsNumber(double);
  -    friend ValueImp *jsNumber(double, bool);
     public:
       double value() const { return val; }
   
  @@ -138,6 +130,7 @@
   
       double val;
     };
  +  
   
     /**
      * @short The "label set" in Ecma-262 spec
  
  
  
  1.20      +2 -2      JavaScriptCore/kjs/math_object.cpp
  
  Index: math_object.cpp
  ===================================================================
  RCS file: /cvs/root/JavaScriptCore/kjs/math_object.cpp,v
  retrieving revision 1.19
  retrieving revision 1.20
  diff -u -r1.19 -r1.20
  --- math_object.cpp	3 Oct 2005 21:11:49 -0000	1.19
  +++ math_object.cpp	6 Oct 2005 01:13:18 -0000	1.20
  @@ -232,13 +232,13 @@
     }
     case MathObjectImp::Pow:
       // ECMA 15.8.2.1.13 (::pow takes care of most of the critera)
  -    if (KJS::isNaN(arg2))
  +    if (isNaN(arg2))
         result = NaN;
   #if !APPLE_CHANGES
       else if (arg2 == 0)
         result = 1;
   #endif
  -    else if (KJS::isNaN(arg) && arg2 != 0)
  +    else if (isNaN(arg) && arg2 != 0)
         result = NaN;
   #if !APPLE_CHANGES
       else if (::fabs(arg) > 1 && KJS::isPosInf(arg2))
  
  
  
  1.87      +25 -36    JavaScriptCore/kjs/nodes.cpp
  
  Index: nodes.cpp
  ===================================================================
  RCS file: /cvs/root/JavaScriptCore/kjs/nodes.cpp,v
  retrieving revision 1.86
  retrieving revision 1.87
  diff -u -r1.86 -r1.87
  --- nodes.cpp	5 Oct 2005 08:05:37 -0000	1.86
  +++ nodes.cpp	6 Oct 2005 01:13:18 -0000	1.87
  @@ -662,13 +662,12 @@
       if (base->getPropertySlot(exec, m_ident, slot)) {
           ValueImp *v = slot.getValue(exec, m_ident);
   
  -        bool knownToBeInteger;
  -        double n = v->toNumber(exec, knownToBeInteger);
  +        double n = v->toNumber(exec);
           
           double newValue = (m_oper == OpPlusPlus) ? n + 1 : n - 1;
  -        base->put(exec, m_ident, jsNumber(newValue, knownToBeInteger));
  +        base->put(exec, m_ident, jsNumber(newValue));
           
  -        return jsNumber(n, knownToBeInteger);
  +        return jsNumber(n);
       }
   
       ++iter;
  @@ -694,13 +693,12 @@
       ValueImp *v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, propertyIndex) : Undefined();
       KJS_CHECKEXCEPTIONVALUE
   
  -    bool knownToBeInteger;
  -    double n = v->toNumber(exec, knownToBeInteger);
  +    double n = v->toNumber(exec);
   
       double newValue = (m_oper == OpPlusPlus) ? n + 1 : n - 1;
  -    base->put(exec, propertyIndex, jsNumber(newValue, knownToBeInteger));
  +    base->put(exec, propertyIndex, jsNumber(newValue));
           
  -    return jsNumber(n, knownToBeInteger);
  +    return jsNumber(n);
     }
   
     Identifier propertyName(subscript->toString(exec));
  @@ -708,13 +706,12 @@
     ValueImp *v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, propertyName) : Undefined();
     KJS_CHECKEXCEPTIONVALUE
   
  -  bool knownToBeInteger;
  -  double n = v->toNumber(exec, knownToBeInteger);
  +  double n = v->toNumber(exec);
     
     double newValue = (m_oper == OpPlusPlus) ? n + 1 : n - 1;
  -  base->put(exec, propertyName, jsNumber(newValue, knownToBeInteger));
  +  base->put(exec, propertyName, jsNumber(newValue));
           
  -  return jsNumber(n, knownToBeInteger);
  +  return jsNumber(n);
   }
   
   // ------------------------------ PostfixDotNode ----------------------------------
  @@ -729,13 +726,12 @@
     ValueImp *v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, m_ident) : Undefined();
     KJS_CHECKEXCEPTIONVALUE
   
  -  bool knownToBeInteger;
  -  double n = v->toNumber(exec, knownToBeInteger);
  +  double n = v->toNumber(exec);
     
     double newValue = (m_oper == OpPlusPlus) ? n + 1 : n - 1;
  -  base->put(exec, m_ident, jsNumber(newValue, knownToBeInteger));
  +  base->put(exec, m_ident, jsNumber(newValue));
           
  -  return jsNumber(n, knownToBeInteger);
  +  return jsNumber(n);
   }
   
   // ECMA 11.4.1
  @@ -892,11 +888,10 @@
       if (base->getPropertySlot(exec, m_ident, slot)) {
           ValueImp *v = slot.getValue(exec, m_ident);
   
  -        bool knownToBeInteger;
  -        double n = v->toNumber(exec, knownToBeInteger);
  +        double n = v->toNumber(exec);
           
           double newValue = (m_oper == OpPlusPlus) ? n + 1 : n - 1;
  -        ValueImp *n2 = jsNumber(newValue, knownToBeInteger);
  +        ValueImp *n2 = jsNumber(newValue);
           base->put(exec, m_ident, n2);
   
           return n2;
  @@ -925,11 +920,10 @@
       ValueImp *v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, propertyIndex) : Undefined();
       KJS_CHECKEXCEPTIONVALUE
   
  -    bool knownToBeInteger;
  -    double n = v->toNumber(exec, knownToBeInteger);
  +    double n = v->toNumber(exec);
   
       double newValue = (m_oper == OpPlusPlus) ? n + 1 : n - 1;
  -    ValueImp *n2 = jsNumber(newValue, knownToBeInteger);
  +    ValueImp *n2 = jsNumber(newValue);
       base->put(exec, propertyIndex, n2);
   
       return n2;
  @@ -940,11 +934,10 @@
     ValueImp *v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, propertyName) : Undefined();
     KJS_CHECKEXCEPTIONVALUE
   
  -  bool knownToBeInteger;
  -  double n = v->toNumber(exec, knownToBeInteger);
  +  double n = v->toNumber(exec);
     
     double newValue = (m_oper == OpPlusPlus) ? n + 1 : n - 1;
  -  ValueImp *n2 = jsNumber(newValue, knownToBeInteger);
  +  ValueImp *n2 = jsNumber(newValue);
     base->put(exec, propertyName, n2);
   
     return n2;
  @@ -962,11 +955,10 @@
     ValueImp *v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, m_ident) : Undefined();
     KJS_CHECKEXCEPTIONVALUE
   
  -  bool knownToBeInteger;
  -  double n = v->toNumber(exec, knownToBeInteger);
  +  double n = v->toNumber(exec);
     
     double newValue = (m_oper == OpPlusPlus) ? n + 1 : n - 1;
  -  ValueImp *n2 = jsNumber(newValue, knownToBeInteger);
  +  ValueImp *n2 = jsNumber(newValue);
     base->put(exec, m_ident, n2);
   
     return n2;
  @@ -991,9 +983,8 @@
     ValueImp *v = expr->evaluate(exec);
     KJS_CHECKEXCEPTIONVALUE
   
  -  bool knownToBeInteger;
  -  double n = v->toNumber(exec, knownToBeInteger);
  -  return jsNumber(-n, knownToBeInteger && n != 0);
  +  double n = v->toNumber(exec);
  +  return jsNumber(-n);
   }
   
   // ------------------------------ BitwiseNotNode -------------------------------
  @@ -1257,11 +1248,9 @@
       v = jsNumber(i1 | i2);
       break;
     case OpModEq: {
  -    bool d1KnownToBeInteger;
  -    double d1 = v1->toNumber(exec, d1KnownToBeInteger);
  -    bool d2KnownToBeInteger;
  -    double d2 = v2->toNumber(exec, d2KnownToBeInteger);
  -    v = jsNumber(fmod(d1, d2), d1KnownToBeInteger && d2KnownToBeInteger && d2 != 0);
  +    double d1 = v1->toNumber(exec);
  +    double d2 = v2->toNumber(exec);
  +    v = jsNumber(fmod(d1, d2));
     }
       break;
     default:
  
  
  
  1.24      +0 -1      JavaScriptCore/kjs/number_object.cpp
  
  Index: number_object.cpp
  ===================================================================
  RCS file: /cvs/root/JavaScriptCore/kjs/number_object.cpp,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -u -r1.23 -r1.24
  --- number_object.cpp	3 Oct 2005 21:11:50 -0000	1.23
  +++ number_object.cpp	6 Oct 2005 01:13:18 -0000	1.24
  @@ -356,7 +356,6 @@
   // ------------------------------ NumberObjectImp ------------------------------
   
   const ClassInfo NumberObjectImp::info = {"Number", &InternalFunctionImp::info, &numberTable, 0};
  -//const ClassInfo NumberObjectImp::info = {"Number", 0, &numberTable, 0};
   
   /* Source for number_object.lut.h
   @begin numberTable 5
  
  
  
  1.13      +7 -29     JavaScriptCore/kjs/operations.cpp
  
  Index: operations.cpp
  ===================================================================
  RCS file: /cvs/root/JavaScriptCore/kjs/operations.cpp,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- operations.cpp	4 Oct 2005 05:57:12 -0000	1.12
  +++ operations.cpp	6 Oct 2005 01:13:18 -0000	1.13
  @@ -142,11 +142,7 @@
       if (t1 == NumberType) {
           double d1 = v1->toNumber(exec);
           double d2 = v2->toNumber(exec);
  -        // FIXME: Isn't this already how NaN behaves?
  -        // Why the extra line of code?
  -        if (isNaN(d1) || isNaN(d2))
  -            return false;
  -        return d1 == d2; /* TODO: +0, -0 ? */
  +        return d1 == d2;
       }
   
       if (t1 == StringType)
  @@ -171,13 +167,8 @@
     if (t1 == NumberType) {
       double n1 = v1->toNumber(exec);
       double n2 = v2->toNumber(exec);
  -    // FIXME: Isn't this already how NaN behaves?
  -    // Why the extra line of code?
  -    if (isNaN(n1) || isNaN(n2))
  -      return false;
       if (n1 == n2)
  -      return true;
  -    /* TODO: +0 and -0 */
  +        return true;
       return false;
     } else if (t1 == StringType) {
       return v1->toString(exec) == v2->toString(exec);
  @@ -230,42 +221,29 @@
       return jsString(p1->toString(exec) + p2->toString(exec));
     }
   
  -  bool n1KnownToBeInteger;
  -  double n1 = p1->toNumber(exec, n1KnownToBeInteger);
  -  bool n2KnownToBeInteger;
  -  double n2 = p2->toNumber(exec, n2KnownToBeInteger);
  -
  -  bool resultKnownToBeInteger = n1KnownToBeInteger && n2KnownToBeInteger;
  -
     if (oper == '+')
  -    return jsNumber(n1 + n2, resultKnownToBeInteger);
  +    return jsNumber(p1->toNumber(exec) + p2->toNumber(exec));
     else
  -    return jsNumber(n1 - n2, resultKnownToBeInteger);
  +    return jsNumber(p1->toNumber(exec) - p2->toNumber(exec));
   }
   
   // ECMA 11.5
   ValueImp *mult(ExecState *exec, ValueImp *v1, ValueImp *v2, char oper)
   {
  -  bool n1KnownToBeInteger;
  -  double n1 = v1->toNumber(exec, n1KnownToBeInteger);
  -  bool n2KnownToBeInteger;
  -  double n2 = v2->toNumber(exec, n2KnownToBeInteger);
  +  double n1 = v1->toNumber(exec);
  +  double n2 = v2->toNumber(exec);
   
     double result;
  -  bool resultKnownToBeInteger;
   
     if (oper == '*') {
       result = n1 * n2;
  -    resultKnownToBeInteger = n1KnownToBeInteger && n2KnownToBeInteger;
     } else if (oper == '/') {
       result = n1 / n2;
  -    resultKnownToBeInteger = false;
     } else {
       result = fmod(n1, n2);
  -    resultKnownToBeInteger = n1KnownToBeInteger && n2KnownToBeInteger && n2 != 0;
     }
   
  -  return jsNumber(result, resultKnownToBeInteger);
  +  return jsNumber(result);
   }
   
   }
  
  
  
  1.7       +1 -2      JavaScriptCore/kjs/operations.h
  
  Index: operations.h
  ===================================================================
  RCS file: /cvs/root/JavaScriptCore/kjs/operations.h,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- operations.h	8 Aug 2005 04:07:29 -0000	1.6
  +++ operations.h	6 Oct 2005 01:13:18 -0000	1.7
  @@ -23,11 +23,10 @@
   #ifndef _KJS_OPERATIONS_H_
   #define _KJS_OPERATIONS_H_
   
  -#include "value.h"
  -
   namespace KJS {
   
     class ExecState;
  +  class ValueImp;
   
   #if APPLE_CHANGES
     inline bool isNaN(double d) { return isnan(d); }
  
  
  
  1.19      +83 -34    JavaScriptCore/kjs/simple_number.h
  
  Index: simple_number.h
  ===================================================================
  RCS file: /cvs/root/JavaScriptCore/kjs/simple_number.h,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- simple_number.h	28 Sep 2005 22:27:39 -0000	1.18
  +++ simple_number.h	6 Oct 2005 01:13:18 -0000	1.19
  @@ -22,6 +22,7 @@
   #ifndef KJS_SIMPLE_NUMBER_H
   #define KJS_SIMPLE_NUMBER_H
   
  +// We include these headers here because simple_number.h is the most low-level header we have.
   #include <float.h>
   #include <math.h>
   #include <stdint.h>
  @@ -37,51 +38,99 @@
   using std::signbit;
   #endif
   
  -#define KJS_MIN_MACRO(a, b) ((a) < (b) ? (a) : (b))
  +#if defined(__GNUC__) && (__GNUC__ > 3)
  +#define ALWAYS_INLINE __attribute__ ((always_inline))
  +#else
  +#define ALWAYS_INLINE inline
  +#endif
   
   namespace KJS {
   
       class ValueImp;
   
  -    static inline bool isNegativeZero(double num)
  -    {
  -#if WIN32
  -        return _fpclass(num) == _FPCLASS_NZ;
  -#else
  -        return num == -0.0 && signbit(num);
  -#endif
  -    }
  -    
       class SimpleNumber {
       public:
  -        static const int           tagBits   = 2;   // Pointer alignment guarantees that we have the low two bits to play with for type tagging
  -        static const unsigned long tag       = 1UL; // 01 is the full tag
  -        static const unsigned long tagMask   = (1UL << tagBits) - 1;
  -        static const int           valueBits = KJS_MIN_MACRO(sizeof(ValueImp *) * 8 - tagBits, sizeof(long) * 8);
  -        static const unsigned long signMask  = 1UL << sizeof(long) * 8 - 1;
  -        static const long          maxValue  = (signMask >> tagBits) - 1;
  -        static const unsigned long umaxValue = maxValue;
  -        static const long          minValue  = -(maxValue + 1);
  +        static const unsigned long tag     = 1; // 01 is the full tag, since it's 2 bits long.
  +        static const unsigned long tagMask = 3; // 11 is the tag mask, since it's 2 bits long.
  +        
  +        ALWAYS_INLINE
  +        static ValueImp *make(double d)
  +        {
  +            if (sizeof(float) == sizeof(unsigned long) &&
  +                sizeof(double) == sizeof(unsigned long long) &&
  +                sizeof(ValueImp*) >= sizeof(unsigned long)) {
  +                // 32-bit
  +                union {
  +                    unsigned long asBits;
  +                    float         asFloat;
  +                } floatunion;
  +                floatunion.asFloat = d;
  +                
  +                if ((floatunion.asBits & tagMask) != 0)
  +                  return 0;
  +                
  +                // Check for loss in conversion to float
  +                union {
  +                    unsigned long long asBits;
  +                    double             asDouble;
  +                } doubleunion1, doubleunion2;
  +                doubleunion1.asDouble = floatunion.asFloat;
  +                doubleunion2.asDouble = d;
  +                if (doubleunion1.asBits != doubleunion2.asBits)
  +                    return 0;
  +                
  +                return reinterpret_cast<ValueImp *>(floatunion.asBits | tag);
  +            } else if (sizeof(double) == sizeof(unsigned long) &&
  +                       sizeof(ValueImp*) >= sizeof(unsigned long)) {
  +                // 64-bit
  +                union {
  +                    unsigned long asBits;
  +                    double        asDouble;
  +                } doubleunion;
  +                doubleunion.asDouble = d;
  +                
  +                if ((doubleunion.asBits & tagMask) != 0)
  +                    return 0;
  +
  +                return reinterpret_cast<ValueImp *>(doubleunion.asBits | tag);
  +            } else {
  +                // could just return 0 here, but nicer to be explicit about not supporting the platform well
  +                abort();
  +            }
  +        }
   
  -        static unsigned long rightShiftSignExtended(uintptr_t l, int n)
  +        static bool is(const ValueImp *imp)
  +        {
  +            return (reinterpret_cast<unsigned long>(imp) & tagMask) == tag;
  +        }
  +        
  +        ALWAYS_INLINE
  +        static double value(const ValueImp *imp)
           {
  -            return (l >> n) | ((l & signMask) ? (~0UL << valueBits) : 0);
  +            assert(is(imp));
  +            
  +            if (sizeof(float) == sizeof(unsigned long)) {
  +                // 32-bit
  +                union {
  +                    unsigned long asBits;
  +                    float         asFloat;
  +                } floatunion;
  +                floatunion.asBits = reinterpret_cast<unsigned long>(imp) & ~tagMask;
  +                return floatunion.asFloat;
  +            } else if (sizeof(double) == sizeof(unsigned long)) {
  +                // 64-bit
  +                union {
  +                    unsigned long asBits;
  +                    double        asDouble;
  +                } doubleunion;
  +                doubleunion.asBits = reinterpret_cast<unsigned long>(imp) & ~tagMask;
  +                return doubleunion.asDouble;
  +            } else {
  +                // could just return 0 here, but nicer to be explicit about not supporting the platform well
  +                abort();
  +            }
           }
           
  -        static  ValueImp *make(long i)          { return reinterpret_cast<ValueImp *>((i << tagBits) | tag); }
  -        static  bool is(const ValueImp *imp)    { return (reinterpret_cast<uintptr_t>(imp) & tagMask) == tag; }
  -        static  long value(const ValueImp *imp) { return rightShiftSignExtended(reinterpret_cast<uintptr_t>(imp), tagBits); }
  -
  -        static  bool fits(int i)                { return !(i > maxValue || i < minValue); }
  -        static  bool fits(long i)               { return !(i > maxValue || i < minValue); }
  -        static  bool fits(long long i)          { return !(i > maxValue || i < minValue); }
  -        static  bool integerFits(double i)      { return !(i > maxValue || i < minValue); }
  -
  -        static  bool fits(double d)             { return !(d > maxValue || d < minValue) && d == (double)(long)d && !isNegativeZero(d); }
  -
  -        static  bool fits(unsigned i)           { return !(i > umaxValue); }
  -        static  bool fits(unsigned long i)      { return !(i > umaxValue); }
  -        static  bool fits(unsigned long long i) { return !(i > umaxValue); }
       };
   
   }
  
  
  
  1.48      +2 -2      JavaScriptCore/kjs/string_object.cpp
  
  Index: string_object.cpp
  ===================================================================
  RCS file: /cvs/root/JavaScriptCore/kjs/string_object.cpp,v
  retrieving revision 1.47
  retrieving revision 1.48
  diff -u -r1.47 -r1.48
  --- string_object.cpp	3 Oct 2005 21:11:51 -0000	1.47
  +++ string_object.cpp	6 Oct 2005 01:13:18 -0000	1.48
  @@ -620,9 +620,9 @@
     case Substring: {
       double start = a0->toNumber(exec);
       double end = a1->toNumber(exec);
  -    if (KJS::isNaN(start))
  +    if (isNaN(start))
         start = 0;
  -    if (KJS::isNaN(end))
  +    if (isNaN(end))
         end = 0;
       if (start < 0)
         start = 0;
  
  
  
  1.62      +2 -2      JavaScriptCore/kjs/ustring.cpp
  
  Index: ustring.cpp
  ===================================================================
  RCS file: /cvs/root/JavaScriptCore/kjs/ustring.cpp,v
  retrieving revision 1.61
  retrieving revision 1.62
  diff -u -r1.61 -r1.62
  --- ustring.cpp	27 Sep 2005 22:36:50 -0000	1.61
  +++ ustring.cpp	6 Oct 2005 01:13:18 -0000	1.62
  @@ -967,7 +967,7 @@
     double d = toDouble();
     bool b = true;
   
  -  if (isNaN(d) || d != static_cast<uint32_t>(d)) {
  +  if (d != static_cast<uint32_t>(d)) {
       b = false;
       d = 0;
     }
  @@ -983,7 +983,7 @@
     double d = toDouble(false, tolerateEmptyString);
     bool b = true;
   
  -  if (isNaN(d) || d != static_cast<uint32_t>(d)) {
  +  if (d != static_cast<uint32_t>(d)) {
       b = false;
       d = 0;
     }
  
  
  
  1.31      +2 -46     JavaScriptCore/kjs/value.cpp
  
  Index: value.cpp
  ===================================================================
  RCS file: /cvs/root/JavaScriptCore/kjs/value.cpp,v
  retrieving revision 1.30
  retrieving revision 1.31
  diff -u -r1.30 -r1.31
  --- value.cpp	3 Oct 2005 21:11:52 -0000	1.30
  +++ value.cpp	6 Oct 2005 01:13:18 -0000	1.31
  @@ -44,7 +44,6 @@
   AllocatedValueImp *ConstantValues::null = NULL;
   AllocatedValueImp *ConstantValues::jsTrue = NULL;
   AllocatedValueImp *ConstantValues::jsFalse = NULL;
  -AllocatedValueImp *ConstantValues::NaN = NULL;
   
   static const double D16 = 65536.0;
   static const double D32 = 4294967296.0;
  @@ -182,48 +181,10 @@
       return s.isNull() ? new StringImp("") : new StringImp(s);
   }
   
  -ValueImp *jsNumber(int i)
  -{
  -    return SimpleNumber::fits(i) ? SimpleNumber::make(i) : new NumberImp(static_cast<double>(i));
  -}
  -
  -ValueImp *jsNumber(unsigned i)
  -{
  -    return SimpleNumber::fits(i) ? SimpleNumber::make(i) : new NumberImp(static_cast<double>(i));
  -}
  -
  -ValueImp *jsNumber(long i)
  -{
  -    return SimpleNumber::fits(i) ? SimpleNumber::make(i) : new NumberImp(static_cast<double>(i));
  -}
  -
  -ValueImp *jsNumber(unsigned long i)
  -{
  -    return SimpleNumber::fits(i) ? SimpleNumber::make(i) : new NumberImp(static_cast<double>(i));
  -}
  -
  -ValueImp *jsNumber(long long i)
  -{
  -    return SimpleNumber::fits(i) ? SimpleNumber::make(i) : new NumberImp(static_cast<double>(i));
  -}
  -
  -ValueImp *jsNumber(unsigned long long i)
  -{
  -    return SimpleNumber::fits(i) ? SimpleNumber::make(i) : new NumberImp(static_cast<double>(i));
  -}
  -
   ValueImp *jsNumber(double d)
   {
  -    return SimpleNumber::fits(d)
  -        ? SimpleNumber::make(static_cast<long>(d))
  -        : (isNaN(d) ? jsNaN() : new NumberImp(d));
  -}
  -
  -ValueImp *jsNumber(double d, bool knownToBeInteger)
  -{
  -    return (knownToBeInteger ? SimpleNumber::integerFits(d) : SimpleNumber::fits(d))
  -        ? SimpleNumber::make(static_cast<long>(d))
  -        : ((!knownToBeInteger && isNaN(d)) ? jsNaN() : new NumberImp(d));
  +  ValueImp *v = SimpleNumber::make(d);
  +  return v ? v : new NumberImp(d);
   }
   
   void ConstantValues::init()
  @@ -232,7 +193,6 @@
       null = new NullImp();
       jsTrue = new BooleanImp(true);
       jsFalse = new BooleanImp(false);
  -    NaN = new NumberImp(::KJS::NaN);
   }
   
   void ConstantValues::clear()
  @@ -241,7 +201,6 @@
       null = NULL;
       jsTrue = NULL;
       jsFalse = NULL;
  -    NaN = NULL;
   }
   
   void ConstantValues::mark()
  @@ -258,9 +217,6 @@
       if (AllocatedValueImp *v = jsFalse)
           if (!v->marked())
               v->mark();
  -    if (AllocatedValueImp *v = NaN)
  -        if (!v->marked())
  -            v->mark();
   }
   
   }
  
  
  
  1.36      +21 -33    JavaScriptCore/kjs/value.h
  
  Index: value.h
  ===================================================================
  RCS file: /cvs/root/JavaScriptCore/kjs/value.h,v
  retrieving revision 1.35
  retrieving revision 1.36
  diff -u -r1.35 -r1.36
  --- value.h	16 Sep 2005 22:42:30 -0000	1.35
  +++ value.h	6 Oct 2005 01:13:18 -0000	1.36
  @@ -101,7 +101,6 @@
       ValueImp *toPrimitive(ExecState *exec, Type preferredType = UnspecifiedType) const;
       bool toBoolean(ExecState *exec) const;
       double toNumber(ExecState *exec) const;
  -    double toNumber(ExecState *exec, bool& knownToBeInteger) const;
       UString toString(ExecState *exec) const;
       ObjectImp *toObject(ExecState *exec) const;
   
  @@ -161,7 +160,6 @@
       virtual ValueImp *toPrimitive(ExecState *exec, Type preferredType = UnspecifiedType) const = 0;
       virtual bool toBoolean(ExecState *exec) const = 0;
       virtual double toNumber(ExecState *exec) const = 0;
  -    double toNumber(ExecState *exec, bool& knownToBeInteger) const;
       virtual UString toString(ExecState *exec) const = 0;
       virtual ObjectImp *toObject(ExecState *exec) const = 0;
   
  @@ -180,17 +178,10 @@
   AllocatedValueImp *jsBoolean(bool = false);
   
   ValueImp *jsNumber(double);
  -ValueImp *jsNumber(double, bool knownToBeInteger);
  -AllocatedValueImp *jsNaN();
  +ValueImp *jsNaN();
   ValueImp *jsZero();
   ValueImp *jsOne();
   ValueImp *jsTwo();
  -ValueImp *jsNumber(int);
  -ValueImp *jsNumber(unsigned);
  -ValueImp *jsNumber(long);
  -ValueImp *jsNumber(unsigned long);
  -ValueImp *jsNumber(long long);
  -ValueImp *jsNumber(unsigned long long);
   
   AllocatedValueImp *jsString(const UString &); // returns empty string if passed null string
   AllocatedValueImp *jsString(const char * = ""); // returns empty string if passed 0
  @@ -204,7 +195,6 @@
       static AllocatedValueImp *null;
       static AllocatedValueImp *jsFalse;
       static AllocatedValueImp *jsTrue;
  -    static AllocatedValueImp *NaN;
   
       static void init();
       static void clear();
  @@ -226,9 +216,9 @@
       return b ? ConstantValues::jsTrue : ConstantValues::jsFalse;
   }
   
  -inline AllocatedValueImp *jsNaN()
  +inline ValueImp *jsNaN()
   {
  -    return ConstantValues::NaN;
  +    return SimpleNumber::make(NaN);
   }
   
   inline ValueImp::ValueImp()
  @@ -372,10 +362,10 @@
   inline bool ValueImp::getUInt32(uint32_t& v) const
   {
       if (SimpleNumber::is(this)) {
  -        long i = SimpleNumber::value(this);
  -        if (i < 0)
  +        double d = SimpleNumber::value(this);
  +        if (!(d >= 0) || d > 0xFFFFFFFFUL) // true for NaN
               return false;
  -        v = i;
  +        v = static_cast<uint32_t>(d);
           return true;
       }
       return downcast()->getUInt32(v);
  @@ -404,7 +394,12 @@
   
   inline bool ValueImp::toBoolean(ExecState *exec) const
   {
  -    return SimpleNumber::is(this) ? SimpleNumber::value(this) : downcast()->toBoolean(exec);
  +    if (SimpleNumber::is(this)) {
  +        double d = SimpleNumber::value(this);
  +        return d < 0 || d > 0; // false for NaN
  +    }
  +
  +    return downcast()->toBoolean(exec);
   }
   
   inline double ValueImp::toNumber(ExecState *exec) const
  @@ -412,34 +407,31 @@
       return SimpleNumber::is(this) ? SimpleNumber::value(this) : downcast()->toNumber(exec);
   }
   
  -inline double ValueImp::toNumber(ExecState *exec, bool& knownToBeInteger) const
  +inline UString ValueImp::toString(ExecState *exec) const
   {
       if (SimpleNumber::is(this)) {
  -        knownToBeInteger = true;
  -        return SimpleNumber::value(this);
  +        double d = SimpleNumber::value(this);
  +        if (d == 0.0) // +0.0 or -0.0
  +            d = 0.0;
  +        return UString::from(d);
       }
  -    knownToBeInteger = false;
  -    return downcast()->toNumber(exec);
  -}
   
  -inline UString ValueImp::toString(ExecState *exec) const
  -{
  -   return SimpleNumber::is(this) ? UString::from(SimpleNumber::value(this)) : downcast()->toString(exec);
  +    return downcast()->toString(exec);
   }
   
   inline ValueImp *jsZero()
   {
  -    return SimpleNumber::make(0);
  +    return SimpleNumber::make(0.0);
   }
   
   inline ValueImp *jsOne()
   {
  -    return SimpleNumber::make(1);
  +    return SimpleNumber::make(1.0);
   }
   
   inline ValueImp *jsTwo()
   {
  -    return SimpleNumber::make(2);
  +    return SimpleNumber::make(2.0);
   }
   
   // compatibility names so we don't have to change so much code
  @@ -448,10 +440,6 @@
   inline AllocatedValueImp *Null() { return jsNull(); }
   inline AllocatedValueImp *Boolean(bool b) { return jsBoolean(b); }
   inline ValueImp *Number(double n) { return jsNumber(n); }
  -inline ValueImp *Number(int n) { return jsNumber(n); }
  -inline ValueImp *Number(unsigned n) { return jsNumber(n); }
  -inline ValueImp *Number(long n) { return jsNumber(n); }
  -inline ValueImp *Number(unsigned long n) { return jsNumber(n); }
   inline AllocatedValueImp *String(const UString& s) { return jsString(s); }
   inline AllocatedValueImp *String(const char *s) { return jsString(s); }
   
  
  
  



More information about the webkit-changes mailing list