/*
 *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
 *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
 *  Copyright (C) 2003-2018 Apple Inc. All rights reserved.
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Library General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Library General Public License for more details.
 *
 *  You should have received a copy of the GNU Library General Public License
 *  along with this library; see the file COPYING.LIB.  If not, write to
 *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 *  Boston, MA 02110-1301, USA.
 *
 */

#pragma once

#include "JSExportMacros.h"
#include <functional>
#include <math.h>
#include <stddef.h>
#include <stdint.h>
#include <wtf/Assertions.h>
#include <wtf/Forward.h>
#include <wtf/HashMap.h>
#include <wtf/HashTraits.h>
#include <wtf/MathExtras.h>
#include <wtf/MediaTime.h>
#include <wtf/StdLibExtras.h>
#include <wtf/TriState.h>

namespace JSC {

class AssemblyHelpers;
class JSBigInt;
class ExecState;
class JSCell;
class JSValueSource;
class VM;
class JSGlobalObject;
class JSObject;
class JSString;
class Identifier;
class PropertyName;
class PropertySlot;
class PutPropertySlot;
class Structure;
#if ENABLE(DFG_JIT)
namespace DFG {
class JITCompiler;
class OSRExitCompiler;
class SpeculativeJIT;
}
#endif
#if ENABLE(C_LOOP)
namespace LLInt {
class CLoop;
}
#endif

struct ClassInfo;
struct DumpContext;
struct Instruction;
struct MethodTable;
enum class Unknown { };

template <class T, typename Traits> class WriteBarrierBase;
template<class T>
using WriteBarrierTraitsSelect = typename std::conditional<std::is_same<T, Unknown>::value,
    DumbValueTraits<T>, DumbPtrTraits<T>
>::type;

enum PreferredPrimitiveType { NoPreference, PreferNumber, PreferString };
enum ECMAMode { StrictMode, NotStrictMode };

enum class CallType : unsigned;
struct CallData;
enum class ConstructType : unsigned;
struct ConstructData;

typedef int64_t EncodedJSValue;
    
union EncodedValueDescriptor {
    int64_t asInt64;
#if USE(JSVALUE32_64)
    double asDouble;
#elif USE(JSVALUE64)
    JSCell* ptr;
#endif
        
#if CPU(BIG_ENDIAN)
    struct {
        int32_t tag;
        int32_t payload;
    } asBits;
#else
    struct {
        int32_t payload;
        int32_t tag;
    } asBits;
#endif
};

#define TagOffset (offsetof(EncodedValueDescriptor, asBits.tag))
#define PayloadOffset (offsetof(EncodedValueDescriptor, asBits.payload))

#if USE(JSVALUE64)
#define CellPayloadOffset 0
#else
#define CellPayloadOffset PayloadOffset
#endif

enum WhichValueWord {
    TagWord,
    PayloadWord
};

int64_t tryConvertToInt52(double);
bool isInt52(double);

enum class SourceCodeRepresentation : uint8_t {
    Other,
    Integer,
    Double
};

class JSValue {
    friend struct EncodedJSValueHashTraits;
    friend struct EncodedJSValueWithRepresentationHashTraits;
    friend class AssemblyHelpers;
    friend class JIT;
    friend class JITSlowPathCall;
    friend class JITStubs;
    friend class JITStubCall;
    friend class JSInterfaceJIT;
    friend class JSValueSource;
    friend class SpecializedThunkJIT;
#if ENABLE(DFG_JIT)
    friend class DFG::JITCompiler;
    friend class DFG::OSRExitCompiler;
    friend class DFG::SpeculativeJIT;
#endif
#if ENABLE(C_LOOP)
    friend class LLInt::CLoop;
#endif

public:
#if USE(JSVALUE32_64)
    enum { Int32Tag =        0xffffffff };
    enum { BooleanTag =      0xfffffffe };
    enum { NullTag =         0xfffffffd };
    enum { UndefinedTag =    0xfffffffc };
    enum { CellTag =         0xfffffffb };
    enum { EmptyValueTag =   0xfffffffa };
    enum { DeletedValueTag = 0xfffffff9 };

