/****************************************************************************
**
** 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 "qjsengine.h"
#include "qjsengine_p.h"
#include "qjsvalue.h"
#include "qjsvalue_p.h"

#include "private/qv4engine_p.h"
#include "private/qv4mm_p.h"
#include "private/qv4errorobject_p.h"
#include "private/qv4globalobject_p.h"
#include "private/qv4script_p.h"
#include "private/qv4runtime_p.h"
#include <private/qqmlbuiltinfunctions_p.h>
#include <private/qqmldebugconnector_p.h>
#include <private/qv4qobjectwrapper_p.h>
#include <private/qv4stackframe_p.h>
#include <private/qv4module_p.h>

#include <QtCore/qdatetime.h>
#include <QtCore/qmetaobject.h>
#include <QtCore/qstringlist.h>
#include <QtCore/qvariant.h>
#include <QtCore/qdatetime.h>

#include <QtCore/qcoreapplication.h>
#include <QtCore/qdir.h>
#include <QtCore/qfile.h>
#include <QtCore/qfileinfo.h>
#include <QtCore/qpluginloader.h>
#include <qthread.h>
#include <qmutex.h>
#include <qwaitcondition.h>
#include <private/qqmlglobal_p.h>
#include <qqmlengine.h>

Q_DECLARE_METATYPE(QList<int>)

/*!
  \since 5.0
  \class QJSEngine
  \reentrant

  \brief The QJSEngine class provides an environment for evaluating JavaScript code.

  \ingroup qtjavascript
  \inmodule QtQml

  \section1 Evaluating Scripts

  Use evaluate() to evaluate script code.

  \snippet code/src_script_qjsengine.cpp 0

  evaluate() returns a QJSValue that holds the result of the
  evaluation. The QJSValue class provides functions for converting
  the result to various C++ types (e.g. QJSValue::toString()
  and QJSValue::toNumber()).

  The following code snippet shows how a script function can be
  defined and then invoked from C++ using QJSValue::call():

  \snippet code/src_script_qjsengine.cpp 1

  As can be seen from the above snippets, a script is provided to the
  engine in the form of a string. One common way of loading scripts is
  by reading the contents of a file and passing it to evaluate():

  \snippet code/src_script_qjsengine.cpp 2

  Here we pass the name of the file as the second argument to
  evaluate().  This does not affect evaluation in any way; the second
  argument is a general-purpose string that is stored in the \c Error
  object for debugging purposes.

  For larger pieces of functionality, you may want to encapsulate
  your code and data into modules. A module is a file that contains
  script code, variables, etc., and uses export statements to describe
  its interface towards the rest of the application. With the help of
  import statements, a module can refer to functionality from other modules.
  This allows building a scripted application from smaller connected building blocks
  in a safe way. In contrast, the approach of using evaluate() carries the risk
  that internal variables or functions from one evaluate() call accidentally pollute the
  global object and affect subsequent evaluations.

  The following example provides a module that can add numbers:

  \code
  export function sum(left, right)
  {
      return left + right
  }
  \endcode

  This module can be loaded with QJSEngine::import() if it is saved under
  the name \c{math.mjs}:

  \code
  QJSvalue module = myEngine.importModule("./math.mjs");
  QJSValue sumFunction = module.property("sum");
  QJSValue result = sumFunction.call(args);
  \endcode

  Modules can also use functionality from other modules using import
  statements:

  \code
  import { sum } from "./math.mjs";
  export function addTwice(left, right)
  {
      return sum(left, right) * 2;
  }
  \endcode

  \section1 Engine Configuration

  The globalObject() function returns the \b {Global Object}
  associated with the script engine. Properties of the Global Object
  are accessible from any script code (i.e. they are global
  variables). Typically, before evaluating "user" scripts, you will
  want to configure a script engine by adding one or more properties
  to the Global Object:

  \snippet code/src_script_qjsengine.cpp 3

  Adding custom properties to the scripting environment is one of the
  standard means of providing a scripting API that is specific to your
  application. Usually these custom properties are objects created by
  the newQObject() or newObject() functions.

  \section1 Script Exceptions

  evaluate() can throw a script exception (e.g. due to a syntax
  error). If it does, then evaluate() returns the value that was thrown
  (typically an \c{Error} object). Use \l QJSValue::isError() to check
  for exceptions.

  For detailed information about the error, use \l QJSValue::toString() to
  obtain an error message, and use \l QJSValue::property() to query the
  properties of the \c Error object. The following properties are available:

  \list
  \li \c name
  \li \c message
  \li \c fileName
  \li \c lineNumber
  \li \c stack
  \endlist

  \snippet code/src_script_qjsengine.cpp 4

  \section1 Script Object Creation

  Use newObject() to create a JavaScript object; this is the
  C++ equivalent of the script statement \c{new Object()}. You can use
  the object-specific functionality in QJSValue to manipulate the
  script object (e.g. QJSValue::setProperty()). Similarly, use
  newArray() to create a JavaScript array object.

  \section1 QObject Integration

  Use newQObject() to wrap a QObject (or subclass)
  pointer. newQObject() returns a proxy script object; properties,
  children, and signals and slots of the QObject are available as
  properties of the proxy object. No binding code is needed because it
  is done dynamically using the Qt meta object system.

  \snippet code/src_script_qjsengine.cpp 5

  Use newQMetaObject() to wrap a QMetaObject; this gives you a
  "script representation" of a QObject-based class. newQMetaObject()
  returns a proxy script object; enum values of the class are available
  as properties of the proxy object.

  Constructors exposed to the meta-object system (using Q_INVOKABLE) can be
  called from the script to create a new QObject instance with
  JavaScriptOwnership. For example, given the following class definition:

  \snippet code/src_script_qjsengine.cpp 7

  The \c staticMetaObject for the class can be exposed to JavaScript like so:

  \snippet code/src_script_qjsengine.cpp 8

  Instances of the class can then be created in JavaScript:

  \snippet code/src_script_qjsengine.cpp 9

  \note Currently only classes using the Q_OBJECT macro are supported; it is
  not possible to expose the \c staticMetaObject of a Q_GADGET class to
  JavaScript.

  \section2 Dynamic QObject Properties

  Dynamic QObject properties are not supported. For example, the following code
  will not work:

  \snippet code/src_script_qjsengine.cpp 6

  \section1 Extensions

  QJSEngine provides a compliant ECMAScript implementation. By default,
  familiar utilities like logging are not available, but they can can be
  installed via the \l installExtensions() function.

  \sa QJSValue, {Making Applications Scriptable},
      {List of JavaScript Objects and Functions}

*/

