/****************************************************************************
**
** 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 <QtCore/qstring.h>
#include <QtCore/qvarlengtharray.h>
#include <QtCore/qdatetime.h>
#include "qjsengine.h"
#include "qjsvalue.h"
#include "qjsvalue_p.h"
#include "qv4value_p.h"
#include "qv4object_p.h"
#include "qv4functionobject_p.h"
#include "qv4dateobject_p.h"
#include "qv4runtime_p.h"
#include "qv4variantobject_p.h"
#include "qv4regexpobject_p.h"
#include "qv4errorobject_p.h"
#include <private/qv4mm_p.h>
#include <private/qv4jscall_p.h>
#include <private/qv4qobjectwrapper_p.h>

/*!
  \since 5.0
  \class QJSValue

  \brief The QJSValue class acts as a container for Qt/JavaScript data types.

  \ingroup qtjavascript
  \inmodule QtQml

  QJSValue supports the types defined in the \l{ECMA-262}
  standard: The primitive types, which are Undefined, Null, Boolean,
  Number, and String; and the Object and Array types. Additionally, built-in
  support is provided for Qt/C++ types such as QVariant and QObject.

  For the object-based types (including Date and RegExp), use the
  newT() functions in QJSEngine (e.g. QJSEngine::newObject())
  to create a QJSValue of the desired type. For the primitive types,
  use one of the QJSValue constructor overloads. For other types, e.g.
  registered gadget types such as QPoint, you can use QJSEngine::toScriptValue.

  The methods named isT() (e.g. isBool(), isUndefined()) can be
  used to test if a value is of a certain type. The methods named
  toT() (e.g. toBool(), toString()) can be used to convert a
  QJSValue to another type. You can also use the generic
  qjsvalue_cast() function.

  Object values have zero or more properties which are themselves
  QJSValues. Use setProperty() to set a property of an object, and
  call property() to retrieve the value of a property.

  \snippet code/src_script_qjsvalue.cpp 0

  If you want to iterate over the properties of a script object, use
  the QJSValueIterator class.

  Object values have an internal \c{prototype} property, which can be
  accessed with prototype() and setPrototype().

  Function objects (objects for which isCallable()) returns true) can
  be invoked by calling call(). Constructor functions can be used to
  construct new objects by calling callAsConstructor().

  Use equals() or strictlyEquals() to compare a QJSValue to another.

  Note that a QJSValue for which isObject() is true only carries a
  reference to an actual object; copying the QJSValue will only
  copy the object reference, not the object itself. If you want to
  clone an object (i.e. copy an object's properties to another
  object), you can do so with the help of a \c{for-in} statement in
  script code, or QJSValueIterator in C++.

  \sa QJSEngine, QJSValueIterator

  \section1 Working With Arrays

  To create an array using QJSValue, use \l QJSEngine::newArray():

  \code
  // Assumes that this class was declared in QML.
  QJSValue jsArray = engine->newArray(3);
  \endcode

  To set individual elements in the array, use
  the \l {QJSValue::}{setProperty(quint32 arrayIndex, const QJSValue &value)}
  overload. For example, to fill the array above with integers:

  \code
  for (int i = 0; i < 3; ++i) {
      jsArray.setProperty(i, QRandomGenerator::global().generate());
  }
  \endcode

  To determine the length of the array, access the \c "length" property.
  To access array elements, use the
  \l {QJSValue::}{property(quint32 arrayIndex)} overload. The following code
  reads the array we created above back into a list:

  \code
  QVector<int> integers;
  const int length = jsArray.property("length").toInt();
  for (int i = 0; i < length; ++i) {
      integers.append(jsArray.property(i).toInt());
  }
  \endcode
*/

/*!
    \enum QJSValue::SpecialValue

    This enum is used to specify a single-valued type.

    \value UndefinedValue An undefined value.

    \value NullValue A null value.
*/

/*!
    \typedef QJSValueList
    \relates QJSValue

    This is a typedef for a QList<QJSValue>.
*/

/*!
    \enum QJSValue::ErrorType
    \since 5.12

    Use this enum for JavaScript language-specific types of Error objects.

    They may be useful when emulating language features in C++ requires the use
    of specialized exception types. In addition, they may help to more clearly
    communicate certain typical conditions, instead of throwing a generic
    JavaScript exception. For example, code that deals with networking and
    resource locators may find it useful to propagate errors related to
    malformed locators using the URIError type.

    \omitvalue NoError
    \value GenericError A generic Error object, but not of a specific sub-type.
    \omitvalue EvalError
    \value RangeError A value did not match the expected set or range.
    \value ReferenceError A non-existing variable referenced.
    \value SyntaxError An invalid token or sequence of tokens was encountered
    that does not conform with the syntax of the language.
    \value TypeError An operand or argument is incompatible with the type
    expected.
    \value URIError A URI handling function was used incorrectly or the URI
    provided is malformed.
*/

QT_BEGIN_NAMESPACE

using namespace QV4;

/*!
  Constructs a new QJSValue with a boolean \a value.
*/
QJSValue::QJSValue(bool value)
{
    QJSValuePrivate::setVariant(this, QVariant(value));
}

/*!
  \internal
*/
QJSValue::QJSValue(ExecutionEngine *e, quint64 val)
{
    QJSValuePrivate::setValue(this, e, val);
}

/*!
  Constructs a new QJSValue with a number \a value.
*/
QJSValue::QJSValue(int value)
{
    QJSValuePrivate::setVariant(this, QVariant(value));
}

