/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQml module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <qv4jsonobject_p.h>
#include <qv4objectproto_p.h>
#include <qv4numberobject_p.h>
#include <qv4stringobject_p.h>
#include <qv4booleanobject_p.h>
#include <qv4objectiterator_p.h>
#include <qv4scopedvalue_p.h>
#include <qv4runtime_p.h>
#include <qv4variantobject_p.h>
#include "qv4string_p.h"
#include "qv4jscall_p.h"
#include <qv4symbol_p.h>

#include <qstack.h>
#include <qstringlist.h>

#include <wtf/MathExtras.h>

using namespace QV4;

//#define PARSER_DEBUG
#ifdef PARSER_DEBUG
static int indent = 0;
#define BEGIN qDebug() << QByteArray(4*indent++, ' ').constData()
#define END --indent
#define DEBUG qDebug() << QByteArray(4*indent, ' ').constData()
#else
#define BEGIN if (1) ; else qDebug()
#define END do {} while (0)
#define DEBUG if (1) ; else qDebug()
#endif


DEFINE_OBJECT_VTABLE(JsonObject);

static const int nestingLimit = 1024;


JsonParser::JsonParser(ExecutionEngine *engine, const QChar *json, int length)
    : engine(engine), head(json), json(json), nestingLevel(0), lastError(QJsonParseError::NoError)
{
    end = json + length;
}



/*

begin-array     = ws %x5B ws  ; [ left square bracket

begin-object    = ws %x7B ws  ; { left curly bracket

end-array       = ws %x5D ws  ; ] right square bracket

end-object      = ws %x7D ws  ; } right curly bracket

name-separator  = ws %x3A ws  ; : colon

value-separator = ws %x2C ws  ; , comma

Insignificant whitespace is allowed before or after any of the six
structural characters.

ws = *(
          %x20 /              ; Space
          %x09 /              ; Horizontal tab
          %x0A /              ; Line feed or New line
          %x0D                ; Carriage return
      )

*/

enum {
    Space = 0x20,
    Tab = 0x09,
    LineFeed = 0x0a,
    Return = 0x0d,
    BeginArray = 0x5b,
    BeginObject = 0x7b,
    EndArray = 0x5d,
    EndObject = 0x7d,
    NameSeparator = 0x3a,
    ValueSeparator = 0x2c,
    Quote = 0x22
};

bool JsonParser::eatSpace()
{
    while (json < end) {
        if (*json > Space)
            break;
        if (*json != Space &&
            *json != Tab &&
            *json != LineFeed &&
            *json != Return)
            break;
        ++json;
    }
    return (json < end);
}

QChar JsonParser::nextToken()
{
    if (!eatSpace())
        return 0;
    QChar token = *json++;
    switch (token.unicode()) {
    case BeginArray:
    case BeginObject:
    case NameSeparator:
    case ValueSeparator:
    case EndArray:
    case EndObject:
        eatSpace();
    case Quote:
        break;
    default:
        token = 0;
        break;
    }
    return token;
}

/*
    JSON-text = object / array
*/
ReturnedValue JsonParser::parse(QJsonParseError *error)
{
#ifdef PARSER_DEBUG
    indent = 0;
    qDebug() << ">>>>> parser begin";
#endif

    eatSpace();

    Scope scope(engine);
    ScopedValue v(scope);
    if (!parseValue(v)) {
#ifdef PARSER_DEBUG
        qDebug() << ">>>>> parser error";
#endif
        if (lastError == QJsonParseError::NoError)
            lastError = QJsonParseError::IllegalValue;
        error->offset = json - head;
        error->error  = lastError;
        return Encode::undefined();
    }

    // some input left...
    if (eatSpace()) {
        lastError = QJsonParseError::IllegalValue;
        error->offset = json - head;
        error->error  = lastError;
        return Encode::undefined();
    }

    END;
    error->offset = 0;
    error->error = QJsonParseError::NoError;
    return v->asReturnedValue();
}

/*
    object = begin-object [ member *( value-separator member ) ]
    end-object
*/

