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