    enum { LowestTag =  DeletedValueTag };

#endif

    static EncodedJSValue encode(JSValue);
    static JSValue decode(EncodedJSValue);

    enum JSNullTag { JSNull };
    enum JSUndefinedTag { JSUndefined };
    enum JSTrueTag { JSTrue };
    enum JSFalseTag { JSFalse };
    enum JSCellTag { JSCellType };
    enum EncodeAsDoubleTag { EncodeAsDouble };

    JSValue();
    JSValue(JSNullTag);
    JSValue(JSUndefinedTag);
    JSValue(JSTrueTag);
    JSValue(JSFalseTag);
    JSValue(JSCell* ptr);
    JSValue(const JSCell* ptr);

    // Numbers
    JSValue(EncodeAsDoubleTag, double);
    explicit JSValue(double);
    explicit JSValue(char);
    explicit JSValue(unsigned char);
    explicit JSValue(short);
    explicit JSValue(unsigned short);
    explicit JSValue(int);
    explicit JSValue(unsigned);
    explicit JSValue(long);
    explicit JSValue(unsigned long);
    explicit JSValue(long long);
    explicit JSValue(unsigned long long);

    explicit operator bool() const;
    bool operator==(const JSValue& other) const;
    bool operator!=(const JSValue& other) const;

    bool isInt32() const;
    bool isUInt32() const;
    bool isDouble() const;
    bool isTrue() const;
    bool isFalse() const;

    int32_t asInt32() const;
    uint32_t asUInt32() const;
    int64_t asAnyInt() const;
    double asDouble() const;
    bool asBoolean() const;
    double asNumber() const;
    
    int32_t asInt32ForArithmetic() const; // Boolean becomes an int, but otherwise like asInt32().

    // Querying the type.
    bool isEmpty() const;
    bool isFunction(VM&) const;
    bool isCallable(VM&, CallType&, CallData&) const;
    bool isConstructor(VM&) const;
    bool isConstructor(VM&, ConstructType&, ConstructData&) const;
    bool isUndefined() const;
    bool isNull() const;
    bool isUndefinedOrNull() const;
    bool isBoolean() const;
    bool isAnyInt() const;
    bool isNumber() const;
    bool isString() const;
    bool isBigInt() const;
    bool isSymbol() const;
    bool isPrimitive() const;
    bool isGetterSetter() const;
    bool isCustomGetterSetter() const;
    bool isObject() const;
    bool inherits(VM&, const ClassInfo*) const;
    template<typename Target> bool inherits(VM&) const;
    const ClassInfo* classInfoOrNull(VM&) const;
        
    // Extracting the value.
    bool getString(ExecState*, WTF::String&) const;
    WTF::String getString(ExecState*) const; // null string if not a string
    JSObject* getObject() const; // 0 if not an object

    // Extracting integer values.
    bool getUInt32(uint32_t&) const;
        
    // Basic conversions.
    JSValue toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const;
    bool getPrimitiveNumber(ExecState*, double& number, JSValue&);

    bool toBoolean(ExecState*) const;
    TriState pureToBoolean() const;

    // toNumber conversion is expected to be side effect free if an exception has
    // been set in the ExecState already.
    double toNumber(ExecState*) const;
    
    Variant<JSBigInt*, double> toNumeric(ExecState*) const;
    Variant<JSBigInt*, int32_t> toBigIntOrInt32(ExecState*) const;

    // toNumber conversion if it can be done without side effects.
    std::optional<double> toNumberFromPrimitive() const;

    JSString* toString(ExecState*) const; // On exception, this returns the empty string.
    JSString* toStringOrNull(ExecState*) const; // On exception, this returns null, to make exception checks faster.
    Identifier toPropertyKey(ExecState*) const;
    WTF::String toWTFString(ExecState*) const;
    JSObject* toObject(ExecState*) const;
    JSObject* toObject(ExecState*, JSGlobalObject*) const;