ReturnedValue JsonParser::parseObject()
{
    if (++nestingLevel > nestingLimit) {
        lastError = QJsonParseError::DeepNesting;
        return Encode::undefined();
    }

    BEGIN << "parseObject pos=" << json;
    Scope scope(engine);

    ScopedObject o(scope, engine->newObject());

    QChar token = nextToken();
    while (token == Quote) {
        if (!parseMember(o))
            return Encode::undefined();
        token = nextToken();
        if (token != ValueSeparator)
            break;
        token = nextToken();
        if (token == EndObject) {
            lastError = QJsonParseError::MissingObject;
            return Encode::undefined();
        }
    }

    DEBUG << "end token=" << token;
    if (token != EndObject) {
        lastError = QJsonParseError::UnterminatedObject;
        return Encode::undefined();
    }

    END;

    --nestingLevel;
    return o.asReturnedValue();
}

/*
    member = string name-separator value
*/
bool JsonParser::parseMember(Object *o)
{
    BEGIN << "parseMember";
    Scope scope(engine);

    QString key;
    if (!parseString(&key))
        return false;
    QChar token = nextToken();
    if (token != NameSeparator) {
        lastError = QJsonParseError::MissingNameSeparator;
        return false;
    }
    ScopedValue val(scope);
    if (!parseValue(val))
        return false;

    ScopedString s(scope, engine->newString(key));
    PropertyKey skey = s->toPropertyKey();
    if (skey.isArrayIndex()) {
        o->put(skey.asArrayIndex(), val);
    } else {
        // avoid trouble with properties named __proto__
        o->insertMember(s, val);
    }

    END;
    return true;
}

/*
    array = begin-array [ value *( value-separator value ) ] end-array
*/
ReturnedValue JsonParser::parseArray()
{
    Scope scope(engine);
    BEGIN << "parseArray";
    ScopedArrayObject array(scope, engine->newArrayObject());

    if (++nestingLevel > nestingLimit) {
        lastError = QJsonParseError::DeepNesting;
        return Encode::undefined();
    }

    if (!eatSpace()) {
        lastError = QJsonParseError::UnterminatedArray;
        return Encode::undefined();
    }
    if (*json == EndArray) {
        nextToken();
    } else {
        uint index = 0;
        while (1) {
            ScopedValue val(scope);
            if (!parseValue(val))
                return Encode::undefined();
            array->arraySet(index, val);
            QChar token = nextToken();
            if (token == EndArray)
                break;
            else if (token != ValueSeparator) {
                if (!eatSpace())
                    lastError = QJsonParseError::UnterminatedArray;
                else
                    lastError = QJsonParseError::MissingValueSeparator;
                return Encode::undefined();
            }
            ++index;
        }
    }

    DEBUG << "size =" << array->getLength();
    END;

    --nestingLevel;
    return array.asReturnedValue();
}

/*
value = false / null / true / object / array / number / string

*/

bool JsonParser::parseValue(Value *val)
{
    BEGIN << "parse Value" << *json;

    switch ((json++)->unicode()) {
    case 'n':
        if (end - json < 3) {
            lastError = QJsonParseError::IllegalValue;
            return false;
        }
        if (*json++ == 'u' &&
            *json++ == 'l' &&
            *json++ == 'l') {
            *val = Value::nullValue();
            DEBUG << "value: null";
            END;
            return true;
        }
        lastError = QJsonParseError::IllegalValue;
        return false;
    case 't':
        if (end - json < 3) {
            lastError = QJsonParseError::IllegalValue;
            return false;
        }
        if (*json++ == 'r' &&
            *json++ == 'u' &&
            *json++ == 'e') {
            *val = Value::fromBoolean(true);
            DEBUG << "value: true";
            END;
            return true;
        }
        lastError = QJsonParseError::IllegalValue;
        return false;
    case 'f':
        if (end - json < 4) {
            lastError = QJsonParseError::IllegalValue;
            return false;
        }
        if (*json++ == 'a' &&
            *json++ == 'l' &&
            *json++ == 's' &&
            *json++ == 'e') {
            *val = Value::fromBoolean(false);
            DEBUG << "value: false";
            END;
            return true;
        }
        lastError = QJsonParseError::IllegalValue;
        return false;
    case Quote: {
        QString value;
        if (!parseString(&value))
            return false;
        DEBUG << "value: string";
        END;
        *val = Value::fromHeapObject(engine->newString(value));
        return true;
    }
    case BeginArray: {
        *val = parseArray();
        if (val->isUndefined())
            return false;
        DEBUG << "value: array";
        END;
        return true;
    }
    case BeginObject: {
        *val = parseObject();
        if (val->isUndefined())
            return false;
        DEBUG << "value: object";
        END;
        return true;
    }
    case EndArray:
        lastError = QJsonParseError::MissingObject;
        return false;
    default:
        --json;
        if (!parseNumber(val))
            return false;
        DEBUG << "value: number";
        END;
    }

    return true;
}





