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

source code of qtscript/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNumberCell.h