JavaScriptCore/runtime/JSNumberCell.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 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 JSNumberCell_h
       
    24 #define JSNumberCell_h
       
    25 
       
    26 #include "CallFrame.h"
       
    27 #include "JSCell.h"
       
    28 #include "JSImmediate.h"
       
    29 #include "Collector.h"
       
    30 #include "UString.h"
       
    31 #include <stddef.h> // for size_t
       
    32 
       
    33 namespace JSC {
       
    34 
       
    35     extern const double NaN;
       
    36     extern const double Inf;
       
    37 
       
    38 #if USE(JSVALUE32)
       
    39     JSValue jsNumberCell(ExecState*, double);
       
    40 
       
    41     class Identifier;
       
    42     class JSCell;
       
    43     class JSObject;
       
    44     class JSString;
       
    45     class PropertySlot;
       
    46 
       
    47     struct ClassInfo;
       
    48     struct Instruction;
       
    49 
       
    50     class JSNumberCell : public JSCell {
       
    51         friend class JIT;
       
    52         friend JSValue jsNumberCell(JSGlobalData*, double);
       
    53         friend JSValue jsNumberCell(ExecState*, double);
       
    54 
       
    55     public:
       
    56         double value() const { return m_value; }
       
    57 
       
    58         virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const;
       
    59         virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue& value);
       
    60         virtual bool toBoolean(ExecState*) const;
       
    61         virtual double toNumber(ExecState*) const;
       
    62         virtual UString toString(ExecState*) const;
       
    63         virtual JSObject* toObject(ExecState*) const;
       
    64 
       
    65         virtual JSObject* toThisObject(ExecState*) const;
       
    66         virtual JSValue getJSNumber();
       
    67 
       
    68         void* operator new(size_t size, ExecState* exec)
       
    69         {
       
    70             return exec->heap()->allocateNumber(size);
       
    71         }
       
    72 
       
    73         void* operator new(size_t size, JSGlobalData* globalData)
       
    74         {
       
    75             return globalData->heap.allocateNumber(size);
       
    76         }
       
    77 
       
    78         static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(NumberType, OverridesGetOwnPropertySlot | NeedsThisConversion), AnonymousSlotCount); }
       
    79 
       
    80     private:
       
    81         JSNumberCell(JSGlobalData* globalData, double value)
       
    82             : JSCell(globalData->numberStructure.get())
       
    83             , m_value(value)
       
    84         {
       
    85         }
       
    86 
       
    87         JSNumberCell(ExecState* exec, double value)
       
    88             : JSCell(exec->globalData().numberStructure.get())
       
    89             , m_value(value)
       
    90         {
       
    91         }
       
    92 
       
    93         virtual bool getUInt32(uint32_t&) const;
       
    94 
       
    95         double m_value;
       
    96     };
       
    97 
       
    98     JSValue jsNumberCell(JSGlobalData*, double);
       
    99 
       
   100     inline bool isNumberCell(JSValue v)
       
   101     {
       
   102         return v.isCell() && v.asCell()->isNumber();
       
   103     }
       
   104 
       
   105     inline JSNumberCell* asNumberCell(JSValue v)
       
   106     {
       
   107         ASSERT(isNumberCell(v));
       
   108         return static_cast<JSNumberCell*>(v.asCell());
       
   109     }
       
   110 
       
   111     ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, ExecState* exec, double d)
       
   112     {
       
   113         *this = jsNumberCell(exec, d);
       
   114     }
       
   115 
       
   116     inline JSValue::JSValue(ExecState* exec, double d)
       
   117     {
       
   118         JSValue v = JSImmediate::from(d);
       
   119         *this = v ? v : jsNumberCell(exec, d);
       
   120     }
       
   121 
       
   122     inline JSValue::JSValue(ExecState* exec, int i)
       
   123     {
       
   124         JSValue v = JSImmediate::from(i);
       
   125         *this = v ? v : jsNumberCell(exec, i);
       
   126     }
       
   127 
       
   128     inline JSValue::JSValue(ExecState* exec, unsigned i)
       
   129     {
       
   130         JSValue v = JSImmediate::from(i);
       
   131         *this = v ? v : jsNumberCell(exec, i);
       
   132     }
       
   133 
       
   134     inline JSValue::JSValue(ExecState* exec, long i)
       
   135     {
       
   136         JSValue v = JSImmediate::from(i);
       
   137         *this = v ? v : jsNumberCell(exec, i);
       
   138     }
       
   139 
       
   140     inline JSValue::JSValue(ExecState* exec, unsigned long i)
       
   141     {
       
   142         JSValue v = JSImmediate::from(i);
       
   143         *this = v ? v : jsNumberCell(exec, i);
       
   144     }
       
   145 
       
   146     inline JSValue::JSValue(ExecState* exec, long long i)
       
   147     {
       
   148         JSValue v = JSImmediate::from(i);
       
   149         *this = v ? v : jsNumberCell(exec, static_cast<double>(i));
       
   150     }
       
   151 
       
   152     inline JSValue::JSValue(ExecState* exec, unsigned long long i)
       
   153     {
       
   154         JSValue v = JSImmediate::from(i);
       
   155         *this = v ? v : jsNumberCell(exec, static_cast<double>(i));
       
   156     }
       
   157 
       
   158     inline JSValue::JSValue(JSGlobalData* globalData, double d)
       
   159     {
       
   160         JSValue v = JSImmediate::from(d);
       
   161         *this = v ? v : jsNumberCell(globalData, d);
       
   162     }
       
   163 
       
   164     inline JSValue::JSValue(JSGlobalData* globalData, int i)
       
   165     {
       
   166         JSValue v = JSImmediate::from(i);
       
   167         *this = v ? v : jsNumberCell(globalData, i);
       
   168     }
       
   169 
       
   170     inline JSValue::JSValue(JSGlobalData* globalData, unsigned i)
       
   171     {
       
   172         JSValue v = JSImmediate::from(i);
       
   173         *this = v ? v : jsNumberCell(globalData, i);
       
   174     }
       
   175 
       
   176     inline bool JSValue::isDouble() const
       
   177     {
       
   178         return isNumberCell(asValue());
       
   179     }
       
   180 
       
   181     inline double JSValue::asDouble() const
       
   182     {
       
   183         return asNumberCell(asValue())->value();
       
   184     }
       
   185 
       
   186     inline bool JSValue::isNumber() const
       
   187     {
       
   188         return JSImmediate::isNumber(asValue()) || isDouble();
       
   189     }
       
   190 
       
   191     inline double JSValue::uncheckedGetNumber() const
       
   192     {
       
   193         ASSERT(isNumber());
       
   194         return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : asDouble();
       
   195     }
       
   196 
       
   197 #endif // USE(JSVALUE32)
       
   198 
       
   199 #if USE(JSVALUE64)
       
   200     ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, ExecState*, double d)
       
   201     {
       
   202         *this = JSImmediate::fromNumberOutsideIntegerRange(d);
       
   203     }
       
   204 
       
   205     inline JSValue::JSValue(ExecState*, double d)
       
   206     {
       
   207         JSValue v = JSImmediate::from(d);
       
   208         ASSERT(v);
       
   209         *this = v;
       
   210     }
       
   211 
       
   212     inline JSValue::JSValue(ExecState*, int i)
       
   213     {
       
   214         JSValue v = JSImmediate::from(i);
       
   215         ASSERT(v);
       
   216         *this = v;
       
   217     }
       
   218 
       
   219     inline JSValue::JSValue(ExecState*, unsigned i)
       
   220     {
       
   221         JSValue v = JSImmediate::from(i);
       
   222         ASSERT(v);
       
   223         *this = v;
       
   224     }
       
   225 
       
   226     inline JSValue::JSValue(ExecState*, long i)
       
   227     {
       
   228         JSValue v = JSImmediate::from(i);
       
   229         ASSERT(v);
       
   230         *this = v;
       
   231     }
       
   232 
       
   233     inline JSValue::JSValue(ExecState*, unsigned long i)
       
   234     {
       
   235         JSValue v = JSImmediate::from(i);
       
   236         ASSERT(v);
       
   237         *this = v;
       
   238     }
       
   239 
       
   240     inline JSValue::JSValue(ExecState*, long long i)
       
   241     {
       
   242         JSValue v = JSImmediate::from(static_cast<double>(i));
       
   243         ASSERT(v);
       
   244         *this = v;
       
   245     }
       
   246 
       
   247     inline JSValue::JSValue(ExecState*, unsigned long long i)
       
   248     {
       
   249         JSValue v = JSImmediate::from(static_cast<double>(i));
       
   250         ASSERT(v);
       
   251         *this = v;
       
   252     }
       
   253 
       
   254     inline JSValue::JSValue(JSGlobalData*, double d)
       
   255     {
       
   256         JSValue v = JSImmediate::from(d);
       
   257         ASSERT(v);
       
   258         *this = v;
       
   259     }
       
   260 
       
   261     inline JSValue::JSValue(JSGlobalData*, int i)
       
   262     {
       
   263         JSValue v = JSImmediate::from(i);
       
   264         ASSERT(v);
       
   265         *this = v;
       
   266     }
       
   267 
       
   268     inline JSValue::JSValue(JSGlobalData*, unsigned i)
       
   269     {
       
   270         JSValue v = JSImmediate::from(i);
       
   271         ASSERT(v);
       
   272         *this = v;
       
   273     }
       
   274 
       
   275     inline bool JSValue::isDouble() const
       
   276     {
       
   277         return JSImmediate::isDouble(asValue());
       
   278     }
       
   279 
       
   280     inline double JSValue::asDouble() const
       
   281     {
       
   282         return JSImmediate::doubleValue(asValue());
       
   283     }
       
   284 
       
   285     inline bool JSValue::isNumber() const
       
   286     {
       
   287         return JSImmediate::isNumber(asValue());
       
   288     }
       
   289 
       
   290     inline double JSValue::uncheckedGetNumber() const
       
   291     {
       
   292         ASSERT(isNumber());
       
   293         return JSImmediate::toDouble(asValue());
       
   294     }
       
   295 
       
   296 #endif // USE(JSVALUE64)
       
   297 
       
   298 #if USE(JSVALUE32) || USE(JSVALUE64)
       
   299 
       
   300     inline JSValue::JSValue(ExecState*, char i)
       
   301     {
       
   302         ASSERT(JSImmediate::from(i));
       
   303         *this = JSImmediate::from(i);
       
   304     }
       
   305 
       
   306     inline JSValue::JSValue(ExecState*, unsigned char i)
       
   307     {
       
   308         ASSERT(JSImmediate::from(i));
       
   309         *this = JSImmediate::from(i);
       
   310     }
       
   311 
       
   312     inline JSValue::JSValue(ExecState*, short i)
       
   313     {
       
   314         ASSERT(JSImmediate::from(i));
       
   315         *this = JSImmediate::from(i);
       
   316     }
       
   317 
       
   318     inline JSValue::JSValue(ExecState*, unsigned short i)
       
   319     {
       
   320         ASSERT(JSImmediate::from(i));
       
   321         *this = JSImmediate::from(i);
       
   322     }
       
   323 
       
   324     inline JSValue jsNaN(ExecState* exec)
       
   325     {
       
   326         return jsNumber(exec, NaN);
       
   327     }
       
   328 
       
   329     inline JSValue jsNaN(JSGlobalData* globalData)
       
   330     {
       
   331         return jsNumber(globalData, NaN);
       
   332     }
       
   333 
       
   334     // --- JSValue inlines ----------------------------
       
   335 
       
   336     ALWAYS_INLINE JSValue JSValue::toJSNumber(ExecState* exec) const
       
   337     {
       
   338         return isNumber() ? asValue() : jsNumber(exec, this->toNumber(exec));
       
   339     }
       
   340 
       
   341     inline bool JSValue::getNumber(double &result) const
       
   342     {
       
   343         if (isInt32())
       
   344             result = asInt32();
       
   345         else if (LIKELY(isDouble()))
       
   346             result = asDouble();
       
   347         else {
       
   348             ASSERT(!isNumber());
       
   349             return false;
       
   350         }
       
   351         return true;
       
   352     }
       
   353 
       
   354 #endif // USE(JSVALUE32) || USE(JSVALUE64)
       
   355 
       
   356 } // namespace JSC
       
   357 
       
   358 #endif // JSNumberCell_h