/*
        number = [ minus ] int [ frac ] [ exp ]
        decimal-point = %x2E       ; .
        digit1-9 = %x31-39         ; 1-9
        e = %x65 / %x45            ; e E
        exp = e [ minus / plus ] 1*DIGIT
        frac = decimal-point 1*DIGIT
        int = zero / ( digit1-9 *DIGIT )
        minus = %x2D               ; -
        plus = %x2B                ; +
        zero = %x30                ; 0

*/

bool JsonParser::parseNumber(Value *val)
{
    BEGIN << "parseNumber" << *json;

    const QChar *start = json;
    bool isInt = true;

    // minus
    if (json < end && *json == '-')
        ++json;

    // int = zero / ( digit1-9 *DIGIT )
    if (json < end && *json == '0') {
        ++json;
    } else {
        while (json < end && *json >= '0' && *json <= '9')
            ++json;
    }

    // frac = decimal-point 1*DIGIT
    if (json < end && *json == '.') {
        isInt = false;
        ++json;
        while (json < end && *json >= '0' && *json <= '9')
            ++json;
    }

    // exp = e [ minus / plus ] 1*DIGIT
    if (json < end && (*json == 'e' || *json == 'E')) {
        isInt = false;
        ++json;
        if (json < end && (*json == '-' || *json == '+'))
            ++json;
        while (json < end && *json >= '0' && *json <= '9')
            ++json;
    }

    QString number(start, json - start);
    DEBUG << "numberstring" << number;

    if (isInt) {
        bool ok;
        int n = number.toInt(&ok);
        if (ok && n < (1<<25) && n > -(1<<25)) {
            *val = Value::fromInt32(n);
            END;
            return true;
        }
    }

    bool ok;
    double d;
    d = number.toDouble(&ok);

    if (!ok) {
        lastError = QJsonParseError::IllegalNumber;
        return false;
    }

    * val = Value::fromDouble(d);

    END;
    return true;
}

/*

        string = quotation-mark *char quotation-mark

        char = unescaped /
               escape (
                   %x22 /          ; "    quotation mark  U+0022
                   %x5C /          ; \    reverse solidus U+005C
                   %x2F /          ; /    solidus         U+002F
                   %x62 /          ; b    backspace       U+0008
                   %x66 /          ; f    form feed       U+000C
                   %x6E /          ; n    line feed       U+000A
                   %x72 /          ; r    carriage return U+000D
                   %x74 /          ; t    tab             U+0009
                   %x75 4HEXDIG )  ; uXXXX                U+XXXX

        escape = %x5C              ; \

        quotation-mark = %x22      ; "

        unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
 */
static inline bool addHexDigit(QChar digit, uint *result)
{
    ushort d = digit.unicode();
    *result <<= 4;
    if (d >= '0' && d <= '9')
        *result |= (d - '0');
    else if (d >= 'a' && d <= 'f')
        *result |= (d - 'a') + 10;
    else if (d >= 'A' && d <= 'F')
        *result |= (d - 'A') + 10;
    else
        return false;
    return true;
}