    // Integer conversions.
    JS_EXPORT_PRIVATE double toInteger(ExecState*) const;
    JS_EXPORT_PRIVATE double toIntegerPreserveNaN(ExecState*) const;
    int32_t toInt32(ExecState*) const;
    uint32_t toUInt32(ExecState*) const;
    uint32_t toIndex(ExecState*, const char* errorName) const;
    double toLength(ExecState*) const;

    // Floating point conversions (this is a convenience function for WebCore;
    // single precision float is not a representation used in JS or JSC).
    float toFloat(ExecState* exec) const { return static_cast<float>(toNumber(exec)); }

    // Object operations, with the toObject operation included.
    JSValue get(ExecState*, PropertyName) const;
    JSValue get(ExecState*, PropertyName, PropertySlot&) const;
    JSValue get(ExecState*, unsigned propertyName) const;
    JSValue get(ExecState*, unsigned propertyName, PropertySlot&) const;
    JSValue get(ExecState*, uint64_t propertyName) const;

    bool getPropertySlot(ExecState*, PropertyName, PropertySlot&) const;
    template<typename CallbackWhenNoException> typename std::result_of<CallbackWhenNoException(bool, PropertySlot&)>::type getPropertySlot(ExecState*, PropertyName, CallbackWhenNoException) const;
    template<typename CallbackWhenNoException> typename std::result_of<CallbackWhenNoException(bool, PropertySlot&)>::type getPropertySlot(ExecState*, PropertyName, PropertySlot&, CallbackWhenNoException) const;

    bool getOwnPropertySlot(ExecState*, PropertyName, PropertySlot&) const;

