]> git.saurik.com Git - apple/javascriptcore.git/blob - runtime/JSValue.h
JavaScriptCore-554.1.tar.gz
[apple/javascriptcore.git] / runtime / JSValue.h
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 #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 <math.h>
32 #include <wtf/AlwaysInline.h>
33 #include <wtf/Assertions.h>
34 #include <wtf/HashTraits.h>
35 #include <wtf/MathExtras.h>
36
37 namespace JSC {
38
39 class Identifier;
40 class JSCell;
41 class JSGlobalData;
42 class JSImmediate;
43 class JSObject;
44 class JSString;
45 class PropertySlot;
46 class PutPropertySlot;
47 class UString;
48
49 struct ClassInfo;
50 struct Instruction;
51
52 enum PreferredPrimitiveType { NoPreference, PreferNumber, PreferString };
53
54 #if USE(JSVALUE32_64)
55 typedef int64_t EncodedJSValue;
56 #else
57 typedef void* EncodedJSValue;
58 #endif
59
60 double nonInlineNaN();
61 int32_t toInt32SlowCase(double, bool& ok);
62 uint32_t toUInt32SlowCase(double, bool& ok);
63
64 class JSValue {
65 friend class JSImmediate;
66 friend struct EncodedJSValueHashTraits;
67 friend class JIT;
68 friend class JITStubs;
69 friend class JITStubCall;
70
71 public:
72 static EncodedJSValue encode(JSValue value);
73 static JSValue decode(EncodedJSValue ptr);
74 #if !USE(JSVALUE32_64)
75 private:
76 static JSValue makeImmediate(intptr_t value);
77 intptr_t immediateValue();
78 public:
79 #endif
80 enum JSNullTag { JSNull };
81 enum JSUndefinedTag { JSUndefined };
82 enum JSTrueTag { JSTrue };
83 enum JSFalseTag { JSFalse };
84
85 JSValue();
86 JSValue(JSNullTag);
87 JSValue(JSUndefinedTag);
88 JSValue(JSTrueTag);
89 JSValue(JSFalseTag);
90 JSValue(JSCell* ptr);
91 JSValue(const JSCell* ptr);
92
93 // Numbers
94 JSValue(ExecState*, double);
95 JSValue(ExecState*, char);
96 JSValue(ExecState*, unsigned char);
97 JSValue(ExecState*, short);
98 JSValue(ExecState*, unsigned short);
99 JSValue(ExecState*, int);
100 JSValue(ExecState*, unsigned);
101 JSValue(ExecState*, long);
102 JSValue(ExecState*, unsigned long);
103 JSValue(ExecState*, long long);
104 JSValue(ExecState*, unsigned long long);
105 JSValue(JSGlobalData*, double);
106 JSValue(JSGlobalData*, int);
107 JSValue(JSGlobalData*, unsigned);
108
109 operator bool() const;
110 bool operator==(const JSValue& other) const;
111 bool operator!=(const JSValue& other) const;
112
113 bool isInt32() const;
114 bool isUInt32() const;
115 bool isDouble() const;
116 bool isTrue() const;
117 bool isFalse() const;
118
119 int32_t asInt32() const;
120 uint32_t asUInt32() const;
121 double asDouble() const;
122
123 // Querying the type.
124 bool isUndefined() const;
125 bool isNull() const;
126 bool isUndefinedOrNull() const;
127 bool isBoolean() const;
128 bool isNumber() const;
129 bool isString() const;
130 bool isGetterSetter() const;
131 bool isObject() const;
132 bool isObject(const ClassInfo*) const;
133
134 // Extracting the value.
135 bool getBoolean(bool&) const;
136 bool getBoolean() const; // false if not a boolean
137 bool getNumber(double&) const;
138 double uncheckedGetNumber() const;
139 bool getString(UString&) const;
140 UString getString() const; // null string if not a string
141 JSObject* getObject() const; // 0 if not an object
142
143 CallType getCallData(CallData&);
144 ConstructType getConstructData(ConstructData&);
145
146 // Extracting integer values.
147 bool getUInt32(uint32_t&) const;
148
149 // Basic conversions.
150 JSValue toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const;
151 bool getPrimitiveNumber(ExecState*, double& number, JSValue&);
152
153 bool toBoolean(ExecState*) const;
154
155 // toNumber conversion is expected to be side effect free if an exception has
156 // been set in the ExecState already.
157 double toNumber(ExecState*) const;
158 JSValue toJSNumber(ExecState*) const; // Fast path for when you expect that the value is an immediate number.
159 UString toString(ExecState*) const;
160 JSObject* toObject(ExecState*) const;
161
162 // Integer conversions.
163 double toInteger(ExecState*) const;
164 double toIntegerPreserveNaN(ExecState*) const;
165 int32_t toInt32(ExecState*) const;
166 int32_t toInt32(ExecState*, bool& ok) const;
167 uint32_t toUInt32(ExecState*) const;
168 uint32_t toUInt32(ExecState*, bool& ok) const;
169
170 // Floating point conversions (this is a convenience method for webcore;
171 // signle precision float is not a representation used in JS or JSC).
172 float toFloat(ExecState* exec) const { return static_cast<float>(toNumber(exec)); }
173
174 // Garbage collection.
175 void mark();
176 bool marked() const;
177
178 // Object operations, with the toObject operation included.
179 JSValue get(ExecState*, const Identifier& propertyName) const;
180 JSValue get(ExecState*, const Identifier& propertyName, PropertySlot&) const;
181 JSValue get(ExecState*, unsigned propertyName) const;
182 JSValue get(ExecState*, unsigned propertyName, PropertySlot&) const;
183 void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
184 void put(ExecState*, unsigned propertyName, JSValue);
185
186 bool needsThisConversion() const;
187 JSObject* toThisObject(ExecState*) const;
188 UString toThisString(ExecState*) const;
189 JSString* toThisJSString(ExecState*);
190
191 static bool equal(ExecState* exec, JSValue v1, JSValue v2);
192 static bool equalSlowCase(ExecState* exec, JSValue v1, JSValue v2);
193 static bool equalSlowCaseInline(ExecState* exec, JSValue v1, JSValue v2);
194 static bool strictEqual(JSValue v1, JSValue v2);
195 static bool strictEqualSlowCase(JSValue v1, JSValue v2);
196 static bool strictEqualSlowCaseInline(JSValue v1, JSValue v2);
197
198 JSValue getJSNumber(); // JSValue() if this is not a JSNumber or number object
199
200 bool isCell() const;
201 JSCell* asCell() const;
202
203 #ifndef NDEBUG
204 char* description();
205 #endif
206
207 private:
208 enum HashTableDeletedValueTag { HashTableDeletedValue };
209 JSValue(HashTableDeletedValueTag);
210
211 inline const JSValue asValue() const { return *this; }
212 JSObject* toObjectSlowCase(ExecState*) const;
213 JSObject* toThisObjectSlowCase(ExecState*) const;
214
215 enum { Int32Tag = 0xffffffff };
216 enum { CellTag = 0xfffffffe };
217 enum { TrueTag = 0xfffffffd };
218 enum { FalseTag = 0xfffffffc };
219 enum { NullTag = 0xfffffffb };
220 enum { UndefinedTag = 0xfffffffa };
221 enum { DeletedValueTag = 0xfffffff9 };
222
223 enum { LowestTag = DeletedValueTag };
224
225 uint32_t tag() const;
226 int32_t payload() const;
227
228 JSObject* synthesizePrototype(ExecState*) const;
229 JSObject* synthesizeObject(ExecState*) const;
230
231 #if USE(JSVALUE32_64)
232 union {
233 EncodedJSValue asEncodedJSValue;
234 double asDouble;
235 #if PLATFORM(BIG_ENDIAN)
236 struct {
237 int32_t tag;
238 int32_t payload;
239 } asBits;
240 #else
241 struct {
242 int32_t payload;
243 int32_t tag;
244 } asBits;
245 #endif
246 } u;
247 #else // USE(JSVALUE32_64)
248 JSCell* m_ptr;
249 #endif // USE(JSVALUE32_64)
250 };
251
252 #if USE(JSVALUE32_64)
253 typedef IntHash<EncodedJSValue> EncodedJSValueHash;
254
255 struct EncodedJSValueHashTraits : HashTraits<EncodedJSValue> {
256 static const bool emptyValueIsZero = false;
257 static EncodedJSValue emptyValue() { return JSValue::encode(JSValue()); }
258 static void constructDeletedValue(EncodedJSValue& slot) { slot = JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); }
259 static bool isDeletedValue(EncodedJSValue value) { return value == JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); }
260 };
261 #else
262 typedef PtrHash<EncodedJSValue> EncodedJSValueHash;
263
264 struct EncodedJSValueHashTraits : HashTraits<EncodedJSValue> {
265 static void constructDeletedValue(EncodedJSValue& slot) { slot = JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); }
266 static bool isDeletedValue(EncodedJSValue value) { return value == JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); }
267 };
268 #endif
269
270 // Stand-alone helper functions.
271 inline JSValue jsNull()
272 {
273 return JSValue(JSValue::JSNull);
274 }
275
276 inline JSValue jsUndefined()
277 {
278 return JSValue(JSValue::JSUndefined);
279 }
280
281 inline JSValue jsBoolean(bool b)
282 {
283 return b ? JSValue(JSValue::JSTrue) : JSValue(JSValue::JSFalse);
284 }
285
286 ALWAYS_INLINE JSValue jsNumber(ExecState* exec, double d)
287 {
288 return JSValue(exec, d);
289 }
290
291 ALWAYS_INLINE JSValue jsNumber(ExecState* exec, char i)
292 {
293 return JSValue(exec, i);
294 }
295
296 ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned char i)
297 {
298 return JSValue(exec, i);
299 }
300
301 ALWAYS_INLINE JSValue jsNumber(ExecState* exec, short i)
302 {
303 return JSValue(exec, i);
304 }
305
306 ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned short i)
307 {
308 return JSValue(exec, i);
309 }
310
311 ALWAYS_INLINE JSValue jsNumber(ExecState* exec, int i)
312 {
313 return JSValue(exec, i);
314 }
315
316 ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned i)
317 {
318 return JSValue(exec, i);
319 }
320
321 ALWAYS_INLINE JSValue jsNumber(ExecState* exec, long i)
322 {
323 return JSValue(exec, i);
324 }
325
326 ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned long i)
327 {
328 return JSValue(exec, i);
329 }
330
331 ALWAYS_INLINE JSValue jsNumber(ExecState* exec, long long i)
332 {
333 return JSValue(exec, i);
334 }
335
336 ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned long long i)
337 {
338 return JSValue(exec, i);
339 }
340
341 ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, double d)
342 {
343 return JSValue(globalData, d);
344 }
345
346 ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, int i)
347 {
348 return JSValue(globalData, i);
349 }
350
351 ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, unsigned i)
352 {
353 return JSValue(globalData, i);
354 }
355
356 inline bool operator==(const JSValue a, const JSCell* b) { return a == JSValue(b); }
357 inline bool operator==(const JSCell* a, const JSValue b) { return JSValue(a) == b; }
358
359 inline bool operator!=(const JSValue a, const JSCell* b) { return a != JSValue(b); }
360 inline bool operator!=(const JSCell* a, const JSValue b) { return JSValue(a) != b; }
361
362 inline int32_t toInt32(double val)
363 {
364 if (!(val >= -2147483648.0 && val < 2147483648.0)) {
365 bool ignored;
366 return toInt32SlowCase(val, ignored);
367 }
368 return static_cast<int32_t>(val);
369 }
370
371 inline uint32_t toUInt32(double val)
372 {
373 if (!(val >= 0.0 && val < 4294967296.0)) {
374 bool ignored;
375 return toUInt32SlowCase(val, ignored);
376 }
377 return static_cast<uint32_t>(val);
378 }
379
380 ALWAYS_INLINE int32_t JSValue::toInt32(ExecState* exec) const
381 {
382 if (isInt32())
383 return asInt32();
384 bool ignored;
385 return toInt32SlowCase(toNumber(exec), ignored);
386 }
387
388 inline uint32_t JSValue::toUInt32(ExecState* exec) const
389 {
390 if (isUInt32())
391 return asInt32();
392 bool ignored;
393 return toUInt32SlowCase(toNumber(exec), ignored);
394 }
395
396 inline int32_t JSValue::toInt32(ExecState* exec, bool& ok) const
397 {
398 if (isInt32()) {
399 ok = true;
400 return asInt32();
401 }
402 return toInt32SlowCase(toNumber(exec), ok);
403 }
404
405 inline uint32_t JSValue::toUInt32(ExecState* exec, bool& ok) const
406 {
407 if (isUInt32()) {
408 ok = true;
409 return asInt32();
410 }
411 return toUInt32SlowCase(toNumber(exec), ok);
412 }
413
414 #if USE(JSVALUE32_64)
415 inline JSValue jsNaN(ExecState* exec)
416 {
417 return JSValue(exec, nonInlineNaN());
418 }
419
420 // JSValue member functions.
421 inline EncodedJSValue JSValue::encode(JSValue value)
422 {
423 return value.u.asEncodedJSValue;
424 }
425
426 inline JSValue JSValue::decode(EncodedJSValue encodedJSValue)
427 {
428 JSValue v;
429 v.u.asEncodedJSValue = encodedJSValue;
430 return v;
431 }
432
433 inline JSValue::JSValue()
434 {
435 u.asBits.tag = CellTag;
436 u.asBits.payload = 0;
437 }
438
439 inline JSValue::JSValue(JSNullTag)
440 {
441 u.asBits.tag = NullTag;
442 u.asBits.payload = 0;
443 }
444
445 inline JSValue::JSValue(JSUndefinedTag)
446 {
447 u.asBits.tag = UndefinedTag;
448 u.asBits.payload = 0;
449 }
450
451 inline JSValue::JSValue(JSTrueTag)
452 {
453 u.asBits.tag = TrueTag;
454 u.asBits.payload = 0;
455 }
456
457 inline JSValue::JSValue(JSFalseTag)
458 {
459 u.asBits.tag = FalseTag;
460 u.asBits.payload = 0;
461 }
462
463 inline JSValue::JSValue(HashTableDeletedValueTag)
464 {
465 u.asBits.tag = DeletedValueTag;
466 u.asBits.payload = 0;
467 }
468
469 inline JSValue::JSValue(JSCell* ptr)
470 {
471 u.asBits.tag = CellTag;
472 u.asBits.payload = reinterpret_cast<int32_t>(ptr);
473 }
474
475 inline JSValue::JSValue(const JSCell* ptr)
476 {
477 u.asBits.tag = CellTag;
478 u.asBits.payload = reinterpret_cast<int32_t>(const_cast<JSCell*>(ptr));
479 }
480
481 inline JSValue::operator bool() const
482 {
483 return u.asBits.payload || tag() != CellTag;
484 }
485
486 inline bool JSValue::operator==(const JSValue& other) const
487 {
488 return u.asEncodedJSValue == other.u.asEncodedJSValue;
489 }
490
491 inline bool JSValue::operator!=(const JSValue& other) const
492 {
493 return u.asEncodedJSValue != other.u.asEncodedJSValue;
494 }
495
496 inline bool JSValue::isUndefined() const
497 {
498 return tag() == UndefinedTag;
499 }
500
501 inline bool JSValue::isNull() const
502 {
503 return tag() == NullTag;
504 }
505
506 inline bool JSValue::isUndefinedOrNull() const
507 {
508 return isUndefined() || isNull();
509 }
510
511 inline bool JSValue::isCell() const
512 {
513 return tag() == CellTag;
514 }
515
516 inline bool JSValue::isInt32() const
517 {
518 return tag() == Int32Tag;
519 }
520
521 inline bool JSValue::isUInt32() const
522 {
523 return tag() == Int32Tag && asInt32() > -1;
524 }
525
526 inline bool JSValue::isDouble() const
527 {
528 return tag() < LowestTag;
529 }
530
531 inline bool JSValue::isTrue() const
532 {
533 return tag() == TrueTag;
534 }
535
536 inline bool JSValue::isFalse() const
537 {
538 return tag() == FalseTag;
539 }
540
541 inline uint32_t JSValue::tag() const
542 {
543 return u.asBits.tag;
544 }
545
546 inline int32_t JSValue::payload() const
547 {
548 return u.asBits.payload;
549 }
550
551 inline int32_t JSValue::asInt32() const
552 {
553 ASSERT(isInt32());
554 return u.asBits.payload;
555 }
556
557 inline uint32_t JSValue::asUInt32() const
558 {
559 ASSERT(isUInt32());
560 return u.asBits.payload;
561 }
562
563 inline double JSValue::asDouble() const
564 {
565 ASSERT(isDouble());
566 return u.asDouble;
567 }
568
569 ALWAYS_INLINE JSCell* JSValue::asCell() const
570 {
571 ASSERT(isCell());
572 return reinterpret_cast<JSCell*>(u.asBits.payload);
573 }
574
575 inline JSValue::JSValue(ExecState* exec, double d)
576 {
577 const int32_t asInt32 = static_cast<int32_t>(d);
578 if (asInt32 != d || (!asInt32 && signbit(d))) { // true for -0.0
579 u.asDouble = d;
580 return;
581 }
582 *this = JSValue(exec, static_cast<int32_t>(d));
583 }
584
585 inline JSValue::JSValue(ExecState* exec, char i)
586 {
587 *this = JSValue(exec, static_cast<int32_t>(i));
588 }
589
590 inline JSValue::JSValue(ExecState* exec, unsigned char i)
591 {
592 *this = JSValue(exec, static_cast<int32_t>(i));
593 }
594
595 inline JSValue::JSValue(ExecState* exec, short i)
596 {
597 *this = JSValue(exec, static_cast<int32_t>(i));
598 }
599
600 inline JSValue::JSValue(ExecState* exec, unsigned short i)
601 {
602 *this = JSValue(exec, static_cast<int32_t>(i));
603 }
604
605 inline JSValue::JSValue(ExecState*, int i)
606 {
607 u.asBits.tag = Int32Tag;
608 u.asBits.payload = i;
609 }
610
611 inline JSValue::JSValue(ExecState* exec, unsigned i)
612 {
613 if (static_cast<int32_t>(i) < 0) {
614 *this = JSValue(exec, static_cast<double>(i));
615 return;
616 }
617 *this = JSValue(exec, static_cast<int32_t>(i));
618 }
619
620 inline JSValue::JSValue(ExecState* exec, long i)
621 {
622 if (static_cast<int32_t>(i) != i) {
623 *this = JSValue(exec, static_cast<double>(i));
624 return;
625 }
626 *this = JSValue(exec, static_cast<int32_t>(i));
627 }
628
629 inline JSValue::JSValue(ExecState* exec, unsigned long i)
630 {
631 if (static_cast<uint32_t>(i) != i) {
632 *this = JSValue(exec, static_cast<double>(i));
633 return;
634 }
635 *this = JSValue(exec, static_cast<uint32_t>(i));
636 }
637
638 inline JSValue::JSValue(ExecState* exec, long long i)
639 {
640 if (static_cast<int32_t>(i) != i) {
641 *this = JSValue(exec, static_cast<double>(i));
642 return;
643 }
644 *this = JSValue(exec, static_cast<int32_t>(i));
645 }
646
647 inline JSValue::JSValue(ExecState* exec, unsigned long long i)
648 {
649 if (static_cast<uint32_t>(i) != i) {
650 *this = JSValue(exec, static_cast<double>(i));
651 return;
652 }
653 *this = JSValue(exec, static_cast<uint32_t>(i));
654 }
655
656 inline JSValue::JSValue(JSGlobalData* globalData, double d)
657 {
658 const int32_t asInt32 = static_cast<int32_t>(d);
659 if (asInt32 != d || (!asInt32 && signbit(d))) { // true for -0.0
660 u.asDouble = d;
661 return;
662 }
663 *this = JSValue(globalData, static_cast<int32_t>(d));
664 }
665
666 inline JSValue::JSValue(JSGlobalData*, int i)
667 {
668 u.asBits.tag = Int32Tag;
669 u.asBits.payload = i;
670 }
671
672 inline JSValue::JSValue(JSGlobalData* globalData, unsigned i)
673 {
674 if (static_cast<int32_t>(i) < 0) {
675 *this = JSValue(globalData, static_cast<double>(i));
676 return;
677 }
678 *this = JSValue(globalData, static_cast<int32_t>(i));
679 }
680
681 inline bool JSValue::isNumber() const
682 {
683 return isInt32() || isDouble();
684 }
685
686 inline bool JSValue::isBoolean() const
687 {
688 return isTrue() || isFalse();
689 }
690
691 inline bool JSValue::getBoolean(bool& v) const
692 {
693 if (isTrue()) {
694 v = true;
695 return true;
696 }
697 if (isFalse()) {
698 v = false;
699 return true;
700 }
701
702 return false;
703 }
704
705 inline bool JSValue::getBoolean() const
706 {
707 ASSERT(isBoolean());
708 return tag() == TrueTag;
709 }
710
711 inline double JSValue::uncheckedGetNumber() const
712 {
713 ASSERT(isNumber());
714 return isInt32() ? asInt32() : asDouble();
715 }
716
717 ALWAYS_INLINE JSValue JSValue::toJSNumber(ExecState* exec) const
718 {
719 return isNumber() ? asValue() : jsNumber(exec, this->toNumber(exec));
720 }
721
722 inline bool JSValue::getNumber(double& result) const
723 {
724 if (isInt32()) {
725 result = asInt32();
726 return true;
727 }
728 if (isDouble()) {
729 result = asDouble();
730 return true;
731 }
732 return false;
733 }
734
735 #else // USE(JSVALUE32_64)
736
737 // JSValue member functions.
738 inline EncodedJSValue JSValue::encode(JSValue value)
739 {
740 return reinterpret_cast<EncodedJSValue>(value.m_ptr);
741 }
742
743 inline JSValue JSValue::decode(EncodedJSValue ptr)
744 {
745 return JSValue(reinterpret_cast<JSCell*>(ptr));
746 }
747
748 inline JSValue JSValue::makeImmediate(intptr_t value)
749 {
750 return JSValue(reinterpret_cast<JSCell*>(value));
751 }
752
753 inline intptr_t JSValue::immediateValue()
754 {
755 return reinterpret_cast<intptr_t>(m_ptr);
756 }
757
758 // 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.
759 inline JSValue::JSValue()
760 : m_ptr(0)
761 {
762 }
763
764 // 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.
765 inline JSValue::JSValue(HashTableDeletedValueTag)
766 : m_ptr(reinterpret_cast<JSCell*>(0x4))
767 {
768 }
769
770 inline JSValue::JSValue(JSCell* ptr)
771 : m_ptr(ptr)
772 {
773 }
774
775 inline JSValue::JSValue(const JSCell* ptr)
776 : m_ptr(const_cast<JSCell*>(ptr))
777 {
778 }
779
780 inline JSValue::operator bool() const
781 {
782 return m_ptr;
783 }
784
785 inline bool JSValue::operator==(const JSValue& other) const
786 {
787 return m_ptr == other.m_ptr;
788 }
789
790 inline bool JSValue::operator!=(const JSValue& other) const
791 {
792 return m_ptr != other.m_ptr;
793 }
794
795 inline bool JSValue::isUndefined() const
796 {
797 return asValue() == jsUndefined();
798 }
799
800 inline bool JSValue::isNull() const
801 {
802 return asValue() == jsNull();
803 }
804 #endif // USE(JSVALUE32_64)
805
806 } // namespace JSC
807
808 #endif // JSValue_h