/*!
  Constructs a new QJSValue with a number \a value.
*/
QJSValue::QJSValue(uint value)
{
    QJSValuePrivate::setVariant(this, QVariant((double)value));
}

/*!
  Constructs a new QJSValue with a number \a value.
*/
QJSValue::QJSValue(double value)
{
    QJSValuePrivate::setVariant(this, QVariant(value));
}

/*!
  Constructs a new QJSValue with a string \a value.
*/
QJSValue::QJSValue(const QString& value)
{
    QJSValuePrivate::setVariant(this, QVariant(value));
}

/*!
  Constructs a new QJSValue with a special \a value.
*/
QJSValue::QJSValue(SpecialValue value)
    : d(0)
{
    if (value == NullValue)
        QJSValuePrivate::setVariant(this, QVariant::fromValue(nullptr));
}

/*!
  Constructs a new QJSValue with a string \a value.
*/
QJSValue::QJSValue(const QLatin1String &value)
{
    QJSValuePrivate::setVariant(this, QVariant(value));
}

/*!
  Constructs a new QJSValue with a string \a value.
*/
#ifndef QT_NO_CAST_FROM_ASCII
QJSValue::QJSValue(const char *value)
{
    QJSValuePrivate::setVariant(this, QVariant(QString::fromUtf8(value)));
}
#endif

/*!
  Constructs a new QJSValue that is a copy of \a other.

  Note that if \a other is an object (i.e., isObject() would return
  true), then only a reference to the underlying object is copied into
  the new script value (i.e., the object itself is not copied).
*/
QJSValue::QJSValue(const QJSValue& other)
    : d(0)
{
    QV4::Value *v = QJSValuePrivate::getValue(&other);
    if (v) {
        QJSValuePrivate::setValue(this, QJSValuePrivate::engine(&other), *v);
    } else if (QVariant *v = QJSValuePrivate::getVariant(&other)) {
        QJSValuePrivate::setVariant(this, *v);
    }
}

/*!
    \fn QJSValue::QJSValue(QJSValue && other)

    Move constructor. Moves from \a other into this QJSValue object.
*/

/*!
    \fn QJSValue &QJSValue::operator=(QJSValue && other)

    Move-assigns \a other to this QJSValue object.
*/

/*!
    Destroys this QJSValue.
*/
QJSValue::~QJSValue()
{
    QJSValuePrivate::free(this);
}

/*!
  Returns true if this QJSValue is of the primitive type Boolean;
  otherwise returns false.

  \sa toBool()
*/
bool QJSValue::isBool() const
{
    QV4::Value *val = QJSValuePrivate::getValue(this);
    if (val)
        return val->isBoolean();
    QVariant *variant = QJSValuePrivate::getVariant(this);
    return variant && variant->userType() == QMetaType::Bool;
}

/*!
  Returns true if this QJSValue is of the primitive type Number;
  otherwise returns false.

  \sa toNumber()
*/
bool QJSValue::isNumber() const
{
    QV4::Value *val = QJSValuePrivate::getValue(this);
    if (val)
        return val->isNumber();
    QVariant *variant = QJSValuePrivate::getVariant(this);
    if (!variant)
        return false;

    switch (variant->userType()) {
    case QMetaType::Double:
    case QMetaType::Int:
    case QMetaType::UInt:
    case QMetaType::Long:
    case QMetaType::ULong:
    case QMetaType::Short:
    case QMetaType::UShort:
    case QMetaType::LongLong:
    case QMetaType::ULongLong:
        return true;
    default:
        return false;
    }
}

/*!
  Returns true if this QJSValue is of the primitive type Null;
  otherwise returns false.
*/
bool QJSValue::isNull() const
{
    QV4::Value *val = QJSValuePrivate::getValue(this);
    if (val)
        return val->isNull();
    QVariant *variant = QJSValuePrivate::getVariant(this);
    if (!variant)
        return false;
    const int type = variant->userType();
    return type == QMetaType::Nullptr || type == QMetaType::VoidStar;
}

/*!
  Returns true if this QJSValue is of the primitive type String;
  otherwise returns false.

  \sa toString()
*/
bool QJSValue::isString() const
{
    QV4::Value *val = QJSValuePrivate::getValue(this);
    if (val)
        return val->isString();
    QVariant *variant = QJSValuePrivate::getVariant(this);
    return variant && variant->userType() == QMetaType::QString;
}

/*!
  Returns true if this QJSValue is of the primitive type Undefined;
  otherwise returns false.
*/
bool QJSValue::isUndefined() const
{
    QV4::Value *val = QJSValuePrivate::getValue(this);
    if (val)
        return val->isUndefined();
    QVariant *variant = QJSValuePrivate::getVariant(this);
    return !variant || variant->userType() == QMetaType::UnknownType || variant->userType() == QMetaType::Void;
}

/*!
  Returns true if this QJSValue is an object of the Error class;
  otherwise returns false.

  \sa errorType(), {QJSEngine#Script Exceptions}{QJSEngine - Script Exceptions}
*/
bool QJSValue::isError() const
{
    QV4::Value *val = QJSValuePrivate::getValue(this);
    if (!val)
        return false;
    return val->as<ErrorObject>();
}

