/*
 * 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 JSValueInlines_h
#define JSValueInlines_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::asNumber() const
    {
        ASSERT(isNumber());
        return isInt32() ? asInt32() : asDouble();
    }

    inline JSValue jsNaN()
    {
        return JSValue(QNaN);
    }

    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));
    }

    inline EncodedJSValue JSValue::encode(JSValue value)
    {
        return value.u.asInt64;
    }

    inline JSValue JSValue::decode(EncodedJSValue encodedJSValue)
    {
        JSValue v;
        v.u.asInt64 = encodedJSValue;
        return v;
    }

#if USE(JSVALUE32_64)
    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);
    }

    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));
    }

    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::isEmpty() const
    {
        return tag() == EmptyValueTag;
    }

    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;
    }

#if ENABLE(LLINT_C_LOOP)
    inline JSValue::JSValue(int32_t tag, int32_t payload)
    {
        u.asBits.tag = tag;
        u.asBits.payload = payload;
    }
#endif

    inline bool JSValue::isNumber() const
    {
        return isInt32() || isDouble();
    }

    inline bool JSValue::isBoolean() const
    {
        return isTrue() || isFalse();
    }

    inline bool JSValue::asBoolean() const
    {
        ASSERT(isBoolean());
        return payload();
    }

#else // !USE(JSVALUE32_64) i.e. USE(JSVALUE64)

    // 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.asInt64 = reinterpret_cast<uintptr_t>(ptr);
    }

    inline JSValue::JSValue(const JSCell* ptr)
    {
        u.asInt64 = reinterpret_cast<uintptr_t>(const_cast<JSCell*>(ptr));
    }

    inline JSValue::operator bool() const
    {
        return u.asInt64;
    }

    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::isEmpty() const
    {
        return u.asInt64 == ValueEmpty;
    }

    inline bool JSValue::isUndefined() const
    {
        return asValue() == JSValue(JSUndefined);
    }

    inline bool JSValue::isNull() const
    {
        return asValue() == JSValue(JSNull);
    }

    inline bool JSValue::isTrue() const
    {
        return asValue() == JSValue(JSTrue);
    }

    inline bool JSValue::isFalse() const
    {
        return asValue() == JSValue(JSFalse);
    }

    inline bool JSValue::asBoolean() const
    {
        ASSERT(isBoolean());
        return asValue() == JSValue(JSTrue);
    }

    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 int64_t reinterpretDoubleToInt64(double value)
    {
        return bitwise_cast<int64_t>(value);
    }
    inline double reinterpretInt64ToDouble(int64_t value)
    {
        return bitwise_cast<double>(value);
    }

    ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, double d)
    {
        u.asInt64 = reinterpretDoubleToInt64(d) + DoubleEncodeOffset;
    }

    inline JSValue::JSValue(int i)
    {
        u.asInt64 = TagTypeNumber | static_cast<uint32_t>(i);
    }

    inline double JSValue::asDouble() const
    {
        ASSERT(isDouble());
        return reinterpretInt64ToDouble(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 // JSValueInlines_h

