summaryrefslogtreecommitdiffstats
path: root/Source/JavaScriptCore/runtime/JSValueInlineMethods.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/runtime/JSValueInlineMethods.h')
-rw-r--r--Source/JavaScriptCore/runtime/JSValueInlineMethods.h532
1 files changed, 532 insertions, 0 deletions
diff --git a/Source/JavaScriptCore/runtime/JSValueInlineMethods.h b/Source/JavaScriptCore/runtime/JSValueInlineMethods.h
new file mode 100644
index 0000000..b4f6f80
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/JSValueInlineMethods.h
@@ -0,0 +1,532 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSValueInlineMethods_h
+#define JSValueInlineMethods_h
+
+#include "JSValue.h"
+
+namespace JSC {
+
+ ALWAYS_INLINE int32_t JSValue::toInt32(ExecState* exec) const
+ {
+ if (isInt32())
+ return asInt32();
+ return JSC::toInt32(toNumber(exec));
+ }
+
+ inline uint32_t JSValue::toUInt32(ExecState* exec) const
+ {
+ // See comment on JSC::toUInt32, above.
+ return toInt32(exec);
+ }
+
+ inline bool JSValue::isUInt32() const
+ {
+ return isInt32() && asInt32() >= 0;
+ }
+
+ inline uint32_t JSValue::asUInt32() const
+ {
+ ASSERT(isUInt32());
+ return asInt32();
+ }
+
+ inline double JSValue::uncheckedGetNumber() const
+ {
+ ASSERT(isNumber());
+ return isInt32() ? asInt32() : asDouble();
+ }
+
+ ALWAYS_INLINE JSValue JSValue::toJSNumber(ExecState* exec) const
+ {
+ return isNumber() ? asValue() : jsNumber(this->toNumber(exec));
+ }
+
+ inline JSValue jsNaN()
+ {
+ return JSValue(nonInlineNaN());
+ }
+
+ inline bool JSValue::getNumber(double& result) const
+ {
+ if (isInt32()) {
+ result = asInt32();
+ return true;
+ }
+ if (isDouble()) {
+ result = asDouble();
+ return true;
+ }
+ return false;
+ }
+
+ inline bool JSValue::getBoolean(bool& v) const
+ {
+ if (isTrue()) {
+ v = true;
+ return true;
+ }
+ if (isFalse()) {
+ v = false;
+ return true;
+ }
+
+ return false;
+ }
+
+ inline JSValue::JSValue(char i)
+ {
+ *this = JSValue(static_cast<int32_t>(i));
+ }
+
+ inline JSValue::JSValue(unsigned char i)
+ {
+ *this = JSValue(static_cast<int32_t>(i));
+ }
+
+ inline JSValue::JSValue(short i)
+ {
+ *this = JSValue(static_cast<int32_t>(i));
+ }
+
+ inline JSValue::JSValue(unsigned short i)
+ {
+ *this = JSValue(static_cast<int32_t>(i));
+ }
+
+ inline JSValue::JSValue(unsigned i)
+ {
+ if (static_cast<int32_t>(i) < 0) {
+ *this = JSValue(EncodeAsDouble, static_cast<double>(i));
+ return;
+ }
+ *this = JSValue(static_cast<int32_t>(i));
+ }
+
+ inline JSValue::JSValue(long i)
+ {
+ if (static_cast<int32_t>(i) != i) {
+ *this = JSValue(EncodeAsDouble, static_cast<double>(i));
+ return;
+ }
+ *this = JSValue(static_cast<int32_t>(i));
+ }
+
+ inline JSValue::JSValue(unsigned long i)
+ {
+ if (static_cast<uint32_t>(i) != i) {
+ *this = JSValue(EncodeAsDouble, static_cast<double>(i));
+ return;
+ }
+ *this = JSValue(static_cast<uint32_t>(i));
+ }
+
+ inline JSValue::JSValue(long long i)
+ {
+ if (static_cast<int32_t>(i) != i) {
+ *this = JSValue(EncodeAsDouble, static_cast<double>(i));
+ return;
+ }
+ *this = JSValue(static_cast<int32_t>(i));
+ }
+
+ inline JSValue::JSValue(unsigned long long i)
+ {
+ if (static_cast<uint32_t>(i) != i) {
+ *this = JSValue(EncodeAsDouble, static_cast<double>(i));
+ return;
+ }
+ *this = JSValue(static_cast<uint32_t>(i));
+ }
+
+ inline JSValue::JSValue(double d)
+ {
+ const int32_t asInt32 = static_cast<int32_t>(d);
+ if (asInt32 != d || (!asInt32 && signbit(d))) { // true for -0.0
+ *this = JSValue(EncodeAsDouble, d);
+ return;
+ }
+ *this = JSValue(static_cast<int32_t>(d));
+ }
+
+#if USE(JSVALUE32_64)
+ inline EncodedJSValue JSValue::encode(JSValue value)
+ {
+ return value.u.asInt64;
+ }
+
+ inline JSValue JSValue::decode(EncodedJSValue encodedJSValue)
+ {
+ JSValue v;
+ v.u.asInt64 = encodedJSValue;
+ return v;
+ }
+
+ inline JSValue::JSValue()
+ {
+ u.asBits.tag = EmptyValueTag;
+ u.asBits.payload = 0;
+ }
+
+ inline JSValue::JSValue(JSNullTag)
+ {
+ u.asBits.tag = NullTag;
+ u.asBits.payload = 0;
+ }
+
+ inline JSValue::JSValue(JSUndefinedTag)
+ {
+ u.asBits.tag = UndefinedTag;
+ u.asBits.payload = 0;
+ }
+
+ inline JSValue::JSValue(JSTrueTag)
+ {
+ u.asBits.tag = BooleanTag;
+ u.asBits.payload = 1;
+ }
+
+ inline JSValue::JSValue(JSFalseTag)
+ {
+ u.asBits.tag = BooleanTag;
+ u.asBits.payload = 0;
+ }
+
+ inline JSValue::JSValue(HashTableDeletedValueTag)
+ {
+ u.asBits.tag = DeletedValueTag;
+ u.asBits.payload = 0;
+ }
+
+ inline JSValue::JSValue(JSCell* ptr)
+ {
+ if (ptr)
+ u.asBits.tag = CellTag;
+ else
+ u.asBits.tag = EmptyValueTag;
+ u.asBits.payload = reinterpret_cast<int32_t>(ptr);
+#if ENABLE(JSC_ZOMBIES)
+ ASSERT(!isZombie());
+#endif
+ }
+
+ inline JSValue::JSValue(const JSCell* ptr)
+ {
+ if (ptr)
+ u.asBits.tag = CellTag;
+ else
+ u.asBits.tag = EmptyValueTag;
+ u.asBits.payload = reinterpret_cast<int32_t>(const_cast<JSCell*>(ptr));
+#if ENABLE(JSC_ZOMBIES)
+ ASSERT(!isZombie());
+#endif
+ }
+
+ inline JSValue::operator bool() const
+ {
+ ASSERT(tag() != DeletedValueTag);
+ return tag() != EmptyValueTag;
+ }
+
+ inline bool JSValue::operator==(const JSValue& other) const
+ {
+ return u.asInt64 == other.u.asInt64;
+ }
+
+ inline bool JSValue::operator!=(const JSValue& other) const
+ {
+ return u.asInt64 != other.u.asInt64;
+ }
+
+ inline bool JSValue::isUndefined() const
+ {
+ return tag() == UndefinedTag;
+ }
+
+ inline bool JSValue::isNull() const
+ {
+ return tag() == NullTag;
+ }
+
+ inline bool JSValue::isUndefinedOrNull() const
+ {
+ return isUndefined() || isNull();
+ }
+
+ inline bool JSValue::isCell() const
+ {
+ return tag() == CellTag;
+ }
+
+ inline bool JSValue::isInt32() const
+ {
+ return tag() == Int32Tag;
+ }
+
+ inline bool JSValue::isDouble() const
+ {
+ return tag() < LowestTag;
+ }
+
+ inline bool JSValue::isTrue() const
+ {
+ return tag() == BooleanTag && payload();
+ }
+
+ inline bool JSValue::isFalse() const
+ {
+ return tag() == BooleanTag && !payload();
+ }
+
+ inline uint32_t JSValue::tag() const
+ {
+ return u.asBits.tag;
+ }
+
+ inline int32_t JSValue::payload() const
+ {
+ return u.asBits.payload;
+ }
+
+ inline int32_t JSValue::asInt32() const
+ {
+ ASSERT(isInt32());
+ return u.asBits.payload;
+ }
+
+ inline double JSValue::asDouble() const
+ {
+ ASSERT(isDouble());
+ return u.asDouble;
+ }
+
+ ALWAYS_INLINE JSCell* JSValue::asCell() const
+ {
+ ASSERT(isCell());
+ return reinterpret_cast<JSCell*>(u.asBits.payload);
+ }
+
+ ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, double d)
+ {
+ u.asDouble = d;
+ }
+
+ inline JSValue::JSValue(int i)
+ {
+ u.asBits.tag = Int32Tag;
+ u.asBits.payload = i;
+ }
+
+ inline bool JSValue::isNumber() const
+ {
+ return isInt32() || isDouble();
+ }
+
+ inline bool JSValue::isBoolean() const
+ {
+ return isTrue() || isFalse();
+ }
+
+ inline bool JSValue::getBoolean() const
+ {
+ ASSERT(isBoolean());
+ return payload();
+ }
+
+#else // USE(JSVALUE32_64)
+
+ // JSValue member functions.
+ inline EncodedJSValue JSValue::encode(JSValue value)
+ {
+ return value.u.ptr;
+ }
+
+ inline JSValue JSValue::decode(EncodedJSValue ptr)
+ {
+ return JSValue(reinterpret_cast<JSCell*>(ptr));
+ }
+
+ // 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.
+ inline JSValue::JSValue()
+ {
+ u.asInt64 = ValueEmpty;
+ }
+
+ // 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.
+ inline JSValue::JSValue(HashTableDeletedValueTag)
+ {
+ u.asInt64 = ValueDeleted;
+ }
+
+ inline JSValue::JSValue(JSCell* ptr)
+ {
+ u.ptr = ptr;
+#if ENABLE(JSC_ZOMBIES)
+ ASSERT(!isZombie());
+#endif
+ }
+
+ inline JSValue::JSValue(const JSCell* ptr)
+ {
+ u.ptr = const_cast<JSCell*>(ptr);
+#if ENABLE(JSC_ZOMBIES)
+ ASSERT(!isZombie());
+#endif
+ }
+
+ inline JSValue::operator bool() const
+ {
+ return u.ptr;
+ }
+
+ inline bool JSValue::operator==(const JSValue& other) const
+ {
+ return u.ptr == other.u.ptr;
+ }
+
+ inline bool JSValue::operator!=(const JSValue& other) const
+ {
+ return u.ptr != other.u.ptr;
+ }
+
+ inline bool JSValue::isUndefined() const
+ {
+ return asValue() == jsUndefined();
+ }
+
+ inline bool JSValue::isNull() const
+ {
+ return asValue() == jsNull();
+ }
+
+ inline bool JSValue::isTrue() const
+ {
+ return asValue() == JSValue(JSTrue);
+ }
+
+ inline bool JSValue::isFalse() const
+ {
+ return asValue() == JSValue(JSFalse);
+ }
+
+ inline bool JSValue::getBoolean() const
+ {
+ ASSERT(asValue() == jsBoolean(true) || asValue() == jsBoolean(false));
+ return asValue() == jsBoolean(true);
+ }
+
+ inline int32_t JSValue::asInt32() const
+ {
+ ASSERT(isInt32());
+ return static_cast<int32_t>(u.asInt64);
+ }
+
+ inline bool JSValue::isDouble() const
+ {
+ return isNumber() && !isInt32();
+ }
+
+ inline JSValue::JSValue(JSNullTag)
+ {
+ u.asInt64 = ValueNull;
+ }
+
+ inline JSValue::JSValue(JSUndefinedTag)
+ {
+ u.asInt64 = ValueUndefined;
+ }
+
+ inline JSValue::JSValue(JSTrueTag)
+ {
+ u.asInt64 = ValueTrue;
+ }
+
+ inline JSValue::JSValue(JSFalseTag)
+ {
+ u.asInt64 = ValueFalse;
+ }
+
+ inline bool JSValue::isUndefinedOrNull() const
+ {
+ // Undefined and null share the same value, bar the 'undefined' bit in the extended tag.
+ return (u.asInt64 & ~TagBitUndefined) == ValueNull;
+ }
+
+ inline bool JSValue::isBoolean() const
+ {
+ return (u.asInt64 & ~1) == ValueFalse;
+ }
+
+ inline bool JSValue::isCell() const
+ {
+ return !(u.asInt64 & TagMask);
+ }
+
+ inline bool JSValue::isInt32() const
+ {
+ return (u.asInt64 & TagTypeNumber) == TagTypeNumber;
+ }
+
+ inline intptr_t reinterpretDoubleToIntptr(double value)
+ {
+ return bitwise_cast<intptr_t>(value);
+ }
+ inline double reinterpretIntptrToDouble(intptr_t value)
+ {
+ return bitwise_cast<double>(value);
+ }
+
+ ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, double d)
+ {
+ u.asInt64 = reinterpretDoubleToIntptr(d) + DoubleEncodeOffset;
+ }
+
+ inline JSValue::JSValue(int i)
+ {
+ u.asInt64 = TagTypeNumber | static_cast<uint32_t>(i);
+ }
+
+ inline double JSValue::asDouble() const
+ {
+ return reinterpretIntptrToDouble(u.asInt64 - DoubleEncodeOffset);
+ }
+
+ inline bool JSValue::isNumber() const
+ {
+ return u.asInt64 & TagTypeNumber;
+ }
+
+ ALWAYS_INLINE JSCell* JSValue::asCell() const
+ {
+ ASSERT(isCell());
+ return u.ptr;
+ }
+
+#endif // USE(JSVALUE64)
+
+} // namespace JSC
+
+#endif // JSValueInlineMethods_h