/*!
    \enum QJSEngine::Extension

    This enum is used to specify extensions to be installed via
    \l installExtensions().

    \value TranslationExtension Indicates that translation functions (\c qsTr(),
        for example) should be installed. This also installs the Qt.uiLanguage property.

    \value ConsoleExtension Indicates that console functions (\c console.log(),
        for example) should be installed.

    \value GarbageCollectionExtension Indicates that garbage collection
        functions (\c gc(), for example) should be installed.

    \value AllExtensions Indicates that all extension should be installed.

    \b TranslationExtension

    The relation between script translation functions and C++ translation
    functions is described in the following table:

    \table
    \header \li Script Function \li Corresponding C++ Function
    \row    \li qsTr()       \li QObject::tr()
    \row    \li QT_TR_NOOP() \li QT_TR_NOOP()
    \row    \li qsTranslate() \li QCoreApplication::translate()
    \row    \li QT_TRANSLATE_NOOP() \li QT_TRANSLATE_NOOP()
    \row    \li qsTrId() \li qtTrId()
    \row    \li QT_TRID_NOOP() \li QT_TRID_NOOP()
    \endtable

    This flag also adds an \c arg() function to the string prototype.

    For more information, see the \l {Internationalization with Qt}
    documentation.

    \b ConsoleExtension

    The \l {Console API}{console} object implements a subset of the
    \l {https://developer.mozilla.org/en-US/docs/Web/API/Console}{Console API},
    which provides familiar logging functions, such as \c console.log().

    The list of functions added is as follows:

    \list
    \li \c console.assert()
    \li \c console.debug()
    \li \c console.exception()
    \li \c console.info()
    \li \c console.log() (equivalent to \c console.debug())
    \li \c console.error()
    \li \c console.time()
    \li \c console.timeEnd()
    \li \c console.trace()
    \li \c console.count()
    \li \c console.warn()
    \li \c {print()} (equivalent to \c console.debug())
    \endlist

    For more information, see the \l {Console API} documentation.

    \b GarbageCollectionExtension

    The \c gc() function is equivalent to calling \l collectGarbage().
*/

