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(nonInlineNaN());
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
);
231 #if ENABLE(JSC_ZOMBIES)
236 inline JSValue::JSValue(const JSCell
* ptr
)
239 u
.asBits
.tag
= CellTag
;
241 u
.asBits
.tag
= EmptyValueTag
;
242 u
.asBits
.payload
= reinterpret_cast<int32_t>(const_cast<JSCell
*>(ptr
));
243 #if ENABLE(JSC_ZOMBIES)
248 inline JSValue::operator bool() const
250 ASSERT(tag() != DeletedValueTag
);
251 return tag() != EmptyValueTag
;
254 inline bool JSValue::operator==(const JSValue
& other
) const
256 return u
.asInt64
== other
.u
.asInt64
;
259 inline bool JSValue::operator!=(const JSValue
& other
) const
261 return u
.asInt64
!= other
.u
.asInt64
;
264 inline bool JSValue::isUndefined() const
266 return tag() == UndefinedTag
;
269 inline bool JSValue::isNull() const
271 return tag() == NullTag
;
274 inline bool JSValue::isUndefinedOrNull() const
276 return isUndefined() || isNull();
279 inline bool JSValue::isCell() const
281 return tag() == CellTag
;
284 inline bool JSValue::isInt32() const
286 return tag() == Int32Tag
;
289 inline bool JSValue::isDouble() const
291 return tag() < LowestTag
;
294 inline bool JSValue::isTrue() const
296 return tag() == BooleanTag
&& payload();
299 inline bool JSValue::isFalse() const
301 return tag() == BooleanTag
&& !payload();
304 inline uint32_t JSValue::tag() const
309 inline int32_t JSValue::payload() const
311 return u
.asBits
.payload
;
314 inline int32_t JSValue::asInt32() const
317 return u
.asBits
.payload
;
320 inline double JSValue::asDouble() const
326 ALWAYS_INLINE JSCell
* JSValue::asCell() const
329 return reinterpret_cast<JSCell
*>(u
.asBits
.payload
);
332 ALWAYS_INLINE
JSValue::JSValue(EncodeAsDoubleTag
, double d
)
337 inline JSValue::JSValue(int i
)
339 u
.asBits
.tag
= Int32Tag
;
340 u
.asBits
.payload
= i
;
343 inline bool JSValue::isNumber() const
345 return isInt32() || isDouble();
348 inline bool JSValue::isBoolean() const
350 return isTrue() || isFalse();
353 inline bool JSValue::getBoolean() const
359 #else // USE(JSVALUE32_64)
361 // JSValue member functions.
362 inline EncodedJSValue
JSValue::encode(JSValue value
)
367 inline JSValue
JSValue::decode(EncodedJSValue ptr
)
369 return JSValue(reinterpret_cast<JSCell
*>(ptr
));
372 // 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.
373 inline JSValue::JSValue()
375 u
.asInt64
= ValueEmpty
;
378 // 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.
379 inline JSValue::JSValue(HashTableDeletedValueTag
)
381 u
.asInt64
= ValueDeleted
;
384 inline JSValue::JSValue(JSCell
* ptr
)
387 #if ENABLE(JSC_ZOMBIES)
392 inline JSValue::JSValue(const JSCell
* ptr
)
394 u
.ptr
= const_cast<JSCell
*>(ptr
);
395 #if ENABLE(JSC_ZOMBIES)
400 inline JSValue::operator bool() const
405 inline bool JSValue::operator==(const JSValue
& other
) const
407 return u
.ptr
== other
.u
.ptr
;
410 inline bool JSValue::operator!=(const JSValue
& other
) const
412 return u
.ptr
!= other
.u
.ptr
;
415 inline bool JSValue::isUndefined() const
417 return asValue() == jsUndefined();
420 inline bool JSValue::isNull() const
422 return asValue() == jsNull();
425 inline bool JSValue::isTrue() const
427 return asValue() == JSValue(JSTrue
);
430 inline bool JSValue::isFalse() const
432 return asValue() == JSValue(JSFalse
);
435 inline bool JSValue::getBoolean() const
437 ASSERT(asValue() == jsBoolean(true) || asValue() == jsBoolean(false));
438 return asValue() == jsBoolean(true);
441 inline int32_t JSValue::asInt32() const
444 return static_cast<int32_t>(u
.asInt64
);
447 inline bool JSValue::isDouble() const
449 return isNumber() && !isInt32();
452 inline JSValue::JSValue(JSNullTag
)
454 u
.asInt64
= ValueNull
;
457 inline JSValue::JSValue(JSUndefinedTag
)
459 u
.asInt64
= ValueUndefined
;
462 inline JSValue::JSValue(JSTrueTag
)
464 u
.asInt64
= ValueTrue
;
467 inline JSValue::JSValue(JSFalseTag
)
469 u
.asInt64
= ValueFalse
;
472 inline bool JSValue::isUndefinedOrNull() const
474 // Undefined and null share the same value, bar the 'undefined' bit in the extended tag.
475 return (u
.asInt64
& ~TagBitUndefined
) == ValueNull
;
478 inline bool JSValue::isBoolean() const
480 return (u
.asInt64
& ~1) == ValueFalse
;
483 inline bool JSValue::isCell() const
485 return !(u
.asInt64
& TagMask
);
488 inline bool JSValue::isInt32() const
490 return (u
.asInt64
& TagTypeNumber
) == TagTypeNumber
;
493 inline intptr_t reinterpretDoubleToIntptr(double value
)
495 return bitwise_cast
<intptr_t>(value
);
497 inline double reinterpretIntptrToDouble(intptr_t value
)
499 return bitwise_cast
<double>(value
);
502 ALWAYS_INLINE
JSValue::JSValue(EncodeAsDoubleTag
, double d
)
504 u
.asInt64
= reinterpretDoubleToIntptr(d
) + DoubleEncodeOffset
;
507 inline JSValue::JSValue(int i
)
509 u
.asInt64
= TagTypeNumber
| static_cast<uint32_t>(i
);
512 inline double JSValue::asDouble() const
514 return reinterpretIntptrToDouble(u
.asInt64
- DoubleEncodeOffset
);
517 inline bool JSValue::isNumber() const
519 return u
.asInt64
& TagTypeNumber
;
522 ALWAYS_INLINE JSCell
* JSValue::asCell() const
528 #endif // USE(JSVALUE64)
532 #endif // JSValueInlineMethods_h