    bool put(ExecState*, PropertyName, JSValue, PutPropertySlot&);
    bool putInline(ExecState*, PropertyName, JSValue, PutPropertySlot&);
    JS_EXPORT_PRIVATE bool putToPrimitive(ExecState*, PropertyName, JSValue, PutPropertySlot&);
    JS_EXPORT_PRIVATE bool putToPrimitiveByIndex(ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
    bool putByIndex(ExecState*, unsigned propertyName, JSValue, bool shouldThrow);

    JSValue toThis(ExecState*, ECMAMode) const;

    static bool equal(ExecState*, JSValue v1, JSValue v2);
    static bool equalSlowCase(ExecState*, JSValue v1, JSValue v2);
    static bool equalSlowCaseInline(ExecState*, JSValue v1, JSValue v2);
    static bool strictEqual(ExecState*, JSValue v1, JSValue v2);
    static bool strictEqualSlowCase(ExecState*, JSValue v1, JSValue v2);
    static bool strictEqualSlowCaseInline(ExecState*, JSValue v1, JSValue v2);
    static TriState pureStrictEqual(JSValue v1, JSValue v2);

    bool isCell() const;
    JSCell* asCell() const;
    JS_EXPORT_PRIVATE bool isValidCallee();

    Structure* structureOrNull() const;
    JSValue structureOrUndefined() const;

    JS_EXPORT_PRIVATE void dump(PrintStream&) const;
    void dumpInContext(PrintStream&, DumpContext*) const;
    void dumpInContextAssumingStructure(PrintStream&, DumpContext*, Structure*) const;
    void dumpForBacktrace(PrintStream&) const;

    JS_EXPORT_PRIVATE JSObject* synthesizePrototype(ExecState*) const;
    bool requireObjectCoercible(ExecState*) const;

    // Constants used for Int52. Int52 isn't part of JSValue right now, but JSValues may be
    // converted to Int52s and back again.
    static constexpr const unsigned numberOfInt52Bits = 52;
    static constexpr const int64_t notInt52 = static_cast<int64_t>(1) << numberOfInt52Bits;
    static constexpr const unsigned int52ShiftAmount = 12;
    
    static ptrdiff_t offsetOfPayload() { return OBJECT_OFFSETOF(JSValue, u.asBits.payload); }
    static ptrdiff_t offsetOfTag() { return OBJECT_OFFSETOF(JSValue, u.asBits.tag); }

#if USE(JSVALUE32_64)
    /*
     * On 32-bit platforms USE(JSVALUE32_64) should be defined, and we use a NaN-encoded
     * form for immediates.
     *
     * The encoding makes use of unused NaN space in the IEEE754 representation.  Any value
     * with the top 13 bits set represents a QNaN (with the sign bit set).  QNaN values
     * can encode a 51-bit payload.  Hardware produced and C-library payloads typically
     * have a payload of zero.  We assume that non-zero payloads are available to encode
     * pointer and integer values.  Since any 64-bit bit pattern where the top 15 bits are
     * all set represents a NaN with a non-zero payload, we can use this space in the NaN
     * ranges to encode other values (however there are also other ranges of NaN space that
     * could have been selected).
     *
     * For JSValues that do not contain a double value, the high 32 bits contain the tag
     * values listed in the enums below, which all correspond to NaN-space. In the case of
     * cell, integer and bool values the lower 32 bits (the 'payload') contain the pointer
     * integer or boolean value; in the case of all other tags the payload is 0.
     */
    uint32_t tag() const;
    int32_t payload() const;

    // This should only be used by the LLInt C Loop interpreter and OSRExit code who needs
    // synthesize JSValue from its "register"s holding tag and payload values.
    explicit JSValue(int32_t tag, int32_t payload);

#elif USE(JSVALUE64)
    /*
     * On 64-bit platforms USE(JSVALUE64) should be defined, and we use a NaN-encoded
     * form for immediates.
     *
     * The encoding makes use of unused NaN space in the IEEE754 representation.  Any value
     * with the top 13 bits set represents a QNaN (with the sign bit set).  QNaN values
     * can encode a 51-bit payload.  Hardware produced and C-library payloads typically
     * have a payload of zero.  We assume that non-zero payloads are available to encode
     * pointer and integer values.  Since any 64-bit bit pattern where the top 15 bits are
     * all set represents a NaN with a non-zero payload, we can use this space in the NaN
     * ranges to encode other values (however there are also other ranges of NaN space that
     * could have been selected).
     *
     * This range of NaN space is represented by 64-bit numbers begining with the 16-bit
     * hex patterns 0xFFFE and 0xFFFF - we rely on the fact that no valid double-precision
     * numbers will fall in these ranges.
     *
     * The top 16-bits denote the type of the encoded JSValue:
     *
     *     Pointer {  0000:PPPP:PPPP:PPPP
     *              / 0001:****:****:****
     *     Double  {         ...
     *              \ FFFE:****:****:****
     *     Integer {  FFFF:0000:IIII:IIII
     *
     * The scheme we have implemented encodes double precision values by performing a
     * 64-bit integer addition of the value 2^48 to the number. After this manipulation
     * no encoded double-precision value will begin with the pattern 0x0000 or 0xFFFF.
     * Values must be decoded by reversing this operation before subsequent floating point
     * operations may be peformed.
     *
     * 32-bit signed integers are marked with the 16-bit tag 0xFFFF.
     *
     * The tag 0x0000 denotes a pointer, or another form of tagged immediate. Boolean,
     * null and undefined values are represented by specific, invalid pointer values:
     *
     *     False:     0x06
     *     True:      0x07
     *     Undefined: 0x0a
     *     Null:      0x02
     *
     * These values have the following properties:
     * - Bit 1 (TagBitTypeOther) is set for all four values, allowing real pointers to be
     *   quickly distinguished from all immediate values, including these invalid pointers.
     * - With bit 3 is masked out (TagBitUndefined) Undefined and Null share the
     *   same value, allowing null & undefined to be quickly detected.
     *
     * No valid JSValue will have the bit pattern 0x0, this is used to represent array
     * holes, and as a C++ 'no value' result (e.g. JSValue() has an internal value of 0).
     */

    // These values are #defines since using static const integers here is a ~1% regression!

    // This value is 2^48, used to encode doubles such that the encoded value will begin
    // with a 16-bit pattern within the range 0x0001..0xFFFE.
    #define DoubleEncodeOffset 0x1000000000000ll
    // If all bits in the mask are set, this indicates an integer number,
    // if any but not all are set this value is a double precision number.
    #define TagTypeNumber 0xffff000000000000ll

    // All non-numeric (bool, null, undefined) immediates have bit 2 set.
    #define TagBitTypeOther 0x2ll
    #define TagBitBool      0x4ll
    #define TagBitUndefined 0x8ll
    // Combined integer value for non-numeric immediates.
    #define ValueFalse     (TagBitTypeOther | TagBitBool | false)
    #define ValueTrue      (TagBitTypeOther | TagBitBool | true)
    #define ValueUndefined (TagBitTypeOther | TagBitUndefined)
    #define ValueNull      (TagBitTypeOther)

    // TagMask is used to check for all types of immediate values (either number or 'other').
    #define TagMask (TagTypeNumber | TagBitTypeOther)

    // These special values are never visible to JavaScript code; Empty is used to represent
    // Array holes, and for uninitialized JSValues. Deleted is used in hash table code.
    // These values would map to cell types in the JSValue encoding, but not valid GC cell
    // pointer should have either of these values (Empty is null, deleted is at an invalid
    // alignment for a GC cell, and in the zero page).
    #define ValueEmpty   0x0ll
    #define ValueDeleted 0x4ll

    #define TagBitsWasm (TagBitTypeOther | 0x1)
    #define TagWasmMask (TagTypeNumber | 0x7)
    // We tag Wasm non-JSCell pointers with a 3 at the bottom. We can test if a 64-bit JSValue pattern
    // is a Wasm callee by masking the upper 16 bits and the lower 3 bits, and seeing if
    // the resulting value is 3. The full test is: x & TagWasmMask == TagBitsWasm
    // This works because the lower 3 bits of the non-number immediate values are as follows:
    // undefined: 0b010
    // null:      0b010
    // true:      0b111
    // false:     0b110
    // The test rejects all of these because none have just the value 3 in their lower 3 bits.
    // The test rejects all numbers because they have non-zero upper 16 bits.
    // The test also rejects normal cells because they won't have the number 3 as
    // their lower 3 bits. Note, this bit pattern also allows the normal JSValue isCell(), etc,
    // predicates to work on a Wasm::Callee because the various tests will fail if you
    // bit casted a boxed Wasm::Callee* to a JSValue. isCell() would fail since it sees
    // TagBitTypeOther. The other tests also trivially fail, since it won't be a number,
    // and it won't be equal to null, undefined, true, or false. The isBoolean() predicate
    // will fail because we won't have TagBitBool set.
#endif

private:
    template <class T> JSValue(WriteBarrierBase<T, WriteBarrierTraitsSelect<T>>);

    enum HashTableDeletedValueTag { HashTableDeletedValue };
    JSValue(HashTableDeletedValueTag);

    inline const JSValue asValue() const { return *this; }
    JS_EXPORT_PRIVATE double toNumberSlowCase(ExecState*) const;
    JS_EXPORT_PRIVATE JSString* toStringSlowCase(ExecState*, bool returnEmptyStringOnError) const;
    JS_EXPORT_PRIVATE WTF::String toWTFStringSlowCase(ExecState*) const;
    JS_EXPORT_PRIVATE JSObject* toObjectSlowCase(ExecState*, JSGlobalObject*) const;
    JS_EXPORT_PRIVATE JSValue toThisSlowCase(ExecState*, ECMAMode) const;

    EncodedValueDescriptor u;
};

typedef IntHash<EncodedJSValue> EncodedJSValueHash;

#if USE(JSVALUE32_64)
struct EncodedJSValueHashTraits : HashTraits<EncodedJSValue> {
    static const bool emptyValueIsZero = false;
    static EncodedJSValue emptyValue() { return JSValue::encode(JSValue()); }
    static void constructDeletedValue(EncodedJSValue& slot) { slot = JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); }
    static bool isDeletedValue(EncodedJSValue value) { return value == JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); }
};
#else
struct EncodedJSValueHashTraits : HashTraits<EncodedJSValue> {
    static void constructDeletedValue(EncodedJSValue& slot) { slot = JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); }
    static bool isDeletedValue(EncodedJSValue value) { return value == JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); }
};
#endif