QT_BEGIN_NAMESPACE

static void checkForApplicationInstance()
{
    if (!QCoreApplication::instance())
        qFatal("QJSEngine: Must construct a QCoreApplication before a QJSEngine");
}

/*!
    Constructs a QJSEngine object.

    The globalObject() is initialized to have properties as described in
    \l{ECMA-262}, Section 15.1.
*/
QJSEngine::QJSEngine()
    : QJSEngine(nullptr)
{
}

/*!
    Constructs a QJSEngine object with the given \a parent.

    The globalObject() is initialized to have properties as described in
    \l{ECMA-262}, Section 15.1.
*/

QJSEngine::QJSEngine(QObject *parent)
    : QObject(*new QJSEnginePrivate, parent)
    , m_v4Engine(new QV4::ExecutionEngine(this))
{
    checkForApplicationInstance();

    QJSEnginePrivate::addToDebugServer(this);
}

/*!
    \internal
*/
QJSEngine::QJSEngine(QJSEnginePrivate &dd, QObject *parent)
    : QObject(dd, parent)
    , m_v4Engine(new QV4::ExecutionEngine(this))
{
    checkForApplicationInstance();
}

/*!
    Destroys this QJSEngine.

    Garbage is not collected from the persistent JS heap during QJSEngine
    destruction. If you need all memory freed, call collectGarbage manually
    right before destroying the QJSEngine.
*/
QJSEngine::~QJSEngine()
{
    QJSEnginePrivate::removeFromDebugServer(this);
    delete m_v4Engine;
}

/*!
    \fn QV4::ExecutionEngine *QJSEngine::handle() const
    \internal
*/

/*!
    Runs the garbage collector.

    The garbage collector will attempt to reclaim memory by locating and disposing of objects that are
    no longer reachable in the script environment.

    Normally you don't need to call this function; the garbage collector will automatically be invoked
    when the QJSEngine decides that it's wise to do so (i.e. when a certain number of new objects
    have been created). However, you can call this function to explicitly request that garbage
    collection should be performed as soon as possible.
*/
void QJSEngine::collectGarbage()
{
    m_v4Engine->memoryManager->runGC();
}

#if QT_DEPRECATED_SINCE(5, 6)

/*!
  \since 5.4
  \obsolete

  Installs translator functions on the given \a object, or on the Global
  Object if no object is specified.

  The relation between script translator functions and C++ translator
  functions is described in the following table:

    \table
    \header \li Script Function \li Corresponding C++ Function
    \row    \li qsTr()       \li QObject::tr()
    \row    \li QT_TR_NOOP() \li QT_TR_NOOP()
    \row    \li qsTranslate() \li QCoreApplication::translate()
    \row    \li QT_TRANSLATE_NOOP() \li QT_TRANSLATE_NOOP()
    \row    \li qsTrId() \li qtTrId()
    \row    \li QT_TRID_NOOP() \li QT_TRID_NOOP()
    \endtable

  It also adds an arg() method to the string prototype.

  \sa {Internationalization with Qt}
*/
void QJSEngine::installTranslatorFunctions(const QJSValue &object)
{
    installExtensions(TranslationExtension, object);
}

#endif // QT_DEPRECATED_SINCE(5, 6)