/*!
  \since 5.12
  Returns the error type this QJSValue represents if it is an Error object.
  Otherwise, returns \c NoError."

  \sa isError(), {QJSEngine#Script Exceptions}{QJSEngine - Script Exceptions}
*/
QJSValue::ErrorType QJSValue::errorType() const
{
    QV4::Value *val = QJSValuePrivate::getValue(this);
    if (!val)
        return NoError;
    QV4::ErrorObject *error = val->as<ErrorObject>();
    if (!error)
        return NoError;
    switch (error->d()->errorType) {
    case QV4::Heap::ErrorObject::Error:
        return GenericError;
    case QV4::Heap::ErrorObject::EvalError:
        return EvalError;
    case QV4::Heap::ErrorObject::RangeError:
        return RangeError;
    case QV4::Heap::ErrorObject::ReferenceError:
        return ReferenceError;
    case QV4::Heap::ErrorObject::SyntaxError:
        return SyntaxError;
    case QV4::Heap::ErrorObject::TypeError:
        return TypeError;
    case QV4::Heap::ErrorObject::URIError:
        return URIError;
    }
    Q_UNREACHABLE();
    return NoError;
}

/*!
  Returns true if this QJSValue is an object of the Array class;
  otherwise returns false.

  \sa QJSEngine::newArray()
*/
bool QJSValue::isArray() const
{
    QV4::Value *val = QJSValuePrivate::getValue(this);
    if (!val)
        return false;
    return val->as<ArrayObject>();
}

/*!
  Returns true if this QJSValue is of the Object type; otherwise
  returns false.

  Note that function values, variant values, and QObject values are
  objects, so this function returns true for such values.

  \sa QJSEngine::newObject()
*/
bool QJSValue::isObject() const
{
    QV4::Value *val = QJSValuePrivate::getValue(this);
    if (!val)
        return false;
    return val->as<QV4::Object>();
}

/*!
  Returns true if this QJSValue can be called a function, otherwise
  returns false.

  \sa call()
*/
bool QJSValue::isCallable() const
{
    QV4::Value *val = QJSValuePrivate::getValue(this);
    if (!val)
        return false;
    return val->as<FunctionObject>();
}

/*!
  Returns true if this QJSValue is a variant value;
  otherwise returns false.

  \sa toVariant()
*/
bool QJSValue::isVariant() const
{
    QV4::Value *val = QJSValuePrivate::getValue(this);
    if (!val)
        return false;
    return val->as<QV4::VariantObject>();
}

/*!
  Returns the string value of this QJSValue, as defined in
  \l{ECMA-262} section 9.8, "ToString".

  Note that if this QJSValue is an object, calling this function
  has side effects on the script engine, since the engine will call
  the object's toString() function (and possibly valueOf()) in an
  attempt to convert the object to a primitive value (possibly
  resulting in an uncaught script exception).

  \sa isString()
*/
QString QJSValue::toString() const
{
    QV4::Value scratch;
    QV4::Value *val = QJSValuePrivate::valueForData(this, &scratch);

    if (!val) {
        QVariant *variant = QJSValuePrivate::getVariant(this);
        Q_ASSERT(variant);
        if (variant->userType() == QMetaType::QVariantMap)
            return QStringLiteral("[object Object]");
        else if (variant->userType() == QMetaType::QVariantList) {
            const QVariantList list = variant->toList();
            QString result;
            for (int i = 0; i < list.count(); ++i) {
                if (i > 0)
                    result.append(QLatin1Char(','));
                result.append(list.at(i).toString());
            }
            return result;
        }
        return variant->toString();
    }
    return val->toQStringNoThrow();
}

/*!
  Returns the number value of this QJSValue, as defined in
  \l{ECMA-262} section 9.3, "ToNumber".

  Note that if this QJSValue is an object, calling this function
  has side effects on the script engine, since the engine will call
  the object's valueOf() function (and possibly toString()) in an
  attempt to convert the object to a primitive value (possibly
  resulting in an uncaught script exception).

  \sa isNumber(), toInt(), toUInt()
*/
double QJSValue::toNumber() const
{
    QV4::Value scratch;
    QV4::Value *val = QJSValuePrivate::valueForData(this, &scratch);

    if (!val) {
        QVariant *variant = QJSValuePrivate::getVariant(this);
        Q_ASSERT(variant);

        if (variant->userType() == QMetaType::QString)
            return RuntimeHelpers::stringToNumber(variant->toString());
        else if (variant->canConvert<double>())
            return variant->value<double>();
        else
            return std::numeric_limits<double>::quiet_NaN();
    }

    double dbl = val->toNumber();
    QV4::ExecutionEngine *engine = QJSValuePrivate::engine(this);
    if (engine && engine->hasException) {
        engine->catchException();
        return 0;
    }
    return dbl;
}

/*!
  Returns the boolean value of this QJSValue, using the conversion
  rules described in \l{ECMA-262} section 9.2, "ToBoolean".

  Note that if this QJSValue is an object, calling this function
  has side effects on the script engine, since the engine will call
  the object's valueOf() function (and possibly toString()) in an
  attempt to convert the object to a primitive value (possibly
  resulting in an uncaught script exception).

  \sa isBool()
*/
bool QJSValue::toBool() const
{
    QV4::Value scratch;
    QV4::Value *val = QJSValuePrivate::valueForData(this, &scratch);

    if (!val) {
        QVariant *variant = QJSValuePrivate::getVariant(this);
        if (variant->userType() == QMetaType::QString)
            return variant->toString().length() > 0;
        else
            return variant->toBool();
    }

    bool b = val->toBoolean();
    QV4::ExecutionEngine *engine = QJSValuePrivate::engine(this);
    if (engine && engine->hasException) {
        engine->catchException();
        return false;
    }
    return b;
}