typedef std::pair<EncodedJSValue, SourceCodeRepresentation> EncodedJSValueWithRepresentation;

struct EncodedJSValueWithRepresentationHashTraits : HashTraits<EncodedJSValueWithRepresentation> {
    static const bool emptyValueIsZero = false;
    static EncodedJSValueWithRepresentation emptyValue() { return std::make_pair(JSValue::encode(JSValue()), SourceCodeRepresentation::Other); }
    static void constructDeletedValue(EncodedJSValueWithRepresentation& slot) { slot = std::make_pair(JSValue::encode(JSValue(JSValue::HashTableDeletedValue)), SourceCodeRepresentation::Other); }
    static bool isDeletedValue(EncodedJSValueWithRepresentation value) { return value == std::make_pair(JSValue::encode(JSValue(JSValue::HashTableDeletedValue)), SourceCodeRepresentation::Other); }
};

struct EncodedJSValueWithRepresentationHash {
    static unsigned hash(const EncodedJSValueWithRepresentation& value)
    {
        return WTF::pairIntHash(EncodedJSValueHash::hash(value.first), IntHash<SourceCodeRepresentation>::hash(value.second));
    }
    static bool equal(const EncodedJSValueWithRepresentation& a, const EncodedJSValueWithRepresentation& b)
    {
        return a == b;
    }
    static const bool safeToCompareToEmptyOrDeleted = true;
};

