JavaScriptCore/runtime/JSValue.h
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 /*
       
     2  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
       
     3  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
       
     4  *  Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009 Apple Inc. All rights reserved.
       
     5  *
       
     6  *  This library is free software; you can redistribute it and/or
       
     7  *  modify it under the terms of the GNU Library General Public
       
     8  *  License as published by the Free Software Foundation; either
       
     9  *  version 2 of the License, or (at your option) any later version.
       
    10  *
       
    11  *  This library is distributed in the hope that it will be useful,
       
    12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    14  *  Library General Public License for more details.
       
    15  *
       
    16  *  You should have received a copy of the GNU Library General Public License
       
    17  *  along with this library; see the file COPYING.LIB.  If not, write to
       
    18  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
       
    19  *  Boston, MA 02110-1301, USA.
       
    20  *
       
    21  */
       
    22 
       
    23 #ifndef JSValue_h
       
    24 #define JSValue_h
       
    25 
       
    26 #include <math.h>
       
    27 #include <stddef.h> // for size_t
       
    28 #include <stdint.h>
       
    29 #include <wtf/AlwaysInline.h>
       
    30 #include <wtf/Assertions.h>
       
    31 #include <wtf/HashTraits.h>
       
    32 #include <wtf/MathExtras.h>
       
    33 
       
    34 namespace JSC {
       
    35 
       
    36     class ExecState;
       
    37     class Identifier;
       
    38     class JSCell;
       
    39     class JSGlobalData;
       
    40     class JSImmediate;
       
    41     class JSObject;
       
    42     class JSString;
       
    43     class PropertySlot;
       
    44     class PutPropertySlot;
       
    45     class UString;
       
    46 
       
    47     struct ClassInfo;
       
    48     struct Instruction;
       
    49 
       
    50     enum PreferredPrimitiveType { NoPreference, PreferNumber, PreferString };
       
    51 
       
    52 #if USE(JSVALUE32_64)
       
    53     typedef int64_t EncodedJSValue;
       
    54 #else
       
    55     typedef void* EncodedJSValue;
       
    56 #endif
       
    57 
       
    58     double nonInlineNaN();
       
    59     int32_t toInt32SlowCase(double, bool& ok);
       
    60     uint32_t toUInt32SlowCase(double, bool& ok);
       
    61 
       
    62     class JSValue {
       
    63         friend class JSImmediate;
       
    64         friend struct EncodedJSValueHashTraits;
       
    65         friend class JIT;
       
    66         friend class JITStubs;
       
    67         friend class JITStubCall;
       
    68         friend class JSInterfaceJIT;
       
    69         friend class SpecializedThunkJIT;
       
    70 
       
    71     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
       
    80         enum JSNullTag { JSNull };
       
    81         enum JSUndefinedTag { JSUndefined };
       
    82         enum JSTrueTag { JSTrue };
       
    83         enum JSFalseTag { JSFalse };
       
    84         enum EncodeAsDoubleTag { EncodeAsDouble };
       
    85 
       
    86         JSValue();
       
    87         JSValue(JSNullTag);
       
    88         JSValue(JSUndefinedTag);
       
    89         JSValue(JSTrueTag);
       
    90         JSValue(JSFalseTag);
       
    91         JSValue(JSCell* ptr);
       
    92         JSValue(const JSCell* ptr);
       
    93 
       
    94         // Numbers
       
    95         JSValue(EncodeAsDoubleTag, ExecState*, double);
       
    96         JSValue(ExecState*, double);
       
    97         JSValue(ExecState*, char);
       
    98         JSValue(ExecState*, unsigned char);
       
    99         JSValue(ExecState*, short);
       
   100         JSValue(ExecState*, unsigned short);
       
   101         JSValue(ExecState*, int);
       
   102         JSValue(ExecState*, unsigned);
       
   103         JSValue(ExecState*, long);
       
   104         JSValue(ExecState*, unsigned long);
       
   105         JSValue(ExecState*, long long);
       
   106         JSValue(ExecState*, unsigned long long);
       
   107         JSValue(JSGlobalData*, double);
       
   108         JSValue(JSGlobalData*, int);
       
   109         JSValue(JSGlobalData*, unsigned);
       
   110 
       
   111         operator bool() const;
       
   112         bool operator==(const JSValue& other) const;
       
   113         bool operator!=(const JSValue& other) const;
       
   114 
       
   115         bool isInt32() const;
       
   116         bool isUInt32() const;
       
   117         bool isDouble() const;
       
   118         bool isTrue() const;
       
   119         bool isFalse() const;
       
   120 
       
   121         int32_t asInt32() const;
       
   122         uint32_t asUInt32() const;
       
   123         double asDouble() const;
       
   124 
       
   125         // Querying the type.
       
   126         bool isUndefined() const;
       
   127         bool isNull() const;
       
   128         bool isUndefinedOrNull() const;
       
   129         bool isBoolean() const;
       
   130         bool isNumber() const;
       
   131         bool isString() const;
       
   132         bool isGetterSetter() const;
       
   133         bool isObject() const;
       
   134         bool inherits(const ClassInfo*) const;
       
   135         
       
   136         // Extracting the value.
       
   137         bool getBoolean(bool&) const;
       
   138         bool getBoolean() const; // false if not a boolean
       
   139         bool getNumber(double&) const;
       
   140         double uncheckedGetNumber() const;
       
   141         bool getString(ExecState* exec, UString&) const;
       
   142         UString getString(ExecState* exec) const; // null string if not a string
       
   143         JSObject* getObject() const; // 0 if not an object
       
   144 
       
   145         // Extracting integer values.
       
   146         bool getUInt32(uint32_t&) const;
       
   147         
       
   148         // Basic conversions.
       
   149         JSValue toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const;
       
   150         bool getPrimitiveNumber(ExecState*, double& number, JSValue&);
       
   151 
       
   152         bool toBoolean(ExecState*) const;
       
   153 
       
   154         // toNumber conversion is expected to be side effect free if an exception has
       
   155         // been set in the ExecState already.
       
   156         double toNumber(ExecState*) const;
       
   157         JSValue toJSNumber(ExecState*) const; // Fast path for when you expect that the value is an immediate number.
       
   158         UString toString(ExecState*) const;
       
   159         UString toPrimitiveString(ExecState*) const;
       
   160         JSObject* toObject(ExecState*) const;
       
   161 
       
   162         // Integer conversions.
       
   163         double toInteger(ExecState*) const;
       
   164         double toIntegerPreserveNaN(ExecState*) const;
       
   165         int32_t toInt32(ExecState*) const;
       
   166         int32_t toInt32(ExecState*, bool& ok) const;
       
   167         uint32_t toUInt32(ExecState*) const;
       
   168         uint32_t toUInt32(ExecState*, bool& ok) const;
       
   169 
       
   170 #if ENABLE(JSC_ZOMBIES)
       
   171         bool isZombie() const;
       
   172 #endif
       
   173 
       
   174         // Floating point conversions (this is a convenience method for webcore;
       
   175         // signle precision float is not a representation used in JS or JSC).
       
   176         float toFloat(ExecState* exec) const { return static_cast<float>(toNumber(exec)); }
       
   177 
       
   178         // Object operations, with the toObject operation included.
       
   179         JSValue get(ExecState*, const Identifier& propertyName) const;
       
   180         JSValue get(ExecState*, const Identifier& propertyName, PropertySlot&) const;
       
   181         JSValue get(ExecState*, unsigned propertyName) const;
       
   182         JSValue get(ExecState*, unsigned propertyName, PropertySlot&) const;
       
   183         void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
       
   184         void putDirect(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
       
   185         void put(ExecState*, unsigned propertyName, JSValue);
       
   186 
       
   187         bool needsThisConversion() const;
       
   188         JSObject* toThisObject(ExecState*) const;
       
   189         UString toThisString(ExecState*) const;
       
   190         JSString* toThisJSString(ExecState*) const;
       
   191 
       
   192         static bool equal(ExecState* exec, JSValue v1, JSValue v2);
       
   193         static bool equalSlowCase(ExecState* exec, JSValue v1, JSValue v2);
       
   194         static bool equalSlowCaseInline(ExecState* exec, JSValue v1, JSValue v2);
       
   195         static bool strictEqual(ExecState* exec, JSValue v1, JSValue v2);
       
   196         static bool strictEqualSlowCase(ExecState* exec, JSValue v1, JSValue v2);
       
   197         static bool strictEqualSlowCaseInline(ExecState* exec, JSValue v1, JSValue v2);
       
   198 
       
   199         JSValue getJSNumber(); // JSValue() if this is not a JSNumber or number object
       
   200 
       
   201         bool isCell() const;
       
   202         JSCell* asCell() const;
       
   203         bool isValidCallee();
       
   204 
       
   205 #ifndef NDEBUG
       
   206         char* description();
       
   207 #endif
       
   208 
       
   209     private:
       
   210         enum HashTableDeletedValueTag { HashTableDeletedValue };
       
   211         JSValue(HashTableDeletedValueTag);
       
   212 
       
   213         inline const JSValue asValue() const { return *this; }
       
   214         JSObject* toObjectSlowCase(ExecState*) const;
       
   215         JSObject* toThisObjectSlowCase(ExecState*) const;
       
   216 
       
   217         JSObject* synthesizePrototype(ExecState*) const;
       
   218         JSObject* synthesizeObject(ExecState*) const;
       
   219 
       
   220 #if USE(JSVALUE32_64)
       
   221         enum { Int32Tag =        0xffffffff };
       
   222         enum { CellTag =         0xfffffffe };
       
   223         enum { TrueTag =         0xfffffffd };
       
   224         enum { FalseTag =        0xfffffffc };
       
   225         enum { NullTag =         0xfffffffb };
       
   226         enum { UndefinedTag =    0xfffffffa };
       
   227         enum { EmptyValueTag =   0xfffffff9 };
       
   228         enum { DeletedValueTag = 0xfffffff8 };
       
   229         
       
   230         enum { LowestTag =  DeletedValueTag };
       
   231         
       
   232         uint32_t tag() const;
       
   233         int32_t payload() const;
       
   234 
       
   235         union {
       
   236             EncodedJSValue asEncodedJSValue;
       
   237             double asDouble;
       
   238 #if CPU(BIG_ENDIAN)
       
   239             struct {
       
   240                 int32_t tag;
       
   241                 int32_t payload;
       
   242             } asBits;
       
   243 #else
       
   244             struct {
       
   245                 int32_t payload;
       
   246                 int32_t tag;
       
   247             } asBits;
       
   248 #endif
       
   249         } u;
       
   250 #else // USE(JSVALUE32_64)
       
   251         JSCell* m_ptr;
       
   252 #endif // USE(JSVALUE32_64)
       
   253     };
       
   254 
       
   255 #if USE(JSVALUE32_64)
       
   256     typedef IntHash<EncodedJSValue> EncodedJSValueHash;
       
   257 
       
   258     struct EncodedJSValueHashTraits : HashTraits<EncodedJSValue> {
       
   259         static const bool emptyValueIsZero = false;
       
   260         static EncodedJSValue emptyValue() { return JSValue::encode(JSValue()); }
       
   261         static void constructDeletedValue(EncodedJSValue& slot) { slot = JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); }
       
   262         static bool isDeletedValue(EncodedJSValue value) { return value == JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); }
       
   263     };
       
   264 #else
       
   265     typedef PtrHash<EncodedJSValue> EncodedJSValueHash;
       
   266 
       
   267     struct EncodedJSValueHashTraits : HashTraits<EncodedJSValue> {
       
   268         static void constructDeletedValue(EncodedJSValue& slot) { slot = JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); }
       
   269         static bool isDeletedValue(EncodedJSValue value) { return value == JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); }
       
   270     };
       
   271 #endif
       
   272 
       
   273     // Stand-alone helper functions.
       
   274     inline JSValue jsNull()
       
   275     {
       
   276         return JSValue(JSValue::JSNull);
       
   277     }
       
   278 
       
   279     inline JSValue jsUndefined()
       
   280     {
       
   281         return JSValue(JSValue::JSUndefined);
       
   282     }
       
   283 
       
   284     inline JSValue jsBoolean(bool b)
       
   285     {
       
   286         return b ? JSValue(JSValue::JSTrue) : JSValue(JSValue::JSFalse);
       
   287     }
       
   288 
       
   289     ALWAYS_INLINE JSValue jsDoubleNumber(ExecState* exec, double d)
       
   290     {
       
   291         return JSValue(JSValue::EncodeAsDouble, exec, d);
       
   292     }
       
   293 
       
   294     ALWAYS_INLINE JSValue jsNumber(ExecState* exec, double d)
       
   295     {
       
   296         return JSValue(exec, d);
       
   297     }
       
   298 
       
   299     ALWAYS_INLINE JSValue jsNumber(ExecState* exec, char i)
       
   300     {
       
   301         return JSValue(exec, i);
       
   302     }
       
   303 
       
   304     ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned char i)
       
   305     {
       
   306         return JSValue(exec, i);
       
   307     }
       
   308 
       
   309     ALWAYS_INLINE JSValue jsNumber(ExecState* exec, short i)
       
   310     {
       
   311         return JSValue(exec, i);
       
   312     }
       
   313 
       
   314     ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned short i)
       
   315     {
       
   316         return JSValue(exec, i);
       
   317     }
       
   318 
       
   319     ALWAYS_INLINE JSValue jsNumber(ExecState* exec, int i)
       
   320     {
       
   321         return JSValue(exec, i);
       
   322     }
       
   323 
       
   324     ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned i)
       
   325     {
       
   326         return JSValue(exec, i);
       
   327     }
       
   328 
       
   329     ALWAYS_INLINE JSValue jsNumber(ExecState* exec, long i)
       
   330     {
       
   331         return JSValue(exec, i);
       
   332     }
       
   333 
       
   334     ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned long i)
       
   335     {
       
   336         return JSValue(exec, i);
       
   337     }
       
   338 
       
   339     ALWAYS_INLINE JSValue jsNumber(ExecState* exec, long long i)
       
   340     {
       
   341         return JSValue(exec, i);
       
   342     }
       
   343 
       
   344     ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned long long i)
       
   345     {
       
   346         return JSValue(exec, i);
       
   347     }
       
   348 
       
   349     ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, double d)
       
   350     {
       
   351         return JSValue(globalData, d);
       
   352     }
       
   353 
       
   354     ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, int i)
       
   355     {
       
   356         return JSValue(globalData, i);
       
   357     }
       
   358 
       
   359     ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, unsigned i)
       
   360     {
       
   361         return JSValue(globalData, i);
       
   362     }
       
   363 
       
   364     inline bool operator==(const JSValue a, const JSCell* b) { return a == JSValue(b); }
       
   365     inline bool operator==(const JSCell* a, const JSValue b) { return JSValue(a) == b; }
       
   366 
       
   367     inline bool operator!=(const JSValue a, const JSCell* b) { return a != JSValue(b); }
       
   368     inline bool operator!=(const JSCell* a, const JSValue b) { return JSValue(a) != b; }
       
   369 
       
   370     inline int32_t toInt32(double val)
       
   371     {
       
   372         if (!(val >= -2147483648.0 && val < 2147483648.0)) {
       
   373             bool ignored;
       
   374             return toInt32SlowCase(val, ignored);
       
   375         }
       
   376         return static_cast<int32_t>(val);
       
   377     }
       
   378 
       
   379     inline uint32_t toUInt32(double val)
       
   380     {
       
   381         if (!(val >= 0.0 && val < 4294967296.0)) {
       
   382             bool ignored;
       
   383             return toUInt32SlowCase(val, ignored);
       
   384         }
       
   385         return static_cast<uint32_t>(val);
       
   386     }
       
   387 
       
   388     // FIXME: We should deprecate this and just use JSValue::asCell() instead.
       
   389     JSCell* asCell(JSValue);
       
   390 
       
   391     inline JSCell* asCell(JSValue value)
       
   392     {
       
   393         return value.asCell();
       
   394     }
       
   395 
       
   396     ALWAYS_INLINE int32_t JSValue::toInt32(ExecState* exec) const
       
   397     {
       
   398         if (isInt32())
       
   399             return asInt32();
       
   400         bool ignored;
       
   401         return toInt32SlowCase(toNumber(exec), ignored);
       
   402     }
       
   403 
       
   404     inline uint32_t JSValue::toUInt32(ExecState* exec) const
       
   405     {
       
   406         if (isUInt32())
       
   407             return asInt32();
       
   408         bool ignored;
       
   409         return toUInt32SlowCase(toNumber(exec), ignored);
       
   410     }
       
   411 
       
   412     inline int32_t JSValue::toInt32(ExecState* exec, bool& ok) const
       
   413     {
       
   414         if (isInt32()) {
       
   415             ok = true;
       
   416             return asInt32();
       
   417         }
       
   418         return toInt32SlowCase(toNumber(exec), ok);
       
   419     }
       
   420 
       
   421     inline uint32_t JSValue::toUInt32(ExecState* exec, bool& ok) const
       
   422     {
       
   423         if (isUInt32()) {
       
   424             ok = true;
       
   425             return asInt32();
       
   426         }
       
   427         return toUInt32SlowCase(toNumber(exec), ok);
       
   428     }
       
   429 
       
   430 #if USE(JSVALUE32_64)
       
   431     inline JSValue jsNaN(ExecState* exec)
       
   432     {
       
   433         return JSValue(exec, nonInlineNaN());
       
   434     }
       
   435 
       
   436     // JSValue member functions.
       
   437     inline EncodedJSValue JSValue::encode(JSValue value)
       
   438     {
       
   439         return value.u.asEncodedJSValue;
       
   440     }
       
   441 
       
   442     inline JSValue JSValue::decode(EncodedJSValue encodedJSValue)
       
   443     {
       
   444         JSValue v;
       
   445         v.u.asEncodedJSValue = encodedJSValue;
       
   446 #if ENABLE(JSC_ZOMBIES)
       
   447         ASSERT(!v.isZombie());
       
   448 #endif
       
   449         return v;
       
   450     }
       
   451 
       
   452     inline JSValue::JSValue()
       
   453     {
       
   454         u.asBits.tag = EmptyValueTag;
       
   455         u.asBits.payload = 0;
       
   456     }
       
   457 
       
   458     inline JSValue::JSValue(JSNullTag)
       
   459     {
       
   460         u.asBits.tag = NullTag;
       
   461         u.asBits.payload = 0;
       
   462     }
       
   463     
       
   464     inline JSValue::JSValue(JSUndefinedTag)
       
   465     {
       
   466         u.asBits.tag = UndefinedTag;
       
   467         u.asBits.payload = 0;
       
   468     }
       
   469     
       
   470     inline JSValue::JSValue(JSTrueTag)
       
   471     {
       
   472         u.asBits.tag = TrueTag;
       
   473         u.asBits.payload = 0;
       
   474     }
       
   475     
       
   476     inline JSValue::JSValue(JSFalseTag)
       
   477     {
       
   478         u.asBits.tag = FalseTag;
       
   479         u.asBits.payload = 0;
       
   480     }
       
   481 
       
   482     inline JSValue::JSValue(HashTableDeletedValueTag)
       
   483     {
       
   484         u.asBits.tag = DeletedValueTag;
       
   485         u.asBits.payload = 0;
       
   486     }
       
   487 
       
   488     inline JSValue::JSValue(JSCell* ptr)
       
   489     {
       
   490         if (ptr)
       
   491             u.asBits.tag = CellTag;
       
   492         else
       
   493             u.asBits.tag = EmptyValueTag;
       
   494         u.asBits.payload = reinterpret_cast<int32_t>(ptr);
       
   495 #if ENABLE(JSC_ZOMBIES)
       
   496         ASSERT(!isZombie());
       
   497 #endif
       
   498     }
       
   499 
       
   500     inline JSValue::JSValue(const JSCell* ptr)
       
   501     {
       
   502         if (ptr)
       
   503             u.asBits.tag = CellTag;
       
   504         else
       
   505             u.asBits.tag = EmptyValueTag;
       
   506         u.asBits.payload = reinterpret_cast<int32_t>(const_cast<JSCell*>(ptr));
       
   507 #if ENABLE(JSC_ZOMBIES)
       
   508         ASSERT(!isZombie());
       
   509 #endif
       
   510     }
       
   511 
       
   512     inline JSValue::operator bool() const
       
   513     {
       
   514         ASSERT(tag() != DeletedValueTag);
       
   515         return tag() != EmptyValueTag;
       
   516     }
       
   517 
       
   518     inline bool JSValue::operator==(const JSValue& other) const
       
   519     {
       
   520         return u.asEncodedJSValue == other.u.asEncodedJSValue;
       
   521     }
       
   522 
       
   523     inline bool JSValue::operator!=(const JSValue& other) const
       
   524     {
       
   525         return u.asEncodedJSValue != other.u.asEncodedJSValue;
       
   526     }
       
   527 
       
   528     inline bool JSValue::isUndefined() const
       
   529     {
       
   530         return tag() == UndefinedTag;
       
   531     }
       
   532 
       
   533     inline bool JSValue::isNull() const
       
   534     {
       
   535         return tag() == NullTag;
       
   536     }
       
   537 
       
   538     inline bool JSValue::isUndefinedOrNull() const
       
   539     {
       
   540         return isUndefined() || isNull();
       
   541     }
       
   542 
       
   543     inline bool JSValue::isCell() const
       
   544     {
       
   545         return tag() == CellTag;
       
   546     }
       
   547 
       
   548     inline bool JSValue::isInt32() const
       
   549     {
       
   550         return tag() == Int32Tag;
       
   551     }
       
   552 
       
   553     inline bool JSValue::isUInt32() const
       
   554     {
       
   555         return tag() == Int32Tag && asInt32() > -1;
       
   556     }
       
   557 
       
   558     inline bool JSValue::isDouble() const
       
   559     {
       
   560         return tag() < LowestTag;
       
   561     }
       
   562 
       
   563     inline bool JSValue::isTrue() const
       
   564     {
       
   565         return tag() == TrueTag;
       
   566     }
       
   567 
       
   568     inline bool JSValue::isFalse() const
       
   569     {
       
   570         return tag() == FalseTag;
       
   571     }
       
   572 
       
   573     inline uint32_t JSValue::tag() const
       
   574     {
       
   575         return u.asBits.tag;
       
   576     }
       
   577     
       
   578     inline int32_t JSValue::payload() const
       
   579     {
       
   580         return u.asBits.payload;
       
   581     }
       
   582     
       
   583     inline int32_t JSValue::asInt32() const
       
   584     {
       
   585         ASSERT(isInt32());
       
   586         return u.asBits.payload;
       
   587     }
       
   588     
       
   589     inline uint32_t JSValue::asUInt32() const
       
   590     {
       
   591         ASSERT(isUInt32());
       
   592         return u.asBits.payload;
       
   593     }
       
   594     
       
   595     inline double JSValue::asDouble() const
       
   596     {
       
   597         ASSERT(isDouble());
       
   598         return u.asDouble;
       
   599     }
       
   600     
       
   601     ALWAYS_INLINE JSCell* JSValue::asCell() const
       
   602     {
       
   603         ASSERT(isCell());
       
   604         return reinterpret_cast<JSCell*>(u.asBits.payload);
       
   605     }
       
   606 
       
   607     ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, ExecState*, double d)
       
   608     {
       
   609         u.asDouble = d;
       
   610     }
       
   611 
       
   612     inline JSValue::JSValue(ExecState* exec, double d)
       
   613     {
       
   614         const int32_t asInt32 = static_cast<int32_t>(d);
       
   615         if (asInt32 != d || (!asInt32 && signbit(d))) { // true for -0.0
       
   616             u.asDouble = d;
       
   617             return;
       
   618         }
       
   619         *this = JSValue(exec, static_cast<int32_t>(d));
       
   620     }
       
   621 
       
   622     inline JSValue::JSValue(ExecState* exec, char i)
       
   623     {
       
   624         *this = JSValue(exec, static_cast<int32_t>(i));
       
   625     }
       
   626 
       
   627     inline JSValue::JSValue(ExecState* exec, unsigned char i)
       
   628     {
       
   629         *this = JSValue(exec, static_cast<int32_t>(i));
       
   630     }
       
   631 
       
   632     inline JSValue::JSValue(ExecState* exec, short i)
       
   633     {
       
   634         *this = JSValue(exec, static_cast<int32_t>(i));
       
   635     }
       
   636 
       
   637     inline JSValue::JSValue(ExecState* exec, unsigned short i)
       
   638     {
       
   639         *this = JSValue(exec, static_cast<int32_t>(i));
       
   640     }
       
   641 
       
   642     inline JSValue::JSValue(ExecState*, int i)
       
   643     {
       
   644         u.asBits.tag = Int32Tag;
       
   645         u.asBits.payload = i;
       
   646     }
       
   647 
       
   648     inline JSValue::JSValue(ExecState* exec, unsigned i)
       
   649     {
       
   650         if (static_cast<int32_t>(i) < 0) {
       
   651             *this = JSValue(exec, static_cast<double>(i));
       
   652             return;
       
   653         }
       
   654         *this = JSValue(exec, static_cast<int32_t>(i));
       
   655     }
       
   656 
       
   657     inline JSValue::JSValue(ExecState* exec, long i)
       
   658     {
       
   659         if (static_cast<int32_t>(i) != i) {
       
   660             *this = JSValue(exec, static_cast<double>(i));
       
   661             return;
       
   662         }
       
   663         *this = JSValue(exec, static_cast<int32_t>(i));
       
   664     }
       
   665 
       
   666     inline JSValue::JSValue(ExecState* exec, unsigned long i)
       
   667     {
       
   668         if (static_cast<uint32_t>(i) != i) {
       
   669             *this = JSValue(exec, static_cast<double>(i));
       
   670             return;
       
   671         }
       
   672         *this = JSValue(exec, static_cast<uint32_t>(i));
       
   673     }
       
   674 
       
   675     inline JSValue::JSValue(ExecState* exec, long long i)
       
   676     {
       
   677         if (static_cast<int32_t>(i) != i) {
       
   678             *this = JSValue(exec, static_cast<double>(i));
       
   679             return;
       
   680         }
       
   681         *this = JSValue(exec, static_cast<int32_t>(i));
       
   682     }
       
   683 
       
   684     inline JSValue::JSValue(ExecState* exec, unsigned long long i)
       
   685     {
       
   686         if (static_cast<uint32_t>(i) != i) {
       
   687             *this = JSValue(exec, static_cast<double>(i));
       
   688             return;
       
   689         }
       
   690         *this = JSValue(exec, static_cast<uint32_t>(i));
       
   691     }
       
   692 
       
   693     inline JSValue::JSValue(JSGlobalData* globalData, double d)
       
   694     {
       
   695         const int32_t asInt32 = static_cast<int32_t>(d);
       
   696         if (asInt32 != d || (!asInt32 && signbit(d))) { // true for -0.0
       
   697             u.asDouble = d;
       
   698             return;
       
   699         }
       
   700         *this = JSValue(globalData, static_cast<int32_t>(d));
       
   701     }
       
   702     
       
   703     inline JSValue::JSValue(JSGlobalData*, int i)
       
   704     {
       
   705         u.asBits.tag = Int32Tag;
       
   706         u.asBits.payload = i;
       
   707     }
       
   708     
       
   709     inline JSValue::JSValue(JSGlobalData* globalData, unsigned i)
       
   710     {
       
   711         if (static_cast<int32_t>(i) < 0) {
       
   712             *this = JSValue(globalData, static_cast<double>(i));
       
   713             return;
       
   714         }
       
   715         *this = JSValue(globalData, static_cast<int32_t>(i));
       
   716     }
       
   717 
       
   718     inline bool JSValue::isNumber() const
       
   719     {
       
   720         return isInt32() || isDouble();
       
   721     }
       
   722 
       
   723     inline bool JSValue::isBoolean() const
       
   724     {
       
   725         return isTrue() || isFalse();
       
   726     }
       
   727 
       
   728     inline bool JSValue::getBoolean(bool& v) const
       
   729     {
       
   730         if (isTrue()) {
       
   731             v = true;
       
   732             return true;
       
   733         }
       
   734         if (isFalse()) {
       
   735             v = false;
       
   736             return true;
       
   737         }
       
   738         
       
   739         return false;
       
   740     }
       
   741 
       
   742     inline bool JSValue::getBoolean() const
       
   743     {
       
   744         ASSERT(isBoolean());
       
   745         return tag() == TrueTag;
       
   746     }
       
   747 
       
   748     inline double JSValue::uncheckedGetNumber() const
       
   749     {
       
   750         ASSERT(isNumber());
       
   751         return isInt32() ? asInt32() : asDouble();
       
   752     }
       
   753 
       
   754     ALWAYS_INLINE JSValue JSValue::toJSNumber(ExecState* exec) const
       
   755     {
       
   756         return isNumber() ? asValue() : jsNumber(exec, this->toNumber(exec));
       
   757     }
       
   758 
       
   759     inline bool JSValue::getNumber(double& result) const
       
   760     {
       
   761         if (isInt32()) {
       
   762             result = asInt32();
       
   763             return true;
       
   764         }
       
   765         if (isDouble()) {
       
   766             result = asDouble();
       
   767             return true;
       
   768         }
       
   769         return false;
       
   770     }
       
   771 
       
   772 #else // USE(JSVALUE32_64)
       
   773 
       
   774     // JSValue member functions.
       
   775     inline EncodedJSValue JSValue::encode(JSValue value)
       
   776     {
       
   777         return reinterpret_cast<EncodedJSValue>(value.m_ptr);
       
   778     }
       
   779 
       
   780     inline JSValue JSValue::decode(EncodedJSValue ptr)
       
   781     {
       
   782         return JSValue(reinterpret_cast<JSCell*>(ptr));
       
   783     }
       
   784 
       
   785     inline JSValue JSValue::makeImmediate(intptr_t value)
       
   786     {
       
   787         return JSValue(reinterpret_cast<JSCell*>(value));
       
   788     }
       
   789 
       
   790     inline intptr_t JSValue::immediateValue()
       
   791     {
       
   792         return reinterpret_cast<intptr_t>(m_ptr);
       
   793     }
       
   794     
       
   795     // 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.
       
   796     inline JSValue::JSValue()
       
   797         : m_ptr(0)
       
   798     {
       
   799     }
       
   800 
       
   801     // 0x4 can never occur naturally because it has a tag of 00, indicating a pointer value, but a payload of 0x4, which is in the (invalid) zero page.
       
   802     inline JSValue::JSValue(HashTableDeletedValueTag)
       
   803         : m_ptr(reinterpret_cast<JSCell*>(0x4))
       
   804     {
       
   805     }
       
   806 
       
   807     inline JSValue::JSValue(JSCell* ptr)
       
   808         : m_ptr(ptr)
       
   809     {
       
   810 #if ENABLE(JSC_ZOMBIES)
       
   811         ASSERT(!isZombie());
       
   812 #endif
       
   813     }
       
   814 
       
   815     inline JSValue::JSValue(const JSCell* ptr)
       
   816         : m_ptr(const_cast<JSCell*>(ptr))
       
   817     {
       
   818 #if ENABLE(JSC_ZOMBIES)
       
   819         ASSERT(!isZombie());
       
   820 #endif
       
   821     }
       
   822 
       
   823     inline JSValue::operator bool() const
       
   824     {
       
   825         return m_ptr;
       
   826     }
       
   827 
       
   828     inline bool JSValue::operator==(const JSValue& other) const
       
   829     {
       
   830         return m_ptr == other.m_ptr;
       
   831     }
       
   832 
       
   833     inline bool JSValue::operator!=(const JSValue& other) const
       
   834     {
       
   835         return m_ptr != other.m_ptr;
       
   836     }
       
   837 
       
   838     inline bool JSValue::isUndefined() const
       
   839     {
       
   840         return asValue() == jsUndefined();
       
   841     }
       
   842 
       
   843     inline bool JSValue::isNull() const
       
   844     {
       
   845         return asValue() == jsNull();
       
   846     }
       
   847 #endif // USE(JSVALUE32_64)
       
   848 
       
   849 } // namespace JSC
       
   850 
       
   851 #endif // JSValue_h