/*!
  Returns the signed 32-bit integer value of this QJSValue, using
  the conversion rules described in \l{ECMA-262} section 9.5, "ToInt32".

  Note that if this QJSValue is an object, calling this function
  has side effects on the script engine, since the engine will call
  the object's valueOf() function (and possibly toString()) in an
  attempt to convert the object to a primitive value (possibly
  resulting in an uncaught script exception).

  \sa toNumber(), toUInt()
*/
qint32 QJSValue::toInt() const
{
    QV4::Value scratch;
    QV4::Value *val = QJSValuePrivate::valueForData(this, &scratch);

    if (!val) {
        QVariant *variant = QJSValuePrivate::getVariant(this);
        if (variant->userType() == QMetaType::QString)
            return QV4::Value::toInt32(RuntimeHelpers::stringToNumber(variant->toString()));
        else
            return variant->toInt();
    }

    qint32 i = val->toInt32();
    QV4::ExecutionEngine *engine = QJSValuePrivate::engine(this);
    if (engine && engine->hasException) {
        engine->catchException();
        return 0;
    }
    return i;
}

/*!
  Returns the unsigned 32-bit integer value of this QJSValue, using
  the conversion rules described in \l{ECMA-262} section 9.6, "ToUint32".

  Note that if this QJSValue is an object, calling this function
  has side effects on the script engine, since the engine will call
  the object's valueOf() function (and possibly toString()) in an
  attempt to convert the object to a primitive value (possibly
  resulting in an uncaught script exception).

  \sa toNumber(), toInt()
*/
quint32 QJSValue::toUInt() const
{
    QV4::Value scratch;
    QV4::Value *val = QJSValuePrivate::valueForData(this, &scratch);

    if (!val) {
        QVariant *variant = QJSValuePrivate::getVariant(this);
        if (variant->userType() == QMetaType::QString)
            return QV4::Value::toUInt32(RuntimeHelpers::stringToNumber(variant->toString()));
        else
            return variant->toUInt();
    }

    quint32 u = val->toUInt32();
    QV4::ExecutionEngine *engine = QJSValuePrivate::engine(this);
    if (engine && engine->hasException) {
        engine->catchException();
        return 0;
    }
    return u;
}

/*!
  Returns the QVariant value of this QJSValue, if it can be
  converted to a QVariant; otherwise returns an invalid QVariant.
  The conversion is performed according to the following table:

    \table
    \header \li Input Type \li Result
    \row    \li Undefined  \li An invalid QVariant.
    \row    \li Null       \li A QVariant containing a null pointer (QMetaType::Nullptr).
    \row    \li Boolean    \li A QVariant containing the value of the boolean.
    \row    \li Number     \li A QVariant containing the value of the number.
    \row    \li String     \li A QVariant containing the value of the string.
    \row    \li QVariant Object \li The result is the QVariant value of the object (no conversion).
    \row    \li QObject Object \li A QVariant containing a pointer to the QObject.
    \row    \li Date Object \li A QVariant containing the date value (toDateTime()).
    \row    \li RegExp Object \li A QVariant containing the regular expression value.
    \row    \li Array Object \li The array is converted to a QVariantList. Each element is converted to a QVariant, recursively; cyclic references are not followed.
    \row    \li Object     \li The object is converted to a QVariantMap. Each property is converted to a QVariant, recursively; cyclic references are not followed.
    \endtable

  \sa isVariant()
*/
QVariant QJSValue::toVariant() const
{
    QVariant *variant = QJSValuePrivate::getVariant(this);
    if (variant)
        return *variant;

    QV4::Value scratch;
    QV4::Value *val = QJSValuePrivate::valueForData(this, &scratch);
    Q_ASSERT(val);

    if (QV4::Object *o = val->as<QV4::Object>())
        return o->engine()->toVariant(*val, /*typeHint*/ -1, /*createJSValueForObjects*/ false);

    if (String *s = val->stringValue())
        return QVariant(s->toQString());
    if (val->isBoolean())
        return QVariant(val->booleanValue());
    if (val->isNumber()) {
        if (val->isInt32())
            return QVariant(val->integerValue());
        return QVariant(val->asDouble());
    }
    if (val->isNull())
        return QVariant(QMetaType::Nullptr, nullptr);
    Q_ASSERT(val->isUndefined());
    return QVariant();
}

/*!
  Calls this QJSValue as a function, passing \a args as arguments
  to the function, and using the globalObject() as the "this"-object.
  Returns the value returned from the function.

  If this QJSValue is not callable, call() does nothing and
  returns an undefined QJSValue.

  Calling call() can cause an exception to occur in the script engine;
  in that case, call() returns the value that was thrown (typically an
  \c{Error} object). You can call isError() on the return value to
  determine whether an exception occurred.

  \sa isCallable(), callWithInstance(), callAsConstructor()
*/
QJSValue QJSValue::call(const QJSValueList &args)
{
    QV4::Value *val = QJSValuePrivate::getValue(this);
    if (!val)
        return QJSValue();

    FunctionObject *f = val->as<FunctionObject>();
    if (!f)
        return QJSValue();

    QV4::ExecutionEngine *engine = QJSValuePrivate::engine(this);
    Q_ASSERT(engine);

    Scope scope(engine);
    JSCallData jsCallData(scope, args.length());
    *jsCallData->thisObject = engine->globalObject;
    for (int i = 0; i < args.size(); ++i) {
        if (!QJSValuePrivate::checkEngine(engine, args.at(i))) {
            qWarning("QJSValue::call() failed: cannot call function with argument created in a different engine");
            return QJSValue();
        }
        jsCallData->args[i] = QJSValuePrivate::convertedToValue(engine, args.at(i));
    }

    ScopedValue result(scope, f->call(jsCallData));
    if (engine->hasException)
        result = engine->catchException();
    if (engine->isInterrupted.loadAcquire())
        result = engine->newErrorObject(QStringLiteral("Interrupted"));

    return QJSValue(engine, result->asReturnedValue());
}

