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