]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - runtime/JSValue.h
JavaScriptCore-1097.3.3.tar.gz
[apple/javascriptcore.git] / runtime / JSValue.h
index cbf8fc54880da6f344fe762094737bf56f09b4f2..7facb935390a6039cbf74e123003e62c4acb8500 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
- *  Copyright (C) 2003, 2004, 2005, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Library General Public
  *
  */
 
-#include <stddef.h> // for size_t
-#include <stdint.h>
-
 #ifndef JSValue_h
 #define JSValue_h
 
-#include "CallData.h"
-#include "ConstructData.h"
 #include <math.h>
+#include <stddef.h> // for size_t
+#include <stdint.h>
 #include <wtf/AlwaysInline.h>
 #include <wtf/Assertions.h>
+#include <wtf/HashMap.h>
 #include <wtf/HashTraits.h>
 #include <wtf/MathExtras.h>
+#include <wtf/StdLibExtras.h>
 
 namespace JSC {
 
+    class ExecState;
     class Identifier;
     class JSCell;
     class JSGlobalData;
-    class JSImmediate;
+    class JSGlobalObject;
     class JSObject;
     class JSString;
     class PropertySlot;
     class PutPropertySlot;
     class UString;
+#if ENABLE(DFG_JIT)
+    namespace DFG {
+        class AssemblyHelpers;
+        class JITCompiler;
+        class JITCodeGenerator;
+        class JSValueSource;
+        class OSRExitCompiler;
+        class SpeculativeJIT;
+    }
+#endif
+    namespace LLInt {
+        class Data;
+    }
 
     struct ClassInfo;
     struct Instruction;
+    struct MethodTable;
+
+    template <class T> class WriteBarrierBase;
 
     enum PreferredPrimitiveType { NoPreference, PreferNumber, PreferString };
 
+
 #if USE(JSVALUE32_64)
     typedef int64_t EncodedJSValue;
 #else
     typedef void* EncodedJSValue;
 #endif
+    
+    union EncodedValueDescriptor {
+        int64_t asInt64;
+#if USE(JSVALUE32_64)
+        double asDouble;
+#elif USE(JSVALUE64)
+        JSCell* ptr;
+#endif
+        
+#if CPU(BIG_ENDIAN)
+        struct {
+            int32_t tag;
+            int32_t payload;
+        } asBits;
+#else
+        struct {
+            int32_t payload;
+            int32_t tag;
+        } asBits;
+#endif
+    };
+
+    // This implements ToInt32, defined in ECMA-262 9.5.
+    JS_EXPORT_PRIVATE int32_t toInt32(double);
 
-    double nonInlineNaN();
-    int32_t toInt32SlowCase(double, bool& ok);
-    uint32_t toUInt32SlowCase(double, bool& ok);
+    // This implements ToUInt32, defined in ECMA-262 9.6.
+    inline uint32_t toUInt32(double number)
+    {
+        // As commented in the spec, the operation of ToInt32 and ToUint32 only differ
+        // in how the result is interpreted; see NOTEs in sections 9.5 and 9.6.
+        return toInt32(number);
+    }
 
     class JSValue {
-        friend class JSImmediate;
         friend struct EncodedJSValueHashTraits;
         friend class JIT;
         friend class JITStubs;
         friend class JITStubCall;
+        friend class JSInterfaceJIT;
+        friend class SpecializedThunkJIT;
+#if ENABLE(DFG_JIT)
+        friend class DFG::AssemblyHelpers;
+        friend class DFG::JITCompiler;
+        friend class DFG::JITCodeGenerator;
+        friend class DFG::JSValueSource;
+        friend class DFG::OSRExitCompiler;
+        friend class DFG::SpeculativeJIT;
+#endif
+        friend class LLInt::Data;
 
     public:
-        static EncodedJSValue encode(JSValue value);
-        static JSValue decode(EncodedJSValue ptr);
-#if !USE(JSVALUE32_64)
-    private:
-        static JSValue makeImmediate(intptr_t value);
-        intptr_t immediateValue();
-    public:
-#endif
+        static EncodedJSValue encode(JSValue);
+        static JSValue decode(EncodedJSValue);
+
         enum JSNullTag { JSNull };
         enum JSUndefinedTag { JSUndefined };
         enum JSTrueTag { JSTrue };
         enum JSFalseTag { JSFalse };
+        enum EncodeAsDoubleTag { EncodeAsDouble };
 
         JSValue();
         JSValue(JSNullTag);
@@ -91,20 +142,18 @@ namespace JSC {
         JSValue(const JSCell* ptr);
 
         // Numbers
-        JSValue(ExecState*, double);
-        JSValue(ExecState*, char);
-        JSValue(ExecState*, unsigned char);
-        JSValue(ExecState*, short);
-        JSValue(ExecState*, unsigned short);
-        JSValue(ExecState*, int);
-        JSValue(ExecState*, unsigned);
-        JSValue(ExecState*, long);
-        JSValue(ExecState*, unsigned long);
-        JSValue(ExecState*, long long);
-        JSValue(ExecState*, unsigned long long);
-        JSValue(JSGlobalData*, double);
-        JSValue(JSGlobalData*, int);
-        JSValue(JSGlobalData*, unsigned);
+        JSValue(EncodeAsDoubleTag, double);
+        explicit JSValue(double);
+        explicit JSValue(char);
+        explicit JSValue(unsigned char);
+        explicit JSValue(short);
+        explicit JSValue(unsigned short);
+        explicit JSValue(int);
+        explicit JSValue(unsigned);
+        explicit JSValue(long);
+        explicit JSValue(unsigned long);
+        explicit JSValue(long long);
+        explicit JSValue(unsigned long long);
 
         operator bool() const;
         bool operator==(const JSValue& other) const;
@@ -119,30 +168,28 @@ namespace JSC {
         int32_t asInt32() const;
         uint32_t asUInt32() const;
         double asDouble() const;
+        bool asBoolean() const;
+        double asNumber() const;
 
         // Querying the type.
+        bool isEmpty() const;
+        bool isFunction() const;
         bool isUndefined() const;
         bool isNull() const;
         bool isUndefinedOrNull() const;
         bool isBoolean() const;
         bool isNumber() const;
         bool isString() const;
+        bool isPrimitive() const;
         bool isGetterSetter() const;
         bool isObject() const;
-        bool isObject(const ClassInfo*) const;
+        bool inherits(const ClassInfo*) const;
         
         // Extracting the value.
-        bool getBoolean(bool&) const;
-        bool getBoolean() const; // false if not a boolean
-        bool getNumber(double&) const;
-        double uncheckedGetNumber() const;
-        bool getString(UString&) const;
-        UString getString() const; // null string if not a string
+        bool getString(ExecState* exec, UString&) const;
+        UString getString(ExecState* exec) const; // null string if not a string
         JSObject* getObject() const; // 0 if not an object
 
-        CallType getCallData(CallData&);
-        ConstructType getConstructData(ConstructData&);
-
         // Extracting integer values.
         bool getUInt32(uint32_t&) const;
         
@@ -155,98 +202,176 @@ namespace JSC {
         // toNumber conversion is expected to be side effect free if an exception has
         // been set in the ExecState already.
         double toNumber(ExecState*) const;
-        JSValue toJSNumber(ExecState*) const; // Fast path for when you expect that the value is an immediate number.
-        UString toString(ExecState*) const;
+        JSString* toString(ExecState*) const;
+        UString toUString(ExecState*) const;
+        UString toUStringInline(ExecState*) const;
         JSObject* toObject(ExecState*) const;
+        JSObject* toObject(ExecState*, JSGlobalObject*) const;
 
         // Integer conversions.
-        double toInteger(ExecState*) const;
+        JS_EXPORT_PRIVATE double toInteger(ExecState*) const;
         double toIntegerPreserveNaN(ExecState*) const;
         int32_t toInt32(ExecState*) const;
-        int32_t toInt32(ExecState*, bool& ok) const;
         uint32_t toUInt32(ExecState*) const;
-        uint32_t toUInt32(ExecState*, bool& ok) const;
 
         // Floating point conversions (this is a convenience method for webcore;
         // signle precision float is not a representation used in JS or JSC).
         float toFloat(ExecState* exec) const { return static_cast<float>(toNumber(exec)); }
 
-        // Garbage collection.
-        void mark();
-        bool marked() const;
-
         // Object operations, with the toObject operation included.
         JSValue get(ExecState*, const Identifier& propertyName) const;
         JSValue get(ExecState*, const Identifier& propertyName, PropertySlot&) const;
         JSValue get(ExecState*, unsigned propertyName) const;
         JSValue get(ExecState*, unsigned propertyName, PropertySlot&) const;
         void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
-        void put(ExecState*, unsigned propertyName, JSValue);
+        void putToPrimitive(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
+        void putByIndex(ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
 
-        bool needsThisConversion() const;
         JSObject* toThisObject(ExecState*) const;
-        UString toThisString(ExecState*) const;
-        JSString* toThisJSString(ExecState*);
 
         static bool equal(ExecState* exec, JSValue v1, JSValue v2);
         static bool equalSlowCase(ExecState* exec, JSValue v1, JSValue v2);
         static bool equalSlowCaseInline(ExecState* exec, JSValue v1, JSValue v2);
-        static bool strictEqual(JSValue v1, JSValue v2);
-        static bool strictEqualSlowCase(JSValue v1, JSValue v2);
-        static bool strictEqualSlowCaseInline(JSValue v1, JSValue v2);
-
-        JSValue getJSNumber(); // JSValue() if this is not a JSNumber or number object
+        static bool strictEqual(ExecState* exec, JSValue v1, JSValue v2);
+        static bool strictEqualSlowCase(ExecState* exec, JSValue v1, JSValue v2);
+        static bool strictEqualSlowCaseInline(ExecState* exec, JSValue v1, JSValue v2);
 
         bool isCell() const;
         JSCell* asCell() const;
+        JS_EXPORT_PRIVATE bool isValidCallee();
 
-#ifndef NDEBUG
         char* description();
-#endif
+
+        JS_EXPORT_PRIVATE JSObject* synthesizePrototype(ExecState*) const;
 
     private:
+        template <class T> JSValue(WriteBarrierBase<T>);
+
         enum HashTableDeletedValueTag { HashTableDeletedValue };
         JSValue(HashTableDeletedValueTag);
 
         inline const JSValue asValue() const { return *this; }
-        JSObject* toObjectSlowCase(ExecState*) const;
-        JSObject* toThisObjectSlowCase(ExecState*) const;
+        JS_EXPORT_PRIVATE double toNumberSlowCase(ExecState*) const;
+        JS_EXPORT_PRIVATE JSString* toStringSlowCase(ExecState*) const;
+        JS_EXPORT_PRIVATE UString toUStringSlowCase(ExecState*) const;
+        JS_EXPORT_PRIVATE JSObject* toObjectSlowCase(ExecState*, JSGlobalObject*) const;
+        JS_EXPORT_PRIVATE JSObject* toThisObjectSlowCase(ExecState*) const;
 
+#if USE(JSVALUE32_64)
+        /*
+         * On 32-bit platforms USE(JSVALUE32_64) should be defined, and we use a NaN-encoded
+         * form for immediates.
+         *
+         * The encoding makes use of unused NaN space in the IEEE754 representation.  Any value
+         * with the top 13 bits set represents a QNaN (with the sign bit set).  QNaN values
+         * can encode a 51-bit payload.  Hardware produced and C-library payloads typically
+         * have a payload of zero.  We assume that non-zero payloads are available to encode
+         * pointer and integer values.  Since any 64-bit bit pattern where the top 15 bits are
+         * all set represents a NaN with a non-zero payload, we can use this space in the NaN
+         * ranges to encode other values (however there are also other ranges of NaN space that
+         * could have been selected).
+         *
+         * For JSValues that do not contain a double value, the high 32 bits contain the tag
+         * values listed in the enums below, which all correspond to NaN-space. In the case of
+         * cell, integer and bool values the lower 32 bits (the 'payload') contain the pointer
+         * integer or boolean value; in the case of all other tags the payload is 0.
+         */
         enum { Int32Tag =        0xffffffff };
-        enum { CellTag =         0xfffffffe };
-        enum { TrueTag =         0xfffffffd };
-        enum { FalseTag =        0xfffffffc };
-        enum { NullTag =         0xfffffffb };
-        enum { UndefinedTag =    0xfffffffa };
+        enum { BooleanTag =      0xfffffffe };
+        enum { NullTag =         0xfffffffd };
+        enum { UndefinedTag =    0xfffffffc };
+        enum { CellTag =         0xfffffffb };
+        enum { EmptyValueTag =   0xfffffffa };
         enum { DeletedValueTag = 0xfffffff9 };
 
         enum { LowestTag =  DeletedValueTag };
 
         uint32_t tag() const;
         int32_t payload() const;
-
-        JSObject* synthesizePrototype(ExecState*) const;
-        JSObject* synthesizeObject(ExecState*) const;
-
-#if USE(JSVALUE32_64)
-        union {
-            EncodedJSValue asEncodedJSValue;
-            double asDouble;
-#if PLATFORM(BIG_ENDIAN)
-            struct {
-                int32_t tag;
-                int32_t payload;
-            } asBits;
-#else
-            struct {
-                int32_t payload;
-                int32_t tag;
-            } asBits;
+#elif USE(JSVALUE64)
+        /*
+         * On 64-bit platforms USE(JSVALUE64) should be defined, and we use a NaN-encoded
+         * form for immediates.
+         *
+         * The encoding makes use of unused NaN space in the IEEE754 representation.  Any value
+         * with the top 13 bits set represents a QNaN (with the sign bit set).  QNaN values
+         * can encode a 51-bit payload.  Hardware produced and C-library payloads typically
+         * have a payload of zero.  We assume that non-zero payloads are available to encode
+         * pointer and integer values.  Since any 64-bit bit pattern where the top 15 bits are
+         * all set represents a NaN with a non-zero payload, we can use this space in the NaN
+         * ranges to encode other values (however there are also other ranges of NaN space that
+         * could have been selected).
+         *
+         * This range of NaN space is represented by 64-bit numbers begining with the 16-bit
+         * hex patterns 0xFFFE and 0xFFFF - we rely on the fact that no valid double-precision
+         * numbers will begin fall in these ranges.
+         *
+         * The top 16-bits denote the type of the encoded JSValue:
+         *
+         *     Pointer {  0000:PPPP:PPPP:PPPP
+         *              / 0001:****:****:****
+         *     Double  {         ...
+         *              \ FFFE:****:****:****
+         *     Integer {  FFFF:0000:IIII:IIII
+         *
+         * The scheme we have implemented encodes double precision values by performing a
+         * 64-bit integer addition of the value 2^48 to the number. After this manipulation
+         * no encoded double-precision value will begin with the pattern 0x0000 or 0xFFFF.
+         * Values must be decoded by reversing this operation before subsequent floating point
+         * operations my be peformed.
+         *
+         * 32-bit signed integers are marked with the 16-bit tag 0xFFFF.
+         *
+         * The tag 0x0000 denotes a pointer, or another form of tagged immediate. Boolean,
+         * null and undefined values are represented by specific, invalid pointer values:
+         *
+         *     False:     0x06
+         *     True:      0x07
+         *     Undefined: 0x0a
+         *     Null:      0x02
+         *
+         * These values have the following properties:
+         * - Bit 1 (TagBitTypeOther) is set for all four values, allowing real pointers to be
+         *   quickly distinguished from all immediate values, including these invalid pointers.
+         * - With bit 3 is masked out (TagBitUndefined) Undefined and Null share the
+         *   same value, allowing null & undefined to be quickly detected.
+         *
+         * No valid JSValue will have the bit pattern 0x0, this is used to represent array
+         * holes, and as a C++ 'no value' result (e.g. JSValue() has an internal value of 0).
+         */
+
+        // These values are #defines since using static const integers here is a ~1% regression!
+
+        // This value is 2^48, used to encode doubles such that the encoded value will begin
+        // with a 16-bit pattern within the range 0x0001..0xFFFE.
+        #define DoubleEncodeOffset 0x1000000000000ll
+        // If all bits in the mask are set, this indicates an integer number,
+        // if any but not all are set this value is a double precision number.
+        #define TagTypeNumber 0xffff000000000000ll
+
+        // All non-numeric (bool, null, undefined) immediates have bit 2 set.
+        #define TagBitTypeOther 0x2ll
+        #define TagBitBool      0x4ll
+        #define TagBitUndefined 0x8ll
+        // Combined integer value for non-numeric immediates.
+        #define ValueFalse     (TagBitTypeOther | TagBitBool | false)
+        #define ValueTrue      (TagBitTypeOther | TagBitBool | true)
+        #define ValueUndefined (TagBitTypeOther | TagBitUndefined)
+        #define ValueNull      (TagBitTypeOther)
+
+        // TagMask is used to check for all types of immediate values (either number or 'other').
+        #define TagMask (TagTypeNumber | TagBitTypeOther)
+
+        // These special values are never visible to JavaScript code; Empty is used to represent
+        // Array holes, and for uninitialized JSValues. Deleted is used in hash table code.
+        // These values would map to cell types in the JSValue encoding, but not valid GC cell
+        // pointer should have either of these values (Empty is null, deleted is at an invalid
+        // alignment for a GC cell, and in the zero page).
+        #define ValueEmpty   0x0ll
+        #define ValueDeleted 0x4ll
 #endif
-        } u;
-#else // USE(JSVALUE32_64)
-        JSCell* m_ptr;
-#endif // USE(JSVALUE32_64)
+
+        EncodedValueDescriptor u;
     };
 
 #if USE(JSVALUE32_64)
@@ -267,6 +392,8 @@ namespace JSC {
     };
 #endif
 
+    typedef HashMap<EncodedJSValue, unsigned, EncodedJSValueHash, EncodedJSValueHashTraits> JSValueMap;
+
     // Stand-alone helper functions.
     inline JSValue jsNull()
     {
@@ -283,74 +410,66 @@ namespace JSC {
         return b ? JSValue(JSValue::JSTrue) : JSValue(JSValue::JSFalse);
     }
 
-    ALWAYS_INLINE JSValue jsNumber(ExecState* exec, double d)
-    {
-        return JSValue(exec, d);
-    }
-
-    ALWAYS_INLINE JSValue jsNumber(ExecState* exec, char i)
-    {
-        return JSValue(exec, i);
-    }
-
-    ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned char i)
+    ALWAYS_INLINE JSValue jsDoubleNumber(double d)
     {
-        return JSValue(exec, i);
+        ASSERT(JSValue(JSValue::EncodeAsDouble, d).isNumber());
+        return JSValue(JSValue::EncodeAsDouble, d);
     }
 
-    ALWAYS_INLINE JSValue jsNumber(ExecState* exec, short i)
+    ALWAYS_INLINE JSValue jsNumber(double d)
     {
-        return JSValue(exec, i);
+        ASSERT(JSValue(d).isNumber());
+        return JSValue(d);
     }
 
-    ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned short i)
+    ALWAYS_INLINE JSValue jsNumber(char i)
     {
-        return JSValue(exec, i);
+        return JSValue(i);
     }
 
-    ALWAYS_INLINE JSValue jsNumber(ExecState* exec, int i)
+    ALWAYS_INLINE JSValue jsNumber(unsigned char i)
     {
-        return JSValue(exec, i);
+        return JSValue(i);
     }
 
-    ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned i)
+    ALWAYS_INLINE JSValue jsNumber(short i)
     {
-        return JSValue(exec, i);
+        return JSValue(i);
     }
 
-    ALWAYS_INLINE JSValue jsNumber(ExecState* exec, long i)
+    ALWAYS_INLINE JSValue jsNumber(unsigned short i)
     {
-        return JSValue(exec, i);
+        return JSValue(i);
     }
 
-    ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned long i)
+    ALWAYS_INLINE JSValue jsNumber(int i)
     {
-        return JSValue(exec, i);
+        return JSValue(i);
     }
 
-    ALWAYS_INLINE JSValue jsNumber(ExecState* exec, long long i)
+    ALWAYS_INLINE JSValue jsNumber(unsigned i)
     {
-        return JSValue(exec, i);
+        return JSValue(i);
     }
 
-    ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned long long i)
+    ALWAYS_INLINE JSValue jsNumber(long i)
     {
-        return JSValue(exec, i);
+        return JSValue(i);
     }
 
-    ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, double d)
+    ALWAYS_INLINE JSValue jsNumber(unsigned long i)
     {
-        return JSValue(globalData, d);
+        return JSValue(i);
     }
 
-    ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, int i)
+    ALWAYS_INLINE JSValue jsNumber(long long i)
     {
-        return JSValue(globalData, i);
+        return JSValue(i);
     }
 
