Changeset 46598 in webkit for trunk/JavaScriptCore/runtime


Ignore:
Timestamp:
Jul 30, 2009, 1:57:44 PM (16 years ago)
Author:
[email protected]
Message:

Merged nitro-extreme branch into trunk.

Location:
trunk/JavaScriptCore/runtime
Files:
2 added
25 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/runtime/ArgList.h

    r45891 r46598  
    2323#define ArgList_h
    2424
    25 #include "JSImmediate.h"
    2625#include "Register.h"
    2726
  • trunk/JavaScriptCore/runtime/Arguments.h

    r44224 r46598  
    231231    }
    232232
     233    ALWAYS_INLINE Arguments* Register::arguments() const
     234    {
     235        if (jsValue() == JSValue())
     236            return 0;
     237        return asArguments(jsValue());
     238    }
     239   
     240
    233241} // namespace JSC
    234242
  • trunk/JavaScriptCore/runtime/Collector.cpp

    r46431 r46598  
    11831183    if (cell->isString())
    11841184        return "string";
     1185#if USE(JSVALUE32)
    11851186    if (cell->isNumber())
    11861187        return "number";
     1188#endif
    11871189    if (cell->isGetterSetter())
    11881190        return "gettersetter";
  • trunk/JavaScriptCore/runtime/Collector.h

    r45891 r46598  
    168168
    169169    // cell size needs to be a power of two for certain optimizations in collector.cpp
    170     template<> struct CellSize<sizeof(uint32_t)> { static const size_t m_value = 32; }; // 32-bit
    171     template<> struct CellSize<sizeof(uint64_t)> { static const size_t m_value = 64; }; // 64-bit
     170#if USE(JSVALUE32)
     171    template<> struct CellSize<sizeof(uint32_t)> { static const size_t m_value = 32; };
     172#else
     173    template<> struct CellSize<sizeof(uint32_t)> { static const size_t m_value = 64; };
     174#endif
     175    template<> struct CellSize<sizeof(uint64_t)> { static const size_t m_value = 64; };
     176
    172177    const size_t BLOCK_SIZE = 16 * 4096; // 64k
    173178
  • trunk/JavaScriptCore/runtime/ExceptionHelpers.h

    r46528 r46598  
    3030#define ExceptionHelpers_h
    3131
    32 #include "JSImmediate.h"
    3332
    3433namespace JSC {
  • trunk/JavaScriptCore/runtime/InitializeThreading.cpp

    r44508 r46598  
    3030#include "InitializeThreading.h"
    3131
    32 #include "JSImmediate.h"
    3332#include "Collector.h"
    3433#include "dtoa.h"
  • trunk/JavaScriptCore/runtime/JSArray.cpp

    r46180 r46598  
    135135
    136136    m_storage = static_cast<ArrayStorage*>(fastZeroedMalloc(storageSize(initialCapacity)));
     137    m_storage->m_vectorLength = initialCapacity;
     138
    137139    m_fastAccessCutoff = 0;
    138     m_storage->m_vectorLength = initialCapacity;
    139     m_storage->m_length = 0;
    140140
    141141    checkConsistency();
     
    147147    unsigned initialCapacity = min(initialLength, MIN_SPARSE_ARRAY_INDEX);
    148148
    149     m_storage = static_cast<ArrayStorage*>(fastZeroedMalloc(storageSize(initialCapacity)));
     149    m_storage = static_cast<ArrayStorage*>(fastMalloc(storageSize(initialCapacity)));
     150    m_storage->m_length = initialLength;
     151    m_storage->m_vectorLength = initialCapacity;
     152    m_storage->m_numValuesInVector = 0;
     153    m_storage->m_sparseValueMap = 0;
     154    m_storage->lazyCreationData = 0;
     155
     156    JSValue* vector = m_storage->m_vector;
     157    for (size_t i = 0; i < initialCapacity; ++i)
     158        vector[i] = JSValue();
     159
    150160    m_fastAccessCutoff = 0;
    151     m_storage->m_vectorLength = initialCapacity;
    152     m_storage->m_length = initialLength;
     161
     162    checkConsistency();
    153163
    154164    Heap::heap(this)->reportExtraMemoryCost(initialCapacity * sizeof(JSValue));
    155 
    156     checkConsistency();
    157165}
    158166
     
    160168    : JSObject(structure)
    161169{
    162     unsigned length = list.size();
    163 
    164     m_fastAccessCutoff = length;
    165 
    166     ArrayStorage* storage = static_cast<ArrayStorage*>(fastMalloc(storageSize(length)));
    167 
    168     storage->m_vectorLength = length;
    169     storage->m_numValuesInVector = length;
    170     storage->m_sparseValueMap = 0;
    171     storage->m_length = length;
     170    unsigned initialCapacity = list.size();
     171
     172    m_storage = static_cast<ArrayStorage*>(fastMalloc(storageSize(initialCapacity)));
     173    m_storage->m_length = initialCapacity;
     174    m_storage->m_vectorLength = initialCapacity;
     175    m_storage->m_numValuesInVector = initialCapacity;
     176    m_storage->m_sparseValueMap = 0;
    172177
    173178    size_t i = 0;
    174179    ArgList::const_iterator end = list.end();
    175180    for (ArgList::const_iterator it = list.begin(); it != end; ++it, ++i)
    176         storage->m_vector[i] = *it;
    177 
    178     m_storage = storage;
    179 
    180     Heap::heap(this)->reportExtraMemoryCost(storageSize(length));
    181 
    182     checkConsistency();
     181        m_storage->m_vector[i] = *it;
     182
     183    m_fastAccessCutoff = initialCapacity;
     184
     185    checkConsistency();
     186
     187    Heap::heap(this)->reportExtraMemoryCost(storageSize(initialCapacity));
    183188}
    184189
  • trunk/JavaScriptCore/runtime/JSCell.cpp

    r43153 r46598  
    9191}
    9292
    93 bool JSCell::getTruncatedInt32(int32_t&) const
    94 {
    95     return false;
    96 }
    97 
    98 bool JSCell::getTruncatedUInt32(uint32_t&) const
    99 {
    100     return false;
    101 }
    102 
    10393bool JSCell::getString(UString&stringValue) const
    10494{
  • trunk/JavaScriptCore/runtime/JSCell.h

    r46528 r46598  
    4141        friend class JSString;
    4242        friend class JSValue;
     43        friend class JSAPIValueWrapper;
    4344        friend struct VPtrSet;
    4445
     
    4950    public:
    5051        // Querying the type.
     52#if USE(JSVALUE32)
    5153        bool isNumber() const;
     54#endif
    5255        bool isString() const;
    5356        bool isObject() const;
    5457        virtual bool isGetterSetter() const;
    5558        virtual bool isObject(const ClassInfo*) const;
     59        virtual bool isAPIValueWrapper() const { return false; }
    5660
    5761        Structure* structure() const;
     
    6973        // FIXME: remove these methods, can check isNumberCell in JSValue && then call asNumberCell::*.
    7074        virtual bool getUInt32(uint32_t&) const;
    71         virtual bool getTruncatedInt32(int32_t&) const;
    72         virtual bool getTruncatedUInt32(uint32_t&) const;
    7375
    7476        // Basic conversions.
     
    125127    }
    126128
     129#if USE(JSVALUE32)
    127130    inline bool JSCell::isNumber() const
    128131    {
    129132        return Heap::isNumber(const_cast<JSCell*>(this));
    130133    }
     134#endif
    131135
    132136    inline bool JSCell::isObject() const
     
    153157    {
    154158        return Heap::markCell(this);
    155     }
    156 
    157     ALWAYS_INLINE JSCell* JSValue::asCell() const
    158     {
    159         ASSERT(isCell());
    160         return m_ptr;
    161159    }
    162160
     
    174172    inline bool JSValue::isString() const
    175173    {
    176         return !JSImmediate::isImmediate(asValue()) && asCell()->isString();
     174        return isCell() && asCell()->isString();
    177175    }
    178176
    179177    inline bool JSValue::isGetterSetter() const
    180178    {
    181         return !JSImmediate::isImmediate(asValue()) && asCell()->isGetterSetter();
     179        return isCell() && asCell()->isGetterSetter();
    182180    }
    183181
    184182    inline bool JSValue::isObject() const
    185183    {
    186         return !JSImmediate::isImmediate(asValue()) && asCell()->isObject();
     184        return isCell() && asCell()->isObject();
    187185    }
    188186
    189187    inline bool JSValue::getString(UString& s) const
    190188    {
    191         return !JSImmediate::isImmediate(asValue()) && asCell()->getString(s);
     189        return isCell() && asCell()->getString(s);
    192190    }
    193191
    194192    inline UString JSValue::getString() const
    195193    {
    196         return JSImmediate::isImmediate(asValue()) ? UString() : asCell()->getString();
     194        return isCell() ? asCell()->getString() : UString();
    197195    }
    198196
    199197    inline JSObject* JSValue::getObject() const
    200198    {
    201         return JSImmediate::isImmediate(asValue()) ? 0 : asCell()->getObject();
     199        return isCell() ? asCell()->getObject() : 0;
    202200    }
    203201
    204202    inline CallType JSValue::getCallData(CallData& callData)
    205203    {
    206         return JSImmediate::isImmediate(asValue()) ? CallTypeNone : asCell()->getCallData(callData);
     204        return isCell() ? asCell()->getCallData(callData) : CallTypeNone;
    207205    }
    208206
    209207    inline ConstructType JSValue::getConstructData(ConstructData& constructData)
    210208    {
    211         return JSImmediate::isImmediate(asValue()) ? ConstructTypeNone : asCell()->getConstructData(constructData);
     209        return isCell() ? asCell()->getConstructData(constructData) : ConstructTypeNone;
    212210    }
    213211
    214212    ALWAYS_INLINE bool JSValue::getUInt32(uint32_t& v) const
    215213    {
    216         return JSImmediate::isImmediate(asValue()) ? JSImmediate::getUInt32(asValue(), v) : asCell()->getUInt32(v);
    217     }
    218 
    219     ALWAYS_INLINE bool JSValue::getTruncatedInt32(int32_t& v) const
    220     {
    221         return JSImmediate::isImmediate(asValue()) ? JSImmediate::getTruncatedInt32(asValue(), v) : asCell()->getTruncatedInt32(v);
    222     }
    223 
    224     inline bool JSValue::getTruncatedUInt32(uint32_t& v) const
    225     {
    226         return JSImmediate::isImmediate(asValue()) ? JSImmediate::getTruncatedUInt32(asValue(), v) : asCell()->getTruncatedUInt32(v);
     214        if (isInt32()) {
     215            int32_t i = asInt32();
     216            v = static_cast<uint32_t>(i);
     217            return i >= 0;
     218        }
     219        if (isDouble()) {
     220            double d = asDouble();
     221            v = static_cast<uint32_t>(d);
     222            return v == d;
     223        }
     224        return false;
    227225    }
    228226
     
    234232    inline bool JSValue::marked() const
    235233    {
    236         return JSImmediate::isImmediate(asValue()) || asCell()->marked();
    237     }
     234        return !isCell() || asCell()->marked();
     235    }
     236
     237#if !USE(JSVALUE32_64)
     238    ALWAYS_INLINE JSCell* JSValue::asCell() const
     239    {
     240        ASSERT(isCell());
     241        return m_ptr;
     242    }
     243#endif // !USE(JSVALUE32_64)
    238244
    239245    inline JSValue JSValue::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const
    240246    {
    241         return JSImmediate::isImmediate(asValue()) ? asValue() : asCell()->toPrimitive(exec, preferredType);
     247        return isCell() ? asCell()->toPrimitive(exec, preferredType) : asValue();
    242248    }
    243249
    244250    inline bool JSValue::getPrimitiveNumber(ExecState* exec, double& number, JSValue& value)
    245251    {
    246         if (JSImmediate::isImmediate(asValue())) {
    247             number = JSImmediate::toDouble(asValue());
    248             value = asValue();
    249             return true;
    250         }
    251         return asCell()->getPrimitiveNumber(exec, number, value);
     252        if (isInt32()) {
     253            number = asInt32();
     254            value = *this;
     255            return true;
     256        }
     257        if (isDouble()) {
     258            number = asDouble();
     259            value = *this;
     260            return true;
     261        }
     262        if (isCell())
     263            return asCell()->getPrimitiveNumber(exec, number, value);
     264        if (isTrue()) {
     265            number = 1.0;
     266            value = *this;
     267            return true;
     268        }
     269        if (isFalse() || isNull()) {
     270            number = 0.0;
     271            value = *this;
     272            return true;
     273        }
     274        ASSERT(isUndefined());
     275        number = nonInlineNaN();
     276        value = *this;
     277        return true;
    252278    }
    253279
    254280    inline bool JSValue::toBoolean(ExecState* exec) const
    255281    {
    256         return JSImmediate::isImmediate(asValue()) ? JSImmediate::toBoolean(asValue()) : asCell()->toBoolean(exec);
     282        if (isInt32())
     283            return asInt32() != 0;
     284        if (isDouble())
     285            return asDouble() > 0.0 || asDouble() < 0.0; // false for NaN
     286        if (isCell())
     287            return asCell()->toBoolean(exec);
     288        return isTrue(); // false, null, and undefined all convert to false.
    257289    }
    258290
    259291    ALWAYS_INLINE double JSValue::toNumber(ExecState* exec) const
    260292    {
    261         return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : asCell()->toNumber(exec);
     293        if (isInt32())
     294            return asInt32();
     295        if (isDouble())
     296            return asDouble();
     297        if (isCell())
     298            return asCell()->toNumber(exec);
     299        if (isTrue())
     300            return 1.0;
     301        return isUndefined() ? nonInlineNaN() : 0; // null and false both convert to 0.
    262302    }
    263303
    264304    inline UString JSValue::toString(ExecState* exec) const
    265305    {
    266         return JSImmediate::isImmediate(asValue()) ? JSImmediate::toString(asValue()) : asCell()->toString(exec);
     306        if (isCell())
     307            return asCell()->toString(exec);
     308        if (isInt32())
     309            return UString::from(asInt32());
     310        if (isDouble())
     311            return asDouble() == 0.0 ? "0" : UString::from(asDouble());
     312        if (isTrue())
     313            return "true";
     314        if (isFalse())
     315            return "false";
     316        if (isNull())
     317            return "null";
     318        ASSERT(isUndefined());
     319        return "undefined";
     320    }
     321
     322    inline bool JSValue::needsThisConversion() const
     323    {
     324        if (UNLIKELY(!isCell()))
     325            return true;
     326        return asCell()->structure()->typeInfo().needsThisConversion();
     327    }
     328
     329    inline UString JSValue::toThisString(ExecState* exec) const
     330    {
     331        return isCell() ? asCell()->toThisString(exec) : toString(exec);
     332    }
     333
     334    inline JSValue JSValue::getJSNumber()
     335    {
     336        if (isInt32() || isDouble())
     337            return *this;
     338        if (isCell())
     339            return asCell()->getJSNumber();
     340        return JSValue();
    267341    }
    268342
    269343    inline JSObject* JSValue::toObject(ExecState* exec) const
    270344    {
    271         return JSImmediate::isImmediate(asValue()) ? JSImmediate::toObject(asValue(), exec) : asCell()->toObject(exec);
     345        return isCell() ? asCell()->toObject(exec) : toObjectSlowCase(exec);
    272346    }
    273347
    274348    inline JSObject* JSValue::toThisObject(ExecState* exec) const
    275349    {
    276         if (UNLIKELY(JSImmediate::isImmediate(asValue())))
    277             return JSImmediate::toThisObject(asValue(), exec);
    278         return asCell()->toThisObject(exec);
    279     }
    280 
    281     inline bool JSValue::needsThisConversion() const
    282     {
    283         if (UNLIKELY(JSImmediate::isImmediate(asValue())))
    284             return true;
    285         return asCell()->structure()->typeInfo().needsThisConversion();
    286     }
    287 
    288     inline UString JSValue::toThisString(ExecState* exec) const
    289     {
    290         return JSImmediate::isImmediate(asValue()) ? JSImmediate::toString(asValue()) : asCell()->toThisString(exec);
    291     }
    292 
    293     inline JSValue JSValue::getJSNumber()
    294     {
    295         return JSImmediate::isNumber(asValue()) ? asValue() : JSImmediate::isImmediate(asValue()) ? JSValue() : asCell()->getJSNumber();
     350        return isCell() ? asCell()->toThisObject(exec) : toThisObjectSlowCase(exec);
    296351    }
    297352
  • trunk/JavaScriptCore/runtime/JSFunction.cpp

    r44862 r46598  
    7373JSFunction::~JSFunction()
    7474{
    75 #if ENABLE(JIT)
    7675    // JIT code for other functions may have had calls linked directly to the code for this function; these links
    7776    // are based on a check for the this pointer value for this JSFunction - which will no longer be valid once
    7877    // this memory is freed and may be reused (potentially for another, different JSFunction).
     78#if ENABLE(JIT_OPTIMIZE_CALL)
    7979    if (m_body && m_body->isGenerated())
    8080        m_body->generatedBytecode().unlinkCallers();
    8181#endif
    8282    if (!isHostFunction())
    83         scopeChain().~ScopeChain();
     83        scopeChain().~ScopeChain(); // FIXME: Don't we need to do this in the interpreter too?
    8484}
    8585
  • trunk/JavaScriptCore/runtime/JSGlobalData.cpp

    r45553 r46598  
    119119    , notAnObjectErrorStubStructure(JSNotAnObjectErrorStub::createStructure(jsNull()))
    120120    , notAnObjectStructure(JSNotAnObject::createStructure(jsNull()))
    121 #if !USE(ALTERNATE_JSIMMEDIATE)
     121#if USE(JSVALUE32)
    122122    , numberStructure(JSNumberCell::createStructure(jsNull()))
    123123#endif
  • trunk/JavaScriptCore/runtime/JSGlobalData.h

    r46528 r46598  
    9898        RefPtr<Structure> notAnObjectErrorStubStructure;
    9999        RefPtr<Structure> notAnObjectStructure;
    100 #if !USE(ALTERNATE_JSIMMEDIATE)
     100#if USE(JSVALUE32)
    101101        RefPtr<Structure> numberStructure;
    102102#endif
  • trunk/JavaScriptCore/runtime/JSGlobalObject.h

    r45891 r46598  
    348348            return m_prototype;
    349349
     350#if USE(JSVALUE32)
    350351        if (typeInfo().type() == StringType)
    351352            return exec->lexicalGlobalObject()->stringPrototype();
     
    353354        ASSERT(typeInfo().type() == NumberType);
    354355        return exec->lexicalGlobalObject()->numberPrototype();
     356#else
     357        ASSERT(typeInfo().type() == StringType);
     358        return exec->lexicalGlobalObject()->stringPrototype();
     359#endif
    355360    }
    356361
  • trunk/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp

    r44923 r46598  
    304304    int32_t radix = args.at(1).toInt32(exec);
    305305
    306     if (value.isNumber() && (radix == 0 || radix == 10)) {
    307         if (value.isInt32Fast())
    308             return value;
    309         double d = value.uncheckedGetNumber();
     306    if (radix != 0 && radix != 10)
     307        return jsNumber(exec, parseInt(value.toString(exec), radix));
     308
     309    if (value.isInt32())
     310        return value;
     311
     312    if (value.isDouble()) {
     313        double d = value.asDouble();
    310314        if (isfinite(d))
    311315            return jsNumber(exec, (d > 0) ? floor(d) : ceil(d));
    312316        if (isnan(d) || isinf(d))
    313             return jsNaN(&exec->globalData());
     317            return jsNaN(exec);
    314318        return jsNumber(exec, 0);
    315319    }
  • trunk/JavaScriptCore/runtime/JSImmediate.cpp

    r43122 r46598  
    2121#include "config.h"
    2222#include "JSImmediate.h"
     23
     24#if !USE(JSVALUE32_64)
    2325
    2426#include "BooleanConstructor.h"
     
    7072}
    7173
    72 UString JSImmediate::toString(JSValue v)
    73 {
    74     ASSERT(isImmediate(v));
    75     if (isIntegerNumber(v))
    76         return UString::from(getTruncatedInt32(v));
    77 #if USE(ALTERNATE_JSIMMEDIATE)
    78     if (isNumber(v)) {
    79         ASSERT(isDoubleNumber(v));
    80         double value = doubleValue(v);
    81         if (value == 0.0) // +0.0 or -0.0
    82             return "0";
    83         return UString::from(value);
    84     }
    85 #else
    86         ASSERT(!isNumber(v));
    87 #endif
    88     if (jsBoolean(false) == v)
    89         return "false";
    90     if (jsBoolean(true) == v)
    91         return "true";
    92     if (v.isNull())
    93         return "null";
    94     ASSERT(v.isUndefined());
    95     return "undefined";
    96 }
     74} // namespace JSC
    9775
    98 NEVER_INLINE double JSImmediate::nonInlineNaN()
    99 {
    100     return std::numeric_limits<double>::quiet_NaN();
    101 }
    102 
    103 } // namespace JSC
     76#endif // !USE(JSVALUE32_64)
  • trunk/JavaScriptCore/runtime/JSImmediate.h

    r43153 r46598  
    2323#define JSImmediate_h
    2424
     25#include <wtf/Platform.h>
     26
     27#if !USE(JSVALUE32_64)
     28
    2529#include <wtf/Assertions.h>
    2630#include <wtf/AlwaysInline.h>
     
    4347    class UString;
    4448
    45 #if USE(ALTERNATE_JSIMMEDIATE)
     49#if USE(JSVALUE64)
    4650    inline intptr_t reinterpretDoubleToIntptr(double value)
    4751    {
     
    99103    /*
    100104     * On 64-bit platforms, we support an alternative encoding form for immediates, if
    101      * USE(ALTERNATE_JSIMMEDIATE) is defined.  When this format is used, double precision
     105     * USE(JSVALUE64) is defined.  When this format is used, double precision
    102106     * floating point values may also be encoded as JSImmediates.
    103107     *
     
    156160        friend JSValue jsNumber(JSGlobalData* globalData, unsigned long long i);
    157161
    158 #if USE(ALTERNATE_JSIMMEDIATE)
     162#if USE(JSVALUE64)
    159163        // If all bits in the mask are set, this indicates an integer number,
    160164        // if any but not all are set this value is a double precision number.
     
    178182        static const intptr_t FullTagTypeNull      = TagBitTypeOther;
    179183
    180 #if USE(ALTERNATE_JSIMMEDIATE)
     184#if USE(JSVALUE64)
    181185        static const int32_t IntegerPayloadShift  = 0;
    182186#else
     
    201205        static ALWAYS_INLINE bool isIntegerNumber(JSValue v)
    202206        {
    203 #if USE(ALTERNATE_JSIMMEDIATE)
     207#if USE(JSVALUE64)
    204208            return (rawValue(v) & TagTypeNumber) == TagTypeNumber;
    205209#else
     
    208212        }
    209213
    210 #if USE(ALTERNATE_JSIMMEDIATE)
    211         static ALWAYS_INLINE bool isDoubleNumber(JSValue v)
     214#if USE(JSVALUE64)
     215        static ALWAYS_INLINE bool isDouble(JSValue v)
    212216        {
    213217            return isNumber(v) && !isIntegerNumber(v);
     
    257261        static ALWAYS_INLINE bool areBothImmediateIntegerNumbers(JSValue v1, JSValue v2)
    258262        {
    259 #if USE(ALTERNATE_JSIMMEDIATE)
     263#if USE(JSVALUE64)
    260264            return (rawValue(v1) & rawValue(v2) & TagTypeNumber) == TagTypeNumber;
    261265#else
     
    268272        static JSObject* toObject(JSValue, ExecState*);
    269273        static JSObject* toThisObject(JSValue, ExecState*);
    270         static UString toString(JSValue);
    271274
    272275        static bool getUInt32(JSValue, uint32_t&);
     
    287290
    288291    private:
    289 #if USE(ALTERNATE_JSIMMEDIATE)
     292#if USE(JSVALUE64)
    290293        static const int minImmediateInt = ((-INT_MAX) - 1);
    291294        static const int maxImmediateInt = INT_MAX;
     
    301304        }
    302305
    303         // With USE(ALTERNATE_JSIMMEDIATE) we want the argument to be zero extended, so the
     306        // With USE(JSVALUE64) we want the argument to be zero extended, so the
    304307        // integer doesn't interfere with the tag bits in the upper word.  In the default encoding,
    305308        // if intptr_t id larger then int32_t we sign extend the value through the upper word.
    306 #if USE(ALTERNATE_JSIMMEDIATE)
     309#if USE(JSVALUE64)
    307310        static ALWAYS_INLINE JSValue makeInt(uint32_t value)
    308311#else
     
    313316        }
    314317       
    315 #if USE(ALTERNATE_JSIMMEDIATE)
     318#if USE(JSVALUE64)
    316319        static ALWAYS_INLINE JSValue makeDouble(double value)
    317320        {
     
    338341        static JSValue fromNumberOutsideIntegerRange(T);
    339342
    340 #if USE(ALTERNATE_JSIMMEDIATE)
     343#if USE(JSVALUE64)
    341344        static ALWAYS_INLINE double doubleValue(JSValue v)
    342345        {
     
    364367            return v.immediateValue();
    365368        }
    366 
    367         static double nonInlineNaN();
    368369    };
    369370
     
    375376    ALWAYS_INLINE JSValue JSImmediate::oneImmediate() { return makeInt(1); }
    376377
    377 #if USE(ALTERNATE_JSIMMEDIATE)
     378#if USE(JSVALUE64)
    378379    inline bool doubleToBoolean(double value)
    379380    {
     
    402403    }
    403404
    404 #if USE(ALTERNATE_JSIMMEDIATE)
     405#if USE(JSVALUE64)
    405406    template<typename T>
    406407    inline JSValue JSImmediate::fromNumberOutsideIntegerRange(T value)
     
    443444    ALWAYS_INLINE JSValue JSImmediate::from(int i)
    444445    {
    445 #if !USE(ALTERNATE_JSIMMEDIATE)
     446#if !USE(JSVALUE64)
    446447        if ((i < minImmediateInt) | (i > maxImmediateInt))
    447448            return fromNumberOutsideIntegerRange(i);
     
    509510            return intValue(v);
    510511
    511 #if USE(ALTERNATE_JSIMMEDIATE)
     512#if USE(JSVALUE64)
    512513        if (isNumber(v)) {
    513             ASSERT(isDoubleNumber(v));
     514            ASSERT(isDouble(v));
    514515            return doubleValue(v);
    515516        }
     
    542543    }
    543544
    544     // These are identical logic to the JSValue functions above, and faster than jsNumber(number).toInt32().
    545     int32_t toInt32(double);
    546     uint32_t toUInt32(double);
    547     int32_t toInt32SlowCase(double, bool& ok);
    548     uint32_t toUInt32SlowCase(double, bool& ok);
    549 
    550545    inline JSValue::JSValue(JSNullTag)
    551546    {
     
    576571    {
    577572        return JSImmediate::isBoolean(asValue());
     573    }
     574
     575    inline bool JSValue::isTrue() const
     576    {
     577        return asValue() == JSImmediate::trueImmediate();
     578    }
     579
     580    inline bool JSValue::isFalse() const
     581    {
     582        return asValue() == JSImmediate::falseImmediate();
    578583    }
    579584
     
    593598    }
    594599
    595     ALWAYS_INLINE int32_t JSValue::toInt32(ExecState* exec) const
    596     {
    597         int32_t i;
    598         if (getTruncatedInt32(i))
    599             return i;
    600         bool ignored;
    601         return toInt32SlowCase(toNumber(exec), ignored);
    602     }
    603 
    604     inline uint32_t JSValue::toUInt32(ExecState* exec) const
    605     {
    606         uint32_t i;
    607         if (getTruncatedUInt32(i))
    608             return i;
    609         bool ignored;
    610         return toUInt32SlowCase(toNumber(exec), ignored);
    611     }
    612 
    613     inline int32_t toInt32(double val)
    614     {
    615         if (!(val >= -2147483648.0 && val < 2147483648.0)) {
    616             bool ignored;
    617             return toInt32SlowCase(val, ignored);
    618         }
    619         return static_cast<int32_t>(val);
    620     }
    621 
    622     inline uint32_t toUInt32(double val)
    623     {
    624         if (!(val >= 0.0 && val < 4294967296.0)) {
    625             bool ignored;
    626             return toUInt32SlowCase(val, ignored);
    627         }
    628         return static_cast<uint32_t>(val);
    629     }
    630 
    631     inline int32_t JSValue::toInt32(ExecState* exec, bool& ok) const
    632     {
    633         int32_t i;
    634         if (getTruncatedInt32(i)) {
    635             ok = true;
    636             return i;
    637         }
    638         return toInt32SlowCase(toNumber(exec), ok);
    639     }
    640 
    641     inline uint32_t JSValue::toUInt32(ExecState* exec, bool& ok) const
    642     {
    643         uint32_t i;
    644         if (getTruncatedUInt32(i)) {
    645             ok = true;
    646             return i;
    647         }
    648         return toUInt32SlowCase(toNumber(exec), ok);
    649     }
    650 
    651600    inline bool JSValue::isCell() const
    652601    {
     
    654603    }
    655604
    656     inline bool JSValue::isInt32Fast() const
     605    inline bool JSValue::isInt32() const
    657606    {
    658607        return JSImmediate::isIntegerNumber(asValue());
    659608    }
    660609
    661     inline int32_t JSValue::getInt32Fast() const
    662     {
    663         ASSERT(isInt32Fast());
     610    inline int32_t JSValue::asInt32() const
     611    {
     612        ASSERT(isInt32());
    664613        return JSImmediate::getTruncatedInt32(asValue());
    665614    }
    666615
    667     inline bool JSValue::isUInt32Fast() const
     616    inline bool JSValue::isUInt32() const
    668617    {
    669618        return JSImmediate::isPositiveIntegerNumber(asValue());
    670619    }
    671620
    672     inline uint32_t JSValue::getUInt32Fast() const
    673     {
    674         ASSERT(isUInt32Fast());
     621    inline uint32_t JSValue::asUInt32() const
     622    {
     623        ASSERT(isUInt32());
    675624        return JSImmediate::getTruncatedUInt32(asValue());
    676     }
    677 
    678     inline JSValue JSValue::makeInt32Fast(int32_t i)
    679     {
    680         return JSImmediate::from(i);
    681     }
    682 
    683     inline bool JSValue::areBothInt32Fast(JSValue v1, JSValue v2)
    684     {
    685         return JSImmediate::areBothImmediateIntegerNumbers(v1, v2);
    686625    }
    687626
     
    736675        {
    737676            ASSERT(canDoFastRshift(val, shift) || canDoFastUrshift(val, shift));
    738 #if USE(ALTERNATE_JSIMMEDIATE)
     677#if USE(JSVALUE64)
    739678            return JSImmediate::makeValue(static_cast<intptr_t>(static_cast<uint32_t>(static_cast<int32_t>(JSImmediate::rawValue(val)) >> ((JSImmediate::rawValue(shift) >> JSImmediate::IntegerPayloadShift) & 0x1f))) | JSImmediate::TagTypeNumber);
    740679#else
     
    784723} // namespace JSC
    785724
     725#endif // !USE(JSVALUE32_64)
     726
    786727#endif // JSImmediate_h
  • trunk/JavaScriptCore/runtime/JSNumberCell.cpp

    r43165 r46598  
    2424#include "JSNumberCell.h"
    2525
     26#if USE(JSVALUE32)
     27
    2628#include "NumberObject.h"
    2729#include "UString.h"
    2830
    2931namespace JSC {
    30 
    31 #if !USE(ALTERNATE_JSIMMEDIATE)
    3232
    3333JSValue JSNumberCell::toPrimitive(ExecState*, PreferredPrimitiveType) const
     
    8383}
    8484
    85 bool JSNumberCell::getTruncatedInt32(int32_t& int32) const
    86 {
    87     if (!(m_value >= -2147483648.0 && m_value < 2147483648.0))
    88         return false;
    89     int32 = static_cast<int32_t>(m_value);
    90     return true;
    91 }
    92 
    93 bool JSNumberCell::getTruncatedUInt32(uint32_t& uint32) const
    94 {
    95     if (!(m_value >= 0.0 && m_value < 4294967296.0))
    96         return false;
    97     uint32 = static_cast<uint32_t>(m_value);
    98     return true;
    99 }
    100 
    10185JSValue JSNumberCell::getJSNumber()
    10286{
     
    11498}
    11599
    116 JSValue jsAPIMangledNumber(ExecState* exec, double d)
    117 {
    118     return new (exec) JSNumberCell(JSNumberCell::APIMangled, d);
    119 }
     100} // namespace JSC
    120101
    121 #else
     102#else // USE(JSVALUE32)
     103
     104// Keep our exported symbols lists happy.
     105namespace JSC {
     106
     107JSValue jsNumberCell(ExecState*, double);
    122108
    123109JSValue jsNumberCell(ExecState*, double)
     
    127113}
    128114
    129 JSValue jsAPIMangledNumber(ExecState*, double)
    130 {
    131     ASSERT_NOT_REACHED();
    132     return JSValue();
    133 }
     115} // namespace JSC
    134116
    135 #endif
    136 
    137 } // namespace JSC
     117#endif // USE(JSVALUE32)
  • trunk/JavaScriptCore/runtime/JSNumberCell.h

    r43165 r46598  
    3636    extern const double Inf;
    3737
     38#if USE(JSVALUE32)
    3839    JSValue jsNumberCell(ExecState*, double);
    39     JSValue jsAPIMangledNumber(ExecState*, double);
    40 
    41 #if !USE(ALTERNATE_JSIMMEDIATE)
    4240
    4341    class Identifier;
     
    5452        friend JSValue jsNumberCell(JSGlobalData*, double);
    5553        friend JSValue jsNumberCell(ExecState*, double);
    56         friend JSValue jsAPIMangledNumber(ExecState*, double);
     54
    5755    public:
    5856        double value() const { return m_value; }
     
    6866        virtual JSObject* toThisObject(ExecState*) const;
    6967        virtual JSValue getJSNumber();
    70 
    71         static const uintptr_t JSAPIMangledMagicNumber = 0xbbadbeef;
    72         bool isAPIMangledNumber() const { return m_structure == reinterpret_cast<Structure*>(JSAPIMangledMagicNumber); }
    7368
    7469        void* operator new(size_t size, ExecState* exec)
     
    105100        }
    106101
    107         enum APIMangledTag { APIMangled };
    108         JSNumberCell(APIMangledTag, double value)
    109             : JSCell(reinterpret_cast<Structure*>(JSAPIMangledMagicNumber))
    110             , m_value(value)
    111         {
    112         }
    113 
    114102        virtual bool getUInt32(uint32_t&) const;
    115         virtual bool getTruncatedInt32(int32_t&) const;
    116         virtual bool getTruncatedUInt32(uint32_t&) const;
    117103
    118104        double m_value;
     
    132118    }
    133119
    134 
    135120    inline JSValue::JSValue(ExecState* exec, double d)
    136121    {
     
    193178    }
    194179
    195     inline JSValue::JSValue(JSGlobalData* globalData, long i)
    196     {
    197         JSValue v = JSImmediate::from(i);
    198         *this = v ? v : jsNumberCell(globalData, i);
    199     }
    200 
    201     inline JSValue::JSValue(JSGlobalData* globalData, unsigned long i)
    202     {
    203         JSValue v = JSImmediate::from(i);
    204         *this = v ? v : jsNumberCell(globalData, i);
    205     }
    206 
    207     inline JSValue::JSValue(JSGlobalData* globalData, long long i)
    208     {
    209         JSValue v = JSImmediate::from(i);
    210         *this = v ? v : jsNumberCell(globalData, static_cast<double>(i));
    211     }
    212 
    213     inline JSValue::JSValue(JSGlobalData* globalData, unsigned long long i)
    214     {
    215         JSValue v = JSImmediate::from(i);
    216         *this = v ? v : jsNumberCell(globalData, static_cast<double>(i));
    217     }
    218 
    219     inline bool JSValue::isDoubleNumber() const
     180    inline bool JSValue::isDouble() const
    220181    {
    221182        return isNumberCell(asValue());
    222183    }
    223184
    224     inline double JSValue::getDoubleNumber() const
     185    inline double JSValue::asDouble() const
    225186    {
    226187        return asNumberCell(asValue())->value();
     
    229190    inline bool JSValue::isNumber() const
    230191    {
    231         return JSImmediate::isNumber(asValue()) || isDoubleNumber();
     192        return JSImmediate::isNumber(asValue()) || isDouble();
    232193    }
    233194
     
    235196    {
    236197        ASSERT(isNumber());
    237         return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : getDoubleNumber();
    238     }
    239 
    240     inline bool JSValue::isAPIMangledNumber()
    241     {
    242         ASSERT(isNumber());
    243         return JSImmediate::isImmediate(asValue()) ? false : asNumberCell(asValue())->isAPIMangledNumber();
    244     }
    245 
    246 #else
    247 
     198        return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : asDouble();
     199    }
     200
     201#endif // USE(JSVALUE32)
     202
     203#if USE(JSVALUE64)
    248204    inline JSValue::JSValue(ExecState*, double d)
    249205    {
     
    316272    }
    317273
    318     inline JSValue::JSValue(JSGlobalData*, long i)
    319     {
    320         JSValue v = JSImmediate::from(i);
    321         ASSERT(v);
    322         *this = v;
    323     }
    324 
    325     inline JSValue::JSValue(JSGlobalData*, unsigned long i)
    326     {
    327         JSValue v = JSImmediate::from(i);
    328         ASSERT(v);
    329         *this = v;
    330     }
    331 
    332     inline JSValue::JSValue(JSGlobalData*, long long i)
    333     {
    334         JSValue v = JSImmediate::from(static_cast<double>(i));
    335         ASSERT(v);
    336         *this = v;
    337     }
    338 
    339     inline JSValue::JSValue(JSGlobalData*, unsigned long long i)
    340     {
    341         JSValue v = JSImmediate::from(static_cast<double>(i));
    342         ASSERT(v);
    343         *this = v;
    344     }
    345 
    346     inline bool JSValue::isDoubleNumber() const
    347     {
    348         return JSImmediate::isDoubleNumber(asValue());
    349     }
    350 
    351     inline double JSValue::getDoubleNumber() const
     274    inline bool JSValue::isDouble() const
     275    {
     276        return JSImmediate::isDouble(asValue());
     277    }
     278
     279    inline double JSValue::asDouble() const
    352280    {
    353281        return JSImmediate::doubleValue(asValue());
     
    365293    }
    366294
    367 #endif
     295#endif // USE(JSVALUE64)
     296
     297#if USE(JSVALUE32) || USE(JSVALUE64)
    368298
    369299    inline JSValue::JSValue(ExecState*, char i)
     
    391321    }
    392322
    393     inline JSValue::JSValue(JSGlobalData*, char i)
    394     {
    395         ASSERT(JSImmediate::from(i));
    396         *this = JSImmediate::from(i);
    397     }
    398 
    399     inline JSValue::JSValue(JSGlobalData*, unsigned char i)
    400     {
    401         ASSERT(JSImmediate::from(i));
    402         *this = JSImmediate::from(i);
    403     }
    404 
    405     inline JSValue::JSValue(JSGlobalData*, short i)
    406     {
    407         ASSERT(JSImmediate::from(i));
    408         *this = JSImmediate::from(i);
    409     }
    410 
    411     inline JSValue::JSValue(JSGlobalData*, unsigned short i)
    412     {
    413         ASSERT(JSImmediate::from(i));
    414         *this = JSImmediate::from(i);
    415     }
    416 
    417323    inline JSValue jsNaN(ExecState* exec)
    418324    {
     
    434340    inline bool JSValue::getNumber(double &result) const
    435341    {
    436         if (isInt32Fast())
    437             result = getInt32Fast();
    438         else if (LIKELY(isDoubleNumber()))
    439             result = getDoubleNumber();
     342        if (isInt32())
     343            result = asInt32();
     344        else if (LIKELY(isDouble()))
     345            result = asDouble();
    440346        else {
    441347            ASSERT(!isNumber());
     
    445351    }
    446352
    447     inline bool JSValue::numberToInt32(int32_t& arg)
    448     {
    449         if (isInt32Fast())
    450             arg = getInt32Fast();
    451         else if (LIKELY(isDoubleNumber()))
    452             arg = JSC::toInt32(getDoubleNumber());
    453         else {
    454             ASSERT(!isNumber());
    455             return false;
    456         }
    457         return true;
    458     }
    459 
    460     inline bool JSValue::numberToUInt32(uint32_t& arg)
    461     {
    462         if (isUInt32Fast())
    463             arg = getUInt32Fast();
    464         else if (LIKELY(isDoubleNumber()))
    465             arg = JSC::toUInt32(getDoubleNumber());
    466         else if (isInt32Fast()) {
    467             // FIXME: I think this case can be merged with the uint case; toUInt32SlowCase
    468             // on a negative value is equivalent to simple static_casting.
    469             bool ignored;
    470             arg = toUInt32SlowCase(getInt32Fast(), ignored);
    471         } else {
    472             ASSERT(!isNumber());
    473             return false;
    474         }
    475         return true;
    476     }
     353#endif // USE(JSVALUE32) || USE(JSVALUE64)
    477354
    478355} // namespace JSC
  • trunk/JavaScriptCore/runtime/JSObject.h

    r46528 r46598  
    3434#include "Structure.h"
    3535#include "JSGlobalData.h"
     36#include <wtf/StdLibExtras.h>
    3637
    3738namespace JSC {
     
    196197        bool isUsingInlineStorage() const { return m_structure->isUsingInlineStorage(); }
    197198
    198         static const size_t inlineStorageCapacity = 3;
     199        static const size_t inlineStorageCapacity = sizeof(EncodedJSValue) == 2 * sizeof(void*) ? 4 : 3;
    199200        static const size_t nonInlineBaseStorageCapacity = 16;
    200201
     
    226227        const HashEntry* findPropertyHashEntry(ExecState*, const Identifier& propertyName) const;
    227228        Structure* createInheritorID();
    228 
    229         RefPtr<Structure> m_inheritorID;
    230229
    231230        union {
     
    233232            EncodedJSValue m_inlineStorage[inlineStorageCapacity];
    234233        };
     234
     235        RefPtr<Structure> m_inheritorID;
    235236    };
    236 
    237     JSObject* asObject(JSValue);
    238 
    239     JSObject* constructEmptyObject(ExecState*);
     237   
     238JSObject* constructEmptyObject(ExecState*);
    240239
    241240inline JSObject* asObject(JSValue value)
     
    252251    ASSERT(m_structure->isEmpty());
    253252    ASSERT(prototype().isNull() || Heap::heap(this) == Heap::heap(prototype()));
     253#if USE(JSVALUE64) || USE(JSVALUE32_64)
     254    ASSERT(OBJECT_OFFSETOF(JSObject, m_inlineStorage) % sizeof(double) == 0);
     255#endif
    254256}
    255257
     
    543545{
    544546    if (UNLIKELY(!isCell())) {
    545         JSObject* prototype = JSImmediate::prototype(asValue(), exec);
     547        JSObject* prototype = synthesizePrototype(exec);
    546548        if (propertyName == exec->propertyNames().underscoreProto)
    547549            return prototype;
     
    571573{
    572574    if (UNLIKELY(!isCell())) {
    573         JSObject* prototype = JSImmediate::prototype(asValue(), exec);
     575        JSObject* prototype = synthesizePrototype(exec);
    574576        if (!prototype->getPropertySlot(exec, propertyName, slot))
    575577            return jsUndefined();
     
    591593{
    592594    if (UNLIKELY(!isCell())) {
    593         JSImmediate::toObject(asValue(), exec)->put(exec, propertyName, value, slot);
     595        synthesizeObject(exec)->put(exec, propertyName, value, slot);
    594596        return;
    595597    }
     
    600602{
    601603    if (UNLIKELY(!isCell())) {
    602         JSImmediate::toObject(asValue(), exec)->put(exec, propertyName, value);
     604        synthesizeObject(exec)->put(exec, propertyName, value);
    603605        return;
    604606    }
  • trunk/JavaScriptCore/runtime/JSString.h

    r46528 r46598  
    2424#define JSString_h
    2525
     26#include "CallFrame.h"
    2627#include "CommonIdentifiers.h"
    27 #include "CallFrame.h"
    2828#include "Identifier.h"
    2929#include "JSNumberCell.h"
     
    209209    inline JSString* JSValue::toThisJSString(ExecState* exec)
    210210    {
    211         return JSImmediate::isImmediate(asValue()) ? jsString(exec, JSImmediate::toString(asValue())) : asCell()->toThisJSString(exec);
     211        return isCell() ? asCell()->toThisJSString(exec) : jsString(exec, toString(exec));
    212212    }
    213213
  • trunk/JavaScriptCore/runtime/JSValue.cpp

    r43122 r46598  
    2424#include "JSValue.h"
    2525
     26#include "BooleanConstructor.h"
     27#include "BooleanPrototype.h"
     28#include "ExceptionHelpers.h"
     29#include "JSGlobalObject.h"
    2630#include "JSFunction.h"
     31#include "JSNotAnObject.h"
     32#include "NumberObject.h"
    2733#include <wtf/MathExtras.h>
     34#include <wtf/StringExtras.h>
    2835
    2936namespace JSC {
     
    3441double JSValue::toInteger(ExecState* exec) const
    3542{
    36     if (isInt32Fast())
    37         return getInt32Fast();
     43    if (isInt32())
     44        return asInt32();
    3845    double d = toNumber(exec);
    3946    return isnan(d) ? 0.0 : trunc(d);
     
    4249double JSValue::toIntegerPreserveNaN(ExecState* exec) const
    4350{
    44     if (isInt32Fast())
    45         return getInt32Fast();
     51    if (isInt32())
     52        return asInt32();
    4653    return trunc(toNumber(exec));
    4754}
     55
     56JSObject* JSValue::toObjectSlowCase(ExecState* exec) const
     57{
     58    ASSERT(!isCell());
     59
     60    if (isInt32() || isDouble())
     61        return constructNumber(exec, asValue());
     62    if (isTrue() || isFalse())
     63        return constructBooleanFromImmediateBoolean(exec, asValue());
     64    ASSERT(isUndefinedOrNull());
     65    JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, isNull());
     66    exec->setException(exception);
     67    return new (exec) JSNotAnObject(exec, exception);
     68}
     69
     70JSObject* JSValue::toThisObjectSlowCase(ExecState* exec) const
     71{
     72    ASSERT(!isCell());
     73
     74    if (isInt32() || isDouble())
     75        return constructNumber(exec, asValue());
     76    if (isTrue() || isFalse())
     77        return constructBooleanFromImmediateBoolean(exec, asValue());
     78    ASSERT(isUndefinedOrNull());
     79    return exec->globalThisValue();
     80}
     81
     82JSObject* JSValue::synthesizeObject(ExecState* exec) const
     83{
     84    ASSERT(!isCell());
     85    if (isNumber())
     86        return constructNumber(exec, asValue());
     87    if (isBoolean())
     88        return constructBooleanFromImmediateBoolean(exec, asValue());
     89   
     90    JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, isNull());
     91    exec->setException(exception);
     92    return new (exec) JSNotAnObject(exec, exception);
     93}
     94
     95JSObject* JSValue::synthesizePrototype(ExecState* exec) const
     96{
     97    ASSERT(!isCell());
     98    if (isNumber())
     99        return exec->lexicalGlobalObject()->numberPrototype();
     100    if (isBoolean())
     101        return exec->lexicalGlobalObject()->booleanPrototype();
     102
     103    JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, isNull());
     104    exec->setException(exception);
     105    return new (exec) JSNotAnObject(exec, exception);
     106}
     107
     108#ifndef NDEBUG
     109char* JSValue::description()
     110{
     111    static const size_t size = 32;
     112    static char description[size];
     113    if (isInt32())
     114        snprintf(description, size, "Int32: %d", asInt32());
     115    else if (isDouble())
     116        snprintf(description, size, "Double: %lf", asDouble());
     117    else if (isCell())
     118        snprintf(description, size, "Cell: %p", asCell());
     119    else if (isTrue())
     120        snprintf(description, size, "True");
     121    else if (isFalse())
     122        snprintf(description, size, "False");
     123    else if (isNull())
     124        snprintf(description, size, "Null");
     125    else {
     126        ASSERT(isUndefined());
     127        snprintf(description, size, "Undefined");
     128    }
     129
     130    return description;
     131}
     132#endif
    48133
    49134int32_t toInt32SlowCase(double d, bool& ok)
     
    85170}
    86171
     172NEVER_INLINE double nonInlineNaN()
     173{
     174    return std::numeric_limits<double>::quiet_NaN();
     175}
     176
    87177} // namespace JSC
  • trunk/JavaScriptCore/runtime/JSValue.h

    r43160 r46598  
    2929#include "CallData.h"
    3030#include "ConstructData.h"
     31#include <math.h>
     32#include <wtf/AlwaysInline.h>
     33#include <wtf/Assertions.h>
    3134#include <wtf/HashTraits.h>
    32 #include <wtf/AlwaysInline.h>
     35#include <wtf/MathExtras.h>
    3336
    3437namespace JSC {
     
    4952    enum PreferredPrimitiveType { NoPreference, PreferNumber, PreferString };
    5053
     54#if USE(JSVALUE32_64)
     55    typedef int64_t EncodedJSValue;
     56#else
    5157    typedef void* EncodedJSValue;
     58#endif
     59
     60    double nonInlineNaN();
     61    int32_t toInt32SlowCase(double, bool& ok);
     62    uint32_t toUInt32SlowCase(double, bool& ok);
    5263
    5364    class JSValue {
    5465        friend class JSImmediate;
    55         friend struct JSValueHashTraits;
    56 
    57         static JSValue makeImmediate(intptr_t value)
    58         {
    59             return JSValue(reinterpret_cast<JSCell*>(value));
    60         }
    61 
    62         intptr_t immediateValue()
    63         {
    64             return reinterpret_cast<intptr_t>(m_ptr);
    65         }
    66        
     66        friend struct EncodedJSValueHashTraits;
     67        friend class JIT;
     68        friend class JITStubs;
     69        friend class JITStubCall;
     70
    6771    public:
     72        static EncodedJSValue encode(JSValue value);
     73        static JSValue decode(EncodedJSValue ptr);
     74#if !USE(JSVALUE32_64)
     75    private:
     76        static JSValue makeImmediate(intptr_t value);
     77        intptr_t immediateValue();
     78    public:
     79#endif
    6880        enum JSNullTag { JSNull };
    6981        enum JSUndefinedTag { JSUndefined };
    7082        enum JSTrueTag { JSTrue };
    7183        enum JSFalseTag { JSFalse };
    72 
    73         static EncodedJSValue encode(JSValue value);
    74         static JSValue decode(EncodedJSValue ptr);
    7584
    7685        JSValue();
     
    95104        JSValue(ExecState*, unsigned long long);
    96105        JSValue(JSGlobalData*, double);
    97         JSValue(JSGlobalData*, char);
    98         JSValue(JSGlobalData*, unsigned char);
    99         JSValue(JSGlobalData*, short);
    100         JSValue(JSGlobalData*, unsigned short);
    101106        JSValue(JSGlobalData*, int);
    102107        JSValue(JSGlobalData*, unsigned);
    103         JSValue(JSGlobalData*, long);
    104         JSValue(JSGlobalData*, unsigned long);
    105         JSValue(JSGlobalData*, long long);
    106         JSValue(JSGlobalData*, unsigned long long);
    107108
    108109        operator bool() const;
    109         bool operator==(const JSValue other) const;
    110         bool operator!=(const JSValue other) const;
     110        bool operator==(const JSValue& other) const;
     111        bool operator!=(const JSValue& other) const;
     112
     113        bool isInt32() const;
     114        bool isUInt32() const;
     115        bool isDouble() const;
     116        bool isTrue() const;
     117        bool isFalse() const;
     118
     119        int32_t asInt32() const;
     120        uint32_t asUInt32() const;
     121        double asDouble() const;
    111122
    112123        // Querying the type.
     
    135146        // Extracting integer values.
    136147        bool getUInt32(uint32_t&) const;
    137         bool getTruncatedInt32(int32_t&) const;
    138         bool getTruncatedUInt32(uint32_t&) const;
    139148       
    140149        // Basic conversions.
     
    152161
    153162        // Integer conversions.
    154         // 'x.numberToInt32(output)' is equivalent to 'x.isNumber() && x.toInt32(output)'
    155163        double toInteger(ExecState*) const;
    156164        double toIntegerPreserveNaN(ExecState*) const;
    157165        int32_t toInt32(ExecState*) const;
    158166        int32_t toInt32(ExecState*, bool& ok) const;
    159         bool numberToInt32(int32_t& arg);
    160167        uint32_t toUInt32(ExecState*) const;
    161168        uint32_t toUInt32(ExecState*, bool& ok) const;
    162         bool numberToUInt32(uint32_t& arg);
    163 
    164         // Fast integer operations; these values return results where the value is trivially available
    165         // in a convenient form, for use in optimizations.  No assumptions should be made based on the
    166         // results of these operations, for example !isInt32Fast() does not necessarily indicate the
    167         // result of getNumber will not be 0.
    168         bool isInt32Fast() const;
    169         int32_t getInt32Fast() const;
    170         bool isUInt32Fast() const;
    171         uint32_t getUInt32Fast() const;
    172         static JSValue makeInt32Fast(int32_t);
    173         static bool areBothInt32Fast(JSValue, JSValue);
    174169
    175170        // Floating point conversions (this is a convenience method for webcore;
    176171        // signle precision float is not a representation used in JS or JSC).
    177172        float toFloat(ExecState* exec) const { return static_cast<float>(toNumber(exec)); }
    178 
    179         // API Mangled Numbers
    180         bool isAPIMangledNumber();
    181173
    182174        // Garbage collection.
     
    209201        JSCell* asCell() const;
    210202
     203#ifndef NDEBUG
     204        char* description();
     205#endif
     206
    211207    private:
    212208        enum HashTableDeletedValueTag { HashTableDeletedValue };
     
    214210
    215211        inline const JSValue asValue() const { return *this; }
    216 
    217         bool isDoubleNumber() const;
    218         double getDoubleNumber() const;
    219 
     212        JSObject* toObjectSlowCase(ExecState*) const;
     213        JSObject* toThisObjectSlowCase(ExecState*) const;
     214
     215        enum { Int32Tag =        0xffffffff };
     216        enum { CellTag =         0xfffffffe };
     217        enum { TrueTag =         0xfffffffd };
     218        enum { FalseTag =        0xfffffffc };
     219        enum { NullTag =         0xfffffffb };
     220        enum { UndefinedTag =    0xfffffffa };
     221        enum { DeletedValueTag = 0xfffffff9 };
     222
     223        enum { LowestTag =  DeletedValueTag };
     224
     225        uint32_t tag() const;
     226        int32_t payload() const;
     227
     228        JSObject* synthesizePrototype(ExecState*) const;
     229        JSObject* synthesizeObject(ExecState*) const;
     230
     231#if USE(JSVALUE32_64)
     232        union {
     233            EncodedJSValue asEncodedJSValue;
     234            double asDouble;
     235#if PLATFORM(BIG_ENDIAN)
     236            struct {
     237                int32_t tag;
     238                int32_t payload;
     239            } asBits;
     240#else
     241            struct {
     242                int32_t payload;
     243                int32_t tag;
     244            } asBits;
     245#endif
     246        } u;
     247#else // USE(JSVALUE32_64)
    220248        JSCell* m_ptr;
     249#endif // USE(JSVALUE32_64)
    221250    };
    222251
    223     struct JSValueHashTraits : HashTraits<EncodedJSValue> {
     252#if USE(JSVALUE32_64)
     253    typedef IntHash<EncodedJSValue> EncodedJSValueHash;
     254
     255    struct EncodedJSValueHashTraits : HashTraits<EncodedJSValue> {
     256        static const bool emptyValueIsZero = false;
     257        static EncodedJSValue emptyValue() { return JSValue::encode(JSValue()); }
    224258        static void constructDeletedValue(EncodedJSValue& slot) { slot = JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); }
    225259        static bool isDeletedValue(EncodedJSValue value) { return value == JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); }
    226260    };
     261#else
     262    typedef PtrHash<EncodedJSValue> EncodedJSValueHash;
     263
     264    struct EncodedJSValueHashTraits : HashTraits<EncodedJSValue> {
     265        static void constructDeletedValue(EncodedJSValue& slot) { slot = JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); }
     266        static bool isDeletedValue(EncodedJSValue value) { return value == JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); }
     267    };
     268#endif
    227269
    228270    // Stand-alone helper functions.
     
    302344    }
    303345
    304     ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, char i)
     346    ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, int i)
    305347    {
    306348        return JSValue(globalData, i);
    307349    }
    308350
    309     ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, unsigned char i)
    310     {
    311         return JSValue(globalData, i);
    312     }
    313 
    314     ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, short i)
    315     {
    316         return JSValue(globalData, i);
    317     }
    318 
    319     ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, unsigned short i)
    320     {
    321         return JSValue(globalData, i);
    322     }
    323 
    324     ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, int i)
    325     {
    326         return JSValue(globalData, i);
    327     }
    328 
    329351    ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, unsigned i)
    330     {
    331         return JSValue(globalData, i);
    332     }
    333 
    334     ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, long i)
    335     {
    336         return JSValue(globalData, i);
    337     }
    338 
    339     ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, unsigned long i)
    340     {
    341         return JSValue(globalData, i);
    342     }
    343 
    344     ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, long long i)
    345     {
    346         return JSValue(globalData, i);
    347     }
    348 
    349     ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, unsigned long long i)
    350352    {
    351353        return JSValue(globalData, i);
     
    358360    inline bool operator!=(const JSCell* a, const JSValue b) { return JSValue(a) != b; }
    359361
     362    inline int32_t toInt32(double val)
     363    {
     364        if (!(val >= -2147483648.0 && val < 2147483648.0)) {
     365            bool ignored;
     366            return toInt32SlowCase(val, ignored);
     367        }
     368        return static_cast<int32_t>(val);
     369    }
     370
     371    inline uint32_t toUInt32(double val)
     372    {
     373        if (!(val >= 0.0 && val < 4294967296.0)) {
     374            bool ignored;
     375            return toUInt32SlowCase(val, ignored);
     376        }
     377        return static_cast<uint32_t>(val);
     378    }
     379
     380    ALWAYS_INLINE int32_t JSValue::toInt32(ExecState* exec) const
     381    {
     382        if (isInt32())
     383            return asInt32();
     384        bool ignored;
     385        return toInt32SlowCase(toNumber(exec), ignored);
     386    }
     387
     388    inline uint32_t JSValue::toUInt32(ExecState* exec) const
     389    {
     390        if (isUInt32())
     391            return asInt32();
     392        bool ignored;
     393        return toUInt32SlowCase(toNumber(exec), ignored);
     394    }
     395
     396    inline int32_t JSValue::toInt32(ExecState* exec, bool& ok) const
     397    {
     398        if (isInt32()) {
     399            ok = true;
     400            return asInt32();
     401        }
     402        return toInt32SlowCase(toNumber(exec), ok);
     403    }
     404
     405    inline uint32_t JSValue::toUInt32(ExecState* exec, bool& ok) const
     406    {
     407        if (isUInt32()) {
     408            ok = true;
     409            return asInt32();
     410        }
     411        return toUInt32SlowCase(toNumber(exec), ok);
     412    }
     413
     414#if USE(JSVALUE32_64)
     415    inline JSValue jsNaN(ExecState* exec)
     416    {
     417        return JSValue(exec, nonInlineNaN());
     418    }
     419
    360420    // JSValue member functions.
    361421    inline EncodedJSValue JSValue::encode(JSValue value)
    362422    {
     423        return value.u.asEncodedJSValue;
     424    }
     425
     426    inline JSValue JSValue::decode(EncodedJSValue encodedJSValue)
     427    {
     428        JSValue v;
     429        v.u.asEncodedJSValue = encodedJSValue;
     430        return v;
     431    }
     432
     433    inline JSValue::JSValue()
     434    {
     435        u.asBits.tag = CellTag;
     436        u.asBits.payload = 0;
     437    }
     438
     439    inline JSValue::JSValue(JSNullTag)
     440    {
     441        u.asBits.tag = NullTag;
     442        u.asBits.payload = 0;
     443    }
     444   
     445    inline JSValue::JSValue(JSUndefinedTag)
     446    {
     447        u.asBits.tag = UndefinedTag;
     448        u.asBits.payload = 0;
     449    }
     450   
     451    inline JSValue::JSValue(JSTrueTag)
     452    {
     453        u.asBits.tag = TrueTag;
     454        u.asBits.payload = 0;
     455    }
     456   
     457    inline JSValue::JSValue(JSFalseTag)
     458    {
     459        u.asBits.tag = FalseTag;
     460        u.asBits.payload = 0;
     461    }
     462
     463    inline JSValue::JSValue(HashTableDeletedValueTag)
     464    {
     465        u.asBits.tag = DeletedValueTag;
     466        u.asBits.payload = 0;
     467    }
     468
     469    inline JSValue::JSValue(JSCell* ptr)
     470    {
     471        u.asBits.tag = CellTag;
     472        u.asBits.payload = reinterpret_cast<int32_t>(ptr);
     473    }
     474
     475    inline JSValue::JSValue(const JSCell* ptr)
     476    {
     477        u.asBits.tag = CellTag;
     478        u.asBits.payload = reinterpret_cast<int32_t>(const_cast<JSCell*>(ptr));
     479    }
     480
     481    inline JSValue::operator bool() const
     482    {
     483        return u.asBits.payload || tag() != CellTag;
     484    }
     485
     486    inline bool JSValue::operator==(const JSValue& other) const
     487    {
     488        return u.asEncodedJSValue == other.u.asEncodedJSValue;
     489    }
     490
     491    inline bool JSValue::operator!=(const JSValue& other) const
     492    {
     493        return u.asEncodedJSValue != other.u.asEncodedJSValue;
     494    }
     495
     496    inline bool JSValue::isUndefined() const
     497    {
     498        return tag() == UndefinedTag;
     499    }
     500
     501    inline bool JSValue::isNull() const
     502    {
     503        return tag() == NullTag;
     504    }
     505
     506    inline bool JSValue::isUndefinedOrNull() const
     507    {
     508        return isUndefined() || isNull();
     509    }
     510
     511    inline bool JSValue::isCell() const
     512    {
     513        return tag() == CellTag;
     514    }
     515
     516    inline bool JSValue::isInt32() const
     517    {
     518        return tag() == Int32Tag;
     519    }
     520
     521    inline bool JSValue::isUInt32() const
     522    {
     523        return tag() == Int32Tag && asInt32() > -1;
     524    }
     525
     526    inline bool JSValue::isDouble() const
     527    {
     528        return tag() < LowestTag;
     529    }
     530
     531    inline bool JSValue::isTrue() const
     532    {
     533        return tag() == TrueTag;
     534    }
     535
     536    inline bool JSValue::isFalse() const
     537    {
     538        return tag() == FalseTag;
     539    }
     540
     541    inline uint32_t JSValue::tag() const
     542    {
     543        return u.asBits.tag;
     544    }
     545   
     546    inline int32_t JSValue::payload() const
     547    {
     548        return u.asBits.payload;
     549    }
     550   
     551    inline int32_t JSValue::asInt32() const
     552    {
     553        ASSERT(isInt32());
     554        return u.asBits.payload;
     555    }
     556   
     557    inline uint32_t JSValue::asUInt32() const
     558    {
     559        ASSERT(isUInt32());
     560        return u.asBits.payload;
     561    }
     562   
     563    inline double JSValue::asDouble() const
     564    {
     565        ASSERT(isDouble());
     566        return u.asDouble;
     567    }
     568   
     569    ALWAYS_INLINE JSCell* JSValue::asCell() const
     570    {
     571        ASSERT(isCell());
     572        return reinterpret_cast<JSCell*>(u.asBits.payload);
     573    }
     574
     575    inline JSValue::JSValue(ExecState* exec, double d)
     576    {
     577        const int32_t asInt32 = static_cast<int32_t>(d);
     578        if (asInt32 != d || (!asInt32 && signbit(d))) { // true for -0.0
     579            u.asDouble = d;
     580            return;
     581        }
     582        *this = JSValue(exec, static_cast<int32_t>(d));
     583    }
     584
     585    inline JSValue::JSValue(ExecState* exec, char i)
     586    {
     587        *this = JSValue(exec, static_cast<int32_t>(i));
     588    }
     589
     590    inline JSValue::JSValue(ExecState* exec, unsigned char i)
     591    {
     592        *this = JSValue(exec, static_cast<int32_t>(i));
     593    }
     594
     595    inline JSValue::JSValue(ExecState* exec, short i)
     596    {
     597        *this = JSValue(exec, static_cast<int32_t>(i));
     598    }
     599
     600    inline JSValue::JSValue(ExecState* exec, unsigned short i)
     601    {
     602        *this = JSValue(exec, static_cast<int32_t>(i));
     603    }
     604
     605    inline JSValue::JSValue(ExecState*, int i)
     606    {
     607        u.asBits.tag = Int32Tag;
     608        u.asBits.payload = i;
     609    }
     610
     611    inline JSValue::JSValue(ExecState* exec, unsigned i)
     612    {
     613        if (static_cast<int32_t>(i) < 0) {
     614            *this = JSValue(exec, static_cast<double>(i));
     615            return;
     616        }
     617        *this = JSValue(exec, static_cast<int32_t>(i));
     618    }
     619
     620    inline JSValue::JSValue(ExecState* exec, long i)
     621    {
     622        if (static_cast<int32_t>(i) != i) {
     623            *this = JSValue(exec, static_cast<double>(i));
     624            return;
     625        }
     626        *this = JSValue(exec, static_cast<int32_t>(i));
     627    }
     628
     629    inline JSValue::JSValue(ExecState* exec, unsigned long i)
     630    {
     631        if (static_cast<uint32_t>(i) != i) {
     632            *this = JSValue(exec, static_cast<double>(i));
     633            return;
     634        }
     635        *this = JSValue(exec, static_cast<uint32_t>(i));
     636    }
     637
     638    inline JSValue::JSValue(ExecState* exec, long long i)
     639    {
     640        if (static_cast<int32_t>(i) != i) {
     641            *this = JSValue(exec, static_cast<double>(i));
     642            return;
     643        }
     644        *this = JSValue(exec, static_cast<int32_t>(i));
     645    }
     646
     647    inline JSValue::JSValue(ExecState* exec, unsigned long long i)
     648    {
     649        if (static_cast<uint32_t>(i) != i) {
     650            *this = JSValue(exec, static_cast<double>(i));
     651            return;
     652        }
     653        *this = JSValue(exec, static_cast<uint32_t>(i));
     654    }
     655
     656    inline JSValue::JSValue(JSGlobalData* globalData, double d)
     657    {
     658        const int32_t asInt32 = static_cast<int32_t>(d);
     659        if (asInt32 != d || (!asInt32 && signbit(d))) { // true for -0.0
     660            u.asDouble = d;
     661            return;
     662        }
     663        *this = JSValue(globalData, static_cast<int32_t>(d));
     664    }
     665   
     666    inline JSValue::JSValue(JSGlobalData*, int i)
     667    {
     668        u.asBits.tag = Int32Tag;
     669        u.asBits.payload = i;
     670    }
     671   
     672    inline JSValue::JSValue(JSGlobalData* globalData, unsigned i)
     673    {
     674        if (static_cast<int32_t>(i) < 0) {
     675            *this = JSValue(globalData, static_cast<double>(i));
     676            return;
     677        }
     678        *this = JSValue(globalData, static_cast<int32_t>(i));
     679    }
     680
     681    inline bool JSValue::isNumber() const
     682    {
     683        return isInt32() || isDouble();
     684    }
     685
     686    inline bool JSValue::isBoolean() const
     687    {
     688        return isTrue() || isFalse();
     689    }
     690
     691    inline bool JSValue::getBoolean(bool& v) const
     692    {
     693        if (isTrue()) {
     694            v = true;
     695            return true;
     696        }
     697        if (isFalse()) {
     698            v = false;
     699            return true;
     700        }
     701       
     702        return false;
     703    }
     704
     705    inline bool JSValue::getBoolean() const
     706    {
     707        ASSERT(isBoolean());
     708        return tag() == TrueTag;
     709    }
     710
     711    inline double JSValue::uncheckedGetNumber() const
     712    {
     713        ASSERT(isNumber());
     714        return isInt32() ? asInt32() : asDouble();
     715    }
     716
     717    ALWAYS_INLINE JSValue JSValue::toJSNumber(ExecState* exec) const
     718    {
     719        return isNumber() ? asValue() : jsNumber(exec, this->toNumber(exec));
     720    }
     721
     722    inline bool JSValue::getNumber(double& result) const
     723    {
     724        if (isInt32()) {
     725            result = asInt32();
     726            return true;
     727        }
     728        if (isDouble()) {
     729            result = asDouble();
     730            return true;
     731        }
     732        return false;
     733    }
     734
     735#else // USE(JSVALUE32_64)
     736
     737    // JSValue member functions.
     738    inline EncodedJSValue JSValue::encode(JSValue value)
     739    {
    363740        return reinterpret_cast<EncodedJSValue>(value.m_ptr);
    364741    }
     
    369746    }
    370747
     748    inline JSValue JSValue::makeImmediate(intptr_t value)
     749    {
     750        return JSValue(reinterpret_cast<JSCell*>(value));
     751    }
     752
     753    inline intptr_t JSValue::immediateValue()
     754    {
     755        return reinterpret_cast<intptr_t>(m_ptr);
     756    }
     757   
    371758    // 0x0 can never occur naturally because it has a tag of 00, indicating a pointer value, but a payload of 0x0, which is in the (invalid) zero page.
    372759    inline JSValue::JSValue()
     
    396783    }
    397784
    398     inline bool JSValue::operator==(const JSValue other) const
     785    inline bool JSValue::operator==(const JSValue& other) const
    399786    {
    400787        return m_ptr == other.m_ptr;
    401788    }
    402789
    403     inline bool JSValue::operator!=(const JSValue other) const
     790    inline bool JSValue::operator!=(const JSValue& other) const
    404791    {
    405792        return m_ptr != other.m_ptr;
     
    415802        return asValue() == jsNull();
    416803    }
     804#endif // USE(JSVALUE32_64)
    417805
    418806} // namespace JSC
  • trunk/JavaScriptCore/runtime/Operations.h

    r44224 r46598  
    3939    inline bool JSValue::equal(ExecState* exec, JSValue v1, JSValue v2)
    4040    {
    41         if (JSImmediate::areBothImmediateIntegerNumbers(v1, v2))
     41        if (v1.isInt32() && v2.isInt32())
    4242            return v1 == v2;
    4343
     
    4747    ALWAYS_INLINE bool JSValue::equalSlowCaseInline(ExecState* exec, JSValue v1, JSValue v2)
    4848    {
    49         ASSERT(!JSImmediate::areBothImmediateIntegerNumbers(v1, v2));
    50 
    5149        do {
    5250            if (v1.isNumber() && v2.isNumber())
     
    6159                if (v2.isUndefinedOrNull())
    6260                    return true;
    63                 if (JSImmediate::isImmediate(v2))
     61                if (!v2.isCell())
    6462                    return false;
    6563                return v2.asCell()->structure()->typeInfo().masqueradesAsUndefined();
     
    6765
    6866            if (v2.isUndefinedOrNull()) {
    69                 if (JSImmediate::isImmediate(v1))
     67                if (!v1.isCell())
    7068                    return false;
    7169                return v1.asCell()->structure()->typeInfo().masqueradesAsUndefined();
     
    7977                    return false;
    8078                v1 = p1;
    81                 if (JSImmediate::areBothImmediateIntegerNumbers(v1, v2))
     79                if (v1.isInt32() && v2.isInt32())
    8280                    return v1 == v2;
    8381                continue;
     
    8987                    return false;
    9088                v2 = p2;
    91                 if (JSImmediate::areBothImmediateIntegerNumbers(v1, v2))
     89                if (v1.isInt32() && v2.isInt32())
    9290                    return v1 == v2;
    9391                continue;
     
    115113    ALWAYS_INLINE bool JSValue::strictEqualSlowCaseInline(JSValue v1, JSValue v2)
    116114    {
    117         ASSERT(!JSImmediate::isEitherImmediate(v1, v2));
     115        ASSERT(v1.isCell() && v2.isCell());
    118116
    119117        if (v1.asCell()->isString() && v2.asCell()->isString())
     
    125123    inline bool JSValue::strictEqual(JSValue v1, JSValue v2)
    126124    {
    127         if (JSImmediate::areBothImmediateIntegerNumbers(v1, v2))
     125        if (v1.isInt32() && v2.isInt32())
    128126            return v1 == v2;
    129127
     
    131129            return v1.uncheckedGetNumber() == v2.uncheckedGetNumber();
    132130
    133         if (JSImmediate::isEitherImmediate(v1, v2))
     131        if (!v1.isCell() || !v2.isCell())
    134132            return v1 == v2;
    135133
     
    139137    inline bool jsLess(CallFrame* callFrame, JSValue v1, JSValue v2)
    140138    {
    141         if (JSValue::areBothInt32Fast(v1, v2))
    142             return v1.getInt32Fast() < v2.getInt32Fast();
     139        if (v1.isInt32() && v2.isInt32())
     140            return v1.asInt32() < v2.asInt32();
    143141
    144142        double n1;
     
    164162    inline bool jsLessEq(CallFrame* callFrame, JSValue v1, JSValue v2)
    165163    {
    166         if (JSValue::areBothInt32Fast(v1, v2))
    167             return v1.getInt32Fast() <= v2.getInt32Fast();
     164        if (v1.isInt32() && v2.isInt32())
     165            return v1.asInt32() <= v2.asInt32();
    168166
    169167        double n1;
     
    214212
    215213        if (rightIsNumber & leftIsString) {
    216             RefPtr<UString::Rep> value = v2.isInt32Fast() ?
    217                 concatenate(asString(v1)->value().rep(), v2.getInt32Fast()) :
     214            RefPtr<UString::Rep> value = v2.isInt32() ?
     215                concatenate(asString(v1)->value().rep(), v2.asInt32()) :
    218216                concatenate(asString(v1)->value().rep(), right);
    219217
     
    316314            if (LIKELY(v.isString()))
    317315                result.append(asString(v)->value());
    318             else if (v.isInt32Fast())
    319                 result.appendNumeric(v.getInt32Fast());
     316            else if (v.isInt32())
     317                result.appendNumeric(v.asInt32());
    320318            else {
    321319                double d;
  • trunk/JavaScriptCore/runtime/PropertySlot.h

    r44757 r46598  
    2424#include "Identifier.h"
    2525#include "JSValue.h"
    26 #include "JSImmediate.h"
    2726#include "Register.h"
    2827#include <wtf/Assertions.h>
     
    4039    public:
    4140        PropertySlot()
    42             : m_offset(WTF::notFound)
    43         {
    44             clearBase();
     41        {
     42            clearBase();
     43            clearOffset();
    4544            clearValue();
    4645        }
     
    4847        explicit PropertySlot(const JSValue base)
    4948            : m_slotBase(base)
    50             , m_offset(WTF::notFound)
    51         {
     49        {
     50            clearOffset();
    5251            clearValue();
    5352        }
     
    8382        {
    8483            ASSERT(valueSlot);
    85             m_getValue = JSC_VALUE_SLOT_MARKER;
    86             clearBase();
     84            clearBase();
     85            clearOffset();
     86            m_getValue = JSC_VALUE_SLOT_MARKER;
    8787            m_data.valueSlot = valueSlot;
    8888        }
     
    108108        {
    109109            ASSERT(value);
    110             m_getValue = JSC_VALUE_SLOT_MARKER;
    111             clearBase();
     110            clearBase();
     111            clearOffset();
     112            m_getValue = JSC_VALUE_SLOT_MARKER;
    112113            m_value = value;
    113114            m_data.valueSlot = &m_value;
     
    117118        {
    118119            ASSERT(registerSlot);
     120            clearBase();
     121            clearOffset();
    119122            m_getValue = JSC_REGISTER_SLOT_MARKER;
    120             clearBase();
    121123            m_data.registerSlot = registerSlot;
    122124        }
     
    148150        void setUndefined()
    149151        {
    150             clearBase();
    151152            setValue(jsUndefined());
    152153        }
     
    154155        JSValue slotBase() const
    155156        {
    156             ASSERT(m_slotBase);
    157157            return m_slotBase;
    158158        }
     
    177177            m_value = JSValue();
    178178#endif
     179        }
     180
     181        void clearOffset()
     182        {
     183            // Clear offset even in release builds, in case this PropertySlot has been used before.
     184            // (For other data members, we don't need to clear anything because reuse would meaningfully overwrite them.)
     185            m_offset = WTF::notFound;
    179186        }
    180187
  • trunk/JavaScriptCore/runtime/StringPrototype.cpp

    r46180 r46598  
    377377    unsigned len = s.size();
    378378    JSValue a0 = args.at(0);
    379     if (a0.isUInt32Fast()) {
    380         uint32_t i = a0.getUInt32Fast();
     379    if (a0.isUInt32()) {
     380        uint32_t i = a0.asUInt32();
    381381        if (i < len)
    382382            return jsSingleCharacterSubstring(exec, s, i);
     
    394394    unsigned len = s.size();
    395395    JSValue a0 = args.at(0);
    396     if (a0.isUInt32Fast()) {
    397         uint32_t i = a0.getUInt32Fast();
     396    if (a0.isUInt32()) {
     397        uint32_t i = a0.asUInt32();
    398398        if (i < len)
    399399            return jsNumber(exec, s.data()[i]);
     
    427427    if (a1.isUndefined())
    428428        pos = 0;
    429     else if (a1.isUInt32Fast())
    430         pos = min<uint32_t>(a1.getUInt32Fast(), len);
     429    else if (a1.isUInt32())
     430        pos = min<uint32_t>(a1.asUInt32(), len);
    431431    else {
    432432        double dpos = a1.toInteger(exec);
Note: See TracChangeset for help on using the changeset viewer.