/*!
  Calls this QJSValue as a function, using \a instance as
  the `this' object in the function call, and passing \a args
  as arguments to the function. Returns the value returned from
  the function.

  If this QJSValue is not a function, call() does nothing
  and returns an undefined QJSValue.

  Note that if \a instance is not an object, the global object
  (see \l{QJSEngine::globalObject()}) will be used as the
  `this' object.

  Calling call() can cause an exception to occur in the script engine;
  in that case, call() returns the value that was thrown (typically an
  \c{Error} object). You can call isError() on the return value to
  determine whether an exception occurred.

  \sa call()
*/
QJSValue QJSValue::callWithInstance(const QJSValue &instance, const QJSValueList &args)
{
    QV4::Value *val = QJSValuePrivate::getValue(this);
    if (!val)
        return QJSValue();

    FunctionObject *f = val->as<FunctionObject>();
    if (!f)
        return QJSValue();

    QV4::ExecutionEngine *engine = QJSValuePrivate::engine(this);
    Q_ASSERT(engine);
    Scope scope(engine);

    if (!QJSValuePrivate::checkEngine(engine, instance)) {
        qWarning("QJSValue::call() failed: cannot call function with thisObject created in a different engine");
        return QJSValue();
    }

    JSCallData jsCallData(scope, args.size());
    *jsCallData->thisObject = QJSValuePrivate::convertedToValue(engine, instance);
    for (int i = 0; i < args.size(); ++i) {
        if (!QJSValuePrivate::checkEngine(engine, args.at(i))) {
            qWarning("QJSValue::call() failed: cannot call function with argument created in a different engine");
            return QJSValue();
        }
        jsCallData->args[i] = QJSValuePrivate::convertedToValue(engine, args.at(i));
    }

    ScopedValue result(scope, f->call(jsCallData));
    if (engine->hasException)
        result = engine->catchException();
    if (engine->isInterrupted.loadAcquire())
        result = engine->newErrorObject(QStringLiteral("Interrupted"));

    return QJSValue(engine, result->asReturnedValue());
}

/*!
  Creates a new \c{Object} and calls this QJSValue as a
  constructor, using the created object as the `this' object and
  passing \a args as arguments. If the return value from the
  constructor call is an object, then that object is returned;
  otherwise the default constructed object is returned.

  If this QJSValue is not a function, callAsConstructor() does
  nothing and returns an undefined QJSValue.

  Calling this function can cause an exception to occur in the
  script engine; in that case, the value that was thrown
  (typically an \c{Error} object) is returned. You can call
  isError() on the return value to determine whether an
  exception occurred.

  \sa call(), QJSEngine::newObject()
*/
QJSValue QJSValue::callAsConstructor(const QJSValueList &args)
{
    QV4::Value *val = QJSValuePrivate::getValue(this);
    if (!val)
        return QJSValue();

    FunctionObject *f = val->as<FunctionObject>();
    if (!f)
        return QJSValue();

    QV4::ExecutionEngine *engine = QJSValuePrivate::engine(this);
    Q_ASSERT(engine);

    Scope scope(engine);
    JSCallData jsCallData(scope, args.size());
    for (int i = 0; i < args.size(); ++i) {
        if (!QJSValuePrivate::checkEngine(engine, args.at(i))) {
            qWarning("QJSValue::callAsConstructor() failed: cannot construct function with argument created in a different engine");
            return QJSValue();
        }
        jsCallData->args[i] = QJSValuePrivate::convertedToValue(engine, args.at(i));
    }

    ScopedValue result(scope, f->callAsConstructor(jsCallData));
    if (engine->hasException)
        result = engine->catchException();
    if (engine->isInterrupted.loadAcquire())
        result = engine->newErrorObject(QStringLiteral("Interrupted"));

    return QJSValue(engine, result->asReturnedValue());
}

#ifdef QT_DEPRECATED

/*!
  \obsolete

  Returns the QJSEngine that created this QJSValue,
  or 0 if this QJSValue is invalid or the value is not
  associated with a particular engine.
*/
QJSEngine* QJSValue::engine() const
{
    QV4::ExecutionEngine *engine = QJSValuePrivate::engine(this);
    if (engine)
        return engine->jsEngine();
    return nullptr;
}

#endif // QT_DEPRECATED

/*!
  If this QJSValue is an object, returns the internal prototype
  (\c{__proto__} property) of this object; otherwise returns an
  undefined QJSValue.

  \sa setPrototype(), isObject()
*/
QJSValue QJSValue::prototype() const
{
    QV4::ExecutionEngine *engine = QJSValuePrivate::engine(this);
    if (!engine)
        return QJSValue();
    QV4::Scope scope(engine);
    ScopedObject o(scope, QJSValuePrivate::getValue(this)->as<QV4::Object>());
    if (!o)
        return QJSValue();
    ScopedObject p(scope, o->getPrototypeOf());
    if (!p)
        return QJSValue(NullValue);
    return QJSValue(o->internalClass()->engine, p.asReturnedValue());
}

