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, 2009 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 JSValue_h
24#define JSValue_h
25
26#include "CallData.h"
27#include "ConstructData.h"
28#include <stddef.h> // for size_t
29#include <stdint.h>
30#include <wtf/AlwaysInline.h>
31#include <wtf/Assertions.h>
32#include <wtf/HashTraits.h>
33#include <wtf/MathExtras.h>
34
35namespace JSC {
36
37 class Identifier;
38 class JSCell;
39 class JSGlobalData;
40 class JSImmediate;
41 class JSObject;
42 class JSString;
43 class PropertySlot;
44 class PutPropertySlot;
45 class UString;
46
47 struct ClassInfo;
48 struct Instruction;
49
50 enum PreferredPrimitiveType { NoPreference, PreferNumber, PreferString };
51
52#if USE(JSVALUE32_64)
53 typedef int64_t EncodedJSValue;
54#else
55 typedef void* EncodedJSValue;
56#endif
57
58 double nonInlineNaN();
59 int32_t toInt32SlowCase(double, bool& ok);
60 uint32_t toUInt32SlowCase(double, bool& ok);
61
62 class JSValue {
63 friend class JSImmediate;
64 friend struct EncodedJSValueHashTraits;
65 friend class JIT;
66 friend class JITStubs;
67 friend class JITStubCall;
68
69 public:
70 static EncodedJSValue encode(JSValue value);
71 static JSValue decode(EncodedJSValue ptr);
72#if !USE(JSVALUE32_64)
73 private:
74 static JSValue makeImmediate(intptr_t value);
75 intptr_t immediateValue();
76 public:
77#endif
78 enum JSNullTag { JSNull };
79 enum JSUndefinedTag { JSUndefined };
80 enum JSTrueTag { JSTrue };
81 enum JSFalseTag { JSFalse };
82 enum EncodeAsDoubleTag { EncodeAsDouble };
83
84 JSValue();
85 JSValue(JSNullTag);
86 JSValue(JSUndefinedTag);
87 JSValue(JSTrueTag);
88 JSValue(JSFalseTag);
89 JSValue(JSCell* ptr);
90 JSValue(const JSCell* ptr);
91
92 // Numbers
93 JSValue(EncodeAsDoubleTag, ExecState*, double);
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 inherits(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(ExecState* exec, UString&) const;
140 UString getString(ExecState* exec) 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 UString toPrimitiveString(ExecState*) const;
161 JSObject* toObject(ExecState*) const;
162
163 // Integer conversions.
164 double toInteger(ExecState*) const;
165 double toIntegerPreserveNaN(ExecState*) const;
166 int32_t toInt32(ExecState*) const;
167 int32_t toInt32(ExecState*, bool& ok) const;
168 uint32_t toUInt32(ExecState*) const;
169 uint32_t toUInt32(ExecState*, bool& ok) const;
170
171#if ENABLE(JSC_ZOMBIES)
172 bool isZombie() const;
173#endif
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 // Object operations, with the toObject operation included.
180 JSValue get(ExecState*, const Identifier& propertyName) const;
181 JSValue get(ExecState*, const Identifier& propertyName, PropertySlot&) const;
182 JSValue get(ExecState*, unsigned propertyName) const;
183 JSValue get(ExecState*, unsigned propertyName, PropertySlot&) const;
184 void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
185 void put(ExecState*, unsigned propertyName, JSValue);
186
187 bool needsThisConversion() const;
188 JSObject* toThisObject(ExecState*) const;
189 UString toThisString(ExecState*) const;
190 JSString* toThisJSString(ExecState*);
191
192 static bool equal(ExecState* exec, JSValue v1, JSValue v2);
193 static bool equalSlowCase(ExecState* exec, JSValue v1, JSValue v2);
194 static bool equalSlowCaseInline(ExecState* exec, JSValue v1, JSValue v2);
195 static bool strictEqual(ExecState* exec, JSValue v1, JSValue v2);
196 static bool strictEqualSlowCase(ExecState* exec, JSValue v1, JSValue v2);
197 static bool strictEqualSlowCaseInline(ExecState* exec, JSValue v1, JSValue v2);
198
199 JSValue getJSNumber(); // JSValue() if this is not a JSNumber or number object
200
201 bool isCell() const;
202 JSCell* asCell() const;
203
204#ifndef NDEBUG
205 char* description();
206#endif
207
208 private:
209 enum HashTableDeletedValueTag { HashTableDeletedValue };
210 JSValue(HashTableDeletedValueTag);
211
212 inline const JSValue asValue() const { return *this; }
213 JSObject* toObjectSlowCase(ExecState*) const;
214 JSObject* toThisObjectSlowCase(ExecState*) const;
215
216 enum { Int32Tag = 0xffffffff };
217 enum { CellTag = 0xfffffffe };
218 enum { TrueTag = 0xfffffffd };
219 enum { FalseTag = 0xfffffffc };
220 enum { NullTag = 0xfffffffb };
221 enum { UndefinedTag = 0xfffffffa };
222 enum { EmptyValueTag = 0xfffffff9 };
223 enum { DeletedValueTag = 0xfffffff8 };
224
225 enum { LowestTag = DeletedValueTag };
226
227 uint32_t tag() const;
228 int32_t payload() const;
229
230 JSObject* synthesizePrototype(ExecState*) const;
231 JSObject* synthesizeObject(ExecState*) const;
232
233#if USE(JSVALUE32_64)
234 union {
235 EncodedJSValue asEncodedJSValue;
236 double asDouble;
237#if CPU(BIG_ENDIAN)
238 struct {
239 int32_t tag;
240 int32_t payload;
241 } asBits;
242#else
243 struct {
244 int32_t payload;
245 int32_t tag;
246 } asBits;
247#endif
248 } u;
249#else // USE(JSVALUE32_64)
250 JSCell* m_ptr;
251#endif // USE(JSVALUE32_64)
252 };
253
254#if USE(JSVALUE32_64)
255 typedef IntHash<EncodedJSValue> EncodedJSValueHash;
256
257 struct EncodedJSValueHashTraits : HashTraits<EncodedJSValue> {
258 static const bool emptyValueIsZero = false;
259 static EncodedJSValue emptyValue() { return JSValue::encode(JSValue()); }
260 static void constructDeletedValue(EncodedJSValue& slot) { slot = JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); }
261 static bool isDeletedValue(EncodedJSValue value) { return value == JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); }
262 };
263#else
264 typedef PtrHash<EncodedJSValue> EncodedJSValueHash;
265
266 struct EncodedJSValueHashTraits : HashTraits<EncodedJSValue> {
267 static void constructDeletedValue(EncodedJSValue& slot) { slot = JSValue::encode(value: JSValue(JSValue::HashTableDeletedValue)); }
268 static bool isDeletedValue(EncodedJSValue value) { return value == JSValue::encode(value: JSValue(JSValue::HashTableDeletedValue)); }
269 };
270#endif
271
272 // Stand-alone helper functions.
273 inline JSValue jsNull()
274 {
275 return JSValue(JSValue::JSNull);
276 }
277
278 inline JSValue jsUndefined()
279 {
280 return JSValue(JSValue::JSUndefined);
281 }
282
283 inline JSValue jsBoolean(bool b)
284 {
285 return b ? JSValue(JSValue::JSTrue) : JSValue(JSValue::JSFalse);
286 }
287
288 ALWAYS_INLINE JSValue jsDoubleNumber(ExecState* exec, double d)
289 {
290 return JSValue(JSValue::EncodeAsDouble, exec, d);
291 }
292
293 ALWAYS_INLINE JSValue jsNumber(ExecState* exec, double d)
294 {
295 return JSValue(exec, d);
296 }
297
298 ALWAYS_INLINE JSValue jsNumber(ExecState* exec, char i)
299 {
300 return JSValue(exec, i);
301 }
302
303 ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned char i)
304 {
305 return JSValue(exec, i);
306 }
307
308 ALWAYS_INLINE JSValue jsNumber(ExecState* exec, short i)
309 {
310 return JSValue(exec, i);
311 }
312
313 ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned short i)
314 {
315 return JSValue(exec, i);
316 }
317
318 ALWAYS_INLINE JSValue jsNumber(ExecState* exec, int i)
319 {
320 return JSValue(exec, i);
321 }
322
323 ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned i)
324 {
325 return JSValue(exec, i);
326 }
327
328 ALWAYS_INLINE JSValue jsNumber(ExecState* exec, long i)
329 {
330 return JSValue(exec, i);
331 }
332
333 ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned long i)
334 {
335 return JSValue(exec, i);
336 }
337
338 ALWAYS_INLINE JSValue jsNumber(ExecState* exec, long long i)
339 {
340 return JSValue(exec, i);
341 }
342
343 ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned long long i)
344 {
345 return JSValue(exec, i);
346 }
347
348 ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, double d)
349 {
350 return JSValue(globalData, d);
351 }
352
353 ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, int i)
354 {
355 return JSValue(globalData, i);
356 }
357
358 ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, unsigned i)
359 {
360 return JSValue(globalData, i);
361 }
362
363 inline bool operator==(const JSValue a, const JSCell* b) { return a == JSValue(b); }
364 inline bool operator==(const JSCell* a, const JSValue b) { return JSValue(a) == b; }
365
366 inline bool operator!=(const JSValue a, const JSCell* b) { return a != JSValue(b); }
367 inline bool operator!=(const JSCell* a, const JSValue b) { return JSValue(a) != b; }
368
369 inline int32_t toInt32(double val)
370 {
371 if (!(val >= -2147483648.0 && val < 2147483648.0)) {
372 bool ignored;
373 return toInt32SlowCase(val, ok&: ignored);
374 }
375 return static_cast<int32_t>(val);
376 }
377
378 inline uint32_t toUInt32(double val)
379 {
380 if (!(val >= 0.0 && val < 4294967296.0)) {
381 bool ignored;
382 return toUInt32SlowCase(val, ok&: ignored);
383 }
384 return static_cast<uint32_t>(val);
385 }
386
387 // FIXME: We should deprecate this and just use JSValue::asCell() instead.
388 JSCell* asCell(JSValue);
389
390 inline JSCell* asCell(JSValue value)
391 {
392 return value.asCell();
393 }
394
395 ALWAYS_INLINE int32_t JSValue::toInt32(ExecState* exec) const
396 {
397 if (isInt32())
398 return asInt32();
399 bool ignored;
400 return toInt32SlowCase(toNumber(exec), ok&: ignored);
401 }
402
403 inline uint32_t JSValue::toUInt32(ExecState* exec) const
404 {
405 if (isUInt32())
406 return asInt32();
407 bool ignored;
408 return toUInt32SlowCase(toNumber(exec), ok&: ignored);
409 }
410
411 inline int32_t JSValue::toInt32(ExecState* exec, bool& ok) const
412 {
413 if (isInt32()) {
414 ok = true;
415 return asInt32();
416 }
417 return toInt32SlowCase(toNumber(exec), ok);
418 }
419
420 inline uint32_t JSValue::toUInt32(ExecState* exec, bool& ok) const
421 {
422 if (isUInt32()) {
423 ok = true;
424 return asInt32();
425 }
426 return toUInt32SlowCase(toNumber(exec), ok);
427 }
428
429#if USE(JSVALUE32_64)
430 inline JSValue jsNaN(ExecState* exec)
431 {
432 return JSValue(exec, nonInlineNaN());
433 }
434
435 // JSValue member functions.
436 inline EncodedJSValue JSValue::encode(JSValue value)
437 {
438 return value.u.asEncodedJSValue;
439 }
440
441 inline JSValue JSValue::decode(EncodedJSValue encodedJSValue)
442 {
443 JSValue v;
444 v.u.asEncodedJSValue = encodedJSValue;
445#if ENABLE(JSC_ZOMBIES)
446 ASSERT(!v.isZombie());
447#endif
448 return v;
449 }
450
451 inline JSValue::JSValue()
452 {
453 u.asBits.tag = EmptyValueTag;
454 u.asBits.payload = 0;
455 }
456
457 inline JSValue::JSValue(JSNullTag)
458 {
459 u.asBits.tag = NullTag;
460 u.asBits.payload = 0;
461 }
462
463 inline JSValue::JSValue(JSUndefinedTag)
464 {
465 u.asBits.tag = UndefinedTag;
466 u.asBits.payload = 0;
467 }
468
469 inline JSValue::JSValue(JSTrueTag)
470 {
471 u.asBits.tag = TrueTag;
472 u.asBits.payload = 0;
473 }
474
475 inline JSValue::JSValue(JSFalseTag)
476 {
477 u.asBits.tag = FalseTag;
478 u.asBits.payload = 0;
479 }
480
481 inline JSValue::JSValue(HashTableDeletedValueTag)
482 {
483 u.asBits.tag = DeletedValueTag;
484 u.asBits.payload = 0;
485 }
486
487 inline JSValue::JSValue(JSCell* ptr)
488 {
489 if (ptr)
490 u.asBits.tag = CellTag;
491 else
492 u.asBits.tag = EmptyValueTag;
493 u.asBits.payload = reinterpret_cast<int32_t>(ptr);
494#if ENABLE(JSC_ZOMBIES)
495 ASSERT(!isZombie());
496#endif
497 }
498
499 inline JSValue::JSValue(const JSCell* ptr)
500 {
501 if (ptr)
502 u.asBits.tag = CellTag;
503 else
504 u.asBits.tag = EmptyValueTag;
505 u.asBits.payload = reinterpret_cast<int32_t>(const_cast<JSCell*>(ptr));
506#if ENABLE(JSC_ZOMBIES)
507 ASSERT(!isZombie());
508#endif
509 }
510
511 inline JSValue::operator bool() const
512 {
513 ASSERT(tag() != DeletedValueTag);
514 return tag() != EmptyValueTag;
515 }
516
517 inline bool JSValue::operator==(const JSValue& other) const
518 {
519 return u.asEncodedJSValue == other.u.asEncodedJSValue;
520 }
521
522 inline bool JSValue::operator!=(const JSValue& other) const
523 {
524 return u.asEncodedJSValue != other.u.asEncodedJSValue;
525 }
526
527 inline bool JSValue::isUndefined() const
528 {
529 return tag() == UndefinedTag;
530 }
531
532 inline bool JSValue::isNull() const
533 {
534 return tag() == NullTag;
535 }
536
537 inline bool JSValue::isUndefinedOrNull() const
538 {
539 return isUndefined() || isNull();
540 }
541
542 inline bool JSValue::isCell() const
543 {
544 return tag() == CellTag;
545 }
546
547 inline bool JSValue::isInt32() const
548 {
549 return tag() == Int32Tag;
550 }
551
552 inline bool JSValue::isUInt32() const
553 {
554 return tag() == Int32Tag && asInt32() > -1;
555 }
556
557 inline bool JSValue::isDouble() const
558 {
559 return tag() < LowestTag;
560 }
561
562 inline bool JSValue::isTrue() const
563 {
564 return tag() == TrueTag;
565 }
566
567 inline bool JSValue::isFalse() const
568 {
569 return tag() == FalseTag;
570 }
571
572 inline uint32_t JSValue::tag() const
573 {
574 return u.asBits.tag;
575 }
576
577 inline int32_t JSValue::payload() const
578 {
579 return u.asBits.payload;
580 }
581
582 inline int32_t JSValue::asInt32() const
583 {
584 ASSERT(isInt32());
585 return u.asBits.payload;
586 }
587
588 inline uint32_t JSValue::asUInt32() const
589 {
590 ASSERT(isUInt32());
591 return u.asBits.payload;
592 }
593
594 inline double JSValue::asDouble() const
595 {
596 ASSERT(isDouble());
597 return u.asDouble;
598 }
599
600 ALWAYS_INLINE JSCell* JSValue::asCell() const
601 {
602 ASSERT(isCell());
603 return reinterpret_cast<JSCell*>(u.asBits.payload);
604 }
605
606 ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, ExecState*, double d)
607 {
608 u.asDouble = d;
609 }
610
611 inline JSValue::JSValue(ExecState* exec, double d)
612 {
613 const int32_t asInt32 = static_cast<int32_t>(d);
614 if (asInt32 != d || (!asInt32 && std::signbit(d))) { // true for -0.0
615 u.asDouble = d;
616 return;
617 }
618 *this = JSValue(exec, static_cast<int32_t>(d));
619 }
620
621 inline JSValue::JSValue(ExecState* exec, char i)
622 {
623 *this = JSValue(exec, static_cast<int32_t>(i));
624 }
625
626 inline JSValue::JSValue(ExecState* exec, unsigned char i)
627 {
628 *this = JSValue(exec, static_cast<int32_t>(i));
629 }
630
631 inline JSValue::JSValue(ExecState* exec, short i)
632 {
633 *this = JSValue(exec, static_cast<int32_t>(i));
634 }
635
636 inline JSValue::JSValue(ExecState* exec, unsigned short i)
637 {
638 *this = JSValue(exec, static_cast<int32_t>(i));
639 }
640
641 inline JSValue::JSValue(ExecState*, int i)
642 {
643 u.asBits.tag = Int32Tag;
644 u.asBits.payload = i;
645 }
646
647 inline JSValue::JSValue(ExecState* exec, unsigned i)
648 {
649 if (static_cast<int32_t>(i) < 0) {
650 *this = JSValue(exec, static_cast<double>(i));
651 return;
652 }
653 *this = JSValue(exec, static_cast<int32_t>(i));
654 }
655
656 inline JSValue::JSValue(ExecState* exec, long i)
657 {
658 if (static_cast<int32_t>(i) != i) {
659 *this = JSValue(exec, static_cast<double>(i));
660 return;
661 }
662 *this = JSValue(exec, static_cast<int32_t>(i));
663 }
664
665 inline JSValue::JSValue(ExecState* exec, unsigned long i)
666 {
667 if (static_cast<uint32_t>(i) != i) {
668 *this = JSValue(exec, static_cast<double>(i));
669 return;
670 }
671 *this = JSValue(exec, static_cast<uint32_t>(i));
672 }
673
674 inline JSValue::JSValue(ExecState* exec, long long i)
675 {
676 if (static_cast<int32_t>(i) != i) {
677 *this = JSValue(exec, static_cast<double>(i));
678 return;
679 }
680 *this = JSValue(exec, static_cast<int32_t>(i));
681 }
682
683 inline JSValue::JSValue(ExecState* exec, unsigned long long i)
684 {
685 if (static_cast<uint32_t>(i) != i) {
686 *this = JSValue(exec, static_cast<double>(i));
687 return;
688 }
689 *this = JSValue(exec, static_cast<uint32_t>(i));
690 }
691
692 inline JSValue::JSValue(JSGlobalData* globalData, double d)
693 {
694 const int32_t asInt32 = static_cast<int32_t>(d);
695 if (asInt32 != d || (!asInt32 && std::signbit(d))) { // true for -0.0
696 u.asDouble = d;
697 return;
698 }
699 *this = JSValue(globalData, static_cast<int32_t>(d));
700 }
701
702 inline JSValue::JSValue(JSGlobalData*, int i)
703 {
704 u.asBits.tag = Int32Tag;
705 u.asBits.payload = i;
706 }
707
708 inline JSValue::JSValue(JSGlobalData* globalData, unsigned i)
709 {
710 if (static_cast<int32_t>(i) < 0) {
711 *this = JSValue(globalData, static_cast<double>(i));
712 return;
713 }
714 *this = JSValue(globalData, static_cast<int32_t>(i));
715 }
716
717 inline bool JSValue::isNumber() const
718 {
719 return isInt32() || isDouble();
720 }
721
722 inline bool JSValue::isBoolean() const
723 {
724 return isTrue() || isFalse();
725 }
726
727 inline bool JSValue::getBoolean(bool& v) const
728 {
729 if (isTrue()) {
730 v = true;
731 return true;
732 }
733 if (isFalse()) {
734 v = false;
735 return true;
736 }
737
738 return false;
739 }
740
741 inline bool JSValue::getBoolean() const
742 {
743 ASSERT(isBoolean());
744 return tag() == TrueTag;
745 }
746
747 inline double JSValue::uncheckedGetNumber() const
748 {
749 ASSERT(isNumber());
750 return isInt32() ? asInt32() : asDouble();
751 }
752
753 ALWAYS_INLINE JSValue JSValue::toJSNumber(ExecState* exec) const
754 {
755 return isNumber() ? asValue() : jsNumber(exec, this->toNumber(exec));
756 }
757
758 inline bool JSValue::getNumber(double& result) const
759 {
760 if (isInt32()) {
761 result = asInt32();
762 return true;
763 }
764 if (isDouble()) {
765 result = asDouble();
766 return true;
767 }
768 return false;
769 }
770
771#else // USE(JSVALUE32_64)
772
773 // JSValue member functions.
774 inline EncodedJSValue JSValue::encode(JSValue value)
775 {
776 EncodedJSValue r;
777 memcpy(dest: &r, src: &value.m_ptr, n: sizeof(r));
778 return r;
779 }
780
781 inline JSValue JSValue::decode(EncodedJSValue ptr)
782 {
783 JSCell *cellPtr;
784 memcpy(dest: &cellPtr, src: &ptr, n: sizeof(cellPtr));
785 return JSValue(cellPtr);
786 }
787
788 inline JSValue JSValue::makeImmediate(intptr_t value)
789 {
790 JSCell *cellPtr;
791 memcpy(dest: &cellPtr, src: &value, n: sizeof(cellPtr));
792 return JSValue(cellPtr);
793 }
794
795 inline intptr_t JSValue::immediateValue()
796 {
797 intptr_t v;
798 memcpy(dest: &v, src: &m_ptr, n: sizeof(v));
799 return v;
800 }
801
802 // 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.
803 inline JSValue::JSValue()
804 : m_ptr(0)
805 {
806 }
807
808 // 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.
809 inline JSValue::JSValue(HashTableDeletedValueTag)
810 : m_ptr(reinterpret_cast<JSCell*>(0x4))
811 {
812 }
813
814 inline JSValue::JSValue(JSCell* ptr)
815 : m_ptr(ptr)
816 {
817#if ENABLE(JSC_ZOMBIES)
818 ASSERT(!isZombie());
819#endif
820 }
821
822 inline JSValue::JSValue(const JSCell* ptr)
823 : m_ptr(const_cast<JSCell*>(ptr))
824 {
825#if ENABLE(JSC_ZOMBIES)
826 ASSERT(!isZombie());
827#endif
828 }
829
830 inline JSValue::operator bool() const
831 {
832 return m_ptr;
833 }
834
835 inline bool JSValue::operator==(const JSValue& other) const
836 {
837 return m_ptr == other.m_ptr;
838 }
839
840 inline bool JSValue::operator!=(const JSValue& other) const
841 {
842 return m_ptr != other.m_ptr;
843 }
844
845 inline bool JSValue::isUndefined() const
846 {
847 return asValue() == jsUndefined();
848 }
849
850 inline bool JSValue::isNull() const
851 {
852 return asValue() == jsNull();
853 }
854#endif // USE(JSVALUE32_64)
855
856} // namespace JSC
857
858#endif // JSValue_h
859

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