/*
 * 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
