source: webkit/trunk/JavaScriptCore/runtime/JSNumberCell.h@ 43383

Last change on this file since 43383 was 43165, checked in by [email protected], 16 years ago

Fix the 64-bit build.

  • API/APICast.h:

(toJS):
(toRef):

  • runtime/JSNumberCell.cpp:

(JSC::jsAPIMangledNumber):

  • runtime/JSNumberCell.h:
  • Property svn:eol-style set to native
File size: 12.7 KB
Line 
1/*
2 * Copyright (C) 1999-2001 Harri Porten ([email protected])
3 * Copyright (C) 2001 Peter Kelly ([email protected])
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 JSValue jsNumberCell(ExecState*, double);
39 JSValue jsAPIMangledNumber(ExecState*, double);
40
41#if !USE(ALTERNATE_JSIMMEDIATE)
42
43 class Identifier;
44 class JSCell;
45 class JSObject;
46 class JSString;
47 class PropertySlot;
48
49 struct ClassInfo;
50 struct Instruction;
51
52 class JSNumberCell : public JSCell {
53 friend class JIT;
54 friend JSValue jsNumberCell(JSGlobalData*, double);
55 friend JSValue jsNumberCell(ExecState*, double);
56 friend JSValue jsAPIMangledNumber(ExecState*, double);
57 public:
58 double value() const { return m_value; }
59
60 virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const;
61 virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue& value);
62 virtual bool toBoolean(ExecState*) const;
63 virtual double toNumber(ExecState*) const;
64 virtual UString toString(ExecState*) const;
65 virtual JSObject* toObject(ExecState*) const;
66
67 virtual UString toThisString(ExecState*) const;
68 virtual JSObject* toThisObject(ExecState*) const;
69 virtual JSValue getJSNumber();
70
71 static const uintptr_t JSAPIMangledMagicNumber = 0xbbadbeef;
72 bool isAPIMangledNumber() const { return m_structure == reinterpret_cast<Structure*>(JSAPIMangledMagicNumber); }
73
74 void* operator new(size_t size, ExecState* exec)
75 {
76 #ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
77 return exec->heap()->inlineAllocateNumber(size);
78 #else
79 return exec->heap()->allocateNumber(size);
80 #endif
81 }
82
83 void* operator new(size_t size, JSGlobalData* globalData)
84 {
85 #ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
86 return globalData->heap.inlineAllocateNumber(size);
87 #else
88 return globalData->heap.allocateNumber(size);
89 #endif
90 }
91
92 static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(NumberType, NeedsThisConversion)); }
93
94 private:
95 JSNumberCell(JSGlobalData* globalData, double value)
96 : JSCell(globalData->numberStructure.get())
97 , m_value(value)
98 {
99 }
100
101 JSNumberCell(ExecState* exec, double value)
102 : JSCell(exec->globalData().numberStructure.get())
103 , m_value(value)
104 {
105 }
106
107 enum APIMangledTag { APIMangled };
108 JSNumberCell(APIMangledTag, double value)
109 : JSCell(reinterpret_cast<Structure*>(JSAPIMangledMagicNumber))
110 , m_value(value)
111 {
112 }
113
114 virtual bool getUInt32(uint32_t&) const;
115 virtual bool getTruncatedInt32(int32_t&) const;
116 virtual bool getTruncatedUInt32(uint32_t&) const;
117
118 double m_value;
119 };
120
121 JSValue jsNumberCell(JSGlobalData*, double);
122
123 inline bool isNumberCell(JSValue v)
124 {
125 return v.isCell() && v.asCell()->isNumber();
126 }
127
128 inline JSNumberCell* asNumberCell(JSValue v)
129 {
130 ASSERT(isNumberCell(v));
131 return static_cast<JSNumberCell*>(v.asCell());
132 }
133
134
135 inline JSValue::JSValue(ExecState* exec, double d)
136 {
137 JSValue v = JSImmediate::from(d);
138 *this = v ? v : jsNumberCell(exec, d);
139 }
140
141 inline JSValue::JSValue(ExecState* exec, int i)
142 {
143 JSValue v = JSImmediate::from(i);
144 *this = v ? v : jsNumberCell(exec, i);
145 }
146
147 inline JSValue::JSValue(ExecState* exec, unsigned i)
148 {
149 JSValue v = JSImmediate::from(i);
150 *this = v ? v : jsNumberCell(exec, i);
151 }
152
153 inline JSValue::JSValue(ExecState* exec, long i)
154 {
155 JSValue v = JSImmediate::from(i);
156 *this = v ? v : jsNumberCell(exec, i);
157 }
158
159 inline JSValue::JSValue(ExecState* exec, unsigned long i)
160 {
161 JSValue v = JSImmediate::from(i);
162 *this = v ? v : jsNumberCell(exec, i);
163 }
164
165 inline JSValue::JSValue(ExecState* exec, long long i)
166 {
167 JSValue v = JSImmediate::from(i);
168 *this = v ? v : jsNumberCell(exec, static_cast<double>(i));
169 }
170
171 inline JSValue::JSValue(ExecState* exec, unsigned long long i)
172 {
173 JSValue v = JSImmediate::from(i);
174 *this = v ? v : jsNumberCell(exec, static_cast<double>(i));
175 }
176
177 inline JSValue::JSValue(JSGlobalData* globalData, double d)
178 {
179 JSValue v = JSImmediate::from(d);
180 *this = v ? v : jsNumberCell(globalData, d);
181 }
182
183 inline JSValue::JSValue(JSGlobalData* globalData, int i)
184 {
185 JSValue v = JSImmediate::from(i);
186 *this = v ? v : jsNumberCell(globalData, i);
187 }
188
189 inline JSValue::JSValue(JSGlobalData* globalData, unsigned i)
190 {
191 JSValue v = JSImmediate::from(i);
192 *this = v ? v : jsNumberCell(globalData, i);
193 }
194
195 inline JSValue::JSValue(JSGlobalData* globalData, long i)
196 {
197 JSValue v = JSImmediate::from(i);
198 *this = v ? v : jsNumberCell(globalData, i);
199 }
200
201 inline JSValue::JSValue(JSGlobalData* globalData, unsigned long i)
202 {
203 JSValue v = JSImmediate::from(i);
204 *this = v ? v : jsNumberCell(globalData, i);
205 }
206
207 inline JSValue::JSValue(JSGlobalData* globalData, long long i)
208 {
209 JSValue v = JSImmediate::from(i);
210 *this = v ? v : jsNumberCell(globalData, static_cast<double>(i));
211 }
212
213 inline JSValue::JSValue(JSGlobalData* globalData, unsigned long long i)
214 {
215 JSValue v = JSImmediate::from(i);
216 *this = v ? v : jsNumberCell(globalData, static_cast<double>(i));
217 }
218
219 inline bool JSValue::isDoubleNumber() const
220 {
221 return isNumberCell(asValue());
222 }
223
224 inline double JSValue::getDoubleNumber() const
225 {
226 return asNumberCell(asValue())->value();
227 }
228
229 inline bool JSValue::isNumber() const
230 {
231 return JSImmediate::isNumber(asValue()) || isDoubleNumber();
232 }
233
234 inline double JSValue::uncheckedGetNumber() const
235 {
236 ASSERT(isNumber());
237 return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : getDoubleNumber();
238 }
239
240 inline bool JSValue::isAPIMangledNumber()
241 {
242 ASSERT(isNumber());
243 return JSImmediate::isImmediate(asValue()) ? false : asNumberCell(asValue())->isAPIMangledNumber();
244 }
245
246#else
247
248 inline JSValue::JSValue(ExecState*, double d)
249 {
250 JSValue v = JSImmediate::from(d);
251 ASSERT(v);
252 *this = v;
253 }
254
255 inline JSValue::JSValue(ExecState*, int i)
256 {
257 JSValue v = JSImmediate::from(i);
258 ASSERT(v);
259 *this = v;
260 }
261
262 inline JSValue::JSValue(ExecState*, unsigned i)
263 {
264 JSValue v = JSImmediate::from(i);
265 ASSERT(v);
266 *this = v;
267 }
268
269 inline JSValue::JSValue(ExecState*, long i)
270 {
271 JSValue v = JSImmediate::from(i);
272 ASSERT(v);
273 *this = v;
274 }
275
276 inline JSValue::JSValue(ExecState*, unsigned long i)
277 {
278 JSValue v = JSImmediate::from(i);
279 ASSERT(v);
280 *this = v;
281 }
282
283 inline JSValue::JSValue(ExecState*, long long i)
284 {
285 JSValue v = JSImmediate::from(static_cast<double>(i));
286 ASSERT(v);
287 *this = v;
288 }
289
290 inline JSValue::JSValue(ExecState*, unsigned long long i)
291 {
292 JSValue v = JSImmediate::from(static_cast<double>(i));
293 ASSERT(v);
294 *this = v;
295 }
296
297 inline JSValue::JSValue(JSGlobalData*, double d)
298 {
299 JSValue v = JSImmediate::from(d);
300 ASSERT(v);
301 *this = v;
302 }
303
304 inline JSValue::JSValue(JSGlobalData*, int i)
305 {
306 JSValue v = JSImmediate::from(i);
307 ASSERT(v);
308 *this = v;
309 }
310
311 inline JSValue::JSValue(JSGlobalData*, unsigned i)
312 {
313 JSValue v = JSImmediate::from(i);
314 ASSERT(v);
315 *this = v;
316 }
317
318 inline JSValue::JSValue(JSGlobalData*, long i)
319 {
320 JSValue v = JSImmediate::from(i);
321 ASSERT(v);
322 *this = v;
323 }
324
325 inline JSValue::JSValue(JSGlobalData*, unsigned long i)
326 {
327 JSValue v = JSImmediate::from(i);
328 ASSERT(v);
329 *this = v;
330 }
331
332 inline JSValue::JSValue(JSGlobalData*, long long i)
333 {
334 JSValue v = JSImmediate::from(static_cast<double>(i));
335 ASSERT(v);
336 *this = v;
337 }
338
339 inline JSValue::JSValue(JSGlobalData*, unsigned long long i)
340 {
341 JSValue v = JSImmediate::from(static_cast<double>(i));
342 ASSERT(v);
343 *this = v;
344 }
345
346 inline bool JSValue::isDoubleNumber() const
347 {
348 return JSImmediate::isDoubleNumber(asValue());
349 }
350
351 inline double JSValue::getDoubleNumber() const
352 {
353 return JSImmediate::doubleValue(asValue());
354 }
355
356 inline bool JSValue::isNumber() const
357 {
358 return JSImmediate::isNumber(asValue());
359 }
360
361 inline double JSValue::uncheckedGetNumber() const
362 {
363 ASSERT(isNumber());
364 return JSImmediate::toDouble(asValue());
365 }
366
367#endif
368
369 inline JSValue::JSValue(ExecState*, char i)
370 {
371 ASSERT(JSImmediate::from(i));
372 *this = JSImmediate::from(i);
373 }
374
375 inline JSValue::JSValue(ExecState*, unsigned char i)
376 {
377 ASSERT(JSImmediate::from(i));
378 *this = JSImmediate::from(i);
379 }
380
381 inline JSValue::JSValue(ExecState*, short i)
382 {
383 ASSERT(JSImmediate::from(i));
384 *this = JSImmediate::from(i);
385 }
386
387 inline JSValue::JSValue(ExecState*, unsigned short i)
388 {
389 ASSERT(JSImmediate::from(i));
390 *this = JSImmediate::from(i);
391 }
392
393 inline JSValue::JSValue(JSGlobalData*, char i)
394 {
395 ASSERT(JSImmediate::from(i));
396 *this = JSImmediate::from(i);
397 }
398
399 inline JSValue::JSValue(JSGlobalData*, unsigned char i)
400 {
401 ASSERT(JSImmediate::from(i));
402 *this = JSImmediate::from(i);
403 }
404
405 inline JSValue::JSValue(JSGlobalData*, short i)
406 {
407 ASSERT(JSImmediate::from(i));
408 *this = JSImmediate::from(i);
409 }
410
411 inline JSValue::JSValue(JSGlobalData*, unsigned short i)
412 {
413 ASSERT(JSImmediate::from(i));
414 *this = JSImmediate::from(i);
415 }
416
417 inline JSValue jsNaN(ExecState* exec)
418 {
419 return jsNumber(exec, NaN);
420 }
421
422 inline JSValue jsNaN(JSGlobalData* globalData)
423 {
424 return jsNumber(globalData, NaN);
425 }
426
427 // --- JSValue inlines ----------------------------
428
429 ALWAYS_INLINE JSValue JSValue::toJSNumber(ExecState* exec) const
430 {
431 return isNumber() ? asValue() : jsNumber(exec, this->toNumber(exec));
432 }
433
434 inline bool JSValue::getNumber(double &result) const
435 {
436 if (isInt32Fast())
437 result = getInt32Fast();
438 else if (LIKELY(isDoubleNumber()))
439 result = getDoubleNumber();
440 else {
441 ASSERT(!isNumber());
442 return false;
443 }
444 return true;
445 }
446
447 inline bool JSValue::numberToInt32(int32_t& arg)
448 {
449 if (isInt32Fast())
450 arg = getInt32Fast();
451 else if (LIKELY(isDoubleNumber()))
452 arg = JSC::toInt32(getDoubleNumber());
453 else {
454 ASSERT(!isNumber());
455 return false;
456 }
457 return true;
458 }
459
460 inline bool JSValue::numberToUInt32(uint32_t& arg)
461 {
462 if (isUInt32Fast())
463 arg = getUInt32Fast();
464 else if (LIKELY(isDoubleNumber()))
465 arg = JSC::toUInt32(getDoubleNumber());
466 else if (isInt32Fast()) {
467 // FIXME: I think this case can be merged with the uint case; toUInt32SlowCase
468 // on a negative value is equivalent to simple static_casting.
469 bool ignored;
470 arg = toUInt32SlowCase(getInt32Fast(), ignored);
471 } else {
472 ASSERT(!isNumber());
473 return false;
474 }
475 return true;
476 }
477
478} // namespace JSC
479
480#endif // JSNumberCell_h
Note: See TracBrowser for help on using the repository browser.