/*!
    \since 5.6

    Installs JavaScript \a extensions to add functionality that is not
    available in a standard ECMAScript implementation.

    The extensions are installed on the given \a object, or on the
    \l {globalObject()}{Global Object} if no object is specified.

    Several extensions can be installed at once by \c {OR}-ing the enum values:

    \code
    installExtensions(QJSEngine::TranslationExtension | QJSEngine::ConsoleExtension);
    \endcode

    \sa Extension
*/
void QJSEngine::installExtensions(QJSEngine::Extensions extensions, const QJSValue &object)
{
    QV4::ExecutionEngine *otherEngine = QJSValuePrivate::engine(&object);
    if (otherEngine && otherEngine != m_v4Engine) {
        qWarning("QJSEngine: Trying to install extensions from a different engine");
        return;
    }

    QV4::Scope scope(m_v4Engine);
    QV4::ScopedObject obj(scope);
    QV4::Value *val = QJSValuePrivate::getValue(&object);
    if (val)
        obj = val;
    if (!obj)
        obj = scope.engine->globalObject;

    QV4::GlobalExtensions::init(obj, extensions);
}

/*!
  \since 5.14
  Interrupts or re-enables JavaScript execution.

  If \a interrupted is \c true, any JavaScript executed by this engine
  immediately aborts and returns an error object until this function is
  called again with a value of \c false for \a interrupted.

  This function is thread safe. You may call it from a different thread
  in order to interrupt, for example, an infinite loop in JavaScript.
*/
void QJSEngine::setInterrupted(bool interrupted)
{
    m_v4Engine->isInterrupted = interrupted;
}

/*!
  \since 5.14
  Returns whether JavaScript execution is currently interrupted.

  \sa setInterrupted()
*/
bool QJSEngine::isInterrupted() const
{
    return m_v4Engine->isInterrupted.loadAcquire();
}

static QUrl urlForFileName(const QString &fileName)
{
    if (!fileName.startsWith(QLatin1Char(':')))
        return QUrl::fromLocalFile(fileName);

    QUrl url;
    url.setPath(fileName.mid(1));
    url.setScheme(QLatin1String("qrc"));
    return url;
}

/*!
    Evaluates \a program, using \a lineNumber as the base line number,
    and returns the result of the evaluation.

    The script code will be evaluated in the context of the global object.

    The evaluation of \a program can cause an \l{Script Exceptions}{exception} in the
    engine; in this case the return value will be the exception
    that was thrown (typically an \c{Error} object; see
    QJSValue::isError()).

    \a lineNumber is used to specify a starting line number for \a
    program; line number information reported by the engine that pertains
    to this evaluation will be based on this argument. For example, if
    \a program consists of two lines of code, and the statement on the
    second line causes a script exception, the exception line number
    would be \a lineNumber plus one. When no starting line number is
    specified, line numbers will be 1-based.

    \a fileName is used for error reporting. For example, in error objects
    the file name is accessible through the "fileName" property if it is
    provided with this function.

    \note If an exception was thrown and the exception value is not an
    Error instance (i.e., QJSValue::isError() returns \c false), the
    exception value will still be returned, but there is currently no
    API for detecting that an exception did occur in this case.
*/
QJSValue QJSEngine::evaluate(const QString& program, const QString& fileName, int lineNumber)
{
    QV4::ExecutionEngine *v4 = m_v4Engine;
    QV4::Scope scope(v4);
    QV4::ScopedValue result(scope);

    QV4::Script script(v4->rootContext(), QV4::Compiler::ContextType::Global, program, urlForFileName(fileName).toString(), lineNumber);
    script.strictMode = false;
    if (v4->currentStackFrame)
        script.strictMode = v4->currentStackFrame->v4Function->isStrict();
    else if (v4->globalCode)
        script.strictMode = v4->globalCode->isStrict();
    script.inheritContext = true;
    script.parse();
    if (!scope.engine->hasException)
        result = script.run();
    if (scope.engine->hasException)
        result = v4->catchException();
    if (v4->isInterrupted.loadAcquire())
        result = v4->newErrorObject(QStringLiteral("Interrupted"));

    QJSValue retval(v4, result->asReturnedValue());

    return retval;
}

/*!
    Imports the module located at \a fileName and returns a module namespace object that
    contains all exported variables, constants and functions as properties.

    If this is the first time the module is imported in the engine, the file is loaded
    from the specified location in either the local file system or the Qt resource system
    and evaluated as an ECMAScript module. The file is expected to be encoded in UTF-8 text.

    Subsequent imports of the same module will return the previously imported instance. Modules
    are singletons and remain around until the engine is destroyed.

    The specified \a fileName will internally be normalized using \l QFileInfo::canonicalFilePath().
    That means that multiple imports of the same file on disk using different relative paths will
    load the file only once.

    \note If an exception is thrown during the loading of the module, the return value
    will be the exception (typically an \c{Error} object; see QJSValue::isError()).

    \since 5.12
 */
