]> git.saurik.com Git - apple/javascriptcore.git/blob - runtime/JSCJSValueInlines.h
JavaScriptCore-1218.35.tar.gz
[apple/javascriptcore.git] / runtime / JSCJSValueInlines.h
1 /*
2 * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26 #ifndef JSValueInlines_h
27 #define JSValueInlines_h
28
29 #include "InternalFunction.h"
30 #include "JSCJSValue.h"
31 #include "JSCellInlines.h"
32 #include "JSFunction.h"
33
34 namespace JSC {
35
36 ALWAYS_INLINE int32_t JSValue::toInt32(ExecState* exec) const
37 {
38 if (isInt32())
39 return asInt32();
40 return JSC::toInt32(toNumber(exec));
41 }
42
43 inline uint32_t JSValue::toUInt32(ExecState* exec) const
44 {
45 // See comment on JSC::toUInt32, above.
46 return toInt32(exec);
47 }
48
49 inline bool JSValue::isUInt32() const
50 {
51 return isInt32() && asInt32() >= 0;
52 }
53
54 inline uint32_t JSValue::asUInt32() const
55 {
56 ASSERT(isUInt32());
57 return asInt32();
58 }
59
60 inline double JSValue::asNumber() const
61 {
62 ASSERT(isNumber());
63 return isInt32() ? asInt32() : asDouble();
64 }
65
66 inline JSValue jsNaN()
67 {
68 return JSValue(QNaN);
69 }
70
71 inline JSValue::JSValue(char i)
72 {
73 *this = JSValue(static_cast<int32_t>(i));
74 }
75
76 inline JSValue::JSValue(unsigned char i)
77 {
78 *this = JSValue(static_cast<int32_t>(i));
79 }
80
81 inline JSValue::JSValue(short i)
82 {
83 *this = JSValue(static_cast<int32_t>(i));
84 }
85
86 inline JSValue::JSValue(unsigned short i)
87 {
88 *this = JSValue(static_cast<int32_t>(i));
89 }
90
91 inline JSValue::JSValue(unsigned i)
92 {
93 if (static_cast<int32_t>(i) < 0) {
94 *this = JSValue(EncodeAsDouble, static_cast<double>(i));
95 return;
96 }
97 *this = JSValue(static_cast<int32_t>(i));
98 }
99
100 inline JSValue::JSValue(long i)
101 {
102 if (static_cast<int32_t>(i) != i) {
103 *this = JSValue(EncodeAsDouble, static_cast<double>(i));
104 return;
105 }
106 *this = JSValue(static_cast<int32_t>(i));
107 }
108
109 inline JSValue::JSValue(unsigned long i)
110 {
111 if (static_cast<uint32_t>(i) != i) {
112 *this = JSValue(EncodeAsDouble, static_cast<double>(i));
113 return;
114 }
115 *this = JSValue(static_cast<uint32_t>(i));
116 }
117
118 inline JSValue::JSValue(long long i)
119 {
120 if (static_cast<int32_t>(i) != i) {
121 *this = JSValue(EncodeAsDouble, static_cast<double>(i));
122 return;
123 }
124 *this = JSValue(static_cast<int32_t>(i));
125 }
126
127 inline JSValue::JSValue(unsigned long long i)
128 {
129 if (static_cast<uint32_t>(i) != i) {
130 *this = JSValue(EncodeAsDouble, static_cast<double>(i));
131 return;
132 }
133 *this = JSValue(static_cast<uint32_t>(i));
134 }
135
136 inline JSValue::JSValue(double d)
137 {
138 const int32_t asInt32 = static_cast<int32_t>(d);
139 if (asInt32 != d || (!asInt32 && std::signbit(d))) { // true for -0.0
140 *this = JSValue(EncodeAsDouble, d);
141 return;
142 }
143 *this = JSValue(static_cast<int32_t>(d));
144 }
145
146 inline EncodedJSValue JSValue::encode(JSValue value)
147 {
148 return value.u.asInt64;
149 }
150
151 inline JSValue JSValue::decode(EncodedJSValue encodedJSValue)
152 {
153 JSValue v;
154 v.u.asInt64 = encodedJSValue;
155 return v;
156 }
157
158 #if USE(JSVALUE32_64)
159 inline JSValue::JSValue()
160 {
161 u.asBits.tag = EmptyValueTag;
162 u.asBits.payload = 0;
163 }
164
165 inline JSValue::JSValue(JSNullTag)
166 {
167 u.asBits.tag = NullTag;
168 u.asBits.payload = 0;
169 }
170
171 inline JSValue::JSValue(JSUndefinedTag)
172 {
173 u.asBits.tag = UndefinedTag;
174 u.asBits.payload = 0;
175 }
176
177 inline JSValue::JSValue(JSTrueTag)
178 {
179 u.asBits.tag = BooleanTag;
180 u.asBits.payload = 1;
181 }
182
183 inline JSValue::JSValue(JSFalseTag)
184 {
185 u.asBits.tag = BooleanTag;
186 u.asBits.payload = 0;
187 }
188
189 inline JSValue::JSValue(HashTableDeletedValueTag)
190 {
191 u.asBits.tag = DeletedValueTag;
192 u.asBits.payload = 0;
193 }
194
195 inline JSValue::JSValue(JSCell* ptr)
196 {
197 if (ptr)
198 u.asBits.tag = CellTag;
199 else
200 u.asBits.tag = EmptyValueTag;
201 u.asBits.payload = reinterpret_cast<int32_t>(ptr);
202 }
203
204 inline JSValue::JSValue(const JSCell* ptr)
205 {
206 if (ptr)
207 u.asBits.tag = CellTag;
208 else
209 u.asBits.tag = EmptyValueTag;
210 u.asBits.payload = reinterpret_cast<int32_t>(const_cast<JSCell*>(ptr));
211 }
212
213 inline JSValue::operator bool() const
214 {
215 ASSERT(tag() != DeletedValueTag);
216 return tag() != EmptyValueTag;
217 }
218
219 inline bool JSValue::operator==(const JSValue& other) const
220 {
221 return u.asInt64 == other.u.asInt64;
222 }
223
224 inline bool JSValue::operator!=(const JSValue& other) const
225 {
226 return u.asInt64 != other.u.asInt64;
227 }
228
229 inline bool JSValue::isEmpty() const
230 {
231 return tag() == EmptyValueTag;
232 }
233
234 inline bool JSValue::isUndefined() const
235 {
236 return tag() == UndefinedTag;
237 }
238
239 inline bool JSValue::isNull() const
240 {
241 return tag() == NullTag;
242 }
243
244 inline bool JSValue::isUndefinedOrNull() const
245 {
246 return isUndefined() || isNull();
247 }
248
249 inline bool JSValue::isCell() const
250 {
251 return tag() == CellTag;
252 }
253
254 inline bool JSValue::isInt32() const
255 {
256 return tag() == Int32Tag;
257 }
258
259 inline bool JSValue::isDouble() const
260 {
261 return tag() < LowestTag;
262 }
263
264 inline bool JSValue::isTrue() const
265 {
266 return tag() == BooleanTag && payload();
267 }
268
269 inline bool JSValue::isFalse() const
270 {
271 return tag() == BooleanTag && !payload();
272 }
273
274 inline uint32_t JSValue::tag() const
275 {
276 return u.asBits.tag;
277 }
278
279 inline int32_t JSValue::payload() const
280 {
281 return u.asBits.payload;
282 }
283
284 inline int32_t JSValue::asInt32() const
285 {
286 ASSERT(isInt32());
287 return u.asBits.payload;
288 }
289
290 inline double JSValue::asDouble() const
291 {
292 ASSERT(isDouble());
293 return u.asDouble;
294 }
295
296 ALWAYS_INLINE JSCell* JSValue::asCell() const
297 {
298 ASSERT(isCell());
299 return reinterpret_cast<JSCell*>(u.asBits.payload);
300 }
301
302 ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, double d)
303 {
304 u.asDouble = d;
305 }
306
307 inline JSValue::JSValue(int i)
308 {
309 u.asBits.tag = Int32Tag;
310 u.asBits.payload = i;
311 }
312
313 #if ENABLE(LLINT_C_LOOP)
314 inline JSValue::JSValue(int32_t tag, int32_t payload)
315 {
316 u.asBits.tag = tag;
317 u.asBits.payload = payload;
318 }
319 #endif
320
321 inline bool JSValue::isNumber() const
322 {
323 return isInt32() || isDouble();
324 }
325
326 inline bool JSValue::isBoolean() const
327 {
328 return isTrue() || isFalse();
329 }
330
331 inline bool JSValue::asBoolean() const
332 {
333 ASSERT(isBoolean());
334 return payload();
335 }
336
337 #else // !USE(JSVALUE32_64) i.e. USE(JSVALUE64)
338
339 // 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.
340 inline JSValue::JSValue()
341 {
342 u.asInt64 = ValueEmpty;
343 }
344
345 // 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.
346 inline JSValue::JSValue(HashTableDeletedValueTag)
347 {
348 u.asInt64 = ValueDeleted;
349 }
350
351 inline JSValue::JSValue(JSCell* ptr)
352 {
353 u.asInt64 = reinterpret_cast<uintptr_t>(ptr);
354 }
355
356 inline JSValue::JSValue(const JSCell* ptr)
357 {
358 u.asInt64 = reinterpret_cast<uintptr_t>(const_cast<JSCell*>(ptr));
359 }
360
361 inline JSValue::operator bool() const
362 {
363 return u.asInt64;
364 }
365
366 inline bool JSValue::operator==(const JSValue& other) const
367 {
368 return u.asInt64 == other.u.asInt64;
369 }
370
371 inline bool JSValue::operator!=(const JSValue& other) const
372 {
373 return u.asInt64 != other.u.asInt64;
374 }
375
376 inline bool JSValue::isEmpty() const
377 {
378 return u.asInt64 == ValueEmpty;
379 }
380
381 inline bool JSValue::isUndefined() const
382 {
383 return asValue() == JSValue(JSUndefined);
384 }
385
386 inline bool JSValue::isNull() const
387 {
388 return asValue() == JSValue(JSNull);
389 }
390
391 inline bool JSValue::isTrue() const
392 {
393 return asValue() == JSValue(JSTrue);
394 }
395
396 inline bool JSValue::isFalse() const
397 {
398 return asValue() == JSValue(JSFalse);
399 }
400
401 inline bool JSValue::asBoolean() const
402 {
403 ASSERT(isBoolean());
404 return asValue() == JSValue(JSTrue);
405 }
406
407 inline int32_t JSValue::asInt32() const
408 {
409 ASSERT(isInt32());
410 return static_cast<int32_t>(u.asInt64);
411 }
412
413 inline bool JSValue::isDouble() const
414 {
415 return isNumber() && !isInt32();
416 }
417
418 inline JSValue::JSValue(JSNullTag)
419 {
420 u.asInt64 = ValueNull;
421 }
422
423 inline JSValue::JSValue(JSUndefinedTag)
424 {
425 u.asInt64 = ValueUndefined;
426 }
427
428 inline JSValue::JSValue(JSTrueTag)
429 {
430 u.asInt64 = ValueTrue;
431 }
432
433 inline JSValue::JSValue(JSFalseTag)
434 {
435 u.asInt64 = ValueFalse;
436 }
437
438 inline bool JSValue::isUndefinedOrNull() const
439 {
440 // Undefined and null share the same value, bar the 'undefined' bit in the extended tag.
441 return (u.asInt64 & ~TagBitUndefined) == ValueNull;
442 }
443
444 inline bool JSValue::isBoolean() const
445 {
446 return (u.asInt64 & ~1) == ValueFalse;
447 }
448
449 inline bool JSValue::isCell() const
450 {
451 return !(u.asInt64 & TagMask);
452 }
453
454 inline bool JSValue::isInt32() const
455 {
456 return (u.asInt64 & TagTypeNumber) == TagTypeNumber;
457 }
458
459 inline int64_t reinterpretDoubleToInt64(double value)
460 {
461 return bitwise_cast<int64_t>(value);
462 }
463 inline double reinterpretInt64ToDouble(int64_t value)
464 {
465 return bitwise_cast<double>(value);
466 }
467
468 ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, double d)
469 {
470 u.asInt64 = reinterpretDoubleToInt64(d) + DoubleEncodeOffset;
471 }
472
473 inline JSValue::JSValue(int i)
474 {
475 u.asInt64 = TagTypeNumber | static_cast<uint32_t>(i);
476 }
477
478 inline double JSValue::asDouble() const
479 {
480 ASSERT(isDouble());
481 return reinterpretInt64ToDouble(u.asInt64 - DoubleEncodeOffset);
482 }
483
484 inline bool JSValue::isNumber() const
485 {
486 return u.asInt64 & TagTypeNumber;
487 }
488
489 ALWAYS_INLINE JSCell* JSValue::asCell() const
490 {
491 ASSERT(isCell());
492 return u.ptr;
493 }
494
495 #endif // USE(JSVALUE64)
496
497 inline bool JSValue::isString() const
498 {
499 return isCell() && asCell()->isString();
500 }
501
502 inline bool JSValue::isPrimitive() const
503 {
504 return !isCell() || asCell()->isString();
505 }
506
507 inline bool JSValue::isGetterSetter() const
508 {
509 return isCell() && asCell()->isGetterSetter();
510 }
511
512 inline bool JSValue::isObject() const
513 {
514 return isCell() && asCell()->isObject();
515 }
516
517 inline bool JSValue::getString(ExecState* exec, String& s) const
518 {
519 return isCell() && asCell()->getString(exec, s);
520 }
521
522 inline String JSValue::getString(ExecState* exec) const
523 {
524 return isCell() ? asCell()->getString(exec) : String();
525 }
526
527 template <typename Base> String HandleConverter<Base, Unknown>::getString(ExecState* exec) const
528 {
529 return jsValue().getString(exec);
530 }
531
532 inline JSObject* JSValue::getObject() const
533 {
534 return isCell() ? asCell()->getObject() : 0;
535 }
536
537 ALWAYS_INLINE bool JSValue::getUInt32(uint32_t& v) const
538 {
539 if (isInt32()) {
540 int32_t i = asInt32();
541 v = static_cast<uint32_t>(i);
542 return i >= 0;
543 }
544 if (isDouble()) {
545 double d = asDouble();
546 v = static_cast<uint32_t>(d);
547 return v == d;
548 }
549 return false;
550 }
551
552 inline JSValue JSValue::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const
553 {
554 return isCell() ? asCell()->toPrimitive(exec, preferredType) : asValue();
555 }
556
557 inline bool JSValue::getPrimitiveNumber(ExecState* exec, double& number, JSValue& value)
558 {
559 if (isInt32()) {
560 number = asInt32();
561 value = *this;
562 return true;
563 }
564 if (isDouble()) {
565 number = asDouble();
566 value = *this;
567 return true;
568 }
569 if (isCell())
570 return asCell()->getPrimitiveNumber(exec, number, value);
571 if (isTrue()) {
572 number = 1.0;
573 value = *this;
574 return true;
575 }
576 if (isFalse() || isNull()) {
577 number = 0.0;
578 value = *this;
579 return true;
580 }
581 ASSERT(isUndefined());
582 number = QNaN;
583 value = *this;
584 return true;
585 }
586
587 ALWAYS_INLINE double JSValue::toNumber(ExecState* exec) const
588 {
589 if (isInt32())
590 return asInt32();
591 if (isDouble())
592 return asDouble();
593 return toNumberSlowCase(exec);
594 }
595
596 inline JSObject* JSValue::toObject(ExecState* exec) const
597 {
598 return isCell() ? asCell()->toObject(exec, exec->lexicalGlobalObject()) : toObjectSlowCase(exec, exec->lexicalGlobalObject());
599 }
600
601 inline JSObject* JSValue::toObject(ExecState* exec, JSGlobalObject* globalObject) const
602 {
603 return isCell() ? asCell()->toObject(exec, globalObject) : toObjectSlowCase(exec, globalObject);
604 }
605
606 inline bool JSValue::isFunction() const
607 {
608 return isCell() && (asCell()->inherits(&JSFunction::s_info) || asCell()->inherits(&InternalFunction::s_info));
609 }
610
611 // this method is here to be after the inline declaration of JSCell::inherits
612 inline bool JSValue::inherits(const ClassInfo* classInfo) const
613 {
614 return isCell() && asCell()->inherits(classInfo);
615 }
616
617 inline JSObject* JSValue::toThisObject(ExecState* exec) const
618 {
619 return isCell() ? asCell()->methodTable()->toThisObject(asCell(), exec) : toThisObjectSlowCase(exec);
620 }
621
622 inline JSValue JSValue::get(ExecState* exec, PropertyName propertyName) const
623 {
624 PropertySlot slot(asValue());
625 return get(exec, propertyName, slot);
626 }
627
628 inline JSValue JSValue::get(ExecState* exec, PropertyName propertyName, PropertySlot& slot) const
629 {
630 if (UNLIKELY(!isCell())) {
631 JSObject* prototype = synthesizePrototype(exec);
632 if (!prototype->getPropertySlot(exec, propertyName, slot))
633 return jsUndefined();
634 return slot.getValue(exec, propertyName);
635 }
636 JSCell* cell = asCell();
637 while (true) {
638 if (cell->fastGetOwnPropertySlot(exec, propertyName, slot))
639 return slot.getValue(exec, propertyName);
640 JSValue prototype = asObject(cell)->prototype();
641 if (!prototype.isObject())
642 return jsUndefined();
643 cell = asObject(prototype);
644 }
645 }
646
647 inline JSValue JSValue::get(ExecState* exec, unsigned propertyName) const
648 {
649 PropertySlot slot(asValue());
650 return get(exec, propertyName, slot);
651 }
652
653 inline JSValue JSValue::get(ExecState* exec, unsigned propertyName, PropertySlot& slot) const
654 {
655 if (UNLIKELY(!isCell())) {
656 JSObject* prototype = synthesizePrototype(exec);
657 if (!prototype->getPropertySlot(exec, propertyName, slot))
658 return jsUndefined();
659 return slot.getValue(exec, propertyName);
660 }
661 JSCell* cell = const_cast<JSCell*>(asCell());
662 while (true) {
663 if (cell->methodTable()->getOwnPropertySlotByIndex(cell, exec, propertyName, slot))
664 return slot.getValue(exec, propertyName);
665 JSValue prototype = asObject(cell)->prototype();
666 if (!prototype.isObject())
667 return jsUndefined();
668 cell = prototype.asCell();
669 }
670 }
671
672 inline void JSValue::put(ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
673 {
674 if (UNLIKELY(!isCell())) {
675 putToPrimitive(exec, propertyName, value, slot);
676 return;
677 }
678 asCell()->methodTable()->put(asCell(), exec, propertyName, value, slot);
679 }
680
681 inline void JSValue::putByIndex(ExecState* exec, unsigned propertyName, JSValue value, bool shouldThrow)
682 {
683 if (UNLIKELY(!isCell())) {
684 putToPrimitiveByIndex(exec, propertyName, value, shouldThrow);
685 return;
686 }
687 asCell()->methodTable()->putByIndex(asCell(), exec, propertyName, value, shouldThrow);
688 }
689
690 inline JSValue JSValue::structureOrUndefined() const
691 {
692 if (isCell())
693 return JSValue(asCell()->structure());
694 return jsUndefined();
695 }
696
697 // ECMA 11.9.3
698 inline bool JSValue::equal(ExecState* exec, JSValue v1, JSValue v2)
699 {
700 if (v1.isInt32() && v2.isInt32())
701 return v1 == v2;
702
703 return equalSlowCase(exec, v1, v2);
704 }
705
706 ALWAYS_INLINE bool JSValue::equalSlowCaseInline(ExecState* exec, JSValue v1, JSValue v2)
707 {
708 do {
709 if (v1.isNumber() && v2.isNumber())
710 return v1.asNumber() == v2.asNumber();
711
712 bool s1 = v1.isString();
713 bool s2 = v2.isString();
714 if (s1 && s2)
715 return asString(v1)->value(exec) == asString(v2)->value(exec);
716
717 if (v1.isUndefinedOrNull()) {
718 if (v2.isUndefinedOrNull())
719 return true;
720 if (!v2.isCell())
721 return false;
722 return v2.asCell()->structure()->masqueradesAsUndefined(exec->lexicalGlobalObject());
723 }
724
725 if (v2.isUndefinedOrNull()) {
726 if (!v1.isCell())
727 return false;
728 return v1.asCell()->structure()->masqueradesAsUndefined(exec->lexicalGlobalObject());
729 }
730
731 if (v1.isObject()) {
732 if (v2.isObject())
733 return v1 == v2;
734 JSValue p1 = v1.toPrimitive(exec);
735 if (exec->hadException())
736 return false;
737 v1 = p1;
738 if (v1.isInt32() && v2.isInt32())
739 return v1 == v2;
740 continue;
741 }
742
743 if (v2.isObject()) {
744 JSValue p2 = v2.toPrimitive(exec);
745 if (exec->hadException())
746 return false;
747 v2 = p2;
748 if (v1.isInt32() && v2.isInt32())
749 return v1 == v2;
750 continue;
751 }
752
753 if (s1 || s2) {
754 double d1 = v1.toNumber(exec);
755 double d2 = v2.toNumber(exec);
756 return d1 == d2;
757 }
758
759 if (v1.isBoolean()) {
760 if (v2.isNumber())
761 return static_cast<double>(v1.asBoolean()) == v2.asNumber();
762 } else if (v2.isBoolean()) {
763 if (v1.isNumber())
764 return v1.asNumber() == static_cast<double>(v2.asBoolean());
765 }
766
767 return v1 == v2;
768 } while (true);
769 }
770
771 // ECMA 11.9.3
772 ALWAYS_INLINE bool JSValue::strictEqualSlowCaseInline(ExecState* exec, JSValue v1, JSValue v2)
773 {
774 ASSERT(v1.isCell() && v2.isCell());
775
776 if (v1.asCell()->isString() && v2.asCell()->isString())
777 return asString(v1)->value(exec) == asString(v2)->value(exec);
778
779 return v1 == v2;
780 }
781
782 inline bool JSValue::strictEqual(ExecState* exec, JSValue v1, JSValue v2)
783 {
784 if (v1.isInt32() && v2.isInt32())
785 return v1 == v2;
786
787 if (v1.isNumber() && v2.isNumber())
788 return v1.asNumber() == v2.asNumber();
789
790 if (!v1.isCell() || !v2.isCell())
791 return v1 == v2;
792
793 return strictEqualSlowCaseInline(exec, v1, v2);
794 }
795
796 inline TriState JSValue::pureToBoolean() const
797 {
798 if (isInt32())
799 return asInt32() ? TrueTriState : FalseTriState;
800 if (isDouble())
801 return isNotZeroAndOrdered(asDouble()) ? TrueTriState : FalseTriState; // false for NaN
802 if (isCell())
803 return asCell()->pureToBoolean();
804 return isTrue() ? TrueTriState : FalseTriState;
805 }
806
807 } // namespace JSC
808
809 #endif // JSValueInlines_h
810