]> git.saurik.com Git - apple/javascriptcore.git/blame - runtime/JSNumberCell.h
JavaScriptCore-521.tar.gz
[apple/javascriptcore.git] / runtime / JSNumberCell.h
CommitLineData
9dae56ea
A
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
33namespace JSC {
34
35 extern const double NaN;
36 extern const double Inf;
37
38 JSValuePtr jsNumberCell(ExecState*, double);
39
40#if !USE(ALTERNATE_JSIMMEDIATE)
41
42 class Identifier;
43 class JSCell;
44 class JSObject;
45 class JSString;
46 class PropertySlot;
47
48 struct ClassInfo;
49 struct Instruction;
50
51 class JSNumberCell : public JSCell {
52 friend class JIT;
53 friend JSValuePtr jsNumberCell(JSGlobalData*, double);
54 friend JSValuePtr jsNumberCell(ExecState*, double);
55 public:
56 double value() const { return m_value; }
57
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;
64
65 virtual UString toThisString(ExecState*) const;
66 virtual JSObject* toThisObject(ExecState*) const;
67 virtual JSValuePtr getJSNumber();
68
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
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
87 static PassRefPtr<Structure> createStructure(JSValuePtr proto) { return Structure::create(proto, TypeInfo(NumberType, NeedsThisConversion)); }
88
89 private:
90 JSNumberCell(JSGlobalData* globalData, double value)
91 : JSCell(globalData->numberStructure.get())
92 , m_value(value)
93 {
94 }
95
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 virtual bool getTruncatedInt32(int32_t&) const;
104 virtual bool getTruncatedUInt32(uint32_t&) const;
105
106 double m_value;
107 };
108
109 JSValuePtr jsNumberCell(JSGlobalData*, double);
110
111 inline bool isNumberCell(JSValuePtr v)
112 {
113 return v.isCell() && v.asCell()->isNumber();
114 }
115
116 inline JSNumberCell* asNumberCell(JSValuePtr v)
117 {
118 ASSERT(isNumberCell(v));
119 return static_cast<JSNumberCell*>(v.asCell());
120 }
121
122 ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, double d)
123 {
124 JSValuePtr v = JSImmediate::from(d);
125 return v ? v : jsNumberCell(exec, d);
126 }
127
128 ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, int i)
129 {
130 JSValuePtr v = JSImmediate::from(i);
131 return v ? v : jsNumberCell(exec, i);
132 }
133
134 ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, unsigned i)
135 {
136 JSValuePtr v = JSImmediate::from(i);
137 return v ? v : jsNumberCell(exec, i);
138 }
139
140 ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, long i)
141 {
142 JSValuePtr v = JSImmediate::from(i);
143 return v ? v : jsNumberCell(exec, i);
144 }
145
146 ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, unsigned long i)
147 {
148 JSValuePtr v = JSImmediate::from(i);
149 return v ? v : jsNumberCell(exec, i);
150 }
151
152 ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, long long i)
153 {
154 JSValuePtr v = JSImmediate::from(i);
155 return v ? v : jsNumberCell(exec, static_cast<double>(i));
156 }
157
158 ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, unsigned long long i)
159 {
160 JSValuePtr v = JSImmediate::from(i);
161 return v ? v : jsNumberCell(exec, static_cast<double>(i));
162 }
163
164 ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, double d)
165 {
166 JSValuePtr v = JSImmediate::from(d);
167 return v ? v : jsNumberCell(globalData, d);
168 }
169
170 ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, int i)
171 {
172 JSValuePtr v = JSImmediate::from(i);
173 return v ? v : jsNumberCell(globalData, i);
174 }
175
176 ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, unsigned i)
177 {
178 JSValuePtr v = JSImmediate::from(i);
179 return v ? v : jsNumberCell(globalData, i);
180 }
181
182 ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, long i)
183 {
184 JSValuePtr v = JSImmediate::from(i);
185 return v ? v : jsNumberCell(globalData, i);
186 }
187
188 ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, unsigned long i)
189 {
190 JSValuePtr v = JSImmediate::from(i);
191 return v ? v : jsNumberCell(globalData, i);
192 }
193
194 ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, long long i)
195 {
196 JSValuePtr v = JSImmediate::from(i);
197 return v ? v : jsNumberCell(globalData, static_cast<double>(i));
198 }
199
200 ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, unsigned long long i)
201 {
202 JSValuePtr v = JSImmediate::from(i);
203 return v ? v : jsNumberCell(globalData, static_cast<double>(i));
204 }
205
206 inline bool JSValuePtr::isDoubleNumber() const
207 {
208 return isNumberCell(asValue());
209 }
210
211 inline double JSValuePtr::getDoubleNumber() const
212 {
213 return asNumberCell(asValue())->value();
214 }
215
216 inline bool JSValuePtr::isNumber() const
217 {
218 return JSImmediate::isNumber(asValue()) || isDoubleNumber();
219 }
220
221 inline double JSValuePtr::uncheckedGetNumber() const
222 {
223 ASSERT(isNumber());
224 return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : getDoubleNumber();
225 }
226
227#else
228
229 ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, double d)
230 {
231 JSValuePtr v = JSImmediate::from(d);
232 ASSERT(v);
233 return v;
234 }
235
236 ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, int i)
237 {
238 JSValuePtr v = JSImmediate::from(i);
239 ASSERT(v);
240 return v;
241 }
242
243 ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, unsigned i)
244 {
245 JSValuePtr v = JSImmediate::from(i);
246 ASSERT(v);
247 return v;
248 }
249
250 ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, long i)
251 {
252 JSValuePtr v = JSImmediate::from(i);
253 ASSERT(v);
254 return v;
255 }
256
257 ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, unsigned long i)
258 {
259 JSValuePtr v = JSImmediate::from(i);
260 ASSERT(v);
261 return v;
262 }
263
264 ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, long long i)
265 {
266 JSValuePtr v = JSImmediate::from(static_cast<double>(i));
267 ASSERT(v);
268 return v;
269 }
270
271 ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, unsigned long long i)
272 {
273 JSValuePtr v = JSImmediate::from(static_cast<double>(i));
274 ASSERT(v);
275 return v;
276 }
277
278 ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, double d)
279 {
280 JSValuePtr v = JSImmediate::from(d);
281 ASSERT(v);
282 return v;
283 }
284
285 ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, int i)
286 {
287 JSValuePtr v = JSImmediate::from(i);
288 ASSERT(v);
289 return v;
290 }
291
292 ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, unsigned i)
293 {
294 JSValuePtr v = JSImmediate::from(i);
295 ASSERT(v);
296 return v;
297 }
298
299 ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, long i)
300 {
301 JSValuePtr v = JSImmediate::from(i);
302 ASSERT(v);
303 return v;
304 }
305
306 ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, unsigned long i)
307 {
308 JSValuePtr v = JSImmediate::from(i);
309 ASSERT(v);
310 return v;
311 }
312
313 ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, long long i)
314 {
315 JSValuePtr v = JSImmediate::from(static_cast<double>(i));
316 ASSERT(v);
317 return v;
318 }
319
320 ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, unsigned long long i)
321 {
322 JSValuePtr v = JSImmediate::from(static_cast<double>(i));
323 ASSERT(v);
324 return v;
325 }
326
327 inline bool JSValuePtr::isDoubleNumber() const
328 {
329 return JSImmediate::isDoubleNumber(asValue());
330 }
331
332 inline double JSValuePtr::getDoubleNumber() const
333 {
334 return JSImmediate::doubleValue(asValue());
335 }
336
337 inline bool JSValuePtr::isNumber() const
338 {
339 return JSImmediate::isNumber(asValue());
340 }
341
342 inline double JSValuePtr::uncheckedGetNumber() const
343 {
344 ASSERT(isNumber());
345 return JSImmediate::toDouble(asValue());
346 }
347
348#endif
349
350 ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, char i)
351 {
352 ASSERT(JSImmediate::from(i));
353 return JSImmediate::from(i);
354 }
355
356 ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, unsigned char i)
357 {
358 ASSERT(JSImmediate::from(i));
359 return JSImmediate::from(i);
360 }
361
362 ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, short i)
363 {
364 ASSERT(JSImmediate::from(i));
365 return JSImmediate::from(i);
366 }
367
368 ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, unsigned short i)
369 {
370 ASSERT(JSImmediate::from(i));
371 return JSImmediate::from(i);
372 }
373
374 ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, short i)
375 {
376 ASSERT(JSImmediate::from(i));
377 return JSImmediate::from(i);
378 }
379
380 ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, unsigned short i)
381 {
382 ASSERT(JSImmediate::from(i));
383 return JSImmediate::from(i);
384 }
385
386 inline JSValuePtr jsNaN(ExecState* exec)
387 {
388 return jsNumber(exec, NaN);
389 }
390
391 inline JSValuePtr jsNaN(JSGlobalData* globalData)
392 {
393 return jsNumber(globalData, NaN);
394 }
395
396 // --- JSValue inlines ----------------------------
397
398 ALWAYS_INLINE JSValuePtr JSValuePtr::toJSNumber(ExecState* exec) const
399 {
400 return isNumber() ? asValue() : jsNumber(exec, this->toNumber(exec));
401 }
402
403 inline bool JSValuePtr::getNumber(double &result) const
404 {
405 if (isInt32Fast())
406 result = getInt32Fast();
407 else if (LIKELY(isDoubleNumber()))
408 result = getDoubleNumber();
409 else {
410 ASSERT(!isNumber());
411 return false;
412 }
413 return true;
414 }
415
416 inline bool JSValuePtr::numberToInt32(int32_t& arg)
417 {
418 if (isInt32Fast())
419 arg = getInt32Fast();
420 else if (LIKELY(isDoubleNumber()))
421 arg = JSC::toInt32(getDoubleNumber());
422 else {
423 ASSERT(!isNumber());
424 return false;
425 }
426 return true;
427 }
428
429 inline bool JSValuePtr::numberToUInt32(uint32_t& arg)
430 {
431 if (isUInt32Fast())
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.
438 bool ignored;
439 arg = toUInt32SlowCase(getInt32Fast(), ignored);
440 } else {
441 ASSERT(!isNumber());
442 return false;
443 }
444 return true;
445 }
446
447} // namespace JSC
448
449#endif // JSNumberCell_h