QJSValue QJSEngine::importModule(const QString &fileName)
{
    const QUrl url = urlForFileName(QFileInfo(fileName).canonicalFilePath());
    auto moduleUnit = m_v4Engine->loadModule(url);
    if (m_v4Engine->hasException)
        return QJSValue(m_v4Engine, m_v4Engine->catchException());

    QV4::Scope scope(m_v4Engine);
    QV4::Scoped<QV4::Module> moduleNamespace(scope, moduleUnit->instantiate(m_v4Engine));
    if (m_v4Engine->hasException)
        return QJSValue(m_v4Engine, m_v4Engine->catchException());
    moduleUnit->evaluate();
    if (!m_v4Engine->isInterrupted.loadAcquire())
        return QJSValue(m_v4Engine, moduleNamespace->asReturnedValue());

    return QJSValue(
            m_v4Engine,
            m_v4Engine->newErrorObject(QStringLiteral("Interrupted"))->asReturnedValue());
}

/*!
  Creates a JavaScript object of class Object.

  The prototype of the created object will be the Object
  prototype object.

  \sa newArray(), QJSValue::setProperty()
*/
QJSValue QJSEngine::newObject()
{
    QV4::Scope scope(m_v4Engine);
    QV4::ScopedValue v(scope, m_v4Engine->newObject());
    return QJSValue(m_v4Engine, v->asReturnedValue());
}

/*!
  \since 5.12

  Creates a JavaScript object of class Error, with \a message as the error
  message.

  The prototype of the created object will be \a errorType.

  \sa newObject(), throwError(), QJSValue::isError()
*/
QJSValue QJSEngine::newErrorObject(QJSValue::ErrorType errorType, const QString &message)
{
    QV4::Scope scope(m_v4Engine);
    QV4::ScopedObject error(scope);
    switch (errorType) {
    case QJSValue::RangeError:
        error = m_v4Engine->newRangeErrorObject(message);
        break;
    case QJSValue::SyntaxError:
        error = m_v4Engine->newSyntaxErrorObject(message);
        break;
    case QJSValue::TypeError:
        error = m_v4Engine->newTypeErrorObject(message);
        break;
    case QJSValue::URIError:
        error = m_v4Engine->newURIErrorObject(message);
        break;
    case QJSValue::ReferenceError:
        error = m_v4Engine->newReferenceErrorObject(message);
        break;
    case QJSValue::EvalError:
        error = m_v4Engine->newEvalErrorObject(message);
        break;
    case QJSValue::GenericError:
        error = m_v4Engine->newErrorObject(message);
        break;
    case QJSValue::NoError:
        return QJSValue::UndefinedValue;
    }
    return QJSValue(m_v4Engine, error->asReturnedValue());
}

/*!
  Creates a JavaScript object of class Array with the given \a length.

  \sa newObject()
*/
QJSValue QJSEngine::newArray(uint length)
{
    QV4::Scope scope(m_v4Engine);
    QV4::ScopedArrayObject array(scope, m_v4Engine->newArrayObject());
    if (length < 0x1000)
        array->arrayReserve(length);
    array->setArrayLengthUnchecked(length);
    return QJSValue(m_v4Engine, array.asReturnedValue());
}

/*!
  Creates a JavaScript object that wraps the given QObject \a
  object, using JavaScriptOwnership.

  Signals and slots, properties and children of \a object are
  available as properties of the created QJSValue.

  If \a object is a null pointer, this function returns a null value.

  If a default prototype has been registered for the \a object's class
  (or its superclass, recursively), the prototype of the new script
  object will be set to be that default prototype.

  If the given \a object is deleted outside of the engine's control, any
  attempt to access the deleted QObject's members through the JavaScript
  wrapper object (either by script code or C++) will result in a
  \l{Script Exceptions}{script exception}.

  \sa QJSValue::toQObject()
*/
QJSValue QJSEngine::newQObject(QObject *object)
{
    QV4::ExecutionEngine *v4 = m_v4Engine;
    QV4::Scope scope(v4);
    if (object) {
        QQmlData *ddata = QQmlData::get(object, true);
        if (!ddata || !ddata->explicitIndestructibleSet)
            QQmlEngine::setObjectOwnership(object, QQmlEngine::JavaScriptOwnership);
    }
    QV4::ScopedValue v(scope, QV4::QObjectWrapper::wrap(v4, object));
    return QJSValue(v4, v->asReturnedValue());
}

