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::uncheckedGetNumber() const
60 return isInt32() ? asInt32() : asDouble();
63 ALWAYS_INLINE JSValue JSValue::toJSNumber(ExecState* exec) const
65 return isNumber() ? asValue() : jsNumber(this->toNumber(exec));
68 inline JSValue jsNaN()
70 return JSValue(std::numeric_limits<double>::quiet_NaN());
73 inline bool JSValue::getNumber(double& result) const
86 inline bool JSValue::getBoolean(bool& v) const
100 inline JSValue::JSValue(char i)
102 *this = JSValue(static_cast<int32_t>(i));
105 inline JSValue::JSValue(unsigned char i)
107 *this = JSValue(static_cast<int32_t>(i));
110 inline JSValue::JSValue(short i)
112 *this = JSValue(static_cast<int32_t>(i));
115 inline JSValue::JSValue(unsigned short i)
117 *this = JSValue(static_cast<int32_t>(i));
120 inline JSValue::JSValue(unsigned i)
122 if (static_cast<int32_t>(i) < 0) {
123 *this = JSValue(EncodeAsDouble, static_cast<double>(i));
126 *this = JSValue(static_cast<int32_t>(i));
129 inline JSValue::JSValue(long i)
131 if (static_cast<int32_t>(i) != i) {
132 *this = JSValue(EncodeAsDouble, static_cast<double>(i));
135 *this = JSValue(static_cast<int32_t>(i));
138 inline JSValue::JSValue(unsigned long i)
140 if (static_cast<uint32_t>(i) != i) {
141 *this = JSValue(EncodeAsDouble, static_cast<double>(i));
144 *this = JSValue(static_cast<uint32_t>(i));
147 inline JSValue::JSValue(long long i)
149 if (static_cast<int32_t>(i) != i) {
150 *this = JSValue(EncodeAsDouble, static_cast<double>(i));
153 *this = JSValue(static_cast<int32_t>(i));
156 inline JSValue::JSValue(unsigned long long i)
158 if (static_cast<uint32_t>(i) != i) {
159 *this = JSValue(EncodeAsDouble, static_cast<double>(i));
162 *this = JSValue(static_cast<uint32_t>(i));
165 inline JSValue::JSValue(double d)
167 const int32_t asInt32 = static_cast<int32_t>(d);
168 if (asInt32 != d || (!asInt32 && signbit(d))) { // true for -0.0
169 *this = JSValue(EncodeAsDouble, d);
172 *this = JSValue(static_cast<int32_t>(d));
175 #if USE(JSVALUE32_64)
176 inline EncodedJSValue JSValue::encode(JSValue value)
178 return value.u.asInt64;
181 inline JSValue JSValue::decode(EncodedJSValue encodedJSValue)
184 v.u.asInt64 = encodedJSValue;
188 inline JSValue::JSValue()
190 u.asBits.tag = EmptyValueTag;
191 u.asBits.payload = 0;
194 inline JSValue::JSValue(JSNullTag)
196 u.asBits.tag = NullTag;
197 u.asBits.payload = 0;
200 inline JSValue::JSValue(JSUndefinedTag)
202 u.asBits.tag = UndefinedTag;
203 u.asBits.payload = 0;
206 inline JSValue::JSValue(JSTrueTag)
208 u.asBits.tag = BooleanTag;
209 u.asBits.payload = 1;
212 inline JSValue::JSValue(JSFalseTag)
214 u.asBits.tag = BooleanTag;
215 u.asBits.payload = 0;
218 inline JSValue::JSValue(HashTableDeletedValueTag)
220 u.asBits.tag = DeletedValueTag;
221 u.asBits.payload = 0;
224 inline JSValue::JSValue(JSCell* ptr)
227 u.asBits.tag = CellTag;
229 u.asBits.tag = EmptyValueTag;
230 u.asBits.payload = reinterpret_cast<int32_t>(ptr);
233 inline JSValue::JSValue(const JSCell* ptr)
236 u.asBits.tag = CellTag;
238 u.asBits.tag = EmptyValueTag;
239 u.asBits.payload = reinterpret_cast<int32_t>(const_cast<JSCell*>(ptr));
242 inline JSValue::operator bool() const
244 ASSERT(tag() != DeletedValueTag);
245 return tag() != EmptyValueTag;
248 inline bool JSValue::operator==(const JSValue& other) const
250 return u.asInt64 == other.u.asInt64;
253 inline bool JSValue::operator!=(const JSValue& other) const
255 return u.asInt64 != other.u.asInt64;
258 inline bool JSValue::isUndefined() const
260 return tag() == UndefinedTag;
263 inline bool JSValue::isNull() const
265 return tag() == NullTag;
268 inline bool JSValue::isUndefinedOrNull() const
270 return isUndefined() || isNull();
273 inline bool JSValue::isCell() const
275 return tag() == CellTag;
278 inline bool JSValue::isInt32() const
280 return tag() == Int32Tag;
283 inline bool JSValue::isDouble() const
285 return tag() < LowestTag;
288 inline bool JSValue::isTrue() const
290 return tag() == BooleanTag && payload();
293 inline bool JSValue::isFalse() const
295 return tag() == BooleanTag && !payload();
298 inline uint32_t JSValue::tag() const
303 inline int32_t JSValue::payload() const
305 return u.asBits.payload;
308 inline int32_t JSValue::asInt32() const
311 return u.asBits.payload;
314 inline double JSValue::asDouble() const
320 ALWAYS_INLINE JSCell* JSValue::asCell() const
323 return reinterpret_cast<JSCell*>(u.asBits.payload);
326 ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, double d)
331 inline JSValue::JSValue(int i)
333 u.asBits.tag = Int32Tag;
334 u.asBits.payload = i;
337 inline bool JSValue::isNumber() const
339 return isInt32() || isDouble();
342 inline bool JSValue::isBoolean() const
344 return isTrue() || isFalse();
347 inline bool JSValue::getBoolean() const
353 #else // USE(JSVALUE32_64)
355 // JSValue member functions.
356 inline EncodedJSValue JSValue::encode(JSValue value)
361 inline JSValue JSValue::decode(EncodedJSValue ptr)
363 return JSValue(reinterpret_cast<JSCell*>(ptr));
366 // 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.
367 inline JSValue::JSValue()
369 u.asInt64 = ValueEmpty;
372 // 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.
373 inline JSValue::JSValue(HashTableDeletedValueTag)
375 u.asInt64 = ValueDeleted;
378 inline JSValue::JSValue(JSCell* ptr)
383 inline JSValue::JSValue(const JSCell* ptr)
385 u.ptr = const_cast<JSCell*>(ptr);
388 inline JSValue::operator bool() const
393 inline bool JSValue::operator==(const JSValue& other) const
395 return u.ptr == other.u.ptr;
398 inline bool JSValue::operator!=(const JSValue& other) const
400 return u.ptr != other.u.ptr;
403 inline bool JSValue::isUndefined() const
405 return asValue() == jsUndefined();
408 inline bool JSValue::isNull() const
410 return asValue() == jsNull();
413 inline bool JSValue::isTrue() const
415 return asValue() == JSValue(JSTrue);
418 inline bool JSValue::isFalse() const
420 return asValue() == JSValue(JSFalse);
423 inline bool JSValue::getBoolean() const
425 ASSERT(asValue() == jsBoolean(true) || asValue() == jsBoolean(false));
426 return asValue() == jsBoolean(true);
429 inline int32_t JSValue::asInt32() const
432 return static_cast<int32_t>(u.asInt64);
435 inline bool JSValue::isDouble() const
437 return isNumber() && !isInt32();
440 inline JSValue::JSValue(JSNullTag)
442 u.asInt64 = ValueNull;
445 inline JSValue::JSValue(JSUndefinedTag)
447 u.asInt64 = ValueUndefined;
450 inline JSValue::JSValue(JSTrueTag)
452 u.asInt64 = ValueTrue;
455 inline JSValue::JSValue(JSFalseTag)
457 u.asInt64 = ValueFalse;
460 inline bool JSValue::isUndefinedOrNull() const
462 // Undefined and null share the same value, bar the 'undefined' bit in the extended tag.
463 return (u.asInt64 & ~TagBitUndefined) == ValueNull;
466 inline bool JSValue::isBoolean() const
468 return (u.asInt64 & ~1) == ValueFalse;
471 inline bool JSValue::isCell() const
473 return !(u.asInt64 & TagMask);
476 inline bool JSValue::isInt32() const
478 return (u.asInt64 & TagTypeNumber) == TagTypeNumber;
481 inline intptr_t reinterpretDoubleToIntptr(double value)
483 return bitwise_cast<intptr_t>(value);
485 inline double reinterpretIntptrToDouble(intptr_t value)
487 return bitwise_cast<double>(value);
490 ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, double d)
492 u.asInt64 = reinterpretDoubleToIntptr(d) + DoubleEncodeOffset;
495 inline JSValue::JSValue(int i)
497 u.asInt64 = TagTypeNumber | static_cast<uint32_t>(i);
500 inline double JSValue::asDouble() const
502 return reinterpretIntptrToDouble(u.asInt64 - DoubleEncodeOffset);
505 inline bool JSValue::isNumber() const
507 return u.asInt64 & TagTypeNumber;
510 ALWAYS_INLINE JSCell* JSValue::asCell() const
516 #endif // USE(JSVALUE64)
520 #endif // JSValueInlineMethods_h