JavaScriptCore:
[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         JSNumberCell(JSGlobalData* globalData)
88         : JSCell(globalData->numberStructure.get())
89         {
90         }
91
92     private:
93         JSNumberCell(JSGlobalData* globalData, double value)
94             : JSCell(globalData->numberStructure.get())
95             , m_value(value)
96         {
97         }
98
99         JSNumberCell(ExecState* exec, double value)
100             : JSCell(exec->globalData().numberStructure.get())
101             , m_value(value)
102         {
103         }
104
105         virtual bool getUInt32(uint32_t&) const;
106         virtual bool getTruncatedInt32(int32_t&) const;
107         virtual bool getTruncatedUInt32(uint32_t&) const;
108
109         double m_value;
110     };
111
112     extern const double NaN;
113     extern const double Inf;
114
115     JSNumberCell* asNumberCell(JSValue*);
116
117     JSValue* jsNumberCell(JSGlobalData*, double);
118     JSValue* jsNaN(JSGlobalData*);
119     JSValue* jsNumberCell(ExecState*, double);
120     JSValue* jsNaN(ExecState*);
121
122     inline JSNumberCell* asNumberCell(JSValue* value)
123     {
124         ASSERT(asCell(value)->isNumber());
125         return static_cast<JSNumberCell*>(asCell(value));
126     }
127
128     ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, double d)
129     {
130         JSValue* v = JSImmediate::from(d);
131         return v ? v : jsNumberCell(exec, d);
132     }
133
134     ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, short i)
135     {
136         JSValue* v = JSImmediate::from(i);
137         return v ? v : jsNumberCell(exec, i);
138     }
139
140     ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, unsigned short i)
141     {
142         JSValue* v = JSImmediate::from(i);
143         return v ? v : jsNumberCell(exec, i);
144     }
145
146     ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, int i)
147     {
148         JSValue* v = JSImmediate::from(i);
149         return v ? v : jsNumberCell(exec, i);
150     }
151
152     ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, unsigned i)
153     {
154         JSValue* v = JSImmediate::from(i);
155         return v ? v : jsNumberCell(exec, i);
156     }
157
158     ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, long i)
159     {
160         JSValue* v = JSImmediate::from(i);
161         return v ? v : jsNumberCell(exec, i);
162     }
163
164     ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, unsigned long i)
165     {
166         JSValue* v = JSImmediate::from(i);
167         return v ? v : jsNumberCell(exec, i);
168     }
169
170     ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, long long i)
171     {
172         JSValue* v = JSImmediate::from(i);
173         return v ? v : jsNumberCell(exec, static_cast<double>(i));
174     }
175
176     ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, unsigned long long i)
177     {
178         JSValue* v = JSImmediate::from(i);
179         return v ? v : jsNumberCell(exec, static_cast<double>(i));
180     }
181
182     ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, double d)
183     {
184         JSValue* v = JSImmediate::from(d);
185         return v ? v : jsNumberCell(globalData, d);
186     }
187
188     ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, short i)
189     {
190         JSValue* v = JSImmediate::from(i);
191         return v ? v : jsNumberCell(globalData, i);
192     }
193
194     ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, unsigned short i)
195     {
196         JSValue* v = JSImmediate::from(i);
197         return v ? v : jsNumberCell(globalData, i);
198     }
199
200     ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, int i)
201     {
202         JSValue* v = JSImmediate::from(i);
203         return v ? v : jsNumberCell(globalData, i);
204     }
205
206     ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, unsigned i)
207     {
208         JSValue* v = JSImmediate::from(i);
209         return v ? v : jsNumberCell(globalData, i);
210     }
211
212     ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, long i)
213     {
214         JSValue* v = JSImmediate::from(i);
215         return v ? v : jsNumberCell(globalData, i);
216     }
217
218     ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, unsigned long i)
219     {
220         JSValue* v = JSImmediate::from(i);
221         return v ? v : jsNumberCell(globalData, i);
222     }
223
224     ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, long long i)
225     {
226         JSValue* v = JSImmediate::from(i);
227         return v ? v : jsNumberCell(globalData, static_cast<double>(i));
228     }
229
230     ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, unsigned long long i)
231     {
232         JSValue* v = JSImmediate::from(i);
233         return v ? v : jsNumberCell(globalData, static_cast<double>(i));
234     }
235
236     // --- JSValue inlines ----------------------------
237
238     inline double JSValue::uncheckedGetNumber() const
239     {
240         ASSERT(JSImmediate::isImmediate(asValue()) || asCell()->isNumber());
241         return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : asNumberCell(asValue())->value();
242     }
243
244     inline int32_t JSNumberCell::toInt32() const
245     {
246         if (m_value >= -2147483648.0 && m_value < 2147483648.0)
247             return static_cast<int32_t>(m_value);
248         bool scratch;
249         return JSC::toInt32SlowCase(m_value, scratch);
250     }
251
252     inline uint32_t JSNumberCell::toUInt32() const
253     {
254         if (m_value >= 0.0 && m_value < 4294967296.0)
255             return static_cast<uint32_t>(m_value);
256         bool scratch;
257         return JSC::toUInt32SlowCase(m_value, scratch);
258     }
259
260     ALWAYS_INLINE JSValue* JSValue::toJSNumber(ExecState* exec) const
261     {
262         return JSImmediate::isNumber(asValue()) ? asValue() : jsNumber(exec, this->toNumber(exec));
263     }
264
265 } // namespace JSC
266
267 #endif // JSNumberCell_h