/*!
  \since 5.8

  Creates a JavaScript object that wraps the given QMetaObject
  The \a metaObject must outlive the script engine. It is recommended to only
  use this method with static metaobjects.


  When called as a constructor, a new instance of the class will be created.
  Only constructors exposed by Q_INVOKABLE will be visible from the script engine.

  \sa newQObject(), {QObject Integration}
*/

QJSValue QJSEngine::newQMetaObject(const QMetaObject* metaObject) {
    QV4::ExecutionEngine *v4 = m_v4Engine;
    QV4::Scope scope(v4);
    QV4::ScopedValue v(scope, QV4::QMetaObjectWrapper::create(v4, metaObject));
    return QJSValue(v4, v->asReturnedValue());
}

/*! \fn template <typename T> QJSValue QJSEngine::newQMetaObject()

  \since 5.8
  Creates a JavaScript object that wraps the static QMetaObject associated
  with class \c{T}.

  \sa newQObject(), {QObject Integration}
*/


/*!
  Returns this engine's Global Object.

  By default, the Global Object contains the built-in objects that are
  part of \l{ECMA-262}, such as Math, Date and String. Additionally,
  you can set properties of the Global Object to make your own
  extensions available to all script code. Non-local variables in
  script code will be created as properties of the Global Object, as
  well as local variables in global code.
*/
QJSValue QJSEngine::globalObject() const
{
    QV4::Scope scope(m_v4Engine);
    QV4::ScopedValue v(scope, m_v4Engine->globalObject);
    return QJSValue(m_v4Engine, v->asReturnedValue());
}

/*!
 *  \internal
 * used by QJSEngine::toScriptValue
 */
QJSValue QJSEngine::create(int type, const void *ptr)
{
    QV4::Scope scope(m_v4Engine);
    QV4::ScopedValue v(scope, scope.engine->metaTypeToJS(type, ptr));
    return QJSValue(m_v4Engine, v->asReturnedValue());
}