static inline bool scanEscapeSequence(const QChar *&json, const QChar *end, uint *ch)
{
    ++json;
    if (json >= end)
        return false;

    DEBUG << "scan escape";
    uint escaped = (json++)->unicode();
    switch (escaped) {
    case '"':
        *ch = '"'; break;
    case '\\':
        *ch = '\\'; break;
    case '/':
        *ch = '/'; break;
    case 'b':
        *ch = 0x8; break;
    case 'f':
        *ch = 0xc; break;
    case 'n':
        *ch = 0xa; break;
    case 'r':
        *ch = 0xd; break;
    case 't':
        *ch = 0x9; break;
    case 'u': {
        *ch = 0;
        if (json > end - 4)
            return false;
        for (int i = 0; i < 4; ++i) {
            if (!addHexDigit(*json, ch))
                return false;
            ++json;
        }
        return true;
    }
    default:
        return false;
    }
    return true;
}


bool JsonParser::parseString(QString *string)
{
    BEGIN << "parse string stringPos=" << json;

    while (json < end) {
        if (*json == '"')
            break;
        else if (*json == '\\') {
            uint ch = 0;
            if (!scanEscapeSequence(json, end, &ch)) {
                lastError = QJsonParseError::IllegalEscapeSequence;
                return false;
            }
            if (QChar::requiresSurrogates(ch)) {
                *string += QChar(QChar::highSurrogate(ch)) + QChar(QChar::lowSurrogate(ch));
            } else {
                *string += QChar(ch);
            }
        } else {
            if (json->unicode() <= 0x1f) {
                lastError = QJsonParseError::IllegalEscapeSequence;
                return false;
            }
            *string += *json;
            ++json;
        }
    }
    ++json;

    if (json > end) {
        lastError = QJsonParseError::UnterminatedString;
        return false;
    }

    END;
    return true;
}


struct Stringify
{
    ExecutionEngine *v4;
    FunctionObject *replacerFunction;
    QV4::String *propertyList;
    int propertyListSize;
    QString gap;
    QString indent;
    QStack<Object *> stack;

    bool stackContains(Object *o) {
        for (int i = 0; i < stack.size(); ++i)
            if (stack.at(i)->d() == o->d())
                return true;
        return false;
    }

    Stringify(ExecutionEngine *e) : v4(e), replacerFunction(nullptr), propertyList(nullptr), propertyListSize(0) {}

    QString Str(const QString &key, const Value &v);
    QString JA(Object *a);
    QString JO(Object *o);

    QString makeMember(const QString &key, const Value &v);
};

static QString quote(const QString &str)
{
    QString product;
    const int length = str.length();
    product.reserve(length + 2);
    product += QLatin1Char('"');
    for (int i = 0; i < length; ++i) {
        QChar c = str.at(i);
        switch (c.unicode()) {
        case '"':
            product += QLatin1String("\\\"");
            break;
        case '\\':
            product += QLatin1String("\\\\");
            break;
        case '\b':
            product += QLatin1String("\\b");
            break;
        case '\f':
            product += QLatin1String("\\f");
            break;
        case '\n':
            product += QLatin1String("\\n");
            break;
        case '\r':
            product += QLatin1String("\\r");
            break;
        case '\t':
            product += QLatin1String("\\t");
            break;
        default:
            if (c.unicode() <= 0x1f) {
                product += QLatin1String("\\u00");
                product += (c.unicode() > 0xf ? QLatin1Char('1') : QLatin1Char('0')) +
                        QLatin1Char("0123456789abcdef"[c.unicode() & 0xf]);
            } else {
                product += c;
            }
        }
    }
    product += QLatin1Char('"');
    return product;
}