// Stand-alone helper functions.
inline JSValue jsNull()
{
    return JSValue(JSValue::JSNull);
}

inline JSValue jsUndefined()
{
    return JSValue(JSValue::JSUndefined);
}

inline JSValue jsTDZValue()
{
    return JSValue();
}

inline JSValue jsBoolean(bool b)
{
    return b ? JSValue(JSValue::JSTrue) : JSValue(JSValue::JSFalse);
}

ALWAYS_INLINE JSValue jsDoubleNumber(double d)
{
    ASSERT(JSValue(JSValue::EncodeAsDouble, d).isNumber());
    return JSValue(JSValue::EncodeAsDouble, d);
}

ALWAYS_INLINE JSValue jsNumber(double d)
{
    ASSERT(JSValue(d).isNumber());
    return JSValue(d);
}

ALWAYS_INLINE JSValue jsNumber(MediaTime t)
{
    return jsNumber(t.toDouble());
}

ALWAYS_INLINE JSValue jsNumber(char i)
{
    return JSValue(i);
}

ALWAYS_INLINE JSValue jsNumber(unsigned char i)
{
    return JSValue(i);
}

ALWAYS_INLINE JSValue jsNumber(short i)
{
    return JSValue(i);
}

ALWAYS_INLINE JSValue jsNumber(unsigned short i)
{
    return JSValue(i);
}

ALWAYS_INLINE JSValue jsNumber(int i)
{
    return JSValue(i);
}

ALWAYS_INLINE JSValue jsNumber(unsigned i)
{
    return JSValue(i);
}

ALWAYS_INLINE JSValue jsNumber(long i)
{
    return JSValue(i);
}

ALWAYS_INLINE JSValue jsNumber(unsigned long i)
{
    return JSValue(i);
}

ALWAYS_INLINE JSValue jsNumber(long long i)
{
    return JSValue(i);
}

ALWAYS_INLINE JSValue jsNumber(unsigned long long i)
{
    return JSValue(i);
}

ALWAYS_INLINE EncodedJSValue encodedJSUndefined()
{
    return JSValue::encode(jsUndefined());
}

ALWAYS_INLINE EncodedJSValue encodedJSValue()
{
    return JSValue::encode(JSValue());
}

inline bool operator==(const JSValue a, const JSCell* b) { return a == JSValue(b); }
inline bool operator==(const JSCell* a, const JSValue b) { return JSValue(a) == b; }

inline bool operator!=(const JSValue a, const JSCell* b) { return a != JSValue(b); }
inline bool operator!=(const JSCell* a, const JSValue b) { return JSValue(a) != b; }


bool isThisValueAltered(const PutPropertySlot&, JSObject* baseObject);

// See section 7.2.9: https://tc39.github.io/ecma262/#sec-samevalue
bool sameValue(ExecState*, JSValue a, JSValue b);

} // namespace JSC