-    ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, unsigned i)
+    ALWAYS_INLINE JSValue jsNumber(unsigned long long i)
     {
-        return JSValue(globalData, i);
+        return JSValue(i);
     }
 
     inline bool operator==(const JSValue a, const JSCell* b) { return a == JSValue(b); }
@@ -359,450 +478,6 @@ namespace JSC {
     inline bool operator!=(const JSValue a, const JSCell* b) { return a != JSValue(b); }
     inline bool operator!=(const JSCell* a, const JSValue b) { return JSValue(a) != b; }
 
-    inline int32_t toInt32(double val)
-    {
-        if (!(val >= -2147483648.0 && val < 2147483648.0)) {
-            bool ignored;
-            return toInt32SlowCase(val, ignored);
-        }
-        return static_cast<int32_t>(val);
-    }
-
-    inline uint32_t toUInt32(double val)
-    {
-        if (!(val >= 0.0 && val < 4294967296.0)) {
-            bool ignored;
-            return toUInt32SlowCase(val, ignored);
-        }
-        return static_cast<uint32_t>(val);
-    }
-
-    ALWAYS_INLINE int32_t JSValue::toInt32(ExecState* exec) const
-    {
-        if (isInt32())
-            return asInt32();
-        bool ignored;
-        return toInt32SlowCase(toNumber(exec), ignored);
-    }
-
-    inline uint32_t JSValue::toUInt32(ExecState* exec) const
-    {
-        if (isUInt32())
-            return asInt32();
-        bool ignored;
-        return toUInt32SlowCase(toNumber(exec), ignored);
-    }
-
-    inline int32_t JSValue::toInt32(ExecState* exec, bool& ok) const
-    {
-        if (isInt32()) {
-            ok = true;
-            return asInt32();
-        }
-        return toInt32SlowCase(toNumber(exec), ok);
-    }
-
-    inline uint32_t JSValue::toUInt32(ExecState* exec, bool& ok) const
-    {
-        if (isUInt32()) {
-            ok = true;
-            return asInt32();
-        }
-        return toUInt32SlowCase(toNumber(exec), ok);
-    }
-
-#if USE(JSVALUE32_64)
-    inline JSValue jsNaN(ExecState* exec)
-    {
-        return JSValue(exec, nonInlineNaN());
-    }
-
-    // JSValue member functions.
-    inline EncodedJSValue JSValue::encode(JSValue value)
-    {
-        return value.u.asEncodedJSValue;
-    }
-
-    inline JSValue JSValue::decode(EncodedJSValue encodedJSValue)
-    {
-        JSValue v;
-        v.u.asEncodedJSValue = encodedJSValue;
-        return v;
-    }
-
-    inline JSValue::JSValue()
-    {
-        u.asBits.tag = CellTag;
-        u.asBits.payload = 0;
-    }
-
-    inline JSValue::JSValue(JSNullTag)
-    {
-        u.asBits.tag = NullTag;
-        u.asBits.payload = 0;
-    }
-    
-    inline JSValue::JSValue(JSUndefinedTag)
-    {
-        u.asBits.tag = UndefinedTag;
-        u.asBits.payload = 0;
-    }
-    
-    inline JSValue::JSValue(JSTrueTag)
-    {
-        u.asBits.tag = TrueTag;
-        u.asBits.payload = 0;
-    }
-    
-    inline JSValue::JSValue(JSFalseTag)
-    {
-        u.asBits.tag = FalseTag;
-        u.asBits.payload = 0;
-    }
-
-    inline JSValue::JSValue(HashTableDeletedValueTag)
-    {
-        u.asBits.tag = DeletedValueTag;
-        u.asBits.payload = 0;
-    }
-
-    inline JSValue::JSValue(JSCell* ptr)
-    {
-        u.asBits.tag = CellTag;
-        u.asBits.payload = reinterpret_cast<int32_t>(ptr);
-    }
-
-    inline JSValue::JSValue(const JSCell* ptr)
-    {
-        u.asBits.tag = CellTag;
-        u.asBits.payload = reinterpret_cast<int32_t>(const_cast<JSCell*>(ptr));
-    }
-
-    inline JSValue::operator bool() const
-    {
-        return u.asBits.payload || tag() != CellTag;
-    }
-
-    inline bool JSValue::operator==(const JSValue& other) const
-    {
-        return u.asEncodedJSValue == other.u.asEncodedJSValue;
-    }
-
-    inline bool JSValue::operator!=(const JSValue& other) const
-    {
-        return u.asEncodedJSValue != other.u.asEncodedJSValue;
-    }
-
-    inline bool JSValue::isUndefined() const
-    {
-        return tag() == UndefinedTag;
-    }
-
-    inline bool JSValue::isNull() const
-    {
-        return tag() == NullTag;
-    }
-
-    inline bool JSValue::isUndefinedOrNull() const
-    {
-        return isUndefined() || isNull();
-    }
-
-    inline bool JSValue::isCell() const
-    {
-        return tag() == CellTag;
-    }
-
-    inline bool JSValue::isInt32() const
-    {
-        return tag() == Int32Tag;
-    }
-
-    inline bool JSValue::isUInt32() const
-    {
-        return tag() == Int32Tag && asInt32() > -1;
-    }
-
-    inline bool JSValue::isDouble() const
-    {
-        return tag() < LowestTag;
-    }
-
-    inline bool JSValue::isTrue() const
-    {
-        return tag() == TrueTag;
-    }
-
-    inline bool JSValue::isFalse() const
-    {
-        return tag() == FalseTag;
-    }
-
-    inline uint32_t JSValue::tag() const
-    {
-        return u.asBits.tag;
-    }
-    
-    inline int32_t JSValue::payload() const
-    {
-        return u.asBits.payload;
-    }
-    
-    inline int32_t JSValue::asInt32() const
-    {
-        ASSERT(isInt32());
-        return u.asBits.payload;
-    }
-    
-    inline uint32_t JSValue::asUInt32() const
-    {
-        ASSERT(isUInt32());
-        return u.asBits.payload;
-    }
-    
-    inline double JSValue::asDouble() const
-    {
-        ASSERT(isDouble());
-        return u.asDouble;
-    }
-    
-    ALWAYS_INLINE JSCell* JSValue::asCell() const
-    {
-        ASSERT(isCell());
-        return reinterpret_cast<JSCell*>(u.asBits.payload);
-    }
-
-    inline JSValue::JSValue(ExecState* exec, double d)
-    {
-        const int32_t asInt32 = static_cast<int32_t>(d);
-        if (asInt32 != d || (!asInt32 && signbit(d))) { // true for -0.0
-            u.asDouble = d;
-            return;
-        }
-        *this = JSValue(exec, static_cast<int32_t>(d));
-    }
-
-    inline JSValue::JSValue(ExecState* exec, char i)
-    {
-        *this = JSValue(exec, static_cast<int32_t>(i));
-    }
-
-    inline JSValue::JSValue(ExecState* exec, unsigned char i)
-    {
-        *this = JSValue(exec, static_cast<int32_t>(i));
-    }
-
-    inline JSValue::JSValue(ExecState* exec, short i)
-    {
-        *this = JSValue(exec, static_cast<int32_t>(i));
-    }
-
-    inline JSValue::JSValue(ExecState* exec, unsigned short i)
-    {
-        *this = JSValue(exec, static_cast<int32_t>(i));
-    }
-
-    inline JSValue::JSValue(ExecState*, int i)
-    {
-        u.asBits.tag = Int32Tag;
-        u.asBits.payload = i;
-    }
-
-    inline JSValue::JSValue(ExecState* exec, unsigned i)
-    {
-        if (static_cast<int32_t>(i) < 0) {
-            *this = JSValue(exec, static_cast<double>(i));
-            return;
-        }
-        *this = JSValue(exec, static_cast<int32_t>(i));
-    }
-
-    inline JSValue::JSValue(ExecState* exec, long i)
-    {
-        if (static_cast<int32_t>(i) != i) {
-            *this = JSValue(exec, static_cast<double>(i));
-            return;
-        }
-        *this = JSValue(exec, static_cast<int32_t>(i));
-    }
-
-    inline JSValue::JSValue(ExecState* exec, unsigned long i)
-    {
-        if (static_cast<uint32_t>(i) != i) {
-            *this = JSValue(exec, static_cast<double>(i));
-            return;
-        }
-        *this = JSValue(exec, static_cast<uint32_t>(i));
-    }
-
-    inline JSValue::JSValue(ExecState* exec, long long i)
-    {
-        if (static_cast<int32_t>(i) != i) {
-            *this = JSValue(exec, static_cast<double>(i));
-            return;
-        }
-        *this = JSValue(exec, static_cast<int32_t>(i));
-    }
-
-    inline JSValue::JSValue(ExecState* exec, unsigned long long i)
-    {
-        if (static_cast<uint32_t>(i) != i) {
-            *this = JSValue(exec, static_cast<double>(i));
-            return;
-        }
-        *this = JSValue(exec, static_cast<uint32_t>(i));
-    }
-
-    inline JSValue::JSValue(JSGlobalData* globalData, double d)
-    {
-        const int32_t asInt32 = static_cast<int32_t>(d);
-        if (asInt32 != d || (!asInt32 && signbit(d))) { // true for -0.0
-            u.asDouble = d;
-            return;
-        }
-        *this = JSValue(globalData, static_cast<int32_t>(d));
-    }
-    
-    inline JSValue::JSValue(JSGlobalData*, int i)
-    {
-        u.asBits.tag = Int32Tag;
-        u.asBits.payload = i;
-    }
-    
-    inline JSValue::JSValue(JSGlobalData* globalData, unsigned i)
-    {
-        if (static_cast<int32_t>(i) < 0) {
-            *this = JSValue(globalData, static_cast<double>(i));
-            return;
-        }
-        *this = JSValue(globalData, static_cast<int32_t>(i));
-    }
-
-    inline bool JSValue::isNumber() const
-    {
-        return isInt32() || isDouble();
-    }
-
-    inline bool JSValue::isBoolean() const
-    {
-        return isTrue() || isFalse();
-    }
-
-    inline bool JSValue::getBoolean(bool& v) const
-    {
-        if (isTrue()) {
-            v = true;
-            return true;
-        }
-        if (isFalse()) {
-            v = false;
-            return true;
-        }
-        
-        return false;
-    }
-
-    inline bool JSValue::getBoolean() const
-    {
-        ASSERT(isBoolean());
-        return tag() == TrueTag;
-    }
-
-    inline double JSValue::uncheckedGetNumber() const
-    {
-        ASSERT(isNumber());
-        return isInt32() ? asInt32() : asDouble();
-    }
-
-    ALWAYS_INLINE JSValue JSValue::toJSNumber(ExecState* exec) const
-    {
-        return isNumber() ? asValue() : jsNumber(exec, this->toNumber(exec));
-    }
-
-    inline bool JSValue::getNumber(double& result) const
-    {
-        if (isInt32()) {
-            result = asInt32();
-            return true;
-        }
-        if (isDouble()) {
-            result = asDouble();
-            return true;
-        }
-        return false;
-    }
-
-#else // USE(JSVALUE32_64)
-
-    // JSValue member functions.
-    inline EncodedJSValue JSValue::encode(JSValue value)
-    {
-        return reinterpret_cast<EncodedJSValue>(value.m_ptr);
-    }
-
-    inline JSValue JSValue::decode(EncodedJSValue ptr)
-    {
-        return JSValue(reinterpret_cast<JSCell*>(ptr));
-    }
-
-    inline JSValue JSValue::makeImmediate(intptr_t value)
-    {
-        return JSValue(reinterpret_cast<JSCell*>(value));
-    }
-
-    inline intptr_t JSValue::immediateValue()
-    {
-        return reinterpret_cast<intptr_t>(m_ptr);
-    }
-    
-    // 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.
-    inline JSValue::JSValue()
-        : m_ptr(0)
-    {
-    }
-
-    // 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.
-    inline JSValue::JSValue(HashTableDeletedValueTag)
-        : m_ptr(reinterpret_cast<JSCell*>(0x4))
-    {
-    }
-
-    inline JSValue::JSValue(JSCell* ptr)
-        : m_ptr(ptr)
-    {
-    }
-
-    inline JSValue::JSValue(const JSCell* ptr)
-        : m_ptr(const_cast<JSCell*>(ptr))
-    {
-    }
-
-    inline JSValue::operator bool() const
-    {
-        return m_ptr;
-    }
-
-    inline bool JSValue::operator==(const JSValue& other) const
-    {
-        return m_ptr == other.m_ptr;
-    }
-
-    inline bool JSValue::operator!=(const JSValue& other) const
-    {
-        return m_ptr != other.m_ptr;
-    }
-
-    inline bool JSValue::isUndefined() const
-    {
-        return asValue() == jsUndefined();
-    }
-
-    inline bool JSValue::isNull() const
-    {
-        return asValue() == jsNull();
-    }
-#endif // USE(JSVALUE32_64)
-
 } // namespace JSC
 
 #endif // JSValue_h