f39836245d53de669c61c87641ce2bec337159bd
[WebKit-https.git] / JavaScriptCore / runtime / JSNumberCell.h
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     class Identifier;
36     class JSCell;
37     class JSObject;
38     class JSString;
39     class PropertySlot;
40
41     struct ClassInfo;
42     struct Instruction;
43
44     class JSNumberCell : public JSCell {
45         friend class JIT;
46         friend JSValue* jsNumberCell(JSGlobalData*, double);
47         friend JSValue* jsNaN(JSGlobalData*);
48         friend JSValue* jsNumberCell(ExecState*, double);
49         friend JSValue* jsNaN(ExecState*);
50     public:
51         double value() const { return m_value; }
52
53         virtual JSValue* toPrimitive(ExecState*, PreferredPrimitiveType) const;
54         virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value);
55         virtual bool toBoolean(ExecState*) const;
56         virtual double toNumber(ExecState*) const;
57         virtual UString toString(ExecState*) const;
58         virtual JSObject* toObject(ExecState*) const;
59
60         virtual UString toThisString(ExecState*) const;
61         virtual JSObject* toThisObject(ExecState*) const;
62         virtual JSValue* getJSNumber();
63
64         int32_t toInt32() const;
65         uint32_t toUInt32() const;
66
67         void* operator new(size_t size, ExecState* exec)
68         {
69     #ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
70             return exec->heap()->inlineAllocateNumber(size);
71     #else
72             return exec->heap()->allocateNumber(size);
73     #endif
74         }
75
76         void* operator new(size_t size, JSGlobalData* globalData)
77         {
78     #ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
79             return globalData->heap.inlineAllocateNumber(size);
80     #else
81             return globalData->heap.allocateNumber(size);
82     #endif
83         }
84
85         static PassRefPtr<Structure> createStructure(JSValue* proto) { return Structure::create(proto, TypeInfo(NumberType, NeedsThisConversion)); }
86
87     private:
88         JSNumberCell(JSGlobalData* globalData, double value)
89             : JSCell(globalData->numberStructure.get())
90             , m_value(value)
91         {
92         }
93
94         JSNumberCell(ExecState* exec, double value)
95             : JSCell(exec->globalData().numberStructure.get())
96             , m_value(value)
97         {
98         }
99
100         virtual bool getUInt32(uint32_t&) const;
101         virtual bool getTruncatedInt32(int32_t&) const;
102         virtual bool getTruncatedUInt32(uint32_t&) const;
103
104         double m_value;
105     };
106
107     extern const double NaN;
108     extern const double Inf;
109
110     JSNumberCell* asNumberCell(JSValue*);
111
112     JSValue* jsNumberCell(JSGlobalData*, double);
113     JSValue* jsNaN(JSGlobalData*);
114     JSValue* jsNumberCell(ExecState*, double);
115     JSValue* jsNaN(ExecState*);
116
117     inline JSNumberCell* asNumberCell(JSValue* value)
118     {
119         ASSERT(asCell(value)->isNumber());
120         return static_cast<JSNumberCell*>(asCell(value));
121     }
122
123     ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, double d)
124     {
125         JSValue* v = JSImmediate::from(d);
126         return v ? v : jsNumberCell(exec, d);
127     }
128
129     ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, short i)
130     {
131         JSValue* v = JSImmediate::from(i);
132         return v ? v : jsNumberCell(exec, i);
133     }
134
135     ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, unsigned short i)
136     {
137         JSValue* v = JSImmediate::from(i);
138         return v ? v : jsNumberCell(exec, i);
139     }
140
141     ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, int i)
142     {
143         JSValue* v = JSImmediate::from(i);
144         return v ? v : jsNumberCell(exec, i);
145     }
146
147     ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, unsigned i)
148     {
149         JSValue* v = JSImmediate::from(i);
150         return v ? v : jsNumberCell(exec, i);
151     }
152
153     ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, long i)
154     {
155         JSValue* v = JSImmediate::from(i);
156         return v ? v : jsNumberCell(exec, i);
157     }
158
159     ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, unsigned long i)
160     {
161         JSValue* v = JSImmediate::from(i);
162         return v ? v : jsNumberCell(exec, i);
163     }
164
165     ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, long long i)
166     {
167         JSValue* v = JSImmediate::from(i);
168         return v ? v : jsNumberCell(exec, static_cast<double>(i));
169     }
170
171     ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, unsigned long long i)
172     {
173         JSValue* v = JSImmediate::from(i);
174         return v ? v : jsNumberCell(exec, static_cast<double>(i));
175     }
176
177     ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, double d)
178     {
179         JSValue* v = JSImmediate::from(d);
180         return v ? v : jsNumberCell(globalData, d);
181     }
182
183     ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, short i)
184     {
185         JSValue* v = JSImmediate::from(i);
186         return v ? v : jsNumberCell(globalData, i);
187     }
188
189     ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, unsigned short i)
190     {
191         JSValue* v = JSImmediate::from(i);
192         return v ? v : jsNumberCell(globalData, i);
193     }
194
195     ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, int i)
196     {
197         JSValue* v = JSImmediate::from(i);
198         return v ? v : jsNumberCell(globalData, i);
199     }
200
201     ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, unsigned i)
202     {
203         JSValue* v = JSImmediate::from(i);
204         return v ? v : jsNumberCell(globalData, i);
205     }
206
207     ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, long i)
208     {
209         JSValue* v = JSImmediate::from(i);
210         return v ? v : jsNumberCell(globalData, i);
211     }
212
213     ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, unsigned long i)
214     {
215         JSValue* v = JSImmediate::from(i);
216         return v ? v : jsNumberCell(globalData, i);
217     }
218
219     ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, long long i)
220     {
221         JSValue* v = JSImmediate::from(i);
222         return v ? v : jsNumberCell(globalData, static_cast<double>(i));
223     }
224
225     ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, unsigned long long i)
226     {
227         JSValue* v = JSImmediate::from(i);
228         return v ? v : jsNumberCell(globalData, static_cast<double>(i));
229     }
230
231     // --- JSValue inlines ----------------------------
232
233     inline double JSValue::uncheckedGetNumber() const
234     {
235         ASSERT(JSImmediate::isImmediate(asValue()) || asCell()->isNumber());
236         return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : asNumberCell(asValue())->value();
237     }
238
239     inline int32_t JSNumberCell::toInt32() const
240     {
241         if (m_value >= -2147483648.0 && m_value < 2147483648.0)
242             return static_cast<int32_t>(m_value);
243         bool scratch;
244         return JSC::toInt32SlowCase(m_value, scratch);
245     }
246
247     inline uint32_t JSNumberCell::toUInt32() const
248     {
249         if (m_value >= 0.0 && m_value < 4294967296.0)
250             return static_cast<uint32_t>(m_value);
251         bool scratch;
252         return JSC::toUInt32SlowCase(m_value, scratch);
253     }
254
255     ALWAYS_INLINE JSValue* JSValue::toJSNumber(ExecState* exec) const
256     {
257         return JSImmediate::isNumber(asValue()) ? asValue() : jsNumber(exec, this->toNumber(exec));
258     }
259
260 } // namespace JSC
261
262 #endif // JSNumberCell_h