Rubber-stamped by Brady Eidson.
[webbrowser.git] / JavaScriptCore / runtime / JSNumberCell.h
blobe9e247088a3b4484d491894b0c837a9a788e402a
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.
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"
27 #include "JSCell.h"
28 #include "JSImmediate.h"
29 #include "Collector.h"
30 #include "UString.h"
31 #include <stddef.h> // for size_t
33 namespace JSC {
35 extern const double NaN;
36 extern const double Inf;
38 #if USE(JSVALUE32)
39 JSValue jsNumberCell(ExecState*, double);
41 class Identifier;
42 class JSCell;
43 class JSObject;
44 class JSString;
45 class PropertySlot;
47 struct ClassInfo;
48 struct Instruction;
50 class JSNumberCell : public JSCell {
51 friend class JIT;
52 friend JSValue jsNumberCell(JSGlobalData*, double);
53 friend JSValue jsNumberCell(ExecState*, double);
55 public:
56 double value() const { return m_value; }
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;
65 virtual UString toThisString(ExecState*) const;
66 virtual JSObject* toThisObject(ExecState*) const;
67 virtual JSValue getJSNumber();
69 void* operator new(size_t size, ExecState* exec)
71 return exec->heap()->allocateNumber(size);
74 void* operator new(size_t size, JSGlobalData* globalData)
76 return globalData->heap.allocateNumber(size);
79 static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(NumberType, OverridesGetOwnPropertySlot | NeedsThisConversion)); }
81 private:
82 JSNumberCell(JSGlobalData* globalData, double value)
83 : JSCell(globalData->numberStructure.get())
84 , m_value(value)
88 JSNumberCell(ExecState* exec, double value)
89 : JSCell(exec->globalData().numberStructure.get())
90 , m_value(value)
94 virtual bool getUInt32(uint32_t&) const;
96 double m_value;
99 JSValue jsNumberCell(JSGlobalData*, double);
101 inline bool isNumberCell(JSValue v)
103 return v.isCell() && v.asCell()->isNumber();
106 inline JSNumberCell* asNumberCell(JSValue v)
108 ASSERT(isNumberCell(v));
109 return static_cast<JSNumberCell*>(v.asCell());
112 ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, ExecState* exec, double d)
114 *this = jsNumberCell(exec, d);
117 inline JSValue::JSValue(ExecState* exec, double d)
119 JSValue v = JSImmediate::from(d);
120 *this = v ? v : jsNumberCell(exec, d);
123 inline JSValue::JSValue(ExecState* exec, int i)
125 JSValue v = JSImmediate::from(i);
126 *this = v ? v : jsNumberCell(exec, i);
129 inline JSValue::JSValue(ExecState* exec, unsigned i)
131 JSValue v = JSImmediate::from(i);
132 *this = v ? v : jsNumberCell(exec, i);
135 inline JSValue::JSValue(ExecState* exec, long i)
137 JSValue v = JSImmediate::from(i);
138 *this = v ? v : jsNumberCell(exec, i);
141 inline JSValue::JSValue(ExecState* exec, unsigned long i)
143 JSValue v = JSImmediate::from(i);
144 *this = v ? v : jsNumberCell(exec, i);
147 inline JSValue::JSValue(ExecState* exec, long long i)
149 JSValue v = JSImmediate::from(i);
150 *this = v ? v : jsNumberCell(exec, static_cast<double>(i));
153 inline JSValue::JSValue(ExecState* exec, unsigned long long i)
155 JSValue v = JSImmediate::from(i);
156 *this = v ? v : jsNumberCell(exec, static_cast<double>(i));
159 inline JSValue::JSValue(JSGlobalData* globalData, double d)
161 JSValue v = JSImmediate::from(d);
162 *this = v ? v : jsNumberCell(globalData, d);
165 inline JSValue::JSValue(JSGlobalData* globalData, int i)
167 JSValue v = JSImmediate::from(i);
168 *this = v ? v : jsNumberCell(globalData, i);
171 inline JSValue::JSValue(JSGlobalData* globalData, unsigned i)
173 JSValue v = JSImmediate::from(i);
174 *this = v ? v : jsNumberCell(globalData, i);
177 inline bool JSValue::isDouble() const
179 return isNumberCell(asValue());
182 inline double JSValue::asDouble() const
184 return asNumberCell(asValue())->value();
187 inline bool JSValue::isNumber() const
189 return JSImmediate::isNumber(asValue()) || isDouble();
192 inline double JSValue::uncheckedGetNumber() const
194 ASSERT(isNumber());
195 return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : asDouble();
198 #endif // USE(JSVALUE32)
200 #if USE(JSVALUE64)
201 ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, ExecState*, double d)
203 *this = JSImmediate::fromNumberOutsideIntegerRange(d);
206 inline JSValue::JSValue(ExecState*, double d)
208 JSValue v = JSImmediate::from(d);
209 ASSERT(v);
210 *this = v;
213 inline JSValue::JSValue(ExecState*, int i)
215 JSValue v = JSImmediate::from(i);
216 ASSERT(v);
217 *this = v;
220 inline JSValue::JSValue(ExecState*, unsigned i)
222 JSValue v = JSImmediate::from(i);
223 ASSERT(v);
224 *this = v;
227 inline JSValue::JSValue(ExecState*, long i)
229 JSValue v = JSImmediate::from(i);
230 ASSERT(v);
231 *this = v;
234 inline JSValue::JSValue(ExecState*, unsigned long i)
236 JSValue v = JSImmediate::from(i);
237 ASSERT(v);
238 *this = v;
241 inline JSValue::JSValue(ExecState*, long long i)
243 JSValue v = JSImmediate::from(static_cast<double>(i));
244 ASSERT(v);
245 *this = v;
248 inline JSValue::JSValue(ExecState*, unsigned long long i)
250 JSValue v = JSImmediate::from(static_cast<double>(i));
251 ASSERT(v);
252 *this = v;
255 inline JSValue::JSValue(JSGlobalData*, double d)
257 JSValue v = JSImmediate::from(d);
258 ASSERT(v);
259 *this = v;
262 inline JSValue::JSValue(JSGlobalData*, int i)
264 JSValue v = JSImmediate::from(i);
265 ASSERT(v);
266 *this = v;
269 inline JSValue::JSValue(JSGlobalData*, unsigned i)
271 JSValue v = JSImmediate::from(i);
272 ASSERT(v);
273 *this = v;
276 inline bool JSValue::isDouble() const
278 return JSImmediate::isDouble(asValue());
281 inline double JSValue::asDouble() const
283 return JSImmediate::doubleValue(asValue());
286 inline bool JSValue::isNumber() const
288 return JSImmediate::isNumber(asValue());
291 inline double JSValue::uncheckedGetNumber() const
293 ASSERT(isNumber());
294 return JSImmediate::toDouble(asValue());
297 #endif // USE(JSVALUE64)
299 #if USE(JSVALUE32) || USE(JSVALUE64)
301 inline JSValue::JSValue(ExecState*, char i)
303 ASSERT(JSImmediate::from(i));
304 *this = JSImmediate::from(i);
307 inline JSValue::JSValue(ExecState*, unsigned char i)
309 ASSERT(JSImmediate::from(i));
310 *this = JSImmediate::from(i);
313 inline JSValue::JSValue(ExecState*, short i)
315 ASSERT(JSImmediate::from(i));
316 *this = JSImmediate::from(i);
319 inline JSValue::JSValue(ExecState*, unsigned short i)
321 ASSERT(JSImmediate::from(i));
322 *this = JSImmediate::from(i);
325 inline JSValue jsNaN(ExecState* exec)
327 return jsNumber(exec, NaN);
330 inline JSValue jsNaN(JSGlobalData* globalData)
332 return jsNumber(globalData, NaN);
335 // --- JSValue inlines ----------------------------
337 ALWAYS_INLINE JSValue JSValue::toJSNumber(ExecState* exec) const
339 return isNumber() ? asValue() : jsNumber(exec, this->toNumber(exec));
342 inline bool JSValue::getNumber(double &result) const
344 if (isInt32())
345 result = asInt32();
346 else if (LIKELY(isDouble()))
347 result = asDouble();
348 else {
349 ASSERT(!isNumber());
350 return false;
352 return true;
355 #endif // USE(JSVALUE32) || USE(JSVALUE64)
357 } // namespace JSC
359 #endif // JSNumberCell_h