2 * Copyright (C) 2011 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
26 #ifndef JSValueInlineMethods_h
27 #define JSValueInlineMethods_h
33 ALWAYS_INLINE int32_t JSValue::toInt32(ExecState* exec) const
37 return JSC::toInt32(toNumber(exec));
40 inline uint32_t JSValue::toUInt32(ExecState* exec) const
42 // See comment on JSC::toUInt32, above.
46 inline bool JSValue::isUInt32() const
48 return isInt32() && asInt32() >= 0;
51 inline uint32_t JSValue::asUInt32() const
57 inline double JSValue::asNumber() const
60 return isInt32() ? asInt32() : asDouble();
63 inline JSValue jsNaN()
65 return JSValue(std::numeric_limits<double>::quiet_NaN());
68 inline JSValue::JSValue(char i)
70 *this = JSValue(static_cast<int32_t>(i));
73 inline JSValue::JSValue(unsigned char i)
75 *this = JSValue(static_cast<int32_t>(i));
78 inline JSValue::JSValue(short i)
80 *this = JSValue(static_cast<int32_t>(i));
83 inline JSValue::JSValue(unsigned short i)
85 *this = JSValue(static_cast<int32_t>(i));
88 inline JSValue::JSValue(unsigned i)
90 if (static_cast<int32_t>(i) < 0) {
91 *this = JSValue(EncodeAsDouble, static_cast<double>(i));
94 *this = JSValue(static_cast<int32_t>(i));
97 inline JSValue::JSValue(long i)
99 if (static_cast<int32_t>(i) != i) {
100 *this = JSValue(EncodeAsDouble, static_cast<double>(i));
103 *this = JSValue(static_cast<int32_t>(i));
106 inline JSValue::JSValue(unsigned long i)
108 if (static_cast<uint32_t>(i) != i) {
109 *this = JSValue(EncodeAsDouble, static_cast<double>(i));
112 *this = JSValue(static_cast<uint32_t>(i));
115 inline JSValue::JSValue(long long i)
117 if (static_cast<int32_t>(i) != i) {
118 *this = JSValue(EncodeAsDouble, static_cast<double>(i));
121 *this = JSValue(static_cast<int32_t>(i));
124 inline JSValue::JSValue(unsigned long long i)
126 if (static_cast<uint32_t>(i) != i) {
127 *this = JSValue(EncodeAsDouble, static_cast<double>(i));
130 *this = JSValue(static_cast<uint32_t>(i));
133 inline JSValue::JSValue(double d)
135 const int32_t asInt32 = static_cast<int32_t>(d);
136 if (asInt32 != d || (!asInt32 && signbit(d))) { // true for -0.0
137 *this = JSValue(EncodeAsDouble, d);
140 *this = JSValue(static_cast<int32_t>(d));
143 #if USE(JSVALUE32_64)
144 inline EncodedJSValue JSValue::encode(JSValue value)
146 return value.u.asInt64;
149 inline JSValue JSValue::decode(EncodedJSValue encodedJSValue)
152 v.u.asInt64 = encodedJSValue;
156 inline JSValue::JSValue()
158 u.asBits.tag = EmptyValueTag;
159 u.asBits.payload = 0;
162 inline JSValue::JSValue(JSNullTag)
164 u.asBits.tag = NullTag;
165 u.asBits.payload = 0;
168 inline JSValue::JSValue(JSUndefinedTag)
170 u.asBits.tag = UndefinedTag;
171 u.asBits.payload = 0;
174 inline JSValue::JSValue(JSTrueTag)
176 u.asBits.tag = BooleanTag;
177 u.asBits.payload = 1;
180 inline JSValue::JSValue(JSFalseTag)
182 u.asBits.tag = BooleanTag;
183 u.asBits.payload = 0;
186 inline JSValue::JSValue(HashTableDeletedValueTag)
188 u.asBits.tag = DeletedValueTag;
189 u.asBits.payload = 0;
192 inline JSValue::JSValue(JSCell* ptr)
195 u.asBits.tag = CellTag;
197 u.asBits.tag = EmptyValueTag;
198 u.asBits.payload = reinterpret_cast<int32_t>(ptr);
201 inline JSValue::JSValue(const JSCell* ptr)
204 u.asBits.tag = CellTag;
206 u.asBits.tag = EmptyValueTag;
207 u.asBits.payload = reinterpret_cast<int32_t>(const_cast<JSCell*>(ptr));
210 inline JSValue::operator bool() const
212 ASSERT(tag() != DeletedValueTag);
213 return tag() != EmptyValueTag;
216 inline bool JSValue::operator==(const JSValue& other) const
218 return u.asInt64 == other.u.asInt64;
221 inline bool JSValue::operator!=(const JSValue& other) const
223 return u.asInt64 != other.u.asInt64;
226 inline bool JSValue::isEmpty() const
228 return tag() == EmptyValueTag;
231 inline bool JSValue::isUndefined() const
233 return tag() == UndefinedTag;
236 inline bool JSValue::isNull() const
238 return tag() == NullTag;
241 inline bool JSValue::isUndefinedOrNull() const
243 return isUndefined() || isNull();
246 inline bool JSValue::isCell() const
248 return tag() == CellTag;
251 inline bool JSValue::isInt32() const
253 return tag() == Int32Tag;
256 inline bool JSValue::isDouble() const
258 return tag() < LowestTag;
261 inline bool JSValue::isTrue() const
263 return tag() == BooleanTag && payload();
266 inline bool JSValue::isFalse() const
268 return tag() == BooleanTag && !payload();
271 inline uint32_t JSValue::tag() const
276 inline int32_t JSValue::payload() const
278 return u.asBits.payload;
281 inline int32_t JSValue::asInt32() const
284 return u.asBits.payload;
287 inline double JSValue::asDouble() const
293 ALWAYS_INLINE JSCell* JSValue::asCell() const
296 return reinterpret_cast<JSCell*>(u.asBits.payload);
299 ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, double d)
304 inline JSValue::JSValue(int i)
306 u.asBits.tag = Int32Tag;
307 u.asBits.payload = i;
310 inline bool JSValue::isNumber() const
312 return isInt32() || isDouble();
315 inline bool JSValue::isBoolean() const
317 return isTrue() || isFalse();
320 inline bool JSValue::asBoolean() const
326 #else // USE(JSVALUE32_64)
328 // JSValue member functions.
329 inline EncodedJSValue JSValue::encode(JSValue value)
334 inline JSValue JSValue::decode(EncodedJSValue ptr)
336 return JSValue(reinterpret_cast<JSCell*>(ptr));
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()
342 u.asInt64 = ValueEmpty;
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)
348 u.asInt64 = ValueDeleted;
351 inline JSValue::JSValue(JSCell* ptr)
356 inline JSValue::JSValue(const JSCell* ptr)
358 u.ptr = const_cast<JSCell*>(ptr);
361 inline JSValue::operator bool() const
366 inline bool JSValue::operator==(const JSValue& other) const
368 return u.ptr == other.u.ptr;
371 inline bool JSValue::operator!=(const JSValue& other) const
373 return u.ptr != other.u.ptr;
376 inline bool JSValue::isEmpty() const
378 return u.asInt64 == ValueEmpty;
381 inline bool JSValue::isUndefined() const
383 return asValue() == JSValue(JSUndefined);
386 inline bool JSValue::isNull() const
388 return asValue() == JSValue(JSNull);
391 inline bool JSValue::isTrue() const
393 return asValue() == JSValue(JSTrue);
396 inline bool JSValue::isFalse() const
398 return asValue() == JSValue(JSFalse);
401 inline bool JSValue::asBoolean() const
404 return asValue() == JSValue(JSTrue);
407 inline int32_t JSValue::asInt32() const
410 return static_cast<int32_t>(u.asInt64);
413 inline bool JSValue::isDouble() const
415 return isNumber() && !isInt32();
418 inline JSValue::JSValue(JSNullTag)
420 u.asInt64 = ValueNull;
423 inline JSValue::JSValue(JSUndefinedTag)
425 u.asInt64 = ValueUndefined;
428 inline JSValue::JSValue(JSTrueTag)
430 u.asInt64 = ValueTrue;
433 inline JSValue::JSValue(JSFalseTag)
435 u.asInt64 = ValueFalse;
438 inline bool JSValue::isUndefinedOrNull() const
440 // Undefined and null share the same value, bar the 'undefined' bit in the extended tag.
441 return (u.asInt64 & ~TagBitUndefined) == ValueNull;
444 inline bool JSValue::isBoolean() const
446 return (u.asInt64 & ~1) == ValueFalse;
449 inline bool JSValue::isCell() const
451 return !(u.asInt64 & TagMask);
454 inline bool JSValue::isInt32() const
456 return (u.asInt64 & TagTypeNumber) == TagTypeNumber;
459 inline intptr_t reinterpretDoubleToIntptr(double value)
461 return bitwise_cast<intptr_t>(value);
463 inline double reinterpretIntptrToDouble(intptr_t value)
465 return bitwise_cast<double>(value);
468 ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, double d)
470 u.asInt64 = reinterpretDoubleToIntptr(d) + DoubleEncodeOffset;
473 inline JSValue::JSValue(int i)
475 u.asInt64 = TagTypeNumber | static_cast<uint32_t>(i);
478 inline double JSValue::asDouble() const
480 return reinterpretIntptrToDouble(u.asInt64 - DoubleEncodeOffset);
483 inline bool JSValue::isNumber() const
485 return u.asInt64 & TagTypeNumber;
488 ALWAYS_INLINE JSCell* JSValue::asCell() const
494 #endif // USE(JSVALUE64)
498 #endif // JSValueInlineMethods_h