source: webkit/trunk/JavaScriptCore/runtime/JSValue.h@ 43424

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

JavaScriptCore:

2009-05-02 Sam Weinig <[email protected]>

Roll JSC API number marshaling back in one last time (I hope).

WebCore:

2009-05-03 Sam Weinig <[email protected]>

Roll JSC API number marshaling back in one last time (I hope).

  • Property svn:eol-style set to native
File size: 13.0 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#include <stddef.h> // for size_t
24#include <stdint.h>
25
26#ifndef JSValue_h
27#define JSValue_h
28
29#include "CallData.h"
30#include "ConstructData.h"
31#include <wtf/HashTraits.h>
32#include <wtf/AlwaysInline.h>
33
34namespace JSC {
35
36 class Identifier;
37 class JSCell;
38 class JSGlobalData;
39 class JSImmediate;
40 class JSObject;
41 class JSString;
42 class PropertySlot;
43 class PutPropertySlot;
44 class UString;
45
46 struct ClassInfo;
47 struct Instruction;
48
49 enum PreferredPrimitiveType { NoPreference, PreferNumber, PreferString };
50
51 typedef void* EncodedJSValue;
52
53 class JSValue {
54 friend class JSImmediate;
55 friend struct JSValueHashTraits;
56
57 static JSValue makeImmediate(intptr_t value)
58 {
59 return JSValue(reinterpret_cast<JSCell*>(value));
60 }
61
62 intptr_t immediateValue()
63 {
64 return reinterpret_cast<intptr_t>(m_ptr);
65 }
66
67 public:
68 enum JSNullTag { JSNull };
69 enum JSUndefinedTag { JSUndefined };
70 enum JSTrueTag { JSTrue };
71 enum JSFalseTag { JSFalse };
72
73 static EncodedJSValue encode(JSValue value);
74 static JSValue decode(EncodedJSValue ptr);
75
76 JSValue();
77 JSValue(JSNullTag);
78 JSValue(JSUndefinedTag);
79 JSValue(JSTrueTag);
80 JSValue(JSFalseTag);
81 JSValue(JSCell* ptr);
82 JSValue(const JSCell* ptr);
83
84 // Numbers
85 JSValue(ExecState*, double);
86 JSValue(ExecState*, char);
87 JSValue(ExecState*, unsigned char);
88 JSValue(ExecState*, short);
89 JSValue(ExecState*, unsigned short);
90 JSValue(ExecState*, int);
91 JSValue(ExecState*, unsigned);
92 JSValue(ExecState*, long);
93 JSValue(ExecState*, unsigned long);
94 JSValue(ExecState*, long long);
95 JSValue(ExecState*, unsigned long long);
96 JSValue(JSGlobalData*, double);
97 JSValue(JSGlobalData*, char);
98 JSValue(JSGlobalData*, unsigned char);
99 JSValue(JSGlobalData*, short);
100 JSValue(JSGlobalData*, unsigned short);
101 JSValue(JSGlobalData*, int);
102 JSValue(JSGlobalData*, unsigned);
103 JSValue(JSGlobalData*, long);
104 JSValue(JSGlobalData*, unsigned long);
105 JSValue(JSGlobalData*, long long);
106 JSValue(JSGlobalData*, unsigned long long);
107
108 operator bool() const;
109 bool operator==(const JSValue other) const;
110 bool operator!=(const JSValue other) const;
111
112 // Querying the type.
113 bool isUndefined() const;
114 bool isNull() const;
115 bool isUndefinedOrNull() const;
116 bool isBoolean() const;
117 bool isNumber() const;
118 bool isString() const;
119 bool isGetterSetter() const;
120 bool isObject() const;
121 bool isObject(const ClassInfo*) const;
122
123 // Extracting the value.
124 bool getBoolean(bool&) const;
125 bool getBoolean() const; // false if not a boolean
126 bool getNumber(double&) const;
127 double uncheckedGetNumber() const;
128 bool getString(UString&) const;
129 UString getString() const; // null string if not a string
130 JSObject* getObject() const; // 0 if not an object
131
132 CallType getCallData(CallData&);
133 ConstructType getConstructData(ConstructData&);
134
135 // Extracting integer values.
136 bool getUInt32(uint32_t&) const;
137 bool getTruncatedInt32(int32_t&) const;
138 bool getTruncatedUInt32(uint32_t&) const;
139
140 // Basic conversions.
141 JSValue toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const;
142 bool getPrimitiveNumber(ExecState*, double& number, JSValue&);
143
144 bool toBoolean(ExecState*) const;
145
146 // toNumber conversion is expected to be side effect free if an exception has
147 // been set in the ExecState already.
148 double toNumber(ExecState*) const;
149 JSValue toJSNumber(ExecState*) const; // Fast path for when you expect that the value is an immediate number.
150 UString toString(ExecState*) const;
151 JSObject* toObject(ExecState*) const;
152
153 // Integer conversions.
154 // 'x.numberToInt32(output)' is equivalent to 'x.isNumber() && x.toInt32(output)'
155 double toInteger(ExecState*) const;
156 double toIntegerPreserveNaN(ExecState*) const;
157 int32_t toInt32(ExecState*) const;
158 int32_t toInt32(ExecState*, bool& ok) const;
159 bool numberToInt32(int32_t& arg);
160 uint32_t toUInt32(ExecState*) const;
161 uint32_t toUInt32(ExecState*, bool& ok) const;
162 bool numberToUInt32(uint32_t& arg);
163
164 // Fast integer operations; these values return results where the value is trivially available
165 // in a convenient form, for use in optimizations. No assumptions should be made based on the
166 // results of these operations, for example !isInt32Fast() does not necessarily indicate the
167 // result of getNumber will not be 0.
168 bool isInt32Fast() const;
169 int32_t getInt32Fast() const;
170 bool isUInt32Fast() const;
171 uint32_t getUInt32Fast() const;
172 static JSValue makeInt32Fast(int32_t);
173 static bool areBothInt32Fast(JSValue, JSValue);
174
175 // Floating point conversions (this is a convenience method for webcore;
176 // signle precision float is not a representation used in JS or JSC).
177 float toFloat(ExecState* exec) const { return static_cast<float>(toNumber(exec)); }
178
179 // API Mangled Numbers
180 bool isAPIMangledNumber();
181
182 // Garbage collection.
183 void mark();
184 bool marked() const;
185
186 // Object operations, with the toObject operation included.
187 JSValue get(ExecState*, const Identifier& propertyName) const;
188 JSValue get(ExecState*, const Identifier& propertyName, PropertySlot&) const;
189 JSValue get(ExecState*, unsigned propertyName) const;
190 JSValue get(ExecState*, unsigned propertyName, PropertySlot&) const;
191 void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
192 void put(ExecState*, unsigned propertyName, JSValue);
193
194 bool needsThisConversion() const;
195 JSObject* toThisObject(ExecState*) const;
196 UString toThisString(ExecState*) const;
197 JSString* toThisJSString(ExecState*);
198
199 static bool equal(ExecState* exec, JSValue v1, JSValue v2);
200 static bool equalSlowCase(ExecState* exec, JSValue v1, JSValue v2);
201 static bool equalSlowCaseInline(ExecState* exec, JSValue v1, JSValue v2);
202 static bool strictEqual(JSValue v1, JSValue v2);
203 static bool strictEqualSlowCase(JSValue v1, JSValue v2);
204 static bool strictEqualSlowCaseInline(JSValue v1, JSValue v2);
205
206 JSValue getJSNumber(); // JSValue() if this is not a JSNumber or number object
207
208 bool isCell() const;
209 JSCell* asCell() const;
210
211 private:
212 enum HashTableDeletedValueTag { HashTableDeletedValue };
213 JSValue(HashTableDeletedValueTag);
214
215 inline const JSValue asValue() const { return *this; }
216
217 bool isDoubleNumber() const;
218 double getDoubleNumber() const;
219
220 JSCell* m_ptr;
221 };
222
223 struct JSValueHashTraits : HashTraits<EncodedJSValue> {
224 static void constructDeletedValue(EncodedJSValue& slot) { slot = JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); }
225 static bool isDeletedValue(EncodedJSValue value) { return value == JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); }
226 };
227
228 // Stand-alone helper functions.
229 inline JSValue jsNull()
230 {
231 return JSValue(JSValue::JSNull);
232 }
233
234 inline JSValue jsUndefined()
235 {
236 return JSValue(JSValue::JSUndefined);
237 }
238
239 inline JSValue jsBoolean(bool b)
240 {
241 return b ? JSValue(JSValue::JSTrue) : JSValue(JSValue::JSFalse);
242 }
243
244 ALWAYS_INLINE JSValue jsNumber(ExecState* exec, double d)
245 {
246 return JSValue(exec, d);
247 }
248
249 ALWAYS_INLINE JSValue jsNumber(ExecState* exec, char i)
250 {
251 return JSValue(exec, i);
252 }
253
254 ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned char i)
255 {
256 return JSValue(exec, i);
257 }
258
259 ALWAYS_INLINE JSValue jsNumber(ExecState* exec, short i)
260 {
261 return JSValue(exec, i);
262 }
263
264 ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned short i)
265 {
266 return JSValue(exec, i);
267 }
268
269 ALWAYS_INLINE JSValue jsNumber(ExecState* exec, int i)
270 {
271 return JSValue(exec, i);
272 }
273
274 ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned i)
275 {
276 return JSValue(exec, i);
277 }
278
279 ALWAYS_INLINE JSValue jsNumber(ExecState* exec, long i)
280 {
281 return JSValue(exec, i);
282 }
283
284 ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned long i)
285 {
286 return JSValue(exec, i);
287 }
288
289 ALWAYS_INLINE JSValue jsNumber(ExecState* exec, long long i)
290 {
291 return JSValue(exec, i);
292 }
293
294 ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned long long i)
295 {
296 return JSValue(exec, i);
297 }
298
299 ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, double d)
300 {
301 return JSValue(globalData, d);
302 }
303
304 ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, char i)
305 {
306 return JSValue(globalData, i);
307 }
308
309 ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, unsigned char i)
310 {
311 return JSValue(globalData, i);
312 }
313
314 ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, short i)
315 {
316 return JSValue(globalData, i);
317 }
318
319 ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, unsigned short i)
320 {
321 return JSValue(globalData, i);
322 }
323
324 ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, int i)
325 {
326 return JSValue(globalData, i);
327 }
328
329 ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, unsigned i)
330 {
331 return JSValue(globalData, i);
332 }
333
334 ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, long i)
335 {
336 return JSValue(globalData, i);
337 }
338
339 ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, unsigned long i)
340 {
341 return JSValue(globalData, i);
342 }
343
344 ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, long long i)
345 {
346 return JSValue(globalData, i);
347 }
348
349 ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, unsigned long long i)
350 {
351 return JSValue(globalData, i);
352 }
353
354 inline bool operator==(const JSValue a, const JSCell* b) { return a == JSValue(b); }
355 inline bool operator==(const JSCell* a, const JSValue b) { return JSValue(a) == b; }
356
357 inline bool operator!=(const JSValue a, const JSCell* b) { return a != JSValue(b); }
358 inline bool operator!=(const JSCell* a, const JSValue b) { return JSValue(a) != b; }
359
360 // JSValue member functions.
361 inline EncodedJSValue JSValue::encode(JSValue value)
362 {
363 return reinterpret_cast<EncodedJSValue>(value.m_ptr);
364 }
365
366 inline JSValue JSValue::decode(EncodedJSValue ptr)
367 {
368 return JSValue(reinterpret_cast<JSCell*>(ptr));
369 }
370
371 // 0x0 can never occur naturally because it has a tag of 00, indicating a pointer value, but a payload of 0x0, which is in the (invalid) zero page.
372 inline JSValue::JSValue()
373 : m_ptr(0)
374 {
375 }
376
377 // 0x4 can never occur naturally because it has a tag of 00, indicating a pointer value, but a payload of 0x4, which is in the (invalid) zero page.
378 inline JSValue::JSValue(HashTableDeletedValueTag)
379 : m_ptr(reinterpret_cast<JSCell*>(0x4))
380 {
381 }
382
383 inline JSValue::JSValue(JSCell* ptr)
384 : m_ptr(ptr)
385 {
386 }
387
388 inline JSValue::JSValue(const JSCell* ptr)
389 : m_ptr(const_cast<JSCell*>(ptr))
390 {
391 }
392
393 inline JSValue::operator bool() const
394 {
395 return m_ptr;
396 }
397
398 inline bool JSValue::operator==(const JSValue other) const
399 {
400 return m_ptr == other.m_ptr;
401 }
402
403 inline bool JSValue::operator!=(const JSValue other) const
404 {
405 return m_ptr != other.m_ptr;
406 }
407
408 inline bool JSValue::isUndefined() const
409 {
410 return asValue() == jsUndefined();
411 }
412
413 inline bool JSValue::isNull() const
414 {
415 return asValue() == jsNull();
416 }
417
418} // namespace JSC
419
420#endif // JSValue_h
Note: See TracBrowser for help on using the repository browser.