/*!
  If this QJSValue is an object, sets the internal prototype
  (\c{__proto__} property) of this object to be \a prototype;
  if the QJSValue is null, it sets the prototype to null;
  otherwise does nothing.

  The internal prototype should not be confused with the public
  property with name "prototype"; the public prototype is usually
  only set on functions that act as constructors.

  \sa prototype(), isObject()
*/
void QJSValue::setPrototype(const QJSValue& prototype)
{
    QV4::ExecutionEngine *engine = QJSValuePrivate::engine(this);
    if (!engine)
        return;
    Scope scope(engine);
    ScopedObject o(scope, QJSValuePrivate::getValue(this));
    if (!o)
        return;
    QV4::Value scratch;
    QV4::Value *val = QJSValuePrivate::valueForData(&prototype, &scratch);
    if (!val)
        return;
    if (val->isNull()) {
        o->setPrototypeOf(nullptr);
        return;
    }

    ScopedObject p(scope, val);
    if (!p)
        return;
    if (o->engine() != p->engine()) {
        qWarning("QJSValue::setPrototype() failed: cannot set a prototype created in a different engine");
        return;
    }
    if (!o->setPrototypeOf(p))
        qWarning("QJSValue::setPrototype() failed: cyclic prototype value");
}

/*!
  Assigns the \a other value to this QJSValue.

  Note that if \a other is an object (isObject() returns true),
  only a reference to the underlying object will be assigned;
  the object itself will not be copied.
*/
QJSValue& QJSValue::operator=(const QJSValue& other)
{
    if (d == other.d)
        return *this;

    QJSValuePrivate::free(this);
    d = 0;

    QV4::Value *v = QJSValuePrivate::getValue(&other);
    if (v) {
        QJSValuePrivate::setValue(this, QJSValuePrivate::engine(&other), *v);
    } else if (QVariant *v = QJSValuePrivate::getVariant(&other)) {
        QJSValuePrivate::setVariant(this, *v);
    }
    return *this;
}

static bool js_equal(const QString &string, const QV4::Value &value)
{
    if (String *s = value.stringValue())
        return string == s->toQString();
    if (value.isNumber())
        return RuntimeHelpers::stringToNumber(string) == value.asDouble();
    if (value.isBoolean())
        return RuntimeHelpers::stringToNumber(string) == double(value.booleanValue());
    if (QV4::Object *o = value.objectValue()) {
        Scope scope(o->engine());
        ScopedValue p(scope, RuntimeHelpers::toPrimitive(value, PREFERREDTYPE_HINT));
        return js_equal(string, p);
    }
    return false;
}

/*!
  Returns true if this QJSValue is equal to \a other, otherwise
  returns false. The comparison follows the behavior described in
  \l{ECMA-262} section 11.9.3, "The Abstract Equality Comparison
  Algorithm".

  This function can return true even if the type of this QJSValue
  is different from the type of the \a other value; i.e. the
  comparison is not strict.  For example, comparing the number 9 to
  the string "9" returns true; comparing an undefined value to a null
  value returns true; comparing a \c{Number} object whose primitive
  value is 6 to a \c{String} object whose primitive value is "6"
  returns true; and comparing the number 1 to the boolean value
  \c{true} returns true. If you want to perform a comparison
  without such implicit value conversion, use strictlyEquals().

  Note that if this QJSValue or the \a other value are objects,
  calling this function has side effects on the script engine, since
  the engine will call the object's valueOf() function (and possibly
  toString()) in an attempt to convert the object to a primitive value
  (possibly resulting in an uncaught script exception).

  \sa strictlyEquals()
*/
bool QJSValue::equals(const QJSValue& other) const
{
    QV4::Value s1, s2;
    QV4::Value *v = QJSValuePrivate::valueForData(this, &s1);
    QV4::Value *ov = QJSValuePrivate::valueForData(&other, &s2);

    if (!v) {
        QVariant *variant = QJSValuePrivate::getVariant(this);
        Q_ASSERT(variant);
        if (!ov)
            return *variant == *QJSValuePrivate::getVariant(&other);
        if (variant->userType() == QMetaType::QVariantMap || variant->userType() == QMetaType::QVariantList)
            return false;
        return js_equal(variant->toString(), *ov);
        }
    if (!ov)
        return other.equals(*this);

    return Runtime::CompareEqual::call(*v, *ov);
}

/*!
  Returns true if this QJSValue is equal to \a other using strict
  comparison (no conversion), otherwise returns false. The comparison
  follows the behavior described in \l{ECMA-262} section 11.9.6, "The
  Strict Equality Comparison Algorithm".

  If the type of this QJSValue is different from the type of the
  \a other value, this function returns false. If the types are equal,
  the result depends on the type, as shown in the following table:

    \table
    \header \li Type \li Result
    \row    \li Undefined  \li true
    \row    \li Null       \li true
    \row    \li Boolean    \li true if both values are true, false otherwise
    \row    \li Number     \li false if either value is NaN (Not-a-Number); true if values are equal, false otherwise
    \row    \li String     \li true if both values are exactly the same sequence of characters, false otherwise
    \row    \li Object     \li true if both values refer to the same object, false otherwise
    \endtable

  \sa equals()
*/
bool QJSValue::strictlyEquals(const QJSValue& other) const
{
    QV4::Value s1, s2;
    QV4::Value *v = QJSValuePrivate::valueForData(this, &s1);
    QV4::Value *ov = QJSValuePrivate::valueForData(&other, &s2);

    if (!v) {
        QVariant *variant = QJSValuePrivate::getVariant(this);
        Q_ASSERT(variant);
        if (!ov)
            return *variant == *QJSValuePrivate::getVariant(&other);
        if (variant->userType() == QMetaType::QVariantMap || variant->userType() == QMetaType::QVariantList)
            return false;
        if (String *s = ov->stringValue())
            return variant->toString() == s->toQString();
        return false;
    }
    if (!ov)
        return other.strictlyEquals(*this);

    return RuntimeHelpers::strictEqual(*v, *ov);
}