QString Stringify::Str(const QString &key, const Value &v)
{
    Scope scope(v4);

    ScopedValue value(scope, v);
    ScopedObject o(scope, value);
    if (o) {
        ScopedString s(scope, v4->newString(QStringLiteral("toJSON")));
        ScopedFunctionObject toJSON(scope, o->get(s));
        if (!!toJSON) {
            JSCallData jsCallData(scope, 1);
            *jsCallData->thisObject = value;
            jsCallData->args[0] = v4->newString(key);
            value = toJSON->call(jsCallData);
        }
    }

    if (replacerFunction) {
        ScopedObject holder(scope, v4->newObject());
        holder->put(scope.engine->id_empty(), value);
        JSCallData jsCallData(scope, 2);
        jsCallData->args[0] = v4->newString(key);
        jsCallData->args[1] = value;
        *jsCallData->thisObject = holder;
        value = replacerFunction->call(jsCallData);
    }

    o = value->asReturnedValue();
    if (o) {
        if (NumberObject *n = o->as<NumberObject>())
            value = Encode(n->value());
        else if (StringObject *so = o->as<StringObject>())
            value = so->d()->string;
        else if (BooleanObject *b = o->as<BooleanObject>())
            value = Encode(b->value());
    }

    if (value->isNull())
        return QStringLiteral("null");
    if (value->isBoolean())
        return value->booleanValue() ? QStringLiteral("true") : QStringLiteral("false");
    if (value->isString())
        return quote(value->stringValue()->toQString());

    if (value->isNumber()) {
        double d = value->toNumber();
        return std::isfinite(d) ? value->toQString() : QStringLiteral("null");
    }

    if (const QV4::VariantObject *v = value->as<QV4::VariantObject>()) {
        return quote(v->d()->data().toString());
    }

    o = value->asReturnedValue();
    if (o) {
        if (!o->as<FunctionObject>()) {
            if (o->isArrayLike()) {
                return JA(o.getPointer());
            } else {
                return JO(o);
            }
        }
    }

    return QString();
}

QString Stringify::makeMember(const QString &key, const Value &v)
{
    QString strP = Str(key, v);
    if (!strP.isEmpty()) {
        QString member = quote(key) + QLatin1Char(':');
        if (!gap.isEmpty())
            member += QLatin1Char(' ');
        member += strP;
        return member;
    }
    return QString();
}

QString Stringify::JO(Object *o)
{
    if (stackContains(o)) {
        v4->throwTypeError();
        return QString();
    }

    Scope scope(v4);

    QString result;
    stack.push(o);
    QString stepback = indent;
    indent += gap;

    QStringList partial;
    if (!propertyListSize) {
        ObjectIterator it(scope, o, ObjectIterator::EnumerableOnly);
        ScopedValue name(scope);

        ScopedValue val(scope);
        while (1) {
            name = it.nextPropertyNameAsString(val);
            if (name->isNull())
                break;
            QString key = name->toQString();
            QString member = makeMember(key, val);
            if (!member.isEmpty())
                partial += member;
        }
    } else {
        ScopedValue v(scope);
        for (int i = 0; i < propertyListSize; ++i) {
            bool exists;
            String *s = propertyList + i;
            if (!s)
                continue;
            v = o->get(s, &exists);
            if (!exists)
                continue;
            QString member = makeMember(s->toQString(), v);
            if (!member.isEmpty())
                partial += member;
        }
    }

    if (partial.isEmpty()) {
        result = QStringLiteral("{}");
    } else if (gap.isEmpty()) {
        result = QLatin1Char('{') + partial.join(QLatin1Char(',')) + QLatin1Char('}');
    } else {
        QString separator = QLatin1String(",\n") + indent;
        result = QLatin1String("{\n") + indent + partial.join(separator) + QLatin1Char('\n')
                 + stepback + QLatin1Char('}');
    }

    indent = stepback;
    stack.pop();
    return result;
}