/*!
    \internal
    convert \a value to \a type, store the result in \a ptr
*/
bool QJSEngine::convertV2(const QJSValue &value, int type, void *ptr)
{
    QV4::ExecutionEngine *v4 = QJSValuePrivate::engine(&value);
    QV4::Value scratch;
    QV4::Value *val = QJSValuePrivate::valueForData(&value, &scratch);
    if (v4) {
        QV4::Scope scope(v4);
        QV4::ScopedValue v(scope, *val);
        return scope.engine->metaTypeFromJS(v, type, ptr);
    }

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

        if (variant->userType() == QMetaType::QString) {
            QString string = variant->toString();
            // have a string based value without engine. Do conversion manually
            if (type == QMetaType::Bool) {
                *reinterpret_cast<bool*>(ptr) = string.length() != 0;
                return true;
            }
            if (type == QMetaType::QString) {
                *reinterpret_cast<QString*>(ptr) = string;
                return true;
            }
            double d = QV4::RuntimeHelpers::stringToNumber(string);
            switch (type) {
            case QMetaType::Int:
                *reinterpret_cast<int*>(ptr) = QV4::Value::toInt32(d);
                return true;
            case QMetaType::UInt:
                *reinterpret_cast<uint*>(ptr) = QV4::Value::toUInt32(d);
                return true;
            case QMetaType::LongLong:
                *reinterpret_cast<qlonglong*>(ptr) = QV4::Value::toInteger(d);
                return true;
            case QMetaType::ULongLong:
                *reinterpret_cast<qulonglong*>(ptr) = QV4::Value::toInteger(d);
                return true;
            case QMetaType::Double:
                *reinterpret_cast<double*>(ptr) = d;
                return true;
            case QMetaType::Float:
                *reinterpret_cast<float*>(ptr) = d;
                return true;
            case QMetaType::Short:
                *reinterpret_cast<short*>(ptr) = QV4::Value::toInt32(d);
                return true;
            case QMetaType::UShort:
                *reinterpret_cast<unsigned short*>(ptr) = QV4::Value::toUInt32(d);
                return true;
            case QMetaType::Char:
                *reinterpret_cast<char*>(ptr) = QV4::Value::toInt32(d);
                return true;
            case QMetaType::UChar:
                *reinterpret_cast<unsigned char*>(ptr) = QV4::Value::toUInt32(d);
                return true;
            case QMetaType::QChar:
                *reinterpret_cast<QChar*>(ptr) = QV4::Value::toUInt32(d);
                return true;
            default:
                return false;
            }
        } else {
            return QMetaType::convert(&variant->data_ptr(), variant->userType(), ptr, type);
        }
    }

    Q_ASSERT(val);

    switch (type) {
        case QMetaType::Bool:
            *reinterpret_cast<bool*>(ptr) = val->toBoolean();
            return true;
        case QMetaType::Int:
            *reinterpret_cast<int*>(ptr) = val->toInt32();
            return true;
        case QMetaType::UInt:
            *reinterpret_cast<uint*>(ptr) = val->toUInt32();
            return true;
        case QMetaType::LongLong:
            *reinterpret_cast<qlonglong*>(ptr) = val->toInteger();
            return true;
        case QMetaType::ULongLong:
            *reinterpret_cast<qulonglong*>(ptr) = val->toInteger();
            return true;
        case QMetaType::Double:
            *reinterpret_cast<double*>(ptr) = val->toNumber();
            return true;
        case QMetaType::QString:
            *reinterpret_cast<QString*>(ptr) = val->toQStringNoThrow();
            return true;
        case QMetaType::Float:
            *reinterpret_cast<float*>(ptr) = val->toNumber();
            return true;
        case QMetaType::Short:
            *reinterpret_cast<short*>(ptr) = val->toInt32();
            return true;
        case QMetaType::UShort:
            *reinterpret_cast<unsigned short*>(ptr) = val->toUInt16();
            return true;
        case QMetaType::Char:
            *reinterpret_cast<char*>(ptr) = val->toInt32();
            return true;
        case QMetaType::UChar:
            *reinterpret_cast<unsigned char*>(ptr) = val->toUInt16();
            return true;
        case QMetaType::QChar:
            *reinterpret_cast<QChar*>(ptr) = val->toUInt16();
            return true;
        default:
            return false;
    }
}

/*! \fn template <typename T> QJSValue QJSEngine::toScriptValue(const T &value)

    Creates a QJSValue with the given \a value.

    \sa fromScriptValue()
*/

/*! \fn template <typename T> T QJSEngine::fromScriptValue(const QJSValue &value)

    Returns the given \a value converted to the template type \c{T}.

    \sa toScriptValue()
*/

/*!
    Throws a run-time error (exception) with the given \a message.

    This method is the C++ counterpart of a \c throw() expression in
    JavaScript. It enables C++ code to report run-time errors to QJSEngine.
    Therefore it should only be called from C++ code that was invoked by a
    JavaScript function through QJSEngine.

    When returning from C++, the engine will interrupt the normal flow of
    execution and call the the next pre-registered exception handler with
    an error object that contains the given \a message. The error object
    will point to the location of the top-most context on the JavaScript
    caller stack; specifically, it will have properties \c lineNumber,
    \c fileName and \c stack. These properties are described in
    \l{Script Exceptions}.

    In the following example a C++ method in \e FileAccess.cpp throws an error
    in \e qmlFile.qml at the position where \c readFileAsText() is called:

    \code
    // qmlFile.qml
    function someFunction() {
      ...
      var text = FileAccess.readFileAsText("/path/to/file.txt");
    }
    \endcode

    \code
    // FileAccess.cpp
    // Assuming that FileAccess is a QObject-derived class that has been
    // registered as a singleton type and provides an invokable method
    // readFileAsText()

    QJSValue FileAccess::readFileAsText(const QString & filePath) {
      QFile file(filePath);

      if (!file.open(QIODevice::ReadOnly)) {
        jsEngine->throwError(file.errorString());
        return QString();
      }

      ...
      return content;
    }
    \endcode

    It is also possible to catch the thrown error in JavaScript:
    \code
    // qmlFile.qml
    function someFunction() {
      ...
      var text;
      try {
        text = FileAccess.readFileAsText("/path/to/file.txt");
      } catch (error) {
        console.warn("In " + error.fileName + ":" + "error.lineNumber" +
                     ": " + error.message);
      }
    }
    \endcode

    If you need a more specific run-time error to describe an exception, you can use the
    \l {QJSEngine::}{throwError(QJSValue::ErrorType errorType, const QString &message)}
    overload.

    \since Qt 5.12
    \sa {Script Exceptions}
*/
void QJSEngine::throwError(const QString &message)
{
    m_v4Engine->throwError(message);
}