/*!
  Returns the value of this QJSValue's property with the given \a name.
  If no such property exists, an undefined QJSValue is returned.

  If the property is implemented using a getter function (i.e. has the
  PropertyGetter flag set), calling property() has side-effects on the
  script engine, since the getter function will be called (possibly
  resulting in an uncaught script exception). If an exception
  occurred, property() returns the value that was thrown (typically
  an \c{Error} object).

  To access array elements, use the
  \l {QJSValue::}{setProperty(quint32 arrayIndex, const QJSValue &value)}
  overload instead.

  \sa setProperty(), hasProperty(), QJSValueIterator
*/
QJSValue QJSValue::property(const QString& name) const
{
    QV4::ExecutionEngine *engine = QJSValuePrivate::engine(this);
    if (!engine)
        return QJSValue();

    QV4::Scope scope(engine);
    ScopedObject o(scope, QJSValuePrivate::getValue(this));
    if (!o)
        return QJSValue();

    ScopedString s(scope, engine->newString(name));
    QV4::ScopedValue result(scope, o->get(s->toPropertyKey()));
    if (engine->hasException)
        result = engine->catchException();

    return QJSValue(engine, result->asReturnedValue());
}

/*!
  \overload

  Returns the property at the given \a arrayIndex.

  It is possible to access elements in an array in two ways. The first is to
  use the array index as the property name:

  \code
  qDebug() << jsValueArray.property(QLatin1String("4")).toString();
  \endcode

  The second is to use the overload that takes an index:

  \code
  qDebug() << jsValueArray.property(4).toString();
  \endcode

  Both of these approaches achieve the same result, except that the latter:

  \list
  \li Is easier to use (can use an integer directly)
  \li Is faster (no conversion to integer)
  \endlist

  If this QJSValue is not an Array object, this function behaves
  as if property() was called with the string representation of \a
  arrayIndex.
*/
QJSValue QJSValue::property(quint32 arrayIndex) const
{
    QV4::ExecutionEngine *engine = QJSValuePrivate::engine(this);
    if (!engine)
        return QJSValue();

    QV4::Scope scope(engine);
    ScopedObject o(scope, QJSValuePrivate::getValue(this));
    if (!o)
        return QJSValue();

    QV4::ScopedValue result(scope, arrayIndex == UINT_MAX ? o->get(engine->id_uintMax()) : o->get(arrayIndex));
    if (engine->hasException)
        engine->catchException();
    return QJSValue(engine, result->asReturnedValue());
}

/*!
  Sets the value of this QJSValue's property with the given \a name to
  the given \a value.

  If this QJSValue is not an object, this function does nothing.

  If this QJSValue does not already have a property with name \a name,
  a new property is created.

  To modify array elements, use the
  \l {QJSValue::}{setProperty(quint32 arrayIndex, const QJSValue &value)}
  overload instead.

  \sa property(), deleteProperty()
*/
void QJSValue::setProperty(const QString& name, const QJSValue& value)
{
    QV4::ExecutionEngine *engine = QJSValuePrivate::engine(this);
    if (!engine)
        return;
    Scope scope(engine);

    ScopedObject o(scope, QJSValuePrivate::getValue(this));
    if (!o)
        return;

    if (!QJSValuePrivate::checkEngine(engine, value)) {
        qWarning("QJSValue::setProperty(%s) failed: cannot set value created in a different engine", name.toUtf8().constData());
        return;
    }

    ScopedString s(scope, engine->newString(name));
    QV4::ScopedValue v(scope, QJSValuePrivate::convertedToValue(engine, value));
    o->put(s->toPropertyKey(), v);
    if (engine->hasException)
        engine->catchException();
}

/*!
  \overload

  Sets the property at the given \a arrayIndex to the given \a value.

  It is possible to modify elements in an array in two ways. The first is to
  use the array index as the property name:

  \code
  jsValueArray.setProperty(QLatin1String("4"), value);
  \endcode

  The second is to use the overload that takes an index:

  \code
  jsValueArray.setProperty(4, value);
  \endcode

  Both of these approaches achieve the same result, except that the latter:

  \list
  \li Is easier to use (can use an integer directly)
  \li Is faster (no conversion to integer)
  \endlist

  If this QJSValue is not an Array object, this function behaves
  as if setProperty() was called with the string representation of \a
  arrayIndex.

  \sa {QJSValue::}{property(quint32 arrayIndex)}, {Working With Arrays}
*/
void QJSValue::setProperty(quint32 arrayIndex, const QJSValue& value)
{
    QV4::ExecutionEngine *engine = QJSValuePrivate::engine(this);
    if (!engine)
        return;
    Scope scope(engine);

    ScopedObject o(scope, QJSValuePrivate::getValue(this));
    if (!o)
        return;

    if (!QJSValuePrivate::checkEngine(engine, value)) {
        qWarning("QJSValue::setProperty(%d) failed: cannot set value created in a different engine", arrayIndex);
        return;
    }

    QV4::ScopedValue v(scope, QJSValuePrivate::convertedToValue(engine, value));
    PropertyKey id = arrayIndex != UINT_MAX ? PropertyKey::fromArrayIndex(arrayIndex) : engine->id_uintMax()->propertyKey();
    o->put(id, v);
    if (engine->hasException)
        engine->catchException();
}

/*!
  Attempts to delete this object's property of the given \a name.
  Returns true if the property was deleted, otherwise returns false.

  The behavior of this function is consistent with the JavaScript
  delete operator. In particular:

  \list
  \li Non-configurable properties cannot be deleted.
  \li This function will return true even if this object doesn't
     have a property of the given \a name (i.e., non-existent
     properties are "trivially deletable").
  \li If this object doesn't have an own property of the given
     \a name, but an object in the prototype() chain does, the
     prototype object's property is not deleted, and this function
     returns true.
  \endlist

  \sa setProperty(), hasOwnProperty()
*/
bool QJSValue::deleteProperty(const QString &name)
{
    QV4::ExecutionEngine *engine = QJSValuePrivate::engine(this);
    if (!engine)
        return false;

    Scope scope(engine);
    ScopedObject o(scope, QJSValuePrivate::getValue(this));
    if (!o)
        return false;

    ScopedString s(scope, engine->newString(name));
    return o->deleteProperty(s->toPropertyKey());
}

/*!
  Returns true if this object has a property of the given \a name,
  otherwise returns false.

  \sa property(), hasOwnProperty()
*/
bool QJSValue::hasProperty(const QString &name) const
{
    QV4::ExecutionEngine *engine = QJSValuePrivate::engine(this);
    if (!engine)
        return false;

    Scope scope(engine);
    ScopedObject o(scope, QJSValuePrivate::getValue(this));
    if (!o)
        return false;

    ScopedString s(scope, engine->newString(name));
    return o->hasProperty(s->toPropertyKey());
}

/*!
  Returns true if this object has an own (not prototype-inherited)
  property of the given \a name, otherwise returns false.

  \sa property(), hasProperty()
*/
bool QJSValue::hasOwnProperty(const QString &name) const
{
    QV4::ExecutionEngine *engine = QJSValuePrivate::engine(this);
    if (!engine)
        return false;

    Scope scope(engine);
    ScopedObject o(scope, QJSValuePrivate::getValue(this));
    if (!o)
        return false;

    ScopedString s(scope, engine->newIdentifier(name));
    return o->getOwnProperty(s->propertyKey()) != Attr_Invalid;
}

/*!
 * If this QJSValue is a QObject, returns the QObject pointer
 * that the QJSValue represents; otherwise, returns \nullptr.
 *
 * If the QObject that this QJSValue wraps has been deleted,
 * this function returns \nullptr (i.e. it is possible for toQObject()
 * to return \nullptr even when isQObject() returns true).
 *
 * \sa isQObject()
 */
QObject *QJSValue::toQObject() const
{
    QV4::ExecutionEngine *engine = QJSValuePrivate::engine(this);
    if (!engine)
        return nullptr;
    QV4::Scope scope(engine);
    QV4::Scoped<QV4::QObjectWrapper> wrapper(scope, QJSValuePrivate::getValue(this));
    if (!wrapper)
        return nullptr;

    return wrapper->object();
}

/*!
  \since 5.8

 * If this QJSValue is a QMetaObject, returns the QMetaObject pointer
 * that the QJSValue represents; otherwise, returns \nullptr.
 *
 * \sa isQMetaObject()
 */
const QMetaObject *QJSValue::toQMetaObject() const
{
    QV4::ExecutionEngine *engine = QJSValuePrivate::engine(this);
    if (!engine)
        return nullptr;
    QV4::Scope scope(engine);
    QV4::Scoped<QV4::QMetaObjectWrapper> wrapper(scope, QJSValuePrivate::getValue(this));
    if (!wrapper)
        return nullptr;

    return wrapper->metaObject();
}


/*!
  Returns a QDateTime representation of this value, in local time.
  If this QJSValue is not a date, or the value of the date is NaN
  (Not-a-Number), an invalid QDateTime is returned.

  \sa isDate()
*/
QDateTime QJSValue::toDateTime() const
{
    QV4::Value *val = QJSValuePrivate::getValue(this);
    if (val) {
        QV4::DateObject *date = val->as<DateObject>();
        if (date)
            return date->toQDateTime();
    }
    return QDateTime();
}

/*!
  Returns true if this QJSValue is an object of the Date class;
  otherwise returns false.
*/
bool QJSValue::isDate() const
{
    QV4::Value *val = QJSValuePrivate::getValue(this);
    return val && val->as<DateObject>();
}

/*!
  Returns true if this QJSValue is an object of the RegExp class;
  otherwise returns false.
*/
bool QJSValue::isRegExp() const
{
    QV4::Value *val = QJSValuePrivate::getValue(this);
    return val && val->as<RegExpObject>();
}

/*!
  Returns true if this QJSValue is a QObject; otherwise returns
  false.

  Note: This function returns true even if the QObject that this
  QJSValue wraps has been deleted.

  \sa toQObject(), QJSEngine::newQObject()
*/
bool QJSValue::isQObject() const
{
    QV4::Value *val = QJSValuePrivate::getValue(this);
    return val && val->as<QV4::QObjectWrapper>() != nullptr;
}

/*!
  \since 5.8

  Returns true if this QJSValue is a QMetaObject; otherwise returns
  false.

  \sa toQMetaObject(), QJSEngine::newQMetaObject()
*/
bool QJSValue::isQMetaObject() const
{
    QV4::Value *val = QJSValuePrivate::getValue(this);
    return val && val->as<QV4::QMetaObjectWrapper>() != nullptr;
}

QT_END_NAMESPACE