QString Stringify::JA(Object *a)
{
    if (stackContains(a)) {
        v4->throwTypeError();
        return QString();
    }

    Scope scope(a->engine());

    QString result;
    stack.push(a);
    QString stepback = indent;
    indent += gap;

    QStringList partial;
    uint len = a->getLength();
    ScopedValue v(scope);
    for (uint i = 0; i < len; ++i) {
        bool exists;
        v = a->get(i, &exists);
        if (!exists) {
            partial += QStringLiteral("null");
            continue;
        }
        QString strP = Str(QString::number(i), v);
        if (!strP.isEmpty())
            partial += strP;
        else
            partial += QStringLiteral("null");
    }

    if (partial.isEmpty()) {
        result = QStringLiteral("[]");
    } else if (gap.isEmpty()) {
        result = QLatin1Char('[') + partial.join(QLatin1Char(',')) + QLatin1Char(']');
    } else {
        QString separator = QLatin1String(",\n") + indent;
        result = QLatin1String("[\n") + indent + partial.join(separator) + QLatin1Char('\n') + stepback + QLatin1Char(']');
    }

    indent = stepback;
    stack.pop();
    return result;
}


void Heap::JsonObject::init()
{
    Object::init();
    Scope scope(internalClass->engine);
    ScopedObject o(scope, this);

    o->defineDefaultProperty(QStringLiteral("parse"), QV4::JsonObject::method_parse, 2);
    o->defineDefaultProperty(QStringLiteral("stringify"), QV4::JsonObject::method_stringify, 3);
    ScopedString json(scope, scope.engine->newString(QStringLiteral("JSON")));
    o->defineReadonlyConfigurableProperty(scope.engine->symbol_toStringTag(), json);
}


ReturnedValue JsonObject::method_parse(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
    ExecutionEngine *v4 = b->engine();
    QString jtext;
    if (argc > 0)
        jtext = argv[0].toQString();

    DEBUG << "parsing source = " << jtext;
    JsonParser parser(v4, jtext.constData(), jtext.length());
    QJsonParseError error;
    ReturnedValue result = parser.parse(&error);
    if (error.error != QJsonParseError::NoError) {
        DEBUG << "parse error" << error.errorString();
        RETURN_RESULT(v4->throwSyntaxError(QStringLiteral("JSON.parse: Parse error")));
    }

    return result;
}

ReturnedValue JsonObject::method_stringify(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
    Scope scope(b);
    Stringify stringify(scope.engine);

    ScopedObject o(scope, argc > 1 ? argv[1] : Value::undefinedValue());
    if (o) {
        stringify.replacerFunction = o->as<FunctionObject>();
        if (o->isArrayObject()) {
            uint arrayLen = o->getLength();
            stringify.propertyList = static_cast<QV4::String *>(scope.alloc(arrayLen));
            for (uint i = 0; i < arrayLen; ++i) {
                Value *v = stringify.propertyList + i;
                *v = o->get(i);
                if (v->as<NumberObject>() || v->as<StringObject>() || v->isNumber())
                    *v = v->toString(scope.engine);
                if (!v->isString()) {
                    v->setM(nullptr);
                } else {
                    for (uint j = 0; j <i; ++j) {
                        if (stringify.propertyList[j].m() == v->m()) {
                            v->setM(nullptr);
                            break;
                        }
                    }
                }
            }
        }
    }

    ScopedValue s(scope, argc > 2 ? argv[2] : Value::undefinedValue());
    if (NumberObject *n = s->as<NumberObject>())
        s = Encode(n->value());
    else if (StringObject *so = s->as<StringObject>())
        s = so->d()->string;

    if (s->isNumber()) {
        stringify.gap = QString(qMin(10, (int)s->toInteger()), ' ');
    } else if (String *str = s->stringValue()) {
        stringify.gap = str->toQString().left(10);
    }


    ScopedValue arg0(scope, argc ? argv[0] : Value::undefinedValue());
    QString result = stringify.Str(QString(), arg0);
    if (result.isEmpty() || scope.engine->hasException)
        RETURN_UNDEFINED();
    return Encode(scope.engine->newString(result));
}