/*!
    \overload throwError()

    Throws a run-time error (exception) with the given \a errorType and
    \a message.

    \code
    // Assuming that DataEntry is a QObject-derived class that has been
    // registered as a singleton type and provides an invokable method
    // setAge().

    void DataEntry::setAge(int age) {
      if (age < 0 || age > 200) {
        jsEngine->throwError(QJSValue::RangeError,
                             "Age must be between 0 and 200");
      }
      ...
    }
    \endcode

    \since Qt 5.12
    \sa {Script Exceptions}, newErrorObject()
*/
void QJSEngine::throwError(QJSValue::ErrorType errorType, const QString &message)
{
    QV4::Scope scope(m_v4Engine);
    QJSValue error = newErrorObject(errorType, message);
    QV4::ScopedObject e(scope, QJSValuePrivate::getValue(&error));
    if (!e)
        return;
    m_v4Engine->throwError(e);
}

/*!
  \property QJSEngine::uiLanguage
  \brief the language to be used for translating user interface strings
  \since 5.15

  This property holds the name of the language to be used for user interface
  string translations. It is exposed for reading and writing as \c{Qt.uiLanguage} when
  the QJSEngine::TranslationExtension is installed on the engine. It is always exposed
  in instances of QQmlEngine.

  You can set the value freely and use it in bindings. It is recommended to set it
  after installing translators in your application. By convention, an empty string
  means no translation from the language used in the source code is intended to occur.
*/
void QJSEngine::setUiLanguage(const QString &language)
{
    Q_D(QJSEngine);
    if (language == d->uiLanguage)
        return;
    d->uiLanguage = language;
    emit uiLanguageChanged();
}

QString QJSEngine::uiLanguage() const
{
    Q_D(const QJSEngine);
    return d->uiLanguage;
}

QJSEnginePrivate *QJSEnginePrivate::get(QV4::ExecutionEngine *e)
{
    return e->jsEngine()->d_func();
}

QJSEnginePrivate::~QJSEnginePrivate()
{
    QQmlMetaType::freeUnusedTypesAndCaches();
}

void QJSEnginePrivate::addToDebugServer(QJSEngine *q)
{
    if (QCoreApplication::instance()->thread() != q->thread())
        return;

    QQmlDebugConnector *server = QQmlDebugConnector::instance();
    if (!server || server->hasEngine(q))
        return;

    server->open();
    server->addEngine(q);
}

void QJSEnginePrivate::removeFromDebugServer(QJSEngine *q)
{
    QQmlDebugConnector *server = QQmlDebugConnector::instance();
    if (server && server->hasEngine(q))
        server->removeEngine(q);
}

/*!
   \since 5.5
   \relates QJSEngine

   Returns the QJSEngine associated with \a object, if any.

   This function is useful if you have exposed a QObject to the JavaScript environment
   and later in your program would like to regain access. It does not require you to
   keep the wrapper around that was returned from QJSEngine::newQObject().
 */
QJSEngine *qjsEngine(const QObject *object)
{
    QQmlData *data = QQmlData::get(object, false);
    if (!data || data->jsWrapper.isNullOrUndefined())
        return nullptr;
    return data->jsWrapper.engine()->jsEngine();
}

QT_END_NAMESPACE

#include "moc_qjsengine.cpp"
