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
481 return reinterpretIntptrToDouble(u
.asInt64
- DoubleEncodeOffset
);
484 inline bool JSValue::isNumber() const
486 return u
.asInt64
& TagTypeNumber
;
489 ALWAYS_INLINE JSCell
* JSValue::asCell() const
495 #endif // USE(JSVALUE64)
499 #endif // JSValueInlineMethods_h