ReturnedValue JsonObject::fromJsonValue(ExecutionEngine *engine, const QJsonValue &value)
{
    if (value.isString())
        return engine->newString(value.toString())->asReturnedValue();
    else if (value.isDouble())
        return Encode(value.toDouble());
    else if (value.isBool())
        return Encode(value.toBool());
    else if (value.isArray())
        return fromJsonArray(engine, value.toArray());
    else if (value.isObject())
        return fromJsonObject(engine, value.toObject());
    else if (value.isNull())
        return Encode::null();
    else
        return Encode::undefined();
}

QJsonValue JsonObject::toJsonValue(const Value &value, V4ObjectSet &visitedObjects)
{
    if (value.isNumber())
        return QJsonValue(value.toNumber());
    else if (value.isBoolean())
        return QJsonValue((bool)value.booleanValue());
    else if (value.isNull())
        return QJsonValue(QJsonValue::Null);
    else if (value.isUndefined())
        return QJsonValue(QJsonValue::Undefined);
    else if (String *s = value.stringValue())
        return QJsonValue(s->toQString());

    Q_ASSERT(value.isObject());
    Scope scope(value.as<Object>()->engine());
    ScopedArrayObject a(scope, value);
    if (a)
        return toJsonArray(a, visitedObjects);
    ScopedObject o(scope, value);
    if (o)
        return toJsonObject(o, visitedObjects);
    return QJsonValue(value.toQString());
}

QV4::ReturnedValue JsonObject::fromJsonObject(ExecutionEngine *engine, const QJsonObject &object)
{
    Scope scope(engine);
    ScopedObject o(scope, engine->newObject());
    ScopedString s(scope);
    ScopedValue v(scope);
    for (QJsonObject::const_iterator it = object.begin(), cend = object.end(); it != cend; ++it) {
        v = fromJsonValue(engine, it.value());
        o->put((s = engine->newString(it.key())), v);
    }
    return o.asReturnedValue();
}

QJsonObject JsonObject::toJsonObject(const Object *o, V4ObjectSet &visitedObjects)
{
    QJsonObject result;
    if (!o || o->as<FunctionObject>())
        return result;

    Scope scope(o->engine());

    if (visitedObjects.contains(ObjectItem(o))) {
        // Avoid recursion.
        // For compatibility with QVariant{List,Map} conversion, we return an
        // empty object (and no error is thrown).
        return result;
    }

    visitedObjects.insert(ObjectItem(o));

    ObjectIterator it(scope, o, ObjectIterator::EnumerableOnly);
    ScopedValue name(scope);
    QV4::ScopedValue val(scope);
    while (1) {
        name = it.nextPropertyNameAsString(val);
        if (name->isNull())
            break;

        QString key = name->toQStringNoThrow();
        if (!val->as<FunctionObject>())
            result.insert(key, toJsonValue(val, visitedObjects));
    }

    visitedObjects.remove(ObjectItem(o));

    return result;
}

QV4::ReturnedValue JsonObject::fromJsonArray(ExecutionEngine *engine, const QJsonArray &array)
{
    Scope scope(engine);
    int size = array.size();
    ScopedArrayObject a(scope, engine->newArrayObject());
    a->arrayReserve(size);
    ScopedValue v(scope);
    for (int i = 0; i < size; i++)
        a->arrayPut(i, (v = fromJsonValue(engine, array.at(i))));
    a->setArrayLengthUnchecked(size);
    return a.asReturnedValue();
}

QJsonArray JsonObject::toJsonArray(const ArrayObject *a, V4ObjectSet &visitedObjects)
{
    QJsonArray result;
    if (!a)
        return result;

    Scope scope(a->engine());

    if (visitedObjects.contains(ObjectItem(a))) {
        // Avoid recursion.
        // For compatibility with QVariant{List,Map} conversion, we return an
        // empty array (and no error is thrown).
        return result;
    }

    visitedObjects.insert(ObjectItem(a));

    ScopedValue v(scope);
    quint32 length = a->getLength();
    for (quint32 i = 0; i < length; ++i) {
        v = a->get(i);
        if (v->as<FunctionObject>())
            v = Encode::null();
        result.append(toJsonValue(v, visitedObjects));
    }

    visitedObjects.remove(ObjectItem(a));

    return result;
}
