]>
git.saurik.com Git - apple/javascriptcore.git/blob - runtime/JSNumberCell.h
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.
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.
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.
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.
23 #ifndef JSNumberCell_h
24 #define JSNumberCell_h
26 #include "CallFrame.h"
28 #include "JSImmediate.h"
29 #include "Collector.h"
31 #include <stddef.h> // for size_t
35 extern const double NaN
;
36 extern const double Inf
;
38 JSValuePtr
jsNumberCell(ExecState
*, double);
40 #if !USE(ALTERNATE_JSIMMEDIATE)
51 class JSNumberCell
: public JSCell
{
53 friend JSValuePtr
jsNumberCell(JSGlobalData
*, double);
54 friend JSValuePtr
jsNumberCell(ExecState
*, double);
56 double value() const { return m_value
; }
58 virtual JSValuePtr
toPrimitive(ExecState
*, PreferredPrimitiveType
) const;
59 virtual bool getPrimitiveNumber(ExecState
*, double& number
, JSValuePtr
& 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;
65 virtual UString
toThisString(ExecState
*) const;
66 virtual JSObject
* toThisObject(ExecState
*) const;
67 virtual JSValuePtr
getJSNumber();
69 void* operator new(size_t size
, ExecState
* exec
)
71 #ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
72 return exec
->heap()->inlineAllocateNumber(size
);
74 return exec
->heap()->allocateNumber(size
);
78 void* operator new(size_t size
, JSGlobalData
* globalData
)
80 #ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
81 return globalData
->heap
.inlineAllocateNumber(size
);
83 return globalData
->heap
.allocateNumber(size
);
87 static PassRefPtr
<Structure
> createStructure(JSValuePtr proto
) { return Structure::create(proto
, TypeInfo(NumberType
, NeedsThisConversion
)); }
90 JSNumberCell(JSGlobalData
* globalData
, double value
)
91 : JSCell(globalData
->numberStructure
.get())
96 JSNumberCell(ExecState
* exec
, double value
)
97 : JSCell(exec
->globalData().numberStructure
.get())
102 virtual bool getUInt32(uint32_t&) const;
103 virtual bool getTruncatedInt32(int32_t&) const;
104 virtual bool getTruncatedUInt32(uint32_t&) const;
109 JSValuePtr
jsNumberCell(JSGlobalData
*, double);
111 inline bool isNumberCell(JSValuePtr v
)
113 return v
.isCell() && v
.asCell()->isNumber();
116 inline JSNumberCell
* asNumberCell(JSValuePtr v
)
118 ASSERT(isNumberCell(v
));
119 return static_cast<JSNumberCell
*>(v
.asCell());
122 ALWAYS_INLINE JSValuePtr
jsNumber(ExecState
* exec
, double d
)
124 JSValuePtr v
= JSImmediate::from(d
);
125 return v
? v
: jsNumberCell(exec
, d
);
128 ALWAYS_INLINE JSValuePtr
jsNumber(ExecState
* exec
, int i
)
130 JSValuePtr v
= JSImmediate::from(i
);
131 return v
? v
: jsNumberCell(exec
, i
);
134 ALWAYS_INLINE JSValuePtr
jsNumber(ExecState
* exec
, unsigned i
)
136 JSValuePtr v
= JSImmediate::from(i
);
137 return v
? v
: jsNumberCell(exec
, i
);
140 ALWAYS_INLINE JSValuePtr
jsNumber(ExecState
* exec
, long i
)
142 JSValuePtr v
= JSImmediate::from(i
);
143 return v
? v
: jsNumberCell(exec
, i
);
146 ALWAYS_INLINE JSValuePtr
jsNumber(ExecState
* exec
, unsigned long i
)
148 JSValuePtr v
= JSImmediate::from(i
);
149 return v
? v
: jsNumberCell(exec
, i
);
152 ALWAYS_INLINE JSValuePtr
jsNumber(ExecState
* exec
, long long i
)
154 JSValuePtr v
= JSImmediate::from(i
);
155 return v
? v
: jsNumberCell(exec
, static_cast<double>(i
));
158 ALWAYS_INLINE JSValuePtr
jsNumber(ExecState
* exec
, unsigned long long i
)
160 JSValuePtr v
= JSImmediate::from(i
);
161 return v
? v
: jsNumberCell(exec
, static_cast<double>(i
));
164 ALWAYS_INLINE JSValuePtr
jsNumber(JSGlobalData
* globalData
, double d
)
166 JSValuePtr v
= JSImmediate::from(d
);
167 return v
? v
: jsNumberCell(globalData
, d
);
170 ALWAYS_INLINE JSValuePtr
jsNumber(JSGlobalData
* globalData
, int i
)
172 JSValuePtr v
= JSImmediate::from(i
);
173 return v
? v
: jsNumberCell(globalData
, i
);
176 ALWAYS_INLINE JSValuePtr
jsNumber(JSGlobalData
* globalData
, unsigned i
)
178 JSValuePtr v
= JSImmediate::from(i
);
179 return v
? v
: jsNumberCell(globalData
, i
);
182 ALWAYS_INLINE JSValuePtr
jsNumber(JSGlobalData
* globalData
, long i
)
184 JSValuePtr v
= JSImmediate::from(i
);
185 return v
? v
: jsNumberCell(globalData
, i
);
188 ALWAYS_INLINE JSValuePtr
jsNumber(JSGlobalData
* globalData
, unsigned long i
)
190 JSValuePtr v
= JSImmediate::from(i
);
191 return v
? v
: jsNumberCell(globalData
, i
);
194 ALWAYS_INLINE JSValuePtr
jsNumber(JSGlobalData
* globalData
, long long i
)
196 JSValuePtr v
= JSImmediate::from(i
);
197 return v
? v
: jsNumberCell(globalData
, static_cast<double>(i
));
200 ALWAYS_INLINE JSValuePtr
jsNumber(JSGlobalData
* globalData
, unsigned long long i
)
202 JSValuePtr v
= JSImmediate::from(i
);
203 return v
? v
: jsNumberCell(globalData
, static_cast<double>(i
));
206 inline bool JSValuePtr::isDoubleNumber() const
208 return isNumberCell(asValue());
211 inline double JSValuePtr::getDoubleNumber() const
213 return asNumberCell(asValue())->value();
216 inline bool JSValuePtr::isNumber() const
218 return JSImmediate::isNumber(asValue()) || isDoubleNumber();
221 inline double JSValuePtr::uncheckedGetNumber() const
224 return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : getDoubleNumber();
229 ALWAYS_INLINE JSValuePtr
jsNumber(ExecState
*, double d
)
231 JSValuePtr v
= JSImmediate::from(d
);
236 ALWAYS_INLINE JSValuePtr
jsNumber(ExecState
*, int i
)
238 JSValuePtr v
= JSImmediate::from(i
);
243 ALWAYS_INLINE JSValuePtr
jsNumber(ExecState
*, unsigned i
)
245 JSValuePtr v
= JSImmediate::from(i
);
250 ALWAYS_INLINE JSValuePtr
jsNumber(ExecState
*, long i
)
252 JSValuePtr v
= JSImmediate::from(i
);
257 ALWAYS_INLINE JSValuePtr
jsNumber(ExecState
*, unsigned long i
)
259 JSValuePtr v
= JSImmediate::from(i
);
264 ALWAYS_INLINE JSValuePtr
jsNumber(ExecState
*, long long i
)
266 JSValuePtr v
= JSImmediate::from(static_cast<double>(i
));
271 ALWAYS_INLINE JSValuePtr
jsNumber(ExecState
*, unsigned long long i
)
273 JSValuePtr v
= JSImmediate::from(static_cast<double>(i
));
278 ALWAYS_INLINE JSValuePtr
jsNumber(JSGlobalData
*, double d
)
280 JSValuePtr v
= JSImmediate::from(d
);
285 ALWAYS_INLINE JSValuePtr
jsNumber(JSGlobalData
*, int i
)
287 JSValuePtr v
= JSImmediate::from(i
);
292 ALWAYS_INLINE JSValuePtr
jsNumber(JSGlobalData
*, unsigned i
)
294 JSValuePtr v
= JSImmediate::from(i
);
299 ALWAYS_INLINE JSValuePtr
jsNumber(JSGlobalData
*, long i
)
301 JSValuePtr v
= JSImmediate::from(i
);
306 ALWAYS_INLINE JSValuePtr
jsNumber(JSGlobalData
*, unsigned long i
)
308 JSValuePtr v
= JSImmediate::from(i
);
313 ALWAYS_INLINE JSValuePtr
jsNumber(JSGlobalData
*, long long i
)
315 JSValuePtr v
= JSImmediate::from(static_cast<double>(i
));
320 ALWAYS_INLINE JSValuePtr
jsNumber(JSGlobalData
*, unsigned long long i
)
322 JSValuePtr v
= JSImmediate::from(static_cast<double>(i
));
327 inline bool JSValuePtr::isDoubleNumber() const
329 return JSImmediate::isDoubleNumber(asValue());
332 inline double JSValuePtr::getDoubleNumber() const
334 return JSImmediate::doubleValue(asValue());
337 inline bool JSValuePtr::isNumber() const
339 return JSImmediate::isNumber(asValue());
342 inline double JSValuePtr::uncheckedGetNumber() const
345 return JSImmediate::toDouble(asValue());
350 ALWAYS_INLINE JSValuePtr
jsNumber(ExecState
*, char i
)
352 ASSERT(JSImmediate::from(i
));
353 return JSImmediate::from(i
);
356 ALWAYS_INLINE JSValuePtr
jsNumber(ExecState
*, unsigned char i
)
358 ASSERT(JSImmediate::from(i
));
359 return JSImmediate::from(i
);
362 ALWAYS_INLINE JSValuePtr
jsNumber(ExecState
*, short i
)
364 ASSERT(JSImmediate::from(i
));
365 return JSImmediate::from(i
);
368 ALWAYS_INLINE JSValuePtr
jsNumber(ExecState
*, unsigned short i
)
370 ASSERT(JSImmediate::from(i
));
371 return JSImmediate::from(i
);
374 ALWAYS_INLINE JSValuePtr
jsNumber(JSGlobalData
*, short i
)
376 ASSERT(JSImmediate::from(i
));
377 return JSImmediate::from(i
);
380 ALWAYS_INLINE JSValuePtr
jsNumber(JSGlobalData
*, unsigned short i
)
382 ASSERT(JSImmediate::from(i
));
383 return JSImmediate::from(i
);
386 inline JSValuePtr
jsNaN(ExecState
* exec
)
388 return jsNumber(exec
, NaN
);
391 inline JSValuePtr
jsNaN(JSGlobalData
* globalData
)
393 return jsNumber(globalData
, NaN
);
396 // --- JSValue inlines ----------------------------
398 ALWAYS_INLINE JSValuePtr
JSValuePtr::toJSNumber(ExecState
* exec
) const
400 return isNumber() ? asValue() : jsNumber(exec
, this->toNumber(exec
));
403 inline bool JSValuePtr::getNumber(double &result
) const
406 result
= getInt32Fast();
407 else if (LIKELY(isDoubleNumber()))
408 result
= getDoubleNumber();
416 inline bool JSValuePtr::numberToInt32(int32_t& arg
)
419 arg
= getInt32Fast();
420 else if (LIKELY(isDoubleNumber()))
421 arg
= JSC::toInt32(getDoubleNumber());
429 inline bool JSValuePtr::numberToUInt32(uint32_t& arg
)
432 arg
= getUInt32Fast();
433 else if (LIKELY(isDoubleNumber()))
434 arg
= JSC::toUInt32(getDoubleNumber());
435 else if (isInt32Fast()) {
436 // FIXME: I think this case can be merged with the uint case; toUInt32SlowCase
437 // on a negative value is equivalent to simple static_casting.
439 arg
= toUInt32SlowCase(getInt32Fast(), ignored
);
449 #endif // JSNumberCell_h