diff options
Diffstat (limited to 'src/qml/qml')
37 files changed, 1536 insertions, 1282 deletions
diff --git a/src/qml/qml/qqmlabstractbinding.cpp b/src/qml/qml/qqmlabstractbinding.cpp index 39d609454f..b1c320afd4 100644 --- a/src/qml/qml/qqmlabstractbinding.cpp +++ b/src/qml/qml/qqmlabstractbinding.cpp @@ -191,7 +191,7 @@ void QQmlAbstractBinding::removeFromObject() void QQmlAbstractBinding::printBindingLoopError(QQmlProperty &prop) { - qmlInfo(prop.object()) << QString(QLatin1String("Binding loop detected for property \"%1\"")).arg(prop.name()); + qmlWarning(prop.object()) << QString(QLatin1String("Binding loop detected for property \"%1\"")).arg(prop.name()); } QString QQmlAbstractBinding::expression() const diff --git a/src/qml/qml/qqmlabstracturlinterceptor.h b/src/qml/qml/qqmlabstracturlinterceptor.h index dfb8a46027..665b37fb3a 100644 --- a/src/qml/qml/qqmlabstracturlinterceptor.h +++ b/src/qml/qml/qqmlabstracturlinterceptor.h @@ -47,7 +47,6 @@ QT_BEGIN_NAMESPACE class Q_QML_EXPORT QQmlAbstractUrlInterceptor { - Q_FLAGS(InterceptionPoint) public: enum DataType { //Matches QQmlDataBlob::Type QmlFile = 0, diff --git a/src/qml/qml/qqmlapplicationengine.cpp b/src/qml/qml/qqmlapplicationengine.cpp index 8a97b7eba7..2a96d96302 100644 --- a/src/qml/qml/qqmlapplicationengine.cpp +++ b/src/qml/qml/qqmlapplicationengine.cpp @@ -190,9 +190,14 @@ void QQmlApplicationEnginePrivate::_q_finishLoad(QObject *o) /*! \fn QQmlApplicationEngine::objectCreated(QObject *object, const QUrl &url) - This signal is emitted when an object finishes loading. If loading was successful, \a object contains a pointer to the loaded object. - Otherwise the pointer is NULL. The \a url loaded is also provided, note that if a QString file path was initially passed to the - QQmlApplicationEngine, this url will be the equivalent of QUrl::fromLocalFile(filePath). + This signal is emitted when an object finishes loading. If loading was + successful, \a object contains a pointer to the loaded object, otherwise + the pointer is NULL. + + The \a url to the component the \a object came from is also provided. + + \note If the path to the component was provided as a QString containing a + relative path, the \a url will contain a fully resolved path to the file. */ /*! @@ -226,7 +231,7 @@ QQmlApplicationEngine::QQmlApplicationEngine(const QUrl &url, QObject *parent) This is provided as a convenience, and is the same as using the empty constructor and calling load afterwards. */ QQmlApplicationEngine::QQmlApplicationEngine(const QString &filePath, QObject *parent) - : QQmlApplicationEngine(QUrl::fromLocalFile(filePath), parent) + : QQmlApplicationEngine(QUrl::fromUserInput(filePath, QLatin1String("."), QUrl::AssumeLocalFile), parent) { } @@ -265,7 +270,7 @@ void QQmlApplicationEngine::load(const QUrl &url) void QQmlApplicationEngine::load(const QString &filePath) { Q_D(QQmlApplicationEngine); - d->startLoad(QUrl::fromLocalFile(filePath)); + d->startLoad(QUrl::fromUserInput(filePath, QLatin1String("."), QUrl::AssumeLocalFile)); } /*! diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp index 254d5e1907..19ece44beb 100644 --- a/src/qml/qml/qqmlboundsignal.cpp +++ b/src/qml/qml/qqmlboundsignal.cpp @@ -91,7 +91,7 @@ QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index, function += QQmlPropertyCache::signalParameterStringForJS(v4, signal.parameterNames(), &error); if (!error.isEmpty()) { - qmlInfo(scopeObject()) << error; + qmlWarning(scopeObject()) << error; return; } } else @@ -129,7 +129,7 @@ QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index, QString error; QQmlPropertyCache::signalParameterStringForJS(engine, signalParameters, &error); if (!error.isEmpty()) { - qmlInfo(scopeObject()) << error; + qmlWarning(scopeObject()) << error; return; } runtimeFunction->updateInternalClass(engine, signalParameters); @@ -199,7 +199,10 @@ void QQmlBoundSignalExpression::evaluate(void **a) // for several cases (such as QVariant type and QObject-derived types) //args[ii] = engine->metaTypeToJS(type, a[ii + 1]); if (type == qMetaTypeId<QJSValue>()) { - callData->args[ii] = *QJSValuePrivate::getValue(reinterpret_cast<QJSValue *>(a[ii + 1])); + if (QV4::Value *v4Value = QJSValuePrivate::valueForData(reinterpret_cast<QJSValue *>(a[ii + 1]), &callData->args[ii])) + callData->args[ii] = *v4Value; + else + callData->args[ii] = QV4::Encode::undefined(); } else if (type == QMetaType::QVariant) { callData->args[ii] = scope.engine->fromVariant(*((QVariant *)a[ii + 1])); } else if (type == QMetaType::Int) { diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index 6ebcd142fb..a04f47e6a4 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -47,8 +47,6 @@ #include "qqml.h" #include "qqmlengine.h" #include "qqmlbinding_p.h" -#include <private/qqmldebugconnector_p.h> -#include <private/qqmldebugserviceinterfaces_p.h> #include "qqmlincubator.h" #include "qqmlincubator_p.h" #include <private/qqmljavascriptexpression_p.h> @@ -876,15 +874,6 @@ QQmlComponentPrivate::beginCreate(QQmlContextData *context) depthIncreased = false; } - if (rv) { - if (QQmlEngineDebugService *service = - QQmlDebugConnector::service<QQmlEngineDebugService>()) { - if (!context->isInternal) - context->asQQmlContextPrivate()->instances.append(rv); - service->objectCreated(engine, rv); - } - } - return rv; } @@ -1074,11 +1063,11 @@ struct QmlIncubatorObject : public QV4::Object V4_OBJECT2(QmlIncubatorObject, Object) V4_NEEDS_DESTROY - static QV4::ReturnedValue method_get_statusChanged(QV4::CallContext *ctx); - static QV4::ReturnedValue method_set_statusChanged(QV4::CallContext *ctx); - static QV4::ReturnedValue method_get_status(QV4::CallContext *ctx); - static QV4::ReturnedValue method_get_object(QV4::CallContext *ctx); - static QV4::ReturnedValue method_forceCompletion(QV4::CallContext *ctx); + static void method_get_statusChanged(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_set_statusChanged(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_get_status(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_get_object(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_forceCompletion(const BuiltinFunction *, Scope &scope, CallData *callData); static void markObjects(QV4::Heap::Base *that, QV4::ExecutionEngine *e); @@ -1244,7 +1233,7 @@ void QQmlComponent::createObject(QQmlV4Function *args) if (args->length() >= 2) { QV4::ScopedValue v(scope, (*args)[1]); if (!v->as<QV4::Object>() || v->as<QV4::ArrayObject>()) { - qmlInfo(this) << tr("createObject: value is not an object"); + qmlWarning(this) << tr("createObject: value is not an object"); args->setReturnValue(QV4::Encode::null()); return; } @@ -1361,7 +1350,7 @@ void QQmlComponent::incubateObject(QQmlV4Function *args) QV4::ScopedValue v(scope, (*args)[1]); if (v->isNull()) { } else if (!v->as<QV4::Object>() || v->as<QV4::ArrayObject>()) { - qmlInfo(this) << tr("createObject: value is not an object"); + qmlWarning(this) << tr("createObject: value is not an object"); args->setReturnValue(QV4::Encode::null()); return; } else { @@ -1426,58 +1415,53 @@ QQmlComponentExtension::QQmlComponentExtension(QV4::ExecutionEngine *v4) incubationProto.set(v4, proto); } -QV4::ReturnedValue QV4::QmlIncubatorObject::method_get_object(QV4::CallContext *ctx) +void QV4::QmlIncubatorObject::method_get_object(const BuiltinFunction *, Scope &scope, CallData *callData) { - QV4::Scope scope(ctx); - QV4::Scoped<QmlIncubatorObject> o(scope, ctx->thisObject().as<QmlIncubatorObject>()); + QV4::Scoped<QmlIncubatorObject> o(scope, callData->thisObject.as<QmlIncubatorObject>()); if (!o) - return ctx->engine()->throwTypeError(); + THROW_TYPE_ERROR(); - return QV4::QObjectWrapper::wrap(ctx->d()->engine, o->d()->incubator->object()); + scope.result = QV4::QObjectWrapper::wrap(scope.engine, o->d()->incubator->object()); } -QV4::ReturnedValue QV4::QmlIncubatorObject::method_forceCompletion(QV4::CallContext *ctx) +void QV4::QmlIncubatorObject::method_forceCompletion(const BuiltinFunction *, Scope &scope, CallData *callData) { - QV4::Scope scope(ctx); - QV4::Scoped<QmlIncubatorObject> o(scope, ctx->thisObject().as<QmlIncubatorObject>()); + QV4::Scoped<QmlIncubatorObject> o(scope, callData->thisObject.as<QmlIncubatorObject>()); if (!o) - return ctx->engine()->throwTypeError(); + THROW_TYPE_ERROR(); o->d()->incubator->forceCompletion(); - return QV4::Encode::undefined(); + RETURN_UNDEFINED(); } -QV4::ReturnedValue QV4::QmlIncubatorObject::method_get_status(QV4::CallContext *ctx) +void QV4::QmlIncubatorObject::method_get_status(const BuiltinFunction *, Scope &scope, CallData *callData) { - QV4::Scope scope(ctx); - QV4::Scoped<QmlIncubatorObject> o(scope, ctx->thisObject().as<QmlIncubatorObject>()); + QV4::Scoped<QmlIncubatorObject> o(scope, callData->thisObject.as<QmlIncubatorObject>()); if (!o) - return ctx->engine()->throwTypeError(); + THROW_TYPE_ERROR(); - return QV4::Encode(o->d()->incubator->status()); + scope.result = QV4::Encode(o->d()->incubator->status()); } -QV4::ReturnedValue QV4::QmlIncubatorObject::method_get_statusChanged(QV4::CallContext *ctx) +void QV4::QmlIncubatorObject::method_get_statusChanged(const BuiltinFunction *, Scope &scope, CallData *callData) { - QV4::Scope scope(ctx); - QV4::Scoped<QmlIncubatorObject> o(scope, ctx->thisObject().as<QmlIncubatorObject>()); + QV4::Scoped<QmlIncubatorObject> o(scope, callData->thisObject.as<QmlIncubatorObject>()); if (!o) - return ctx->engine()->throwTypeError(); + THROW_TYPE_ERROR(); - return o->d()->statusChanged.asReturnedValue(); + scope.result = o->d()->statusChanged; } -QV4::ReturnedValue QV4::QmlIncubatorObject::method_set_statusChanged(QV4::CallContext *ctx) +void QV4::QmlIncubatorObject::method_set_statusChanged(const BuiltinFunction *, Scope &scope, CallData *callData) { - QV4::Scope scope(ctx); - QV4::Scoped<QmlIncubatorObject> o(scope, ctx->thisObject().as<QmlIncubatorObject>()); - if (!o || ctx->argc() < 1) - return ctx->engine()->throwTypeError(); + QV4::Scoped<QmlIncubatorObject> o(scope, callData->thisObject.as<QmlIncubatorObject>()); + if (!o || callData->argc < 1) + THROW_TYPE_ERROR(); + o->d()->statusChanged = callData->args[0]; - o->d()->statusChanged = ctx->args()[0]; - return QV4::Encode::undefined(); + RETURN_UNDEFINED(); } QQmlComponentExtension::~QQmlComponentExtension() diff --git a/src/qml/qml/qqmlcustomparser.cpp b/src/qml/qml/qqmlcustomparser.cpp index 85c91a592a..0b0bbef795 100644 --- a/src/qml/qml/qqmlcustomparser.cpp +++ b/src/qml/qml/qqmlcustomparser.cpp @@ -83,7 +83,7 @@ QT_BEGIN_NAMESPACE by \a data, which is a block of data previously returned by a call to compile(). - Errors should be reported using qmlInfo(object). + Errors should be reported using qmlWarning(object). The \a object will be an instance of the TypeClass specified by QML_REGISTER_CUSTOM_TYPE. */ diff --git a/src/qml/qml/qqmldelayedcallqueue.cpp b/src/qml/qml/qqmldelayedcallqueue.cpp index 7552e1e82b..d5d2c9a28d 100644 --- a/src/qml/qml/qqmldelayedcallqueue.cpp +++ b/src/qml/qml/qqmldelayedcallqueue.cpp @@ -105,17 +105,15 @@ void QQmlDelayedCallQueue::init(QV4::ExecutionEngine* engine) m_tickedMethod = metaObject.method(methodIndex); } -QV4::ReturnedValue QQmlDelayedCallQueue::addUniquelyAndExecuteLater(QV4::CallContext *ctx) +void QQmlDelayedCallQueue::addUniquelyAndExecuteLater(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { - const QV4::CallData *callData = ctx->d()->callData; - if (callData->argc == 0) - V4THROW_ERROR("Qt.callLater: no arguments given"); + THROW_GENERIC_ERROR("Qt.callLater: no arguments given"); const QV4::FunctionObject *func = callData->args[0].as<QV4::FunctionObject>(); if (!func) - V4THROW_ERROR("Qt.callLater: first argument not a function or signal"); + THROW_GENERIC_ERROR("Qt.callLater: first argument not a function or signal"); QPair<QObject *, int> functionData = QV4::QObjectMethod::extractQtMethod(func); @@ -171,7 +169,7 @@ QV4::ReturnedValue QQmlDelayedCallQueue::addUniquelyAndExecuteLater(QV4::CallCon m_tickedMethod.invoke(this, Qt::QueuedConnection); m_callbackOutstanding = true; } - return QV4::Encode::undefined(); + scope.result = QV4::Encode::undefined(); } void QQmlDelayedCallQueue::storeAnyArguments(DelayedFunctionCall &dfc, const QV4::CallData *callData, int offset, QV4::ExecutionEngine *engine) diff --git a/src/qml/qml/qqmldelayedcallqueue_p.h b/src/qml/qml/qqmldelayedcallqueue_p.h index ef899170a2..cffde4f0c0 100644 --- a/src/qml/qml/qqmldelayedcallqueue_p.h +++ b/src/qml/qml/qqmldelayedcallqueue_p.h @@ -70,7 +70,7 @@ public: void init(QV4::ExecutionEngine *); - QV4::ReturnedValue addUniquelyAndExecuteLater(QV4::CallContext *ctx); + void addUniquelyAndExecuteLater(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); public Q_SLOTS: void ticked(); diff --git a/src/qml/qml/qqmldirparser.cpp b/src/qml/qml/qqmldirparser.cpp index fde7cc4cef..4cca8a4d58 100644 --- a/src/qml/qml/qqmldirparser.cpp +++ b/src/qml/qml/qqmldirparser.cpp @@ -188,6 +188,15 @@ bool QQmlDirParser::parse(const QString &source) _plugins.append(entry); + } else if (sections[0] == QLatin1String("classname")) { + if (sectionCount < 2) { + reportError(lineNumber, 0, + QStringLiteral("classname directive requires an argument, but %1 were provided").arg(sectionCount - 1)); + + continue; + } + + // Ignore these. qmlimportscanner uses them. } else if (sections[0] == QLatin1String("internal")) { if (sectionCount != 3) { reportError(lineNumber, 0, diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index c2915c840b..e1fa97b52f 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -436,7 +436,6 @@ The following functions are also on the Qt object. \list \li \c "android" - Android - \li \c "blackberry" - BlackBerry OS \li \c "ios" - iOS \li \c "tvos" - tvOS \li \c "linux" - Linux @@ -444,7 +443,6 @@ The following functions are also on the Qt object. \li \c "unix" - Other Unix-based OS \li \c "windows" - Windows \li \c "winrt" - WinRT / UWP - \li \c "winphone" - Windows Phone \endlist \endtable */ @@ -1914,9 +1912,29 @@ void QQmlEnginePrivate::sendExit(int retCode) static void dumpwarning(const QQmlError &error) { - QMessageLogger(error.url().toString().toLatin1().constData(), - error.line(), 0).warning().nospace() - << qPrintable(error.toString()); + switch (error.messageType()) { + case QtDebugMsg: + QMessageLogger(error.url().toString().toLatin1().constData(), + error.line(), 0).debug().nospace() + << qPrintable(error.toString()); + break; + case QtInfoMsg: + QMessageLogger(error.url().toString().toLatin1().constData(), + error.line(), 0).info().nospace() + << qPrintable(error.toString()); + break; + case QtWarningMsg: + case QtFatalMsg: // fatal does not support streaming, and furthermore, is actually fatal. Probably not desirable for QML. + QMessageLogger(error.url().toString().toLatin1().constData(), + error.line(), 0).warning().nospace() + << qPrintable(error.toString()); + break; + case QtCriticalMsg: + QMessageLogger(error.url().toString().toLatin1().constData(), + error.line(), 0).critical().nospace() + << qPrintable(error.toString()); + break; + } } static void dumpwarning(const QList<QQmlError> &errors) @@ -2129,8 +2147,7 @@ bool QQmlEngine::importPlugin(const QString &filePath, const QString &uri, QList Returns the directory where SQL and other offline storage is placed. - QQuickWebView and the SQL databases created with openDatabase() - are stored here. + The SQL databases created with openDatabase() are stored here. The default is QML/OfflineStorage in the platform-standard user application data directory. diff --git a/src/qml/qml/qqmlerror.cpp b/src/qml/qml/qqmlerror.cpp index 0a6c7b4960..7a1e02eec6 100644 --- a/src/qml/qml/qqmlerror.cpp +++ b/src/qml/qml/qqmlerror.cpp @@ -85,11 +85,12 @@ public: QString description; quint16 line; quint16 column; + QtMsgType messageType; QObject *object; }; QQmlErrorPrivate::QQmlErrorPrivate() -: line(0), column(0), object() +: line(0), column(0), messageType(QtMsgType::QtWarningMsg), object() { } @@ -119,12 +120,14 @@ QQmlError &QQmlError::operator=(const QQmlError &other) delete d; d = 0; } else { - if (!d) d = new QQmlErrorPrivate; + if (!d) + d = new QQmlErrorPrivate; d->url = other.d->url; d->description = other.d->description; d->line = other.d->line; d->column = other.d->column; d->object = other.d->object; + d->messageType = other.d->messageType; } return *this; } @@ -150,8 +153,9 @@ bool QQmlError::isValid() const */ QUrl QQmlError::url() const { - if (d) return d->url; - else return QUrl(); + if (d) + return d->url; + return QUrl(); } /*! @@ -159,7 +163,8 @@ QUrl QQmlError::url() const */ void QQmlError::setUrl(const QUrl &url) { - if (!d) d = new QQmlErrorPrivate; + if (!d) + d = new QQmlErrorPrivate; d->url = url; } @@ -168,8 +173,9 @@ void QQmlError::setUrl(const QUrl &url) */ QString QQmlError::description() const { - if (d) return d->description; - else return QString(); + if (d) + return d->description; + return QString(); } /*! @@ -177,7 +183,8 @@ QString QQmlError::description() const */ void QQmlError::setDescription(const QString &description) { - if (!d) d = new QQmlErrorPrivate; + if (!d) + d = new QQmlErrorPrivate; d->description = description; } @@ -186,8 +193,9 @@ void QQmlError::setDescription(const QString &description) */ int QQmlError::line() const { - if (d) return qmlSourceCoordinate(d->line); - else return -1; + if (d) + return qmlSourceCoordinate(d->line); + return -1; } /*! @@ -195,7 +203,8 @@ int QQmlError::line() const */ void QQmlError::setLine(int line) { - if (!d) d = new QQmlErrorPrivate; + if (!d) + d = new QQmlErrorPrivate; d->line = qmlSourceCoordinate(line); } @@ -204,8 +213,9 @@ void QQmlError::setLine(int line) */ int QQmlError::column() const { - if (d) return qmlSourceCoordinate(d->column); - else return -1; + if (d) + return qmlSourceCoordinate(d->column); + return -1; } /*! @@ -213,7 +223,8 @@ int QQmlError::column() const */ void QQmlError::setColumn(int column) { - if (!d) d = new QQmlErrorPrivate; + if (!d) + d = new QQmlErrorPrivate; d->column = qmlSourceCoordinate(column); } @@ -225,8 +236,9 @@ void QQmlError::setColumn(int column) */ QObject *QQmlError::object() const { - if (d) return d->object; - else return 0; + if (d) + return d->object; + return 0; } /*! @@ -234,11 +246,37 @@ QObject *QQmlError::object() const */ void QQmlError::setObject(QObject *object) { - if (!d) d = new QQmlErrorPrivate; + if (!d) + d = new QQmlErrorPrivate; d->object = object; } /*! + \since 5.9 + + Returns the message type. + */ +QtMsgType QQmlError::messageType() const +{ + if (d) + return d->messageType; + return QtMsgType::QtWarningMsg; +} + +/*! + \since 5.9 + + Sets the \a messageType for this message. The message type determines which + QDebug handlers are responsible for recieving the message. + */ +void QQmlError::setMessageType(QtMsgType messageType) +{ + if (!d) + d = new QQmlErrorPrivate; + d->messageType = messageType; +} + +/*! Returns the error as a human readable string. */ QString QQmlError::toString() const diff --git a/src/qml/qml/qqmlerror.h b/src/qml/qml/qqmlerror.h index e4c42223cf..ef529e3828 100644 --- a/src/qml/qml/qqmlerror.h +++ b/src/qml/qml/qqmlerror.h @@ -47,6 +47,7 @@ QT_BEGIN_NAMESPACE +// ### Qt 6: should this be called QQmlMessage, since it can have a message type? class QDebug; class QQmlErrorPrivate; class Q_QML_EXPORT QQmlError @@ -69,6 +70,8 @@ public: void setColumn(int); QObject *object() const; void setObject(QObject *); + QtMsgType messageType() const; + void setMessageType(QtMsgType messageType); QString toString() const; private: diff --git a/src/qml/qml/qqmlextensionplugin.cpp b/src/qml/qml/qqmlextensionplugin.cpp index ca19691e93..097fa71200 100644 --- a/src/qml/qml/qqmlextensionplugin.cpp +++ b/src/qml/qml/qqmlextensionplugin.cpp @@ -117,4 +117,14 @@ void QQmlExtensionPlugin::initializeEngine(QQmlEngine *engine, const char *uri) Q_UNUSED(uri); } +/*! + \class QQmlExtensionInterface + \internal + \inmodule QtQml + + \class QQmlTypesExtensionInterface + \internal + \inmodule QtQml +*/ + QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp index 8712b638c5..bd41659f27 100644 --- a/src/qml/qml/qqmlimport.cpp +++ b/src/qml/qml/qqmlimport.cpp @@ -130,42 +130,74 @@ bool isPathAbsolute(const QString &path) #endif } -// If the type does not already exist as a file import, add the type and return the new type -QQmlType *getTypeForUrl(const QString &urlString, const QHashedStringRef& typeName, +/* + \internal + + Fetches the QQmlType instance registered for \a urlString, creating a + registration for it if it is not already registered, using the associated + \a typeName, \a isCompositeSingleton, \a majorVersion and \a minorVersion + details. + + Errors (if there are any) are placed into \a errors, if it is nonzero. Note + that errors are treated as fatal if \a errors is not set. +*/ +QQmlType *fetchOrCreateTypeForUrl(const QString &urlString, const QHashedStringRef& typeName, bool isCompositeSingleton, QList<QQmlError> *errors, int majorVersion=-1, int minorVersion=-1) { - QUrl url(urlString); + QUrl url(urlString); // ### unfortunate (costly) conversion QQmlType *ret = QQmlMetaType::qmlType(url); - if (!ret) { //QQmlType not yet existing for composite or composite singleton type - int dot = typeName.indexOf(QLatin1Char('.')); - QHashedStringRef unqualifiedtype = dot < 0 ? typeName : QHashedStringRef(typeName.constData() + dot + 1, typeName.length() - dot - 1); - - //XXX: The constData of the string ref is pointing somewhere unsafe in qmlregister, so we need to create a temporary copy - QByteArray buf(unqualifiedtype.toString().toUtf8()); - - if (isCompositeSingleton) { - QQmlPrivate::RegisterCompositeSingletonType reg = { - url, - "", //Empty URI indicates loaded via file imports - majorVersion, - minorVersion, - buf.constData() - }; - ret = QQmlMetaType::qmlTypeFromIndex(QQmlPrivate::qmlregister(QQmlPrivate::CompositeSingletonRegistration, ®)); - } else { - QQmlPrivate::RegisterCompositeType reg = { - url, - "", //Empty URI indicates loaded via file imports - majorVersion, - minorVersion, - buf.constData() - }; - ret = QQmlMetaType::qmlTypeFromIndex(QQmlPrivate::qmlregister(QQmlPrivate::CompositeRegistration, ®)); - } + if (ret) + return ret; + + int dot = typeName.indexOf(QLatin1Char('.')); + QHashedStringRef unqualifiedtype = dot < 0 ? typeName : QHashedStringRef(typeName.constData() + dot + 1, typeName.length() - dot - 1); + + // We need a pointer, but we were passed a string. Take a copy so we + // can guarentee it will live long enough to reach qmlregister. + QByteArray buf(unqualifiedtype.toString().toUtf8()); + + // Register the type. Note that the URI parameters here are empty; for + // file type imports, we do not place them in a URI as we don't + // necessarily have a good and unique one (picture a library import, + // which may be found in multiple plugin locations on disk), but there + // are other reasons for this too. + // + // By not putting them in a URI, we prevent the types from being + // registered on a QQmlTypeModule; this is important, as once types are + // placed on there, they cannot be easily removed, meaning if the + // developer subsequently loads a different import (meaning different + // types) with the same URI (using, say, a different plugin path), it is + // very undesirable that we continue to associate the types from the + // "old" URI with that new module. + // + // Not having URIs also means that the types cannot be found by name + // etc, the only way to look them up is through QQmlImports -- for + // better or worse. + if (isCompositeSingleton) { + QQmlPrivate::RegisterCompositeSingletonType reg = { + url, + "", // uri + majorVersion, + minorVersion, + buf.constData() + }; + ret = QQmlMetaType::qmlTypeFromIndex(QQmlPrivate::qmlregister(QQmlPrivate::CompositeSingletonRegistration, ®)); + } else { + QQmlPrivate::RegisterCompositeType reg = { + url, + "", // uri + majorVersion, + minorVersion, + buf.constData() + }; + ret = QQmlMetaType::qmlTypeFromIndex(QQmlPrivate::qmlregister(QQmlPrivate::CompositeRegistration, ®)); } - if (!ret) {//Usually when a type name is "found" but invalid - //qDebug() << ret << urlString << QQmlMetaType::qmlType(url); + + // This means that the type couldn't be found by URL, but could not be + // registered either, meaning we most likely were passed some kind of bad + // data. + if (!ret) { if (!errors) // Cannot list errors properly, just quit qFatal("%s", QQmlMetaType::typeRegistrationFailures().join('\n').toLatin1().constData()); QQmlError error; @@ -204,20 +236,49 @@ void qmlClearEnginePlugins() typedef QPair<QStaticPlugin, QJsonArray> StaticPluginPair; #endif +/*! + \internal + + A QQmlImportNamespace is a way of seperating imports into a local namespace. + + Within a QML document, there is at least one namespace (the + "unqualified set") where imports without a qualifier are placed, i.e: + + import QtQuick 2.6 + + will have a single namespace (the unqualified set) containing a single import + for QtQuick 2.6. However, there may be others if an import statement gives + a qualifier, i.e the following will result in an additional new + QQmlImportNamespace in the qualified set: + + import MyFoo 1.0 as Foo +*/ class QQmlImportNamespace { public: QQmlImportNamespace() : nextNamespace(0) {} ~QQmlImportNamespace() { qDeleteAll(imports); } + /*! + \internal + + A QQmlImportNamespace::Import represents an actual instance of an import + within a namespace. + + \note The uri here may not necessarily be unique (e.g. for file imports). + + \note Version numbers may be -1 for file imports: this means that no + version was specified as part of the import. Type resolution will be + responsible for attempting to find the "best" possible version. + */ struct Import { - QString uri; - QString url; - int majversion; - int minversion; - bool isLibrary; - QQmlDirComponents qmlDirComponents; - QQmlDirScripts qmlDirScripts; + QString uri; // e.g. QtQuick + QString url; // the base path of the import + int majversion; // the major version imported + int minversion; // the minor version imported + bool isLibrary; // true means that this is not a file import + QQmlDirComponents qmlDirComponents; // a copy of the components listed in the qmldir + QQmlDirScripts qmlDirScripts; // a copy of the scripts in the qmldir bool setQmldirContent(const QString &resolvedUrl, const QQmlTypeLoader::QmldirContent *qmldir, QQmlImportNamespace *nameSpace, QList<QQmlError> *errors); @@ -273,9 +334,12 @@ public: QString base; int ref; + // storage of data related to imports without a namespace mutable QQmlImportNamespace unqualifiedset; QQmlImportNamespace *findQualifiedNamespace(const QHashedStringRef &) const; + + // storage of data related to imports with a namespace mutable QFieldList<QQmlImportNamespace, &QQmlImportNamespace::nextNamespace> qualifiedSets; QQmlTypeLoader *typeLoader; @@ -683,15 +747,17 @@ bool QQmlImportNamespace::Import::resolveType(QQmlTypeLoader *typeLoader, if ((candidate == end) || (c.majorVersion > candidate->majorVersion) || ((c.majorVersion == candidate->majorVersion) && (c.minorVersion > candidate->minorVersion))) { - componentUrl = resolveLocalUrl(QString(url + c.typeName + dotqml_string), c.fileName); - if (c.internal && base) { - if (resolveLocalUrl(*base, c.fileName) != componentUrl) - continue; // failed attempt to access an internal type - } - if (base && (*base == componentUrl)) { - if (typeRecursionDetected) - *typeRecursionDetected = true; - continue; // no recursion + if (base) { + componentUrl = resolveLocalUrl(QString(url + c.typeName + dotqml_string), c.fileName); + if (c.internal) { + if (resolveLocalUrl(*base, c.fileName) != componentUrl) + continue; // failed attempt to access an internal type + } + if (*base == componentUrl) { + if (typeRecursionDetected) + *typeRecursionDetected = true; + continue; // no recursion + } } // This is our best candidate so far @@ -702,9 +768,11 @@ bool QQmlImportNamespace::Import::resolveType(QQmlTypeLoader *typeLoader, } if (candidate != end) { + if (!base) // ensure we have a componentUrl + componentUrl = resolveLocalUrl(QString(url + candidate->typeName + dotqml_string), candidate->fileName); int major = vmajor ? *vmajor : -1; int minor = vminor ? *vminor : -1; - QQmlType *returnType = getTypeForUrl(componentUrl, type, isCompositeSingleton, 0, + QQmlType *returnType = fetchOrCreateTypeForUrl(componentUrl, type, isCompositeSingleton, 0, major, minor); if (type_return) *type_return = returnType; @@ -732,7 +800,7 @@ bool QQmlImportNamespace::Import::resolveType(QQmlTypeLoader *typeLoader, if (typeRecursionDetected) *typeRecursionDetected = true; } else { - QQmlType *returnType = getTypeForUrl(qmlUrl, type, false, 0); + QQmlType *returnType = fetchOrCreateTypeForUrl(qmlUrl, type, false, 0); if (type_return) *type_return = returnType; return returnType != 0; @@ -777,7 +845,7 @@ bool QQmlImportsPrivate::resolveType(const QHashedStringRef& type, int *vmajor, return true; if (s->imports.count() == 1 && !s->imports.at(0)->isLibrary && type_return && s != &unqualifiedset) { // qualified, and only 1 url - *type_return = getTypeForUrl(resolveLocalUrl(s->imports.at(0)->url, unqualifiedtype.toString() + QLatin1String(".qml")), type, false, errors); + *type_return = fetchOrCreateTypeForUrl(resolveLocalUrl(s->imports.at(0)->url, unqualifiedtype.toString() + QLatin1String(".qml")), type, false, errors); return (*type_return != 0); } } diff --git a/src/qml/qml/qqmlincubator.cpp b/src/qml/qml/qqmlincubator.cpp index 963638ca34..54d0b240f5 100644 --- a/src/qml/qml/qqmlincubator.cpp +++ b/src/qml/qml/qqmlincubator.cpp @@ -380,6 +380,23 @@ finishIncubate: } } +void QQmlIncubatorPrivate::cancel(QObject *object, QQmlContext *context) +{ + if (!context) + context = qmlContext(object); + if (!context) + return; + + QQmlContextData *data = QQmlContextData::get(context); + QQmlIncubatorPrivate *p = (QQmlIncubatorPrivate *)data->activeVMEData; + if (!p) + return; + + p->vmeGuard.unguard(object); + if (!p->creator.isNull()) + p->creator->cancel(object); +} + /*! Incubate objects for \a msecs, or until there are no more objects to incubate. */ diff --git a/src/qml/qml/qqmlincubator_p.h b/src/qml/qml/qqmlincubator_p.h index ecf3b6d2ca..758e0a29f6 100644 --- a/src/qml/qml/qqmlincubator_p.h +++ b/src/qml/qml/qqmlincubator_p.h @@ -40,6 +40,8 @@ #ifndef QQMLINCUBATOR_P_H #define QQMLINCUBATOR_P_H +#include "qqmlincubator.h" + #include <private/qintrusivelist_p.h> #include <private/qqmlvme_p.h> #include <private/qrecursionwatcher_p.h> @@ -100,6 +102,9 @@ public: void forceCompletion(QQmlInstantiationInterrupt &i); void incubate(QQmlInstantiationInterrupt &i); + + // used by Qt Quick Controls 2 + Q_QML_PRIVATE_EXPORT static void cancel(QObject *object, QQmlContext *context = 0); }; QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlinfo.cpp b/src/qml/qml/qqmlinfo.cpp index 5b6e02d5b1..dae15e2eca 100644 --- a/src/qml/qml/qqmlinfo.cpp +++ b/src/qml/qml/qqmlinfo.cpp @@ -50,13 +50,45 @@ QT_BEGIN_NAMESPACE /*! + \fn QQmlInfo QtQml::qmlDebug(const QObject *object) + \relates QQmlEngine + \since 5.9 + + Prints debug messages that include the file and line number for the + specified QML \a object. + + When QML types produce logging messages, it improves traceability + if they include the QML file and line number on which the + particular instance was instantiated. + + To include the file and line number, an object must be passed. If + the file and line number is not available for that instance + (either it was not instantiated by the QML engine or location + information is disabled), "unknown location" will be used instead. + + For example, + + \code + qmlDebug(object) << "Internal state: 42"; + \endcode + + prints + + \code + QML MyCustomType (unknown location): Internal state: 42 + \endcode + + \sa QtQml::qmlInfo, QtQml::qmlWarning +*/ + +/*! \fn QQmlInfo QtQml::qmlInfo(const QObject *object) \relates QQmlEngine - Prints warning messages that include the file and line number for the + Prints informational messages that include the file and line number for the specified QML \a object. - When QML types display warning messages, it improves traceability + When QML types produce logging messages, it improves traceability if they include the QML file and line number on which the particular instance was instantiated. @@ -76,14 +108,58 @@ QT_BEGIN_NAMESPACE \code QML MyCustomType (unknown location): component property is a write-once property \endcode + + \note In versions prior to Qt 5.9, qmlInfo reported messages using a warning + QtMsgType. For Qt 5.9 and above, qmlInfo uses an info QtMsgType. To send + warnings, use qmlWarning. + + \sa QtQml::qmlDebug, QtQml::qmlWarning +*/ + + +/*! + \fn QQmlInfo QtQml::qmlWarning(const QObject *object) + \relates QQmlEngine + \since 5.9 + + Prints warning messages that include the file and line number for the + specified QML \a object. + + When QML types produce logging messages, it improves traceability + if they include the QML file and line number on which the + particular instance was instantiated. + + To include the file and line number, an object must be passed. If + the file and line number is not available for that instance + (either it was not instantiated by the QML engine or location + information is disabled), "unknown location" will be used instead. + + For example, + + \code + qmlInfo(object) << tr("property cannot be set to 0"); + \endcode + + prints + + \code + QML MyCustomType (unknown location): property cannot be set to 0 + \endcode + + \sa QtQml::qmlDebug, QtQml::qmlInfo */ class QQmlInfoPrivate { public: - QQmlInfoPrivate() : ref (1), object(0) {} + QQmlInfoPrivate(QtMsgType type) + : ref (1) + , msgType(type) + , object(nullptr) + {} int ref; + QtMsgType msgType; const QObject *object; QString buffer; QList<QQmlError> errors; @@ -110,6 +186,7 @@ QQmlInfo::~QQmlInfo() if (!d->buffer.isEmpty()) { QQmlError error; + error.setMessageType(d->msgType); QObject *object = const_cast<QObject *>(d->object); @@ -139,28 +216,32 @@ QQmlInfo::~QQmlInfo() namespace QtQml { -QQmlInfo qmlInfo(const QObject *me) -{ - QQmlInfoPrivate *d = new QQmlInfoPrivate; - d->object = me; - return QQmlInfo(d); -} +#define MESSAGE_FUNCS(FuncName, MessageLevel) \ + QQmlInfo FuncName(const QObject *me) \ + { \ + QQmlInfoPrivate *d = new QQmlInfoPrivate(MessageLevel); \ + d->object = me; \ + return QQmlInfo(d); \ + } \ + QQmlInfo FuncName(const QObject *me, const QQmlError &error) \ + { \ + QQmlInfoPrivate *d = new QQmlInfoPrivate(MessageLevel); \ + d->object = me; \ + d->errors << error; \ + return QQmlInfo(d); \ + } \ + QQmlInfo FuncName(const QObject *me, const QList<QQmlError> &errors) \ + { \ + QQmlInfoPrivate *d = new QQmlInfoPrivate(MessageLevel); \ + d->object = me; \ + d->errors = errors; \ + return QQmlInfo(d); \ + } -QQmlInfo qmlInfo(const QObject *me, const QQmlError &error) -{ - QQmlInfoPrivate *d = new QQmlInfoPrivate; - d->object = me; - d->errors << error; - return QQmlInfo(d); -} +MESSAGE_FUNCS(qmlDebug, QtMsgType::QtDebugMsg) +MESSAGE_FUNCS(qmlInfo, QtMsgType::QtInfoMsg) +MESSAGE_FUNCS(qmlWarning, QtMsgType::QtWarningMsg) -QQmlInfo qmlInfo(const QObject *me, const QList<QQmlError> &errors) -{ - QQmlInfoPrivate *d = new QQmlInfoPrivate; - d->object = me; - d->errors = errors; - return QQmlInfo(d); -} } // namespace QtQml diff --git a/src/qml/qml/qqmlinfo.h b/src/qml/qml/qqmlinfo.h index ab0281a688..673125632e 100644 --- a/src/qml/qml/qqmlinfo.h +++ b/src/qml/qml/qqmlinfo.h @@ -48,11 +48,19 @@ QT_BEGIN_NAMESPACE class QQmlInfo; +// declared in namespace to avoid symbol conflicts with QtDeclarative namespace QtQml { - // declared in namespace to avoid symbol conflicts with QtDeclarative + Q_QML_EXPORT QQmlInfo qmlDebug(const QObject *me); + Q_QML_EXPORT QQmlInfo qmlDebug(const QObject *me, const QQmlError &error); + Q_QML_EXPORT QQmlInfo qmlDebug(const QObject *me, const QList<QQmlError> &errors); + Q_QML_EXPORT QQmlInfo qmlInfo(const QObject *me); Q_QML_EXPORT QQmlInfo qmlInfo(const QObject *me, const QQmlError &error); Q_QML_EXPORT QQmlInfo qmlInfo(const QObject *me, const QList<QQmlError> &errors); + + Q_QML_EXPORT QQmlInfo qmlWarning(const QObject *me); + Q_QML_EXPORT QQmlInfo qmlWarning(const QObject *me, const QQmlError &error); + Q_QML_EXPORT QQmlInfo qmlWarning(const QObject *me, const QList<QQmlError> &errors); } QT_WARNING_PUSH QT_WARNING_DISABLE_CLANG("-Wheader-hygiene") @@ -93,9 +101,15 @@ public: #endif private: + friend Q_QML_EXPORT QQmlInfo QtQml::qmlDebug(const QObject *me); + friend Q_QML_EXPORT QQmlInfo QtQml::qmlDebug(const QObject *me, const QQmlError &error); + friend Q_QML_EXPORT QQmlInfo QtQml::qmlDebug(const QObject *me, const QList<QQmlError> &errors); friend Q_QML_EXPORT QQmlInfo QtQml::qmlInfo(const QObject *me); friend Q_QML_EXPORT QQmlInfo QtQml::qmlInfo(const QObject *me, const QQmlError &error); friend Q_QML_EXPORT QQmlInfo QtQml::qmlInfo(const QObject *me, const QList<QQmlError> &errors); + friend Q_QML_EXPORT QQmlInfo QtQml::qmlWarning(const QObject *me); + friend Q_QML_EXPORT QQmlInfo QtQml::qmlWarning(const QObject *me, const QQmlError &error); + friend Q_QML_EXPORT QQmlInfo QtQml::qmlWarning(const QObject *me, const QList<QQmlError> &errors); QQmlInfo(QQmlInfoPrivate *); QQmlInfoPrivate *d; diff --git a/src/qml/qml/qqmllist.cpp b/src/qml/qml/qqmllist.cpp index a719956483..edd93ef03d 100644 --- a/src/qml/qml/qqmllist.cpp +++ b/src/qml/qml/qqmllist.cpp @@ -335,7 +335,7 @@ int QQmlListReference::count() const \since 5.0 \inmodule QtQml \brief The QQmlListProperty class allows applications to expose list-like -properties to QML. +properties of QObject-derived classes to QML. QML has many list properties, where more than one object value can be assigned. The use of a list property from QML looks like this: @@ -369,7 +369,8 @@ QML list properties are type-safe - in this case \c {Fruit} is a QObject type th The \l {Qt Quick 1} version of this class is named QDeclarativeListProperty. -\note QQmlListProperty can only be used for lists of QObject-derived object pointers. +\sa {Extending QML - Object and List Property Types Example} + */ /*! diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp index 3876e774c3..712da78807 100644 --- a/src/qml/qml/qqmllocale.cpp +++ b/src/qml/qml/qqmllocale.cpp @@ -56,10 +56,17 @@ using namespace QV4; DEFINE_OBJECT_VTABLE(QQmlLocaleData); +#define THROW_ERROR(string) \ + do { \ + scope.result = scope.engine->throwError(QString::fromUtf8(string)); \ + return; \ + } while (false) + + #define GET_LOCALE_DATA_RESOURCE(OBJECT) \ QV4::Scoped<QQmlLocaleData> r(scope, OBJECT.as<QQmlLocaleData>()); \ if (!r) \ - V4THROW_ERROR("Not a valid Locale object") + THROW_ERROR("Not a valid Locale object") static bool isLocaleObject(const QV4::Value &val) { @@ -80,215 +87,219 @@ void QQmlDateExtension::registerExtension(QV4::ExecutionEngine *engine) engine->dateCtor()->defineDefaultProperty(QStringLiteral("timeZoneUpdated"), method_timeZoneUpdated); } -QV4::ReturnedValue QQmlDateExtension::method_toLocaleString(QV4::CallContext *ctx) +void QQmlDateExtension::method_toLocaleString(const BuiltinFunction *b, Scope &scope, CallData *callData) { - if (ctx->argc() > 2) - return QV4::DatePrototype::method_toLocaleString(ctx); - - QV4::Scope scope(ctx); + if (callData->argc > 2) { + QV4::DatePrototype::method_toLocaleString(b, scope, callData); + return; + } - QV4::DateObject *date = ctx->thisObject().as<DateObject>(); - if (!date) - return QV4::DatePrototype::method_toLocaleString(ctx); + QV4::DateObject *date = callData->thisObject.as<DateObject>(); + if (!date) { + QV4::DatePrototype::method_toLocaleString(b, scope, callData); + return; + } QDateTime dt = date->toQDateTime(); - if (ctx->argc() == 0) { + if (callData->argc == 0) { // Use QLocale for standard toLocaleString() function QLocale locale; - return ctx->d()->engine->newString(locale.toString(dt))->asReturnedValue(); + RETURN_RESULT(scope.engine->newString(locale.toString(dt))); } - if (!isLocaleObject(ctx->args()[0])) - return QV4::DatePrototype::method_toLocaleString(ctx); // Use the default Date toLocaleString() + if (!isLocaleObject(callData->args[0])) { + QV4::DatePrototype::method_toLocaleString(b, scope, callData); // Use the default Date toLocaleString() + return; + } - GET_LOCALE_DATA_RESOURCE(ctx->args()[0]); + GET_LOCALE_DATA_RESOURCE(callData->args[0]); QLocale::FormatType enumFormat = QLocale::LongFormat; QString formattedDt; - if (ctx->argc() == 2) { - if (String *s = ctx->args()[1].stringValue()) { + if (callData->argc == 2) { + if (String *s = callData->args[1].stringValue()) { QString format = s->toQString(); formattedDt = r->d()->locale->toString(dt, format); - } else if (ctx->args()[1].isNumber()) { - quint32 intFormat = ctx->args()[1].toNumber(); + } else if (callData->args[1].isNumber()) { + quint32 intFormat = callData->args[1].toNumber(); QLocale::FormatType format = QLocale::FormatType(intFormat); formattedDt = r->d()->locale->toString(dt, format); } else { - V4THROW_ERROR("Locale: Date.toLocaleString(): Invalid datetime format"); + THROW_ERROR("Locale: Date.toLocaleString(): Invalid datetime format"); } } else { formattedDt = r->d()->locale->toString(dt, enumFormat); } - return ctx->d()->engine->newString(formattedDt)->asReturnedValue(); + scope.result = scope.engine->newString(formattedDt); } -QV4::ReturnedValue QQmlDateExtension::method_toLocaleTimeString(QV4::CallContext *ctx) +void QQmlDateExtension::method_toLocaleTimeString(const BuiltinFunction *b, Scope &scope, CallData *callData) { - if (ctx->argc() > 2) - return QV4::DatePrototype::method_toLocaleTimeString(ctx); - - QV4::Scope scope(ctx); + if (callData->argc > 2) { + QV4::DatePrototype::method_toLocaleTimeString(b, scope, callData); + return; + } - QV4::DateObject *date = ctx->thisObject().as<DateObject>(); - if (!date) - return QV4::DatePrototype::method_toLocaleTimeString(ctx); + QV4::DateObject *date = callData->thisObject.as<DateObject>(); + if (!date) { + QV4::DatePrototype::method_toLocaleTimeString(b, scope, callData); + return; + } QDateTime dt = date->toQDateTime(); QTime time = dt.time(); - if (ctx->argc() == 0) { + if (callData->argc == 0) { // Use QLocale for standard toLocaleString() function QLocale locale; - return ctx->d()->engine->newString(locale.toString(time))->asReturnedValue(); + RETURN_RESULT(scope.engine->newString(locale.toString(time))); } - if (!isLocaleObject(ctx->args()[0])) - return QV4::DatePrototype::method_toLocaleTimeString(ctx); // Use the default Date toLocaleTimeString() + if (!isLocaleObject(callData->args[0])) + return QV4::DatePrototype::method_toLocaleTimeString(b, scope, callData); // Use the default Date toLocaleTimeString() - GET_LOCALE_DATA_RESOURCE(ctx->args()[0]); + GET_LOCALE_DATA_RESOURCE(callData->args[0]); QLocale::FormatType enumFormat = QLocale::LongFormat; QString formattedTime; - if (ctx->argc() == 2) { - if (String *s = ctx->args()[1].stringValue()) { + if (callData->argc == 2) { + if (String *s = callData->args[1].stringValue()) { QString format = s->toQString(); formattedTime = r->d()->locale->toString(time, format); - } else if (ctx->args()[1].isNumber()) { - quint32 intFormat = ctx->args()[1].toNumber(); + } else if (callData->args[1].isNumber()) { + quint32 intFormat = callData->args[1].toNumber(); QLocale::FormatType format = QLocale::FormatType(intFormat); formattedTime = r->d()->locale->toString(time, format); } else { - V4THROW_ERROR("Locale: Date.toLocaleTimeString(): Invalid time format"); + THROW_ERROR("Locale: Date.toLocaleTimeString(): Invalid time format"); } } else { formattedTime = r->d()->locale->toString(time, enumFormat); } - return ctx->d()->engine->newString(formattedTime)->asReturnedValue(); + scope.result = scope.engine->newString(formattedTime); } -QV4::ReturnedValue QQmlDateExtension::method_toLocaleDateString(QV4::CallContext *ctx) +void QQmlDateExtension::method_toLocaleDateString(const BuiltinFunction *b, Scope &scope, CallData *callData) { - if (ctx->argc() > 2) - return QV4::DatePrototype::method_toLocaleDateString(ctx); - - QV4::Scope scope(ctx); + if (callData->argc > 2) { + QV4::DatePrototype::method_toLocaleDateString(b, scope, callData); + return; + } - QV4::DateObject *dateObj = ctx->thisObject().as<DateObject>(); - if (!dateObj) - return QV4::DatePrototype::method_toLocaleDateString(ctx); + QV4::DateObject *dateObj = callData->thisObject.as<DateObject>(); + if (!dateObj) { + QV4::DatePrototype::method_toLocaleDateString(b, scope, callData); + return; + } QDateTime dt = dateObj->toQDateTime(); QDate date = dt.date(); - if (ctx->argc() == 0) { + if (callData->argc == 0) { // Use QLocale for standard toLocaleString() function QLocale locale; - return ctx->d()->engine->newString(locale.toString(date))->asReturnedValue(); + RETURN_RESULT(scope.engine->newString(locale.toString(date))); } - if (!isLocaleObject(ctx->args()[0])) - return QV4::DatePrototype::method_toLocaleDateString(ctx); // Use the default Date toLocaleDateString() + if (!isLocaleObject(callData->args[0])) + return QV4::DatePrototype::method_toLocaleDateString(b, scope, callData); // Use the default Date toLocaleDateString() - GET_LOCALE_DATA_RESOURCE(ctx->args()[0]); + GET_LOCALE_DATA_RESOURCE(callData->args[0]); QLocale::FormatType enumFormat = QLocale::LongFormat; QString formattedDate; - if (ctx->argc() == 2) { - if (String *s = ctx->args()[1].stringValue()) { + if (callData->argc == 2) { + if (String *s = callData->args[1].stringValue()) { QString format = s->toQString(); formattedDate = r->d()->locale->toString(date, format); - } else if (ctx->args()[1].isNumber()) { - quint32 intFormat = ctx->args()[1].toNumber(); + } else if (callData->args[1].isNumber()) { + quint32 intFormat = callData->args[1].toNumber(); QLocale::FormatType format = QLocale::FormatType(intFormat); formattedDate = r->d()->locale->toString(date, format); } else { - V4THROW_ERROR("Locale: Date.loLocaleDateString(): Invalid date format"); + THROW_ERROR("Locale: Date.loLocaleDateString(): Invalid date format"); } } else { formattedDate = r->d()->locale->toString(date, enumFormat); } - return ctx->d()->engine->newString(formattedDate)->asReturnedValue(); + scope.result = scope.engine->newString(formattedDate); } -QV4::ReturnedValue QQmlDateExtension::method_fromLocaleString(QV4::CallContext *ctx) +void QQmlDateExtension::method_fromLocaleString(const BuiltinFunction *, Scope &scope, CallData *callData) { - QV4::ExecutionEngine * const engine = ctx->d()->engine; - if (ctx->argc() == 1) { - if (String *s = ctx->args()[0].stringValue()) { + QV4::ExecutionEngine * const engine = scope.engine; + if (callData->argc == 1) { + if (String *s = callData->args[0].stringValue()) { QLocale locale; QString dateString = s->toQString(); QDateTime dt = locale.toDateTime(dateString); - return QV4::Encode(engine->newDateObject(dt)); + RETURN_RESULT(engine->newDateObject(dt)); } } - QV4::Scope scope(ctx); - - if (ctx->argc() < 1 || ctx->argc() > 3 || !isLocaleObject(ctx->args()[0])) - V4THROW_ERROR("Locale: Date.fromLocaleString(): Invalid arguments"); + if (callData->argc < 1 || callData->argc > 3 || !isLocaleObject(callData->args[0])) + THROW_ERROR("Locale: Date.fromLocaleString(): Invalid arguments"); - GET_LOCALE_DATA_RESOURCE(ctx->args()[0]); + GET_LOCALE_DATA_RESOURCE(callData->args[0]); QLocale::FormatType enumFormat = QLocale::LongFormat; QDateTime dt; - QString dateString = ctx->args()[1].toQStringNoThrow(); - if (ctx->argc() == 3) { - if (String *s = ctx->args()[2].stringValue()) { + QString dateString = callData->args[1].toQStringNoThrow(); + if (callData->argc == 3) { + if (String *s = callData->args[2].stringValue()) { QString format = s->toQString(); dt = r->d()->locale->toDateTime(dateString, format); - } else if (ctx->args()[2].isNumber()) { - quint32 intFormat = ctx->args()[2].toNumber(); + } else if (callData->args[2].isNumber()) { + quint32 intFormat = callData->args[2].toNumber(); QLocale::FormatType format = QLocale::FormatType(intFormat); dt = r->d()->locale->toDateTime(dateString, format); } else { - V4THROW_ERROR("Locale: Date.fromLocaleString(): Invalid datetime format"); + THROW_ERROR("Locale: Date.fromLocaleString(): Invalid datetime format"); } } else { dt = r->d()->locale->toDateTime(dateString, enumFormat); } - return QV4::Encode(engine->newDateObject(dt)); + scope.result = engine->newDateObject(dt); } -QV4::ReturnedValue QQmlDateExtension::method_fromLocaleTimeString(QV4::CallContext *ctx) +void QQmlDateExtension::method_fromLocaleTimeString(const BuiltinFunction *, Scope &scope, CallData *callData) { - QV4::ExecutionEngine * const engine = ctx->d()->engine; + QV4::ExecutionEngine * const engine = scope.engine; - if (ctx->argc() == 1) { - if (String *s = ctx->args()[0].stringValue()) { + if (callData->argc == 1) { + if (String *s = callData->args[0].stringValue()) { QLocale locale; QString timeString = s->toQString(); QTime time = locale.toTime(timeString); QDateTime dt = QDateTime::currentDateTime(); dt.setTime(time); - return QV4::Encode(engine->newDateObject(dt)); + RETURN_RESULT(engine->newDateObject(dt)); } } - if (ctx->argc() < 1 || ctx->argc() > 3 || !isLocaleObject(ctx->args()[0])) - V4THROW_ERROR("Locale: Date.fromLocaleTimeString(): Invalid arguments"); - - QV4::Scope scope(ctx); + if (callData->argc < 1 || callData->argc > 3 || !isLocaleObject(callData->args[0])) + THROW_ERROR("Locale: Date.fromLocaleTimeString(): Invalid arguments"); - GET_LOCALE_DATA_RESOURCE(ctx->args()[0]); + GET_LOCALE_DATA_RESOURCE(callData->args[0]); QLocale::FormatType enumFormat = QLocale::LongFormat; QTime tm; - QString dateString = ctx->args()[1].toQStringNoThrow(); - if (ctx->argc() == 3) { - if (String *s = ctx->args()[2].stringValue()) { + QString dateString = callData->args[1].toQStringNoThrow(); + if (callData->argc == 3) { + if (String *s = callData->args[2].stringValue()) { QString format = s->toQString(); tm = r->d()->locale->toTime(dateString, format); - } else if (ctx->args()[2].isNumber()) { - quint32 intFormat = ctx->args()[2].toNumber(); + } else if (callData->args[2].isNumber()) { + quint32 intFormat = callData->args[2].toNumber(); QLocale::FormatType format = QLocale::FormatType(intFormat); tm = r->d()->locale->toTime(dateString, format); } else { - V4THROW_ERROR("Locale: Date.fromLocaleTimeString(): Invalid datetime format"); + THROW_ERROR("Locale: Date.fromLocaleTimeString(): Invalid datetime format"); } } else { tm = r->d()->locale->toTime(dateString, enumFormat); @@ -300,58 +311,56 @@ QV4::ReturnedValue QQmlDateExtension::method_fromLocaleTimeString(QV4::CallConte dt.setTime(tm); } - return QV4::Encode(engine->newDateObject(dt)); + RETURN_RESULT(engine->newDateObject(dt)); } -QV4::ReturnedValue QQmlDateExtension::method_fromLocaleDateString(QV4::CallContext *ctx) +void QQmlDateExtension::method_fromLocaleDateString(const BuiltinFunction *, Scope &scope, CallData *callData) { - QV4::ExecutionEngine * const engine = ctx->d()->engine; + QV4::ExecutionEngine * const engine = scope.engine; - if (ctx->argc() == 1) { - if (String *s = ctx->args()[0].stringValue()) { + if (callData->argc == 1) { + if (String *s = callData->args[0].stringValue()) { QLocale locale; QString dateString = s->toQString(); QDate date = locale.toDate(dateString); - return QV4::Encode(engine->newDateObject(QDateTime(date))); + RETURN_RESULT(engine->newDateObject(QDateTime(date))); } } - if (ctx->argc() < 1 || ctx->argc() > 3 || !isLocaleObject(ctx->args()[0])) - V4THROW_ERROR("Locale: Date.fromLocaleDateString(): Invalid arguments"); + if (callData->argc < 1 || callData->argc > 3 || !isLocaleObject(callData->args[0])) + THROW_ERROR("Locale: Date.fromLocaleDateString(): Invalid arguments"); - QV4::Scope scope(ctx); - - GET_LOCALE_DATA_RESOURCE(ctx->args()[0]); + GET_LOCALE_DATA_RESOURCE(callData->args[0]); QLocale::FormatType enumFormat = QLocale::LongFormat; QDate dt; - QString dateString = ctx->args()[1].toQStringNoThrow(); - if (ctx->argc() == 3) { - if (String *s = ctx->args()[2].stringValue()) { + QString dateString = callData->args[1].toQStringNoThrow(); + if (callData->argc == 3) { + if (String *s = callData->args[2].stringValue()) { QString format = s->toQString(); dt = r->d()->locale->toDate(dateString, format); - } else if (ctx->args()[2].isNumber()) { - quint32 intFormat = ctx->args()[2].toNumber(); + } else if (callData->args[2].isNumber()) { + quint32 intFormat = callData->args[2].toNumber(); QLocale::FormatType format = QLocale::FormatType(intFormat); dt = r->d()->locale->toDate(dateString, format); } else { - V4THROW_ERROR("Locale: Date.fromLocaleDateString(): Invalid datetime format"); + THROW_ERROR("Locale: Date.fromLocaleDateString(): Invalid datetime format"); } } else { dt = r->d()->locale->toDate(dateString, enumFormat); } - return QV4::Encode(engine->newDateObject(QDateTime(dt))); + RETURN_RESULT(engine->newDateObject(QDateTime(dt))); } -QV4::ReturnedValue QQmlDateExtension::method_timeZoneUpdated(QV4::CallContext *ctx) +void QQmlDateExtension::method_timeZoneUpdated(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (ctx->argc() != 0) - V4THROW_ERROR("Locale: Date.timeZoneUpdated(): Invalid arguments"); + if (callData->argc != 0) + THROW_ERROR("Locale: Date.timeZoneUpdated(): Invalid arguments"); QV4::DatePrototype::timezoneUpdated(); - return QV4::Encode::undefined(); + RETURN_UNDEFINED(); } //----------------- @@ -364,148 +373,143 @@ void QQmlNumberExtension::registerExtension(QV4::ExecutionEngine *engine) engine->numberCtor()->defineDefaultProperty(QStringLiteral("fromLocaleString"), method_fromLocaleString); } -QV4::ReturnedValue QQmlNumberExtension::method_toLocaleString(QV4::CallContext *ctx) +void QQmlNumberExtension::method_toLocaleString(const BuiltinFunction *b, Scope &scope, CallData *callData) { - if (ctx->argc() > 3) - V4THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments"); + if (callData->argc > 3) + THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments"); - double number = ctx->thisObject().toNumber(); + double number = callData->thisObject.toNumber(); - if (ctx->argc() == 0) { + if (callData->argc == 0) { // Use QLocale for standard toLocaleString() function QLocale locale; - return ctx->d()->engine->newString(locale.toString(number))->asReturnedValue(); + RETURN_RESULT(scope.engine->newString(locale.toString(number))); } - if (!isLocaleObject(ctx->args()[0])) - return QV4::NumberPrototype::method_toLocaleString(ctx); // Use the default Number toLocaleString() - - QV4::Scope scope(ctx); + if (!isLocaleObject(callData->args[0])) { + QV4::NumberPrototype::method_toLocaleString(b, scope, callData); // Use the default Number toLocaleString() + return; + } - GET_LOCALE_DATA_RESOURCE(ctx->args()[0]); + GET_LOCALE_DATA_RESOURCE(callData->args[0]); quint16 format = 'f'; - if (ctx->argc() > 1) { - if (!ctx->args()[1].isString()) - V4THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments"); - QString fs = ctx->args()[1].toQString(); + if (callData->argc > 1) { + if (!callData->args[1].isString()) + THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments"); + QString fs = callData->args[1].toQString(); if (fs.length()) format = fs.at(0).unicode(); } int prec = 2; - if (ctx->argc() > 2) { - if (!ctx->args()[2].isNumber()) - V4THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments"); - prec = ctx->args()[2].toInt32(); + if (callData->argc > 2) { + if (!callData->args[2].isNumber()) + THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments"); + prec = callData->args[2].toInt32(); } - return ctx->d()->engine->newString(r->d()->locale->toString(number, (char)format, prec))->asReturnedValue(); + scope.result = scope.engine->newString(r->d()->locale->toString(number, (char)format, prec)); } -QV4::ReturnedValue QQmlNumberExtension::method_toLocaleCurrencyString(QV4::CallContext *ctx) +void QQmlNumberExtension::method_toLocaleCurrencyString(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (ctx->argc() > 2) - V4THROW_ERROR("Locale: Number.toLocaleCurrencyString(): Invalid arguments"); + if (callData->argc > 2) + THROW_ERROR("Locale: Number.toLocaleCurrencyString(): Invalid arguments"); - double number = ctx->thisObject().toNumber(); + double number = callData->thisObject.toNumber(); - if (ctx->argc() == 0) { + if (callData->argc == 0) { // Use QLocale for standard toLocaleString() function QLocale locale; - return ctx->d()->engine->newString(locale.toString(number))->asReturnedValue(); + RETURN_RESULT(scope.engine->newString(locale.toString(number))); } - if (!isLocaleObject(ctx->args()[0])) - V4THROW_ERROR("Locale: Number.toLocaleCurrencyString(): Invalid arguments"); - - QV4::Scope scope(ctx); + if (!isLocaleObject(callData->args[0])) + THROW_ERROR("Locale: Number.toLocaleCurrencyString(): Invalid arguments"); - GET_LOCALE_DATA_RESOURCE(ctx->args()[0]); + GET_LOCALE_DATA_RESOURCE(callData->args[0]); QString symbol; - if (ctx->argc() > 1) { - if (!ctx->args()[1].isString()) - V4THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments"); - symbol = ctx->args()[1].toQStringNoThrow(); + if (callData->argc > 1) { + if (!callData->args[1].isString()) + THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments"); + symbol = callData->args[1].toQStringNoThrow(); } - return ctx->d()->engine->newString(r->d()->locale->toCurrencyString(number, symbol))->asReturnedValue(); + RETURN_RESULT(scope.engine->newString(r->d()->locale->toCurrencyString(number, symbol))); } -QV4::ReturnedValue QQmlNumberExtension::method_fromLocaleString(QV4::CallContext *ctx) +void QQmlNumberExtension::method_fromLocaleString(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (ctx->argc() < 1 || ctx->argc() > 2) - V4THROW_ERROR("Locale: Number.fromLocaleString(): Invalid arguments"); + if (callData->argc < 1 || callData->argc > 2) + THROW_ERROR("Locale: Number.fromLocaleString(): Invalid arguments"); int numberIdx = 0; QLocale locale; - QV4::Scope scope(ctx); - - if (ctx->argc() == 2) { - if (!isLocaleObject(ctx->args()[0])) - V4THROW_ERROR("Locale: Number.fromLocaleString(): Invalid arguments"); + if (callData->argc == 2) { + if (!isLocaleObject(callData->args[0])) + THROW_ERROR("Locale: Number.fromLocaleString(): Invalid arguments"); - GET_LOCALE_DATA_RESOURCE(ctx->args()[0]); + GET_LOCALE_DATA_RESOURCE(callData->args[0]); locale = *r->d()->locale; numberIdx = 1; } - QString ns = ctx->args()[numberIdx].toQString(); + QString ns = callData->args[numberIdx].toQString(); if (!ns.length()) - return QV4::Encode(Q_QNAN); + RETURN_RESULT(QV4::Encode(Q_QNAN)); bool ok = false; double val = locale.toDouble(ns, &ok); if (!ok) - V4THROW_ERROR("Locale: Number.fromLocaleString(): Invalid format") + THROW_ERROR("Locale: Number.fromLocaleString(): Invalid format"); - return QV4::Encode(val); + scope.result = QV4::Encode(val); } //-------------- // Locale object -QV4::ReturnedValue QQmlLocaleData::method_get_firstDayOfWeek(QV4::CallContext *ctx) +void QQmlLocaleData::method_get_firstDayOfWeek(const BuiltinFunction *, Scope &scope, CallData *callData) { - QLocale *locale = getThisLocale(ctx); + QLocale *locale = getThisLocale(scope, callData); if (!locale) - return QV4::Encode::undefined(); + return; int fdow = int(locale->firstDayOfWeek()); if (fdow == 7) fdow = 0; // Qt::Sunday = 7, but Sunday is 0 in JS Date - return QV4::Encode(fdow); + scope.result = QV4::Encode(fdow); } -QV4::ReturnedValue QQmlLocaleData::method_get_measurementSystem(QV4::CallContext *ctx) +void QQmlLocaleData::method_get_measurementSystem(const BuiltinFunction *, Scope &scope, CallData *callData) { - QLocale *locale = getThisLocale(ctx); + QLocale *locale = getThisLocale(scope, callData); if (!locale) - return QV4::Encode::undefined(); - return QV4::Encode(locale->measurementSystem()); + return; + scope.result = QV4::Encode(locale->measurementSystem()); } -QV4::ReturnedValue QQmlLocaleData::method_get_textDirection(QV4::CallContext *ctx) +void QQmlLocaleData::method_get_textDirection(const BuiltinFunction *, Scope &scope, CallData *callData) { - QLocale *locale = getThisLocale(ctx); + QLocale *locale = getThisLocale(scope, callData); if (!locale) - return QV4::Encode::undefined(); + return; - return QV4::Encode(locale->textDirection()); + scope.result = QV4::Encode(locale->textDirection()); } -QV4::ReturnedValue QQmlLocaleData::method_get_weekDays(QV4::CallContext *ctx) +void QQmlLocaleData::method_get_weekDays(const BuiltinFunction *, Scope &scope, CallData *callData) { - QV4::Scope scope(ctx); - QLocale *locale = getThisLocale(ctx); + QLocale *locale = getThisLocale(scope, callData); if (!locale) - return QV4::Encode::undefined(); + return; QList<Qt::DayOfWeek> days = locale->weekdays(); - QV4::ScopedArrayObject result(scope, ctx->d()->engine->newArrayObject()); + QV4::ScopedArrayObject result(scope, scope.engine->newArrayObject()); result->arrayReserve(days.size()); for (int i = 0; i < days.size(); ++i) { int day = days.at(i); @@ -515,59 +519,58 @@ QV4::ReturnedValue QQmlLocaleData::method_get_weekDays(QV4::CallContext *ctx) } result->setArrayLengthUnchecked(days.size()); - return result.asReturnedValue(); + scope.result = result.asReturnedValue(); } -QV4::ReturnedValue QQmlLocaleData::method_get_uiLanguages(QV4::CallContext *ctx) +void QQmlLocaleData::method_get_uiLanguages(const BuiltinFunction *, Scope &scope, CallData *callData) { - QV4::Scope scope(ctx); - QLocale *locale = getThisLocale(ctx); + QLocale *locale = getThisLocale(scope, callData); if (!locale) - return QV4::Encode::undefined(); + return; QStringList langs = locale->uiLanguages(); - QV4::ScopedArrayObject result(scope, ctx->d()->engine->newArrayObject()); + QV4::ScopedArrayObject result(scope, scope.engine->newArrayObject()); result->arrayReserve(langs.size()); QV4::ScopedValue v(scope); for (int i = 0; i < langs.size(); ++i) - result->arrayPut(i, (v = ctx->d()->engine->newString(langs.at(i)))); + result->arrayPut(i, (v = scope.engine->newString(langs.at(i)))); result->setArrayLengthUnchecked(langs.size()); - return result.asReturnedValue(); + scope.result = result.asReturnedValue(); } -QV4::ReturnedValue QQmlLocaleData::method_currencySymbol(QV4::CallContext *ctx) +void QQmlLocaleData::method_currencySymbol(const BuiltinFunction *, Scope &scope, CallData *callData) { - QLocale *locale = getThisLocale(ctx); + QLocale *locale = getThisLocale(scope, callData); if (!locale) - return QV4::Encode::undefined(); + return; - if (ctx->argc() > 1) - V4THROW_ERROR("Locale: currencySymbol(): Invalid arguments"); + if (callData->argc > 1) + THROW_ERROR("Locale: currencySymbol(): Invalid arguments"); QLocale::CurrencySymbolFormat format = QLocale::CurrencySymbol; - if (ctx->argc() == 1) { - quint32 intFormat = ctx->args()[0].toNumber(); + if (callData->argc == 1) { + quint32 intFormat = callData->args[0].toNumber(); format = QLocale::CurrencySymbolFormat(intFormat); } - return ctx->d()->engine->newString(locale->currencySymbol(format))->asReturnedValue(); + scope.result = scope.engine->newString(locale->currencySymbol(format)); } #define LOCALE_FORMAT(FUNC) \ -QV4::ReturnedValue QQmlLocaleData::method_ ##FUNC (QV4::CallContext *ctx) { \ - QLocale *locale = getThisLocale(ctx); \ +void QQmlLocaleData::method_ ##FUNC (const BuiltinFunction *, Scope &scope, CallData *callData) { \ + QLocale *locale = getThisLocale(scope, callData); \ if (!locale) \ - return QV4::Encode::undefined(); \ - if (ctx->argc() > 1) \ - V4THROW_ERROR("Locale: " #FUNC "(): Invalid arguments"); \ + return; \ + if (callData->argc > 1) \ + THROW_ERROR("Locale: " #FUNC "(): Invalid arguments"); \ QLocale::FormatType format = QLocale::LongFormat;\ - if (ctx->argc() == 1) { \ - quint32 intFormat = ctx->args()[0].toUInt32(); \ + if (callData->argc == 1) { \ + quint32 intFormat = callData->args[0].toUInt32(); \ format = QLocale::FormatType(intFormat); \ } \ - return ctx->engine()->newString(locale-> FUNC (format))->asReturnedValue(); \ + scope.result = scope.engine->newString(locale-> FUNC (format)); \ } LOCALE_FORMAT(dateTimeFormat) @@ -576,57 +579,57 @@ LOCALE_FORMAT(dateFormat) // +1 added to idx because JS is 0-based, whereas QLocale months begin at 1. #define LOCALE_FORMATTED_MONTHNAME(VARIABLE) \ -QV4::ReturnedValue QQmlLocaleData::method_ ## VARIABLE (QV4::CallContext *ctx) {\ - QLocale *locale = getThisLocale(ctx); \ +void QQmlLocaleData::method_ ## VARIABLE (const BuiltinFunction *, Scope &scope, CallData *callData) {\ + QLocale *locale = getThisLocale(scope, callData); \ if (!locale) \ - return QV4::Encode::undefined(); \ - if (ctx->argc() < 1 || ctx->argc() > 2) \ - V4THROW_ERROR("Locale: " #VARIABLE "(): Invalid arguments"); \ + return; \ + if (callData->argc < 1 || callData->argc > 2) \ + THROW_ERROR("Locale: " #VARIABLE "(): Invalid arguments"); \ QLocale::FormatType enumFormat = QLocale::LongFormat; \ - int idx = ctx->args()[0].toInt32() + 1; \ + int idx = callData->args[0].toInt32() + 1; \ if (idx < 1 || idx > 12) \ - V4THROW_ERROR("Locale: Invalid month"); \ + THROW_ERROR("Locale: Invalid month"); \ QString name; \ - if (ctx->argc() == 2) { \ - if (ctx->args()[1].isNumber()) { \ - quint32 intFormat = ctx->args()[1].toUInt32(); \ + if (callData->argc == 2) { \ + if (callData->args[1].isNumber()) { \ + quint32 intFormat = callData->args[1].toUInt32(); \ QLocale::FormatType format = QLocale::FormatType(intFormat); \ name = locale-> VARIABLE(idx, format); \ } else { \ - V4THROW_ERROR("Locale: Invalid datetime format"); \ + THROW_ERROR("Locale: Invalid datetime format"); \ } \ } else { \ name = locale-> VARIABLE(idx, enumFormat); \ } \ - return ctx->engine()->newString(name)->asReturnedValue(); \ + scope.result = scope.engine->newString(name); \ } // 0 -> 7 as Qt::Sunday is 7, but Sunday is 0 in JS Date #define LOCALE_FORMATTED_DAYNAME(VARIABLE) \ -QV4::ReturnedValue QQmlLocaleData::method_ ## VARIABLE (QV4::CallContext *ctx) {\ - QLocale *locale = getThisLocale(ctx); \ +void QQmlLocaleData::method_ ## VARIABLE (const BuiltinFunction *, Scope &scope, CallData *callData) {\ + QLocale *locale = getThisLocale(scope, callData); \ if (!locale) \ - return QV4::Encode::undefined(); \ - if (ctx->argc() < 1 || ctx->argc() > 2) \ - V4THROW_ERROR("Locale: " #VARIABLE "(): Invalid arguments"); \ + return; \ + if (callData->argc < 1 || callData->argc > 2) \ + THROW_ERROR("Locale: " #VARIABLE "(): Invalid arguments"); \ QLocale::FormatType enumFormat = QLocale::LongFormat; \ - int idx = ctx->args()[0].toInt32(); \ + int idx = callData->args[0].toInt32(); \ if (idx < 0 || idx > 7) \ - V4THROW_ERROR("Locale: Invalid day"); \ + THROW_ERROR("Locale: Invalid day"); \ if (idx == 0) idx = 7; \ QString name; \ - if (ctx->argc() == 2) { \ - if (ctx->args()[1].isNumber()) { \ - quint32 intFormat = ctx->args()[1].toUInt32(); \ + if (callData->argc == 2) { \ + if (callData->args[1].isNumber()) { \ + quint32 intFormat = callData->args[1].toUInt32(); \ QLocale::FormatType format = QLocale::FormatType(intFormat); \ name = locale-> VARIABLE(idx, format); \ } else { \ - V4THROW_ERROR("Locale: Invalid datetime format"); \ + THROW_ERROR("Locale: Invalid datetime format"); \ } \ } else { \ name = locale-> VARIABLE(idx, enumFormat); \ } \ - return ctx->engine()->newString(name)->asReturnedValue(); \ + scope.result = scope.engine->newString(name); \ } LOCALE_FORMATTED_MONTHNAME(monthName) @@ -634,12 +637,12 @@ LOCALE_FORMATTED_MONTHNAME(standaloneMonthName) LOCALE_FORMATTED_DAYNAME(dayName) LOCALE_FORMATTED_DAYNAME(standaloneDayName) -#define LOCALE_STRING_PROPERTY(VARIABLE) QV4::ReturnedValue QQmlLocaleData::method_get_ ## VARIABLE (QV4::CallContext* ctx) \ +#define LOCALE_STRING_PROPERTY(VARIABLE) void QQmlLocaleData::method_get_ ## VARIABLE (const BuiltinFunction *, Scope &scope, CallData *callData) \ { \ - QLocale *locale = getThisLocale(ctx); \ + QLocale *locale = getThisLocale(scope, callData); \ if (!locale) \ - return QV4::Encode::undefined(); \ - return ctx->engine()->newString(locale-> VARIABLE())->asReturnedValue();\ + return; \ + scope.result = scope.engine->newString(locale-> VARIABLE());\ } LOCALE_STRING_PROPERTY(name) @@ -830,18 +833,22 @@ void QQmlLocale::registerStringLocaleCompare(QV4::ExecutionEngine *engine) engine->stringPrototype()->defineDefaultProperty(QStringLiteral("localeCompare"), method_localeCompare); } -QV4::ReturnedValue QQmlLocale::method_localeCompare(QV4::CallContext *ctx) +void QQmlLocale::method_localeCompare(const BuiltinFunction *b, Scope &scope, CallData *callData) { - if (ctx->argc() != 1 || (!ctx->args()[0].isString() && !ctx->args()[0].as<StringObject>())) - return QV4::StringPrototype::method_localeCompare(ctx); + if (callData->argc != 1 || (!callData->args[0].isString() && !callData->args[0].as<StringObject>())) { + QV4::StringPrototype::method_localeCompare(b, scope, callData); + return; + } - if (!ctx->thisObject().isString() && !ctx->thisObject().as<StringObject>()) - return QV4::StringPrototype::method_localeCompare(ctx); + if (!callData->thisObject.isString() && !callData->thisObject.as<StringObject>()) { + QV4::StringPrototype::method_localeCompare(b, scope, callData); + return; + } - QString thisString = ctx->thisObject().toQStringNoThrow(); - QString thatString = ctx->args()[0].toQStringNoThrow(); + QString thisString = callData->thisObject.toQStringNoThrow(); + QString thatString = callData->args[0].toQStringNoThrow(); - return QV4::Encode(QString::localeAwareCompare(thisString, thatString)); + scope.result = QV4::Encode(QString::localeAwareCompare(thisString, thatString)); } /*! diff --git a/src/qml/qml/qqmllocale_p.h b/src/qml/qml/qqmllocale_p.h index 275f58db7d..1a2ffc72b0 100644 --- a/src/qml/qml/qqmllocale_p.h +++ b/src/qml/qml/qqmllocale_p.h @@ -67,13 +67,13 @@ public: static void registerExtension(QV4::ExecutionEngine *engine); private: - static QV4::ReturnedValue method_toLocaleString(QV4::CallContext *ctx); - static QV4::ReturnedValue method_toLocaleTimeString(QV4::CallContext *ctx); - static QV4::ReturnedValue method_toLocaleDateString(QV4::CallContext *ctx); - static QV4::ReturnedValue method_fromLocaleString(QV4::CallContext *ctx); - static QV4::ReturnedValue method_fromLocaleTimeString(QV4::CallContext *ctx); - static QV4::ReturnedValue method_fromLocaleDateString(QV4::CallContext *ctx); - static QV4::ReturnedValue method_timeZoneUpdated(QV4::CallContext *ctx); + static void method_toLocaleString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_toLocaleTimeString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_toLocaleDateString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_fromLocaleString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_fromLocaleTimeString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_fromLocaleDateString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_timeZoneUpdated(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); }; @@ -83,9 +83,9 @@ public: static void registerExtension(QV4::ExecutionEngine *engine); private: - static QV4::ReturnedValue method_toLocaleString(QV4::CallContext *ctx); - static QV4::ReturnedValue method_fromLocaleString(QV4::CallContext *ctx); - static QV4::ReturnedValue method_toLocaleCurrencyString(QV4::CallContext *ctx); + static void method_toLocaleString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_fromLocaleString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_toLocaleCurrencyString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); }; @@ -135,7 +135,7 @@ public: private: QQmlLocale(); - static QV4::ReturnedValue method_localeCompare(QV4::CallContext *ctx); + static void method_localeCompare(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); }; namespace QV4 { @@ -158,43 +158,43 @@ struct QQmlLocaleData : public QV4::Object V4_OBJECT2(QQmlLocaleData, Object) V4_NEEDS_DESTROY - static QLocale *getThisLocale(QV4::CallContext *ctx) { - QV4::Object *o = ctx->thisObject().as<Object>(); + static QLocale *getThisLocale(QV4::Scope &scope, QV4::CallData *callData) { + QV4::Object *o = callData->thisObject.as<Object>(); QQmlLocaleData *thisObject = o ? o->as<QQmlLocaleData>() : 0; if (!thisObject) { - ctx->engine()->throwTypeError(); + scope.engine->throwTypeError(); return 0; } return thisObject->d()->locale; } - static QV4::ReturnedValue method_currencySymbol(QV4::CallContext *ctx); - static QV4::ReturnedValue method_dateTimeFormat(QV4::CallContext *ctx); - static QV4::ReturnedValue method_timeFormat(QV4::CallContext *ctx); - static QV4::ReturnedValue method_dateFormat(QV4::CallContext *ctx); - static QV4::ReturnedValue method_monthName(QV4::CallContext *ctx); - static QV4::ReturnedValue method_standaloneMonthName(QV4::CallContext *ctx); - static QV4::ReturnedValue method_dayName(QV4::CallContext *ctx); - static QV4::ReturnedValue method_standaloneDayName(QV4::CallContext *ctx); - - static QV4::ReturnedValue method_get_firstDayOfWeek(QV4::CallContext *ctx); - static QV4::ReturnedValue method_get_measurementSystem(QV4::CallContext *ctx); - static QV4::ReturnedValue method_get_textDirection(QV4::CallContext *ctx); - static QV4::ReturnedValue method_get_weekDays(QV4::CallContext *ctx); - static QV4::ReturnedValue method_get_uiLanguages(QV4::CallContext *ctx); - - static QV4::ReturnedValue method_get_name(QV4::CallContext *ctx); - static QV4::ReturnedValue method_get_nativeLanguageName(QV4::CallContext *ctx); - static QV4::ReturnedValue method_get_nativeCountryName(QV4::CallContext *ctx); - static QV4::ReturnedValue method_get_decimalPoint(QV4::CallContext *ctx); - static QV4::ReturnedValue method_get_groupSeparator(QV4::CallContext *ctx); - static QV4::ReturnedValue method_get_percent(QV4::CallContext *ctx); - static QV4::ReturnedValue method_get_zeroDigit(QV4::CallContext *ctx); - static QV4::ReturnedValue method_get_negativeSign(QV4::CallContext *ctx); - static QV4::ReturnedValue method_get_positiveSign(QV4::CallContext *ctx); - static QV4::ReturnedValue method_get_exponential(QV4::CallContext *ctx); - static QV4::ReturnedValue method_get_amText(QV4::CallContext *ctx); - static QV4::ReturnedValue method_get_pmText(QV4::CallContext *ctx); + static void method_currencySymbol(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_dateTimeFormat(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_timeFormat(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_dateFormat(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_monthName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_standaloneMonthName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_dayName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_standaloneDayName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + + static void method_get_firstDayOfWeek(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_get_measurementSystem(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_get_textDirection(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_get_weekDays(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_get_uiLanguages(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + + static void method_get_name(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_get_nativeLanguageName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_get_nativeCountryName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_get_decimalPoint(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_get_groupSeparator(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_get_percent(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_get_zeroDigit(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_get_negativeSign(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_get_positiveSign(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_get_exponential(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_get_amText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_get_pmText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); }; } diff --git a/src/qml/qml/qqmlloggingcategory.cpp b/src/qml/qml/qqmlloggingcategory.cpp index 70e59db07b..764b874131 100644 --- a/src/qml/qml/qqmlloggingcategory.cpp +++ b/src/qml/qml/qqmlloggingcategory.cpp @@ -112,13 +112,13 @@ void QQmlLoggingCategory::componentComplete() { m_initialized = true; if (m_name.isNull()) - qmlInfo(this) << QLatin1String("Declaring the name of the LoggingCategory is mandatory and cannot be changed later !"); + qmlWarning(this) << QLatin1String("Declaring the name of the LoggingCategory is mandatory and cannot be changed later !"); } void QQmlLoggingCategory::setName(const QString &name) { if (m_initialized) { - qmlInfo(this) << QLatin1String("The name of a LoggingCategory cannot be changed after the Item is created"); + qmlWarning(this) << QLatin1String("The name of a LoggingCategory cannot be changed after the Item is created"); return; } diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index 520c44f4da..bd6b9a1599 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -79,7 +79,7 @@ struct QQmlMetaTypeData Files urlToNonFileImportType; // For non-file imported composite and composite // singleton types. This way we can locate any // of them by url, even if it was registered as - // a module via qmlRegisterCompositeType. + // a module via QQmlPrivate::RegisterCompositeType typedef QHash<const QMetaObject *, QQmlType *> MetaObjects; MetaObjects metaObjectToType; typedef QHash<int, QQmlMetaType::StringConverter> StringConverters; diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 2e2a3fb303..85fbd86dc4 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -53,6 +53,8 @@ #include <private/qqmlscriptstring_p.h> #include <private/qqmlpropertyvalueinterceptor_p.h> #include <private/qqmlvaluetypeproxybinding_p.h> +#include <private/qqmldebugconnector_p.h> +#include <private/qqmldebugserviceinterfaces_p.h> QT_USE_NAMESPACE @@ -168,7 +170,7 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI context = new QQmlContextData; context->isInternal = true; - context->imports = compilationUnit->importCache; + context->imports = compilationUnit->typeNameCache; context->initFromTypeCompilationUnit(compilationUnit, subComponentIndex); context->setParent(parentContext); @@ -216,6 +218,17 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI phase = ObjectsCreated; + if (instance) { + if (QQmlEngineDebugService *service + = QQmlDebugConnector::service<QQmlEngineDebugService>()) { + if (!parentContext->isInternal) + parentContext->asQQmlContextPrivate()->instances.append(instance); + service->objectCreated(engine, instance); + } else if (!parentContext->isInternal && QQmlDebugConnector::service<QV4DebugService>()) { + parentContext->asQQmlContextPrivate()->instances.append(instance); + } + } + return instance; } @@ -1137,7 +1150,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo if (customParser && obj->flags & QV4::CompiledData::Object::HasCustomParserBindings) { customParser->engine = QQmlEnginePrivate::get(engine); - customParser->imports = compilationUnit->importCache; + customParser->imports = compilationUnit->typeNameCache; QList<const QV4::CompiledData::Binding *> bindings; const QV4::CompiledData::Object *obj = qmlUnit->objectAt(index); @@ -1257,6 +1270,21 @@ QQmlContextData *QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interru return sharedState->rootContext; } +void QQmlObjectCreator::cancel(QObject *object) +{ + int last = sharedState->allCreatedObjects.count() - 1; + int i = last; + while (i >= 0) { + if (sharedState->allCreatedObjects.at(i) == object) { + if (i < last) + qSwap(sharedState->allCreatedObjects[i], sharedState->allCreatedObjects[last]); + sharedState->allCreatedObjects.pop(); + break; + } + --i; + } +} + void QQmlObjectCreator::clear() { if (phase == Done || phase == Finalizing || phase == Startup) diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h index caee7b9d1d..982324be3c 100644 --- a/src/qml/qml/qqmlobjectcreator_p.h +++ b/src/qml/qml/qqmlobjectcreator_p.h @@ -90,6 +90,7 @@ public: QObject *create(int subComponentIndex = -1, QObject *parent = 0, QQmlInstantiationInterrupt *interrupt = 0); bool populateDeferredProperties(QObject *instance); QQmlContextData *finalize(QQmlInstantiationInterrupt &interrupt); + void cancel(QObject *object); void clear(); QQmlComponentAttached **componentAttachment() const { return &sharedState->componentAttached; } diff --git a/src/qml/qml/qqmlplatform.cpp b/src/qml/qml/qqmlplatform.cpp index a47a0ab4a4..64ca208f1b 100644 --- a/src/qml/qml/qqmlplatform.cpp +++ b/src/qml/qml/qqmlplatform.cpp @@ -59,16 +59,12 @@ QString QQmlPlatform::os() { #if defined(Q_OS_ANDROID) return QStringLiteral("android"); -#elif defined(Q_OS_BLACKBERRY) - return QStringLiteral("blackberry"); #elif defined(Q_OS_IOS) return QStringLiteral("ios"); #elif defined(Q_OS_TVOS) return QStringLiteral("tvos"); #elif defined(Q_OS_MAC) return QStringLiteral("osx"); -#elif defined(Q_OS_WINPHONE) - return QStringLiteral("winphone"); #elif defined(Q_OS_WINRT) return QStringLiteral("winrt"); #elif defined(Q_OS_WIN) diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index 76ac15e2f1..13ad02f7cb 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -2127,11 +2127,11 @@ bool QQmlTypeData::tryLoadFromDiskCache() return true; } -void QQmlTypeData::createTypeAndPropertyCaches(const QQmlRefPointer<QQmlTypeNameCache> &importCache, +void QQmlTypeData::createTypeAndPropertyCaches(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache, const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache) { Q_ASSERT(m_compiledData); - m_compiledData->importCache = importCache; + m_compiledData->typeNameCache = typeNameCache; m_compiledData->resolvedTypes = resolvedTypeCache; QQmlEnginePrivate * const engine = QQmlEnginePrivate::get(typeLoader()->engine()); @@ -2217,10 +2217,10 @@ void QQmlTypeData::done() } } - QQmlRefPointer<QQmlTypeNameCache> importCache; + QQmlRefPointer<QQmlTypeNameCache> typeNameCache; QV4::CompiledData::ResolvedTypeReferenceMap resolvedTypeCache; { - QQmlCompileError error = buildTypeResolutionCaches(&importCache, &resolvedTypeCache); + QQmlCompileError error = buildTypeResolutionCaches(&typeNameCache, &resolvedTypeCache); if (error.isSet()) { setError(error); return; @@ -2240,9 +2240,9 @@ void QQmlTypeData::done() if (!m_document.isNull()) { // Compile component - compile(importCache, resolvedTypeCache); + compile(typeNameCache, resolvedTypeCache); } else { - createTypeAndPropertyCaches(importCache, resolvedTypeCache); + createTypeAndPropertyCaches(typeNameCache, resolvedTypeCache); } if (isError()) @@ -2303,7 +2303,7 @@ void QQmlTypeData::done() qualifier = qualifier.mid(lastDotIndex+1); } - m_compiledData->importCache->add(qualifier.toString(), scriptIndex, enclosingNamespace); + m_compiledData->typeNameCache->add(qualifier.toString(), scriptIndex, enclosingNamespace); QQmlScriptData *scriptData = script.script->scriptData(); scriptData->addref(); m_compiledData->dependentScripts << scriptData; @@ -2428,7 +2428,7 @@ void QQmlTypeData::continueLoadFromIR() QList<QQmlError> errors; - foreach (const QV4::CompiledData::Import *import, m_document->imports) { + for (const QV4::CompiledData::Import *import : qAsConst(m_document->imports)) { if (!addImport(import, &errors)) { Q_ASSERT(errors.size()); QQmlError error(errors.takeFirst()); @@ -2489,12 +2489,12 @@ QString QQmlTypeData::stringAt(int index) const return m_document->jsGenerator.stringTable.stringForIndex(index); } -void QQmlTypeData::compile(const QQmlRefPointer<QQmlTypeNameCache> &importCache, const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache) +void QQmlTypeData::compile(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache, const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache) { Q_ASSERT(m_compiledData.isNull()); QQmlEnginePrivate * const enginePrivate = QQmlEnginePrivate::get(typeLoader()->engine()); - QQmlTypeCompiler compiler(enginePrivate, this, m_document.data(), importCache, resolvedTypeCache); + QQmlTypeCompiler compiler(enginePrivate, this, m_document.data(), typeNameCache, resolvedTypeCache); m_compiledData = compiler.compile(); if (!m_compiledData) { setError(compiler.compilationErrors()); @@ -2575,50 +2575,11 @@ void QQmlTypeData::resolveTypes() int majorVersion = -1; int minorVersion = -1; - QQmlImportNamespace *typeNamespace = 0; - QList<QQmlError> errors; const QString name = stringAt(unresolvedRef.key()); - bool typeFound = m_importCache.resolveType(name, &ref.type, - &majorVersion, &minorVersion, &typeNamespace, &errors); - if (!typeNamespace && !typeFound && !m_implicitImportLoaded) { - // Lazy loading of implicit import - if (loadImplicitImport()) { - // Try again to find the type - errors.clear(); - typeFound = m_importCache.resolveType(name, &ref.type, - &majorVersion, &minorVersion, &typeNamespace, &errors); - } else { - return; //loadImplicitImport() hit an error, and called setError already - } - } - - if ((!typeFound || typeNamespace) && reportErrors) { - // Known to not be a type: - // - known to be a namespace (Namespace {}) - // - type with unknown namespace (UnknownNamespace.SomeType {}) - QQmlError error; - if (typeNamespace) { - error.setDescription(QQmlTypeLoader::tr("Namespace %1 cannot be used as a type").arg(name)); - } else { - if (errors.size()) { - error = errors.takeFirst(); - } else { - // this should not be possible! - // Description should come from error provided by addImport() function. - error.setDescription(QQmlTypeLoader::tr("Unreported error adding script import to import database")); - } - error.setUrl(m_importCache.baseUrl()); - error.setDescription(QQmlTypeLoader::tr("%1 %2").arg(name).arg(error.description())); - } - error.setLine(unresolvedRef->location.line); - error.setColumn(unresolvedRef->location.column); - - errors.prepend(error); - setError(errors); + if (!resolveType(name, majorVersion, minorVersion, ref, unresolvedRef->location.line, unresolvedRef->location.column, reportErrors) && reportErrors) return; - } if (ref.type && ref.type->isComposite()) { ref.typeData = typeLoader()->getType(ref.type->sourceUrl()); @@ -2637,20 +2598,20 @@ void QQmlTypeData::resolveTypes() } QQmlCompileError QQmlTypeData::buildTypeResolutionCaches( - QQmlRefPointer<QQmlTypeNameCache> *importCache, + QQmlRefPointer<QQmlTypeNameCache> *typeNameCache, QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypeCache ) const { - importCache->adopt(new QQmlTypeNameCache); + typeNameCache->adopt(new QQmlTypeNameCache); for (const QString &ns: m_namespaces) - (*importCache)->add(ns); + (*typeNameCache)->add(ns); // Add any Composite Singletons that were used to the import cache for (const QQmlTypeData::TypeReference &singleton: m_compositeSingletons) - (*importCache)->add(singleton.type->qmlTypeName(), singleton.type->sourceUrl(), singleton.prefix); + (*typeNameCache)->add(singleton.type->qmlTypeName(), singleton.type->sourceUrl(), singleton.prefix); - m_importCache.populateCache(*importCache); + m_importCache.populateCache(*typeNameCache); QQmlEnginePrivate * const engine = QQmlEnginePrivate::get(typeLoader()->engine()); @@ -2687,7 +2648,7 @@ QQmlCompileError QQmlTypeData::buildTypeResolutionCaches( return noError; } -bool QQmlTypeData::resolveType(const QString &typeName, int &majorVersion, int &minorVersion, TypeReference &ref) +bool QQmlTypeData::resolveType(const QString &typeName, int &majorVersion, int &minorVersion, TypeReference &ref, int lineNumber, int columnNumber, bool reportErrors) { QQmlImportNamespace *typeNamespace = 0; QList<QQmlError> errors; @@ -2706,7 +2667,7 @@ bool QQmlTypeData::resolveType(const QString &typeName, int &majorVersion, int & } } - if (!typeFound || typeNamespace) { + if ((!typeFound || typeNamespace) && reportErrors) { // Known to not be a type: // - known to be a namespace (Namespace {}) // - type with unknown namespace (UnknownNamespace.SomeType {}) @@ -2725,6 +2686,11 @@ bool QQmlTypeData::resolveType(const QString &typeName, int &majorVersion, int & error.setDescription(QQmlTypeLoader::tr("%1 %2").arg(typeName).arg(error.description())); } + if (lineNumber != -1) + error.setLine(lineNumber); + if (columnNumber != -1) + error.setColumn(columnNumber); + errors.prepend(error); setError(errors); return false; @@ -2744,7 +2710,7 @@ void QQmlTypeData::scriptImported(QQmlScriptBlob *blob, const QV4::CompiledData: } QQmlScriptData::QQmlScriptData() - : importCache(0) + : typeNameCache(0) , m_loaded(false) , m_program(0) { @@ -2801,8 +2767,8 @@ QV4::ReturnedValue QQmlScriptData::scriptValueForContext(QQmlContextData *parent // For backward compatibility, if there are no imports, we need to use the // imports from the parent context. See QTBUG-17518. - if (!importCache->isEmpty()) { - ctxt->imports = importCache; + if (!typeNameCache->isEmpty()) { + ctxt->imports = typeNameCache; } else if (effectiveCtxt) { ctxt->imports = effectiveCtxt->imports; ctxt->importedScripts = effectiveCtxt->importedScripts; @@ -2857,9 +2823,9 @@ QV4::ReturnedValue QQmlScriptData::scriptValueForContext(QQmlContextData *parent void QQmlScriptData::clear() { - if (importCache) { - importCache->release(); - importCache = 0; + if (typeNameCache) { + typeNameCache->release(); + typeNameCache = 0; } for (int ii = 0; ii < scripts.count(); ++ii) @@ -2980,7 +2946,7 @@ void QQmlScriptBlob::done() } } - m_scriptData->importCache = new QQmlTypeNameCache(); + m_scriptData->typeNameCache = new QQmlTypeNameCache(); QSet<QString> ns; @@ -2992,13 +2958,13 @@ void QQmlScriptBlob::done() if (!script.nameSpace.isNull()) { if (!ns.contains(script.nameSpace)) { ns.insert(script.nameSpace); - m_scriptData->importCache->add(script.nameSpace); + m_scriptData->typeNameCache->add(script.nameSpace); } } - m_scriptData->importCache->add(script.qualifier, scriptIndex, script.nameSpace); + m_scriptData->typeNameCache->add(script.qualifier, scriptIndex, script.nameSpace); } - m_importCache.populateCache(m_scriptData->importCache); + m_importCache.populateCache(m_scriptData->typeNameCache); } QString QQmlScriptBlob::stringAt(int index) const diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h index b1d6451974..14141db180 100644 --- a/src/qml/qml/qqmltypeloader_p.h +++ b/src/qml/qml/qqmltypeloader_p.h @@ -449,14 +449,14 @@ private: void continueLoadFromIR(); void resolveTypes(); QQmlCompileError buildTypeResolutionCaches( - QQmlRefPointer<QQmlTypeNameCache> *importCache, + QQmlRefPointer<QQmlTypeNameCache> *typeNameCache, QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypeCache ) const; - void compile(const QQmlRefPointer<QQmlTypeNameCache> &importCache, + void compile(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache, const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache); - void createTypeAndPropertyCaches(const QQmlRefPointer<QQmlTypeNameCache> &importCache, + void createTypeAndPropertyCaches(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache, const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache); - bool resolveType(const QString &typeName, int &majorVersion, int &minorVersion, TypeReference &ref); + bool resolveType(const QString &typeName, int &majorVersion, int &minorVersion, TypeReference &ref, int lineNumber = -1, int columnNumber = -1, bool reportErrors = true); void scriptImported(QQmlScriptBlob *blob, const QV4::CompiledData::Location &location, const QString &qualifier, const QString &nameSpace) override; @@ -504,7 +504,7 @@ public: QUrl url; QString urlString; - QQmlTypeNameCache *importCache; + QQmlTypeNameCache *typeNameCache; QList<QQmlScriptBlob *> scripts; QV4::ReturnedValue scriptValueForContext(QQmlContextData *parentCtxt); diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp index 6ce52bb9e5..44b612e7d2 100644 --- a/src/qml/qml/qqmlvaluetypewrapper.cpp +++ b/src/qml/qml/qqmlvaluetypewrapper.cpp @@ -312,18 +312,18 @@ bool QQmlValueTypeWrapper::write(QObject *target, int propertyIndex) const return true; } -ReturnedValue QQmlValueTypeWrapper::method_toString(CallContext *ctx) +void QQmlValueTypeWrapper::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData) { - Object *o = ctx->thisObject().as<Object>(); + Object *o = callData->thisObject.as<Object>(); if (!o) - return ctx->engine()->throwTypeError(); + THROW_TYPE_ERROR(); QQmlValueTypeWrapper *w = o->as<QQmlValueTypeWrapper>(); if (!w) - return ctx->engine()->throwTypeError(); + THROW_TYPE_ERROR(); if (QQmlValueTypeReference *ref = w->as<QQmlValueTypeReference>()) if (!ref->readReferenceValue()) - return Encode::undefined(); + RETURN_UNDEFINED(); QString result; // Prepare a buffer to pass to QMetaType::convert() @@ -346,7 +346,7 @@ ReturnedValue QQmlValueTypeWrapper::method_toString(CallContext *ctx) } result += QLatin1Char(')'); } - return Encode(ctx->engine()->newString(result)); + scope.result = scope.engine->newString(result); } ReturnedValue QQmlValueTypeWrapper::get(const Managed *m, String *name, bool *hasProperty) diff --git a/src/qml/qml/qqmlvaluetypewrapper_p.h b/src/qml/qml/qqmlvaluetypewrapper_p.h index fec54df770..87f9116056 100644 --- a/src/qml/qml/qqmlvaluetypewrapper_p.h +++ b/src/qml/qml/qqmlvaluetypewrapper_p.h @@ -111,7 +111,7 @@ public: static PropertyAttributes query(const Managed *, String *name); static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes); - static QV4::ReturnedValue method_toString(CallContext *ctx); + static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData); static void initProto(ExecutionEngine *v4); }; diff --git a/src/qml/qml/qqmlvme.cpp b/src/qml/qml/qqmlvme.cpp index 72d4ab7e8f..c60f4edc80 100644 --- a/src/qml/qml/qqmlvme.cpp +++ b/src/qml/qml/qqmlvme.cpp @@ -120,6 +120,18 @@ void QQmlVMEGuard::guard(QQmlObjectCreator *creator) m_contexts[0] = creator->parentContextData(); } +void QQmlVMEGuard::unguard(QObject *object) +{ + for (int ii = 0; ii < m_objectCount; ++ii) { + if (m_objects[ii] == object) { + if (ii < m_objectCount - 1) + ::memmove((void *) m_objects[ii], (void *) m_objects[ii + 1], sizeof(QPointer<QObject> *)); + delete m_objects[--m_objectCount]; + break; + } + } +} + void QQmlVMEGuard::clear() { delete [] m_objects; diff --git a/src/qml/qml/qqmlvme_p.h b/src/qml/qml/qqmlvme_p.h index 99d63380ad..9585b5b6df 100644 --- a/src/qml/qml/qqmlvme_p.h +++ b/src/qml/qml/qqmlvme_p.h @@ -131,6 +131,7 @@ public: ~QQmlVMEGuard(); void guard(QQmlObjectCreator *); + void unguard(QObject *); void clear(); bool isOK() const; diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index 545daa96f8..490a4e19ab 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -325,9 +325,12 @@ QQmlVMEMetaObject::QQmlVMEMetaObject(QObject *obj, if (compiledObject->nProperties || compiledObject->nFunctions) { Q_ASSERT(cache && cache->engine); QV4::ExecutionEngine *v4 = cache->engine; - QV4::Heap::MemberData *data = QV4::MemberData::allocate(v4, compiledObject->nProperties + compiledObject->nFunctions); - propertyAndMethodStorage.set(v4, data); - std::fill(data->data, data->data + data->size, QV4::Encode::undefined()); + uint size = compiledObject->nProperties + compiledObject->nFunctions; + if (size) { + QV4::Heap::MemberData *data = QV4::MemberData::allocate(v4, size); + propertyAndMethodStorage.set(v4, data); + std::fill(data->data, data->data + data->size, QV4::Encode::undefined()); + } // Need JS wrapper to ensure properties/methods are marked. ensureQObjectWrapper(); diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp index 22c3c49c58..d0d9f080da 100644 --- a/src/qml/qml/qqmlxmlhttprequest.cpp +++ b/src/qml/qml/qqmlxmlhttprequest.cpp @@ -71,10 +71,12 @@ using namespace QV4; #if QT_CONFIG(xmlstreamreader) && QT_CONFIG(qml_network) -#define V4THROW_REFERENCE(string) { \ - ScopedObject error(scope, ctx->engine()->newReferenceErrorObject(QStringLiteral(string))); \ - return ctx->engine()->throwError(error); \ - } +#define V4THROW_REFERENCE(string) \ + do { \ + ScopedObject error(scope, scope.engine->newReferenceErrorObject(QStringLiteral(string))); \ + scope.result = scope.engine->throwError(error); \ + return; \ + } while (false) QT_BEGIN_NAMESPACE @@ -274,25 +276,25 @@ public: static void initClass(ExecutionEngine *engine); // JS API - static ReturnedValue method_get_nodeName(CallContext *ctx); - static ReturnedValue method_get_nodeValue(CallContext *ctx); - static ReturnedValue method_get_nodeType(CallContext *ctx); - static ReturnedValue method_get_namespaceUri(CallContext *ctx); - - static ReturnedValue method_get_parentNode(CallContext *ctx); - static ReturnedValue method_get_childNodes(CallContext *ctx); - static ReturnedValue method_get_firstChild(CallContext *ctx); - static ReturnedValue method_get_lastChild(CallContext *ctx); - static ReturnedValue method_get_previousSibling(CallContext *ctx); - static ReturnedValue method_get_nextSibling(CallContext *ctx); - static ReturnedValue method_get_attributes(CallContext *ctx); - - //static ReturnedValue ownerDocument(CallContext *ctx); - //static ReturnedValue namespaceURI(CallContext *ctx); - //static ReturnedValue prefix(CallContext *ctx); - //static ReturnedValue localName(CallContext *ctx); - //static ReturnedValue baseURI(CallContext *ctx); - //static ReturnedValue textContent(CallContext *ctx); + static void method_get_nodeName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_get_nodeValue(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_get_nodeType(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_get_namespaceUri(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + + static void method_get_parentNode(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_get_childNodes(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_get_firstChild(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_get_lastChild(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_get_previousSibling(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_get_nextSibling(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_get_attributes(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + + //static void ownerDocument(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + //static void namespaceURI(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + //static void prefix(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + //static void localName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + //static void baseURI(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + //static void textContent(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); static ReturnedValue getProto(ExecutionEngine *v4); @@ -353,12 +355,12 @@ class Attr : public Node { public: // JS API - static ReturnedValue method_name(CallContext *ctx); -// static ReturnedValue specified(CallContext *); - static ReturnedValue method_value(CallContext *ctx); - static ReturnedValue method_ownerElement(CallContext *ctx); -// static ReturnedValue schemaTypeInfo(CallContext *); -// static ReturnedValue isId(CallContext *c); + static void method_name(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); +// static void specified(CallContext *); + static void method_value(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_ownerElement(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); +// static void schemaTypeInfo(CallContext *); +// static void isId(CallContext *c); // C++ API static ReturnedValue prototype(ExecutionEngine *); @@ -368,7 +370,7 @@ class CharacterData : public Node { public: // JS API - static ReturnedValue method_length(CallContext *ctx); + static void method_length(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); // C++ API static ReturnedValue prototype(ExecutionEngine *v4); @@ -378,8 +380,8 @@ class Text : public CharacterData { public: // JS API - static ReturnedValue method_isElementContentWhitespace(CallContext *ctx); - static ReturnedValue method_wholeText(CallContext *ctx); + static void method_isElementContentWhitespace(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_wholeText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); // C++ API static ReturnedValue prototype(ExecutionEngine *); @@ -396,10 +398,10 @@ class Document : public Node { public: // JS API - static ReturnedValue method_xmlVersion(CallContext *ctx); - static ReturnedValue method_xmlEncoding(CallContext *ctx); - static ReturnedValue method_xmlStandalone(CallContext *ctx); - static ReturnedValue method_documentElement(CallContext *ctx); + static void method_xmlVersion(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_xmlEncoding(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_xmlStandalone(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_documentElement(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); // C++ API static ReturnedValue prototype(ExecutionEngine *); @@ -418,12 +420,11 @@ void NodeImpl::release() document->release(); } -ReturnedValue NodePrototype::method_get_nodeName(CallContext *ctx) +void NodePrototype::method_get_nodeName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { - Scope scope(ctx); - Scoped<Node> r(scope, ctx->thisObject().as<Node>()); + Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r) - return ctx->engine()->throwTypeError(); + THROW_TYPE_ERROR(); QString name; switch (r->d()->d->type) { @@ -440,15 +441,14 @@ ReturnedValue NodePrototype::method_get_nodeName(CallContext *ctx) name = r->d()->d->name; break; } - return Encode(ctx->d()->engine->newString(name)); + scope.result = Encode(scope.engine->newString(name)); } -ReturnedValue NodePrototype::method_get_nodeValue(CallContext *ctx) +void NodePrototype::method_get_nodeValue(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { - Scope scope(ctx); - Scoped<Node> r(scope, ctx->thisObject().as<Node>()); + Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r) - return ctx->engine()->throwTypeError(); + THROW_TYPE_ERROR(); if (r->d()->d->type == NodeImpl::Document || r->d()->d->type == NodeImpl::DocumentFragment || @@ -457,135 +457,128 @@ ReturnedValue NodePrototype::method_get_nodeValue(CallContext *ctx) r->d()->d->type == NodeImpl::Entity || r->d()->d->type == NodeImpl::EntityReference || r->d()->d->type == NodeImpl::Notation) - return Encode::null(); + RETURN_RESULT(Encode::null()); - return Encode(ctx->d()->engine->newString(r->d()->d->data)); + scope.result = Encode(scope.engine->newString(r->d()->d->data)); } -ReturnedValue NodePrototype::method_get_nodeType(CallContext *ctx) +void NodePrototype::method_get_nodeType(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { - Scope scope(ctx); - Scoped<Node> r(scope, ctx->thisObject().as<Node>()); + Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r) - return ctx->engine()->throwTypeError(); + THROW_TYPE_ERROR(); - return Encode(r->d()->d->type); + scope.result = Encode(r->d()->d->type); } -ReturnedValue NodePrototype::method_get_namespaceUri(CallContext *ctx) +void NodePrototype::method_get_namespaceUri(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { - Scope scope(ctx); - Scoped<Node> r(scope, ctx->thisObject().as<Node>()); + Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r) - return ctx->engine()->throwTypeError(); + THROW_TYPE_ERROR(); - return Encode(ctx->d()->engine->newString(r->d()->d->namespaceUri)); + scope.result = Encode(scope.engine->newString(r->d()->d->namespaceUri)); } -ReturnedValue NodePrototype::method_get_parentNode(CallContext *ctx) +void NodePrototype::method_get_parentNode(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { - Scope scope(ctx); - Scoped<Node> r(scope, ctx->thisObject().as<Node>()); + Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r) - return ctx->engine()->throwTypeError(); + THROW_TYPE_ERROR(); if (r->d()->d->parent) - return Node::create(scope.engine, r->d()->d->parent); + scope.result = Node::create(scope.engine, r->d()->d->parent); else - return Encode::null(); + scope.result = Encode::null(); } -ReturnedValue NodePrototype::method_get_childNodes(CallContext *ctx) +void NodePrototype::method_get_childNodes(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { - Scope scope(ctx); - Scoped<Node> r(scope, ctx->thisObject().as<Node>()); + Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r) - return ctx->engine()->throwTypeError(); + THROW_TYPE_ERROR(); - return NodeList::create(scope.engine, r->d()->d); + scope.result = NodeList::create(scope.engine, r->d()->d); } -ReturnedValue NodePrototype::method_get_firstChild(CallContext *ctx) +void NodePrototype::method_get_firstChild(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { - Scope scope(ctx); - Scoped<Node> r(scope, ctx->thisObject().as<Node>()); + Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r) - return ctx->engine()->throwTypeError(); + THROW_TYPE_ERROR(); if (r->d()->d->children.isEmpty()) - return Encode::null(); + scope.result = Encode::null(); else - return Node::create(scope.engine, r->d()->d->children.constFirst()); + scope.result = Node::create(scope.engine, r->d()->d->children.constFirst()); } -ReturnedValue NodePrototype::method_get_lastChild(CallContext *ctx) +void NodePrototype::method_get_lastChild(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { - Scope scope(ctx); - Scoped<Node> r(scope, ctx->thisObject().as<Node>()); + Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r) - return ctx->engine()->throwTypeError(); + THROW_TYPE_ERROR(); if (r->d()->d->children.isEmpty()) - return Encode::null(); + scope.result = Encode::null(); else - return Node::create(scope.engine, r->d()->d->children.constLast()); + scope.result = Node::create(scope.engine, r->d()->d->children.constLast()); } -ReturnedValue NodePrototype::method_get_previousSibling(CallContext *ctx) +void NodePrototype::method_get_previousSibling(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { - Scope scope(ctx); - Scoped<Node> r(scope, ctx->thisObject().as<Node>()); + Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r) - return ctx->engine()->throwTypeError(); + THROW_TYPE_ERROR(); if (!r->d()->d->parent) - return Encode::null(); + RETURN_RESULT(Encode::null()); for (int ii = 0; ii < r->d()->d->parent->children.count(); ++ii) { if (r->d()->d->parent->children.at(ii) == r->d()->d) { if (ii == 0) - return Encode::null(); + scope.result = Encode::null(); else - return Node::create(scope.engine, r->d()->d->parent->children.at(ii - 1)); + scope.result = Node::create(scope.engine, r->d()->d->parent->children.at(ii - 1)); + return; } } - return Encode::null(); + scope.result = Encode::null(); } -ReturnedValue NodePrototype::method_get_nextSibling(CallContext *ctx) +void NodePrototype::method_get_nextSibling(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { - Scope scope(ctx); - Scoped<Node> r(scope, ctx->thisObject().as<Node>()); + Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r) - return ctx->engine()->throwTypeError(); + THROW_TYPE_ERROR(); if (!r->d()->d->parent) - return Encode::null(); + RETURN_RESULT(Encode::null()); for (int ii = 0; ii < r->d()->d->parent->children.count(); ++ii) { if (r->d()->d->parent->children.at(ii) == r->d()->d) { if ((ii + 1) == r->d()->d->parent->children.count()) - return Encode::null(); + scope.result = Encode::null(); else - return Node::create(scope.engine, r->d()->d->parent->children.at(ii + 1)); + scope.result = Node::create(scope.engine, r->d()->d->parent->children.at(ii + 1)); + return; } } - return Encode::null(); + scope.result = Encode::null(); } -ReturnedValue NodePrototype::method_get_attributes(CallContext *ctx) +void NodePrototype::method_get_attributes(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { - Scope scope(ctx); - Scoped<Node> r(scope, ctx->thisObject().as<Node>()); + Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r) - return ctx->engine()->throwTypeError(); + THROW_TYPE_ERROR(); if (r->d()->d->type != NodeImpl::Element) - return Encode::null(); + scope.result = Encode::null(); else - return NamedNodeMap::create(scope.engine, r->d()->d, r->d()->d->attributes); + scope.result = NamedNodeMap::create(scope.engine, r->d()->d, r->d()->d->attributes); } ReturnedValue NodePrototype::getProto(ExecutionEngine *v4) @@ -666,44 +659,40 @@ ReturnedValue Attr::prototype(ExecutionEngine *engine) return d->attrPrototype.value(); } -ReturnedValue Attr::method_name(CallContext *ctx) +void Attr::method_name(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { - Scope scope(ctx); - Scoped<Node> r(scope, ctx->thisObject().as<Node>()); + Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r) - return Encode::undefined(); + RETURN_UNDEFINED(); - return QV4::Encode(scope.engine->newString(r->d()->d->name)); + scope.result = scope.engine->newString(r->d()->d->name); } -ReturnedValue Attr::method_value(CallContext *ctx) +void Attr::method_value(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { - Scope scope(ctx); - Scoped<Node> r(scope, ctx->thisObject().as<Node>()); + Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r) - return Encode::undefined(); + RETURN_UNDEFINED(); - return QV4::Encode(scope.engine->newString(r->d()->d->data)); + scope.result = scope.engine->newString(r->d()->d->data); } -ReturnedValue Attr::method_ownerElement(CallContext *ctx) +void Attr::method_ownerElement(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { - Scope scope(ctx); - Scoped<Node> r(scope, ctx->thisObject().as<Node>()); + Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r) - return Encode::undefined(); + RETURN_UNDEFINED(); - return Node::create(scope.engine, r->d()->d->parent); + scope.result = Node::create(scope.engine, r->d()->d->parent); } -ReturnedValue CharacterData::method_length(CallContext *ctx) +void CharacterData::method_length(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { - Scope scope(ctx); - Scoped<Node> r(scope, ctx->thisObject().as<Node>()); + Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r) - return Encode::undefined(); + RETURN_UNDEFINED(); - return Encode(r->d()->d->data.length()); + scope.result = Encode(r->d()->d->data.length()); } ReturnedValue CharacterData::prototype(ExecutionEngine *v4) @@ -722,23 +711,22 @@ ReturnedValue CharacterData::prototype(ExecutionEngine *v4) return d->characterDataPrototype.value(); } -ReturnedValue Text::method_isElementContentWhitespace(CallContext *ctx) +void Text::method_isElementContentWhitespace(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { - Scope scope(ctx); - Scoped<Node> r(scope, ctx->thisObject().as<Node>()); - if (!r) return Encode::undefined(); + Scoped<Node> r(scope, callData->thisObject.as<Node>()); + if (!r) + RETURN_UNDEFINED(); - return Encode(QStringRef(&r->d()->d->data).trimmed().isEmpty()); + scope.result = Encode(QStringRef(&r->d()->d->data).trimmed().isEmpty()); } -ReturnedValue Text::method_wholeText(CallContext *ctx) +void Text::method_wholeText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { - Scope scope(ctx); - Scoped<Node> r(scope, ctx->thisObject().as<Node>()); + Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r) - return Encode::undefined(); + RETURN_UNDEFINED(); - return QV4::Encode(scope.engine->newString(r->d()->d->data)); + scope.result = scope.engine->newString(r->d()->d->data); } ReturnedValue Text::prototype(ExecutionEngine *v4) @@ -964,44 +952,40 @@ ReturnedValue NodeList::create(ExecutionEngine *v4, NodeImpl *data) return (v4->memoryManager->allocObject<NodeList>(data))->asReturnedValue(); } -ReturnedValue Document::method_documentElement(CallContext *ctx) +void Document::method_documentElement(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { - Scope scope(ctx); - Scoped<Node> r(scope, ctx->thisObject().as<Node>()); + Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r || r->d()->d->type != NodeImpl::Document) - return Encode::undefined(); + RETURN_UNDEFINED(); - return Node::create(scope.engine, static_cast<DocumentImpl *>(r->d()->d)->root); + scope.result = Node::create(scope.engine, static_cast<DocumentImpl *>(r->d()->d)->root); } -ReturnedValue Document::method_xmlStandalone(CallContext *ctx) +void Document::method_xmlStandalone(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { - Scope scope(ctx); - Scoped<Node> r(scope, ctx->thisObject().as<Node>()); + Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r || r->d()->d->type != NodeImpl::Document) - return Encode::undefined(); + RETURN_UNDEFINED(); - return Encode(static_cast<DocumentImpl *>(r->d()->d)->isStandalone); + scope.result = Encode(static_cast<DocumentImpl *>(r->d()->d)->isStandalone); } -ReturnedValue Document::method_xmlVersion(CallContext *ctx) +void Document::method_xmlVersion(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { - Scope scope(ctx); - Scoped<Node> r(scope, ctx->thisObject().as<Node>()); + Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r || r->d()->d->type != NodeImpl::Document) - return Encode::undefined(); + RETURN_UNDEFINED(); - return QV4::Encode(scope.engine->newString(static_cast<DocumentImpl *>(r->d()->d)->version)); + scope.result = scope.engine->newString(static_cast<DocumentImpl *>(r->d()->d)->version); } -ReturnedValue Document::method_xmlEncoding(CallContext *ctx) +void Document::method_xmlEncoding(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { - Scope scope(ctx); - Scoped<Node> r(scope, ctx->thisObject().as<Node>()); + Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r || r->d()->d->type != NodeImpl::Document) - return Encode::undefined(); + RETURN_UNDEFINED(); - return QV4::Encode(scope.engine->newString(static_cast<DocumentImpl *>(r->d()->d)->encoding)); + scope.result = scope.engine->newString(static_cast<DocumentImpl *>(r->d()->d)->encoding); } class QQmlXMLHttpRequest : public QObject @@ -1657,21 +1641,21 @@ struct QQmlXMLHttpRequestCtor : public FunctionObject void setupProto(); - static ReturnedValue method_open(CallContext *ctx); - static ReturnedValue method_setRequestHeader(CallContext *ctx); - static ReturnedValue method_send(CallContext *ctx); - static ReturnedValue method_abort(CallContext *ctx); - static ReturnedValue method_getResponseHeader(CallContext *ctx); - static ReturnedValue method_getAllResponseHeaders(CallContext *ctx); - - static ReturnedValue method_get_readyState(CallContext *ctx); - static ReturnedValue method_get_status(CallContext *ctx); - static ReturnedValue method_get_statusText(CallContext *ctx); - static ReturnedValue method_get_responseText(CallContext *ctx); - static ReturnedValue method_get_responseXML(CallContext *ctx); - static ReturnedValue method_get_response(CallContext *ctx); - static ReturnedValue method_get_responseType(CallContext *ctx); - static ReturnedValue method_set_responseType(CallContext *ctx); + static void method_open(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_setRequestHeader(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_send(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_abort(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_getResponseHeader(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_getAllResponseHeaders(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + + static void method_get_readyState(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_get_status(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_get_statusText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_get_responseText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_get_responseXML(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_get_response(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_get_responseType(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static void method_set_responseType(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); }; } @@ -1733,19 +1717,18 @@ void QQmlXMLHttpRequestCtor::setupProto() // XMLHttpRequest methods -ReturnedValue QQmlXMLHttpRequestCtor::method_open(CallContext *ctx) +void QQmlXMLHttpRequestCtor::method_open(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { - Scope scope(ctx); - Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>()); + Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>()); if (!w) V4THROW_REFERENCE("Not an XMLHttpRequest object"); QQmlXMLHttpRequest *r = w->d()->request; - if (ctx->argc() < 2 || ctx->argc() > 5) - V4THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count"); + if (callData->argc < 2 || callData->argc > 5) + THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count"); // Argument 0 - Method - QString method = ctx->args()[0].toQStringNoThrow().toUpper(); + QString method = callData->args[0].toQStringNoThrow().toUpper(); if (method != QLatin1String("GET") && method != QLatin1String("PUT") && method != QLatin1String("HEAD") && @@ -1754,26 +1737,26 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_open(CallContext *ctx) method != QLatin1String("OPTIONS") && method != QLatin1String("PROPFIND") && method != QLatin1String("PATCH")) - V4THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Unsupported HTTP method type"); + THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Unsupported HTTP method type"); // Argument 1 - URL - QUrl url = QUrl(ctx->args()[1].toQStringNoThrow()); + QUrl url = QUrl(callData->args[1].toQStringNoThrow()); if (url.isRelative()) url = scope.engine->callingQmlContext()->resolvedUrl(url); bool async = true; // Argument 2 - async (optional) - if (ctx->argc() > 2) { - async = ctx->args()[2].booleanValue(); + if (callData->argc > 2) { + async = callData->args[2].booleanValue(); } // Argument 3/4 - user/pass (optional) QString username, password; - if (ctx->argc() > 3) - username = ctx->args()[3].toQStringNoThrow(); - if (ctx->argc() > 4) - password = ctx->args()[4].toQStringNoThrow(); + if (callData->argc > 3) + username = callData->args[3].toQStringNoThrow(); + if (callData->argc > 4) + password = callData->args[4].toQStringNoThrow(); // Clear the fragment (if any) url.setFragment(QString()); @@ -1782,25 +1765,24 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_open(CallContext *ctx) if (!username.isNull()) url.setUserName(username); if (!password.isNull()) url.setPassword(password); - return r->open(w, scope.engine->callingQmlContext(), method, url, async ? QQmlXMLHttpRequest::AsynchronousLoad : QQmlXMLHttpRequest::SynchronousLoad); + scope.result = r->open(w, scope.engine->callingQmlContext(), method, url, async ? QQmlXMLHttpRequest::AsynchronousLoad : QQmlXMLHttpRequest::SynchronousLoad); } -ReturnedValue QQmlXMLHttpRequestCtor::method_setRequestHeader(CallContext *ctx) +void QQmlXMLHttpRequestCtor::method_setRequestHeader(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { - Scope scope(ctx); - Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>()); + Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>()); if (!w) V4THROW_REFERENCE("Not an XMLHttpRequest object"); QQmlXMLHttpRequest *r = w->d()->request; - if (ctx->argc() != 2) - V4THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count"); + if (callData->argc != 2) + THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count"); if (r->readyState() != QQmlXMLHttpRequest::Opened || r->sendFlag()) - V4THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state"); + THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state"); - QString name = ctx->args()[0].toQStringNoThrow(); - QString value = ctx->args()[1].toQStringNoThrow(); + QString name = callData->args[0].toQStringNoThrow(); + QString value = callData->args[1].toQStringNoThrow(); // ### Check that name and value are well formed @@ -1825,148 +1807,139 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_setRequestHeader(CallContext *ctx) nameUpper == QLatin1String("VIA") || nameUpper.startsWith(QLatin1String("PROXY-")) || nameUpper.startsWith(QLatin1String("SEC-"))) - return Encode::undefined(); + RETURN_UNDEFINED(); r->addHeader(name, value); - return Encode::undefined(); + RETURN_UNDEFINED(); } -ReturnedValue QQmlXMLHttpRequestCtor::method_send(CallContext *ctx) +void QQmlXMLHttpRequestCtor::method_send(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { - Scope scope(ctx); - Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>()); + Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>()); if (!w) V4THROW_REFERENCE("Not an XMLHttpRequest object"); QQmlXMLHttpRequest *r = w->d()->request; if (r->readyState() != QQmlXMLHttpRequest::Opened || r->sendFlag()) - V4THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state"); + THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state"); QByteArray data; - if (ctx->argc() > 0) - data = ctx->args()[0].toQStringNoThrow().toUtf8(); + if (callData->argc > 0) + data = callData->args[0].toQStringNoThrow().toUtf8(); - return r->send(w, scope.engine->callingQmlContext(), data); + scope.result = r->send(w, scope.engine->callingQmlContext(), data); } -ReturnedValue QQmlXMLHttpRequestCtor::method_abort(CallContext *ctx) +void QQmlXMLHttpRequestCtor::method_abort(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { - Scope scope(ctx); - Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>()); + Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>()); if (!w) V4THROW_REFERENCE("Not an XMLHttpRequest object"); QQmlXMLHttpRequest *r = w->d()->request; - return r->abort(w, scope.engine->callingQmlContext()); + scope.result = r->abort(w, scope.engine->callingQmlContext()); } -ReturnedValue QQmlXMLHttpRequestCtor::method_getResponseHeader(CallContext *ctx) +void QQmlXMLHttpRequestCtor::method_getResponseHeader(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { - Scope scope(ctx); - Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>()); + Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>()); if (!w) V4THROW_REFERENCE("Not an XMLHttpRequest object"); QQmlXMLHttpRequest *r = w->d()->request; - if (ctx->argc() != 1) - V4THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count"); + if (callData->argc != 1) + THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count"); if (r->readyState() != QQmlXMLHttpRequest::Loading && r->readyState() != QQmlXMLHttpRequest::Done && r->readyState() != QQmlXMLHttpRequest::HeadersReceived) - V4THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state"); + THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state"); - return QV4::Encode(scope.engine->newString(r->header(ctx->args()[0].toQStringNoThrow()))); + scope.result = scope.engine->newString(r->header(callData->args[0].toQStringNoThrow())); } -ReturnedValue QQmlXMLHttpRequestCtor::method_getAllResponseHeaders(CallContext *ctx) +void QQmlXMLHttpRequestCtor::method_getAllResponseHeaders(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { - Scope scope(ctx); - Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>()); + Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>()); if (!w) V4THROW_REFERENCE("Not an XMLHttpRequest object"); QQmlXMLHttpRequest *r = w->d()->request; - if (ctx->argc() != 0) - V4THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count"); + if (callData->argc != 0) + THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count"); if (r->readyState() != QQmlXMLHttpRequest::Loading && r->readyState() != QQmlXMLHttpRequest::Done && r->readyState() != QQmlXMLHttpRequest::HeadersReceived) - V4THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state"); + THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state"); - return QV4::Encode(scope.engine->newString(r->headers())); + scope.result = scope.engine->newString(r->headers()); } // XMLHttpRequest properties -ReturnedValue QQmlXMLHttpRequestCtor::method_get_readyState(CallContext *ctx) +void QQmlXMLHttpRequestCtor::method_get_readyState(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { - Scope scope(ctx); - Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>()); + Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>()); if (!w) V4THROW_REFERENCE("Not an XMLHttpRequest object"); QQmlXMLHttpRequest *r = w->d()->request; - return Encode(r->readyState()); + scope.result = Encode(r->readyState()); } -ReturnedValue QQmlXMLHttpRequestCtor::method_get_status(CallContext *ctx) +void QQmlXMLHttpRequestCtor::method_get_status(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { - Scope scope(ctx); - Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>()); + Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>()); if (!w) V4THROW_REFERENCE("Not an XMLHttpRequest object"); QQmlXMLHttpRequest *r = w->d()->request; if (r->readyState() == QQmlXMLHttpRequest::Unsent || r->readyState() == QQmlXMLHttpRequest::Opened) - V4THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state"); + THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state"); if (r->errorFlag()) - return Encode(0); + scope.result = Encode(0); else - return Encode(r->replyStatus()); + scope.result = Encode(r->replyStatus()); } -ReturnedValue QQmlXMLHttpRequestCtor::method_get_statusText(CallContext *ctx) +void QQmlXMLHttpRequestCtor::method_get_statusText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { - Scope scope(ctx); - Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>()); + Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>()); if (!w) V4THROW_REFERENCE("Not an XMLHttpRequest object"); QQmlXMLHttpRequest *r = w->d()->request; if (r->readyState() == QQmlXMLHttpRequest::Unsent || r->readyState() == QQmlXMLHttpRequest::Opened) - V4THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state"); + THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state"); if (r->errorFlag()) - return QV4::Encode(scope.engine->newString(QString())); + scope.result = scope.engine->newString(QString()); else - return QV4::Encode(scope.engine->newString(r->replyStatusText())); + scope.result = scope.engine->newString(r->replyStatusText()); } -ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseText(CallContext *ctx) +void QQmlXMLHttpRequestCtor::method_get_responseText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { - Scope scope(ctx); - Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>()); + Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>()); if (!w) V4THROW_REFERENCE("Not an XMLHttpRequest object"); QQmlXMLHttpRequest *r = w->d()->request; if (r->readyState() != QQmlXMLHttpRequest::Loading && r->readyState() != QQmlXMLHttpRequest::Done) - return QV4::Encode(scope.engine->newString(QString())); + scope.result = scope.engine->newString(QString()); else - return QV4::Encode(scope.engine->newString(r->responseBody())); + scope.result = scope.engine->newString(r->responseBody()); } -ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseXML(CallContext *ctx) +void QQmlXMLHttpRequestCtor::method_get_responseXML(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { - Scope scope(ctx); - Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>()); + Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>()); if (!w) V4THROW_REFERENCE("Not an XMLHttpRequest object"); QQmlXMLHttpRequest *r = w->d()->request; @@ -1974,66 +1947,63 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseXML(CallContext *ctx) if (!r->receivedXml() || (r->readyState() != QQmlXMLHttpRequest::Loading && r->readyState() != QQmlXMLHttpRequest::Done)) { - return Encode::null(); + scope.result = Encode::null(); } else { if (r->responseType().isEmpty()) r->setResponseType(QLatin1String("document")); - return r->xmlResponseBody(scope.engine); + scope.result = r->xmlResponseBody(scope.engine); } } -ReturnedValue QQmlXMLHttpRequestCtor::method_get_response(CallContext *ctx) +void QQmlXMLHttpRequestCtor::method_get_response(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { - Scope scope(ctx); - Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>()); + Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>()); if (!w) V4THROW_REFERENCE("Not an XMLHttpRequest object"); QQmlXMLHttpRequest *r = w->d()->request; if (r->readyState() != QQmlXMLHttpRequest::Loading && r->readyState() != QQmlXMLHttpRequest::Done) - return QV4::Encode(scope.engine->newString(QString())); + RETURN_RESULT(scope.engine->newString(QString())); const QString& responseType = r->responseType(); if (responseType.compare(QLatin1String("text"), Qt::CaseInsensitive) == 0 || responseType.isEmpty()) { - return QV4::Encode(scope.engine->newString(r->responseBody())); + RETURN_RESULT(scope.engine->newString(r->responseBody())); } else if (responseType.compare(QLatin1String("arraybuffer"), Qt::CaseInsensitive) == 0) { - return QV4::Encode(scope.engine->newArrayBuffer(r->rawResponseBody())); + RETURN_RESULT(scope.engine->newArrayBuffer(r->rawResponseBody())); } else if (responseType.compare(QLatin1String("json"), Qt::CaseInsensitive) == 0) { - return r->jsonResponseBody(scope.engine); + RETURN_RESULT(r->jsonResponseBody(scope.engine)); } else if (responseType.compare(QLatin1String("document"), Qt::CaseInsensitive) == 0) { - return r->xmlResponseBody(scope.engine); + RETURN_RESULT(r->xmlResponseBody(scope.engine)); } else { - return QV4::Encode(scope.engine->newString(QString())); + RETURN_RESULT(scope.engine->newString(QString())); } } -ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseType(CallContext *ctx) +void QQmlXMLHttpRequestCtor::method_get_responseType(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { - Scope scope(ctx); - Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>()); + Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>()); if (!w) V4THROW_REFERENCE("Not an XMLHttpRequest object"); QQmlXMLHttpRequest *r = w->d()->request; - return QV4::Encode(scope.engine->newString(r->responseType())); + scope.result = scope.engine->newString(r->responseType()); } -ReturnedValue QQmlXMLHttpRequestCtor::method_set_responseType(CallContext *ctx) +void QQmlXMLHttpRequestCtor::method_set_responseType(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { - Scope scope(ctx); - Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>()); + Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>()); if (!w) V4THROW_REFERENCE("Not an XMLHttpRequest object"); QQmlXMLHttpRequest *r = w->d()->request; - if (ctx->argc() < 1) - V4THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count"); + if (callData->argc < 1) + THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count"); // Argument 0 - response type - r->setResponseType(ctx->args()[0].toQStringNoThrow()); + r->setResponseType(callData->args[0].toQStringNoThrow()); - return Encode::undefined(); + scope.result = Encode::undefined(); } void qt_rem_qmlxmlhttprequest(ExecutionEngine * /* engine */, void *d) diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp index 19dc100f40..d359a0f62f 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp @@ -85,6 +85,12 @@ using namespace QV4; DEFINE_OBJECT_VTABLE(QtObject); +#define THROW_TYPE_ERROR_WITH_MESSAGE(msg) \ + do { \ + scope.result = scope.engine->throwTypeError(QString::fromUtf8(msg)); \ + return; \ + } while (false) + struct StaticQtMetaObject : public QObject { static const QMetaObject *get() @@ -223,12 +229,12 @@ void QtObject::advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint \qmlmethod bool Qt::isQtObject(object) Returns true if \c object is a valid reference to a Qt or QML object, otherwise false. */ -ReturnedValue QtObject::method_isQtObject(QV4::CallContext *ctx) +void QtObject::method_isQtObject(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (ctx->argc() == 0) - return QV4::Encode(false); + if (callData->argc == 0) + RETURN_RESULT(QV4::Encode(false)); - return QV4::Encode(ctx->args()[0].as<QV4::QObjectWrapper>() != 0); + scope.result = QV4::Encode(callData->args[0].as<QV4::QObjectWrapper>() != 0); } /*! @@ -237,16 +243,16 @@ ReturnedValue QtObject::method_isQtObject(QV4::CallContext *ctx) Returns a color with the specified \c red, \c green, \c blue and \c alpha components. All components should be in the range 0-1 inclusive. */ -ReturnedValue QtObject::method_rgba(QV4::CallContext *ctx) +void QtObject::method_rgba(const BuiltinFunction *, Scope &scope, CallData *callData) { - int argCount = ctx->argc(); + int argCount = callData->argc; if (argCount < 3 || argCount > 4) - V4THROW_ERROR("Qt.rgba(): Invalid arguments"); + THROW_GENERIC_ERROR("Qt.rgba(): Invalid arguments"); - double r = ctx->args()[0].toNumber(); - double g = ctx->args()[1].toNumber(); - double b = ctx->args()[2].toNumber(); - double a = (argCount == 4) ? ctx->args()[3].toNumber() : 1; + double r = callData->args[0].toNumber(); + double g = callData->args[1].toNumber(); + double b = callData->args[2].toNumber(); + double a = (argCount == 4) ? callData->args[3].toNumber() : 1; if (r < 0.0) r=0.0; if (r > 1.0) r=1.0; @@ -257,7 +263,7 @@ ReturnedValue QtObject::method_rgba(QV4::CallContext *ctx) if (a < 0.0) a=0.0; if (a > 1.0) a=1.0; - return ctx->engine()->fromVariant(QQml_colorProvider()->fromRgbF(r, g, b, a)); + scope.result = scope.engine->fromVariant(QQml_colorProvider()->fromRgbF(r, g, b, a)); } /*! @@ -266,16 +272,16 @@ ReturnedValue QtObject::method_rgba(QV4::CallContext *ctx) Returns a color with the specified \c hue, \c saturation, \c lightness and \c alpha components. All components should be in the range 0-1 inclusive. */ -ReturnedValue QtObject::method_hsla(QV4::CallContext *ctx) +void QtObject::method_hsla(const BuiltinFunction *, Scope &scope, CallData *callData) { - int argCount = ctx->argc(); + int argCount = callData->argc; if (argCount < 3 || argCount > 4) - V4THROW_ERROR("Qt.hsla(): Invalid arguments"); + THROW_GENERIC_ERROR("Qt.hsla(): Invalid arguments"); - double h = ctx->args()[0].toNumber(); - double s = ctx->args()[1].toNumber(); - double l = ctx->args()[2].toNumber(); - double a = (argCount == 4) ? ctx->args()[3].toNumber() : 1; + double h = callData->args[0].toNumber(); + double s = callData->args[1].toNumber(); + double l = callData->args[2].toNumber(); + double a = (argCount == 4) ? callData->args[3].toNumber() : 1; if (h < 0.0) h=0.0; if (h > 1.0) h=1.0; @@ -286,7 +292,7 @@ ReturnedValue QtObject::method_hsla(QV4::CallContext *ctx) if (a < 0.0) a=0.0; if (a > 1.0) a=1.0; - return ctx->engine()->fromVariant(QQml_colorProvider()->fromHslF(h, s, l, a)); + scope.result = scope.engine->fromVariant(QQml_colorProvider()->fromHslF(h, s, l, a)); } /*! @@ -297,23 +303,23 @@ All components should be in the range 0-1 inclusive. \since 5.5 */ -ReturnedValue QtObject::method_hsva(QV4::CallContext *ctx) +void QtObject::method_hsva(const BuiltinFunction *, Scope &scope, CallData *callData) { - int argCount = ctx->argc(); + int argCount = callData->argc; if (argCount < 3 || argCount > 4) - V4THROW_ERROR("Qt.hsva(): Invalid arguments"); + THROW_GENERIC_ERROR("Qt.hsva(): Invalid arguments"); - double h = ctx->args()[0].toNumber(); - double s = ctx->args()[1].toNumber(); - double v = ctx->args()[2].toNumber(); - double a = (argCount == 4) ? ctx->args()[3].toNumber() : 1; + double h = callData->args[0].toNumber(); + double s = callData->args[1].toNumber(); + double v = callData->args[2].toNumber(); + double a = (argCount == 4) ? callData->args[3].toNumber() : 1; h = qBound(0.0, h, 1.0); s = qBound(0.0, s, 1.0); v = qBound(0.0, v, 1.0); a = qBound(0.0, a, 1.0); - return ctx->engine()->fromVariant(QQml_colorProvider()->fromHsvF(h, s, v, a)); + scope.result = scope.engine->fromVariant(QQml_colorProvider()->fromHsvF(h, s, v, a)); } /*! @@ -324,35 +330,35 @@ may be either color values or string values. If a string value is supplied it must be convertible to a color, as described for the \l{colorbasictypedocs}{color} basic type. */ -ReturnedValue QtObject::method_colorEqual(QV4::CallContext *ctx) +void QtObject::method_colorEqual(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (ctx->argc() != 2) - V4THROW_ERROR("Qt.colorEqual(): Invalid arguments"); + if (callData->argc != 2) + THROW_GENERIC_ERROR("Qt.colorEqual(): Invalid arguments"); bool ok = false; - QVariant lhs = ctx->d()->engine->toVariant(ctx->args()[0], -1); + QVariant lhs = scope.engine->toVariant(callData->args[0], -1); if (lhs.userType() == QVariant::String) { lhs = QQmlStringConverters::colorFromString(lhs.toString(), &ok); if (!ok) { - V4THROW_ERROR("Qt.colorEqual(): Invalid color name"); + THROW_GENERIC_ERROR("Qt.colorEqual(): Invalid color name"); } } else if (lhs.userType() != QVariant::Color) { - V4THROW_ERROR("Qt.colorEqual(): Invalid arguments"); + THROW_GENERIC_ERROR("Qt.colorEqual(): Invalid arguments"); } - QVariant rhs = ctx->engine()->toVariant(ctx->args()[1], -1); + QVariant rhs = scope.engine->toVariant(callData->args[1], -1); if (rhs.userType() == QVariant::String) { rhs = QQmlStringConverters::colorFromString(rhs.toString(), &ok); if (!ok) { - V4THROW_ERROR("Qt.colorEqual(): Invalid color name"); + THROW_GENERIC_ERROR("Qt.colorEqual(): Invalid color name"); } } else if (rhs.userType() != QVariant::Color) { - V4THROW_ERROR("Qt.colorEqual(): Invalid arguments"); + THROW_GENERIC_ERROR("Qt.colorEqual(): Invalid arguments"); } bool equal = (lhs == rhs); - return QV4::Encode(equal); + scope.result = QV4::Encode(equal); } /*! @@ -362,47 +368,47 @@ Returns a \c rect with the top-left corner at \c x, \c y and the specified \c wi The returned object has \c x, \c y, \c width and \c height attributes with the given values. */ -ReturnedValue QtObject::method_rect(QV4::CallContext *ctx) +void QtObject::method_rect(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (ctx->argc() != 4) - V4THROW_ERROR("Qt.rect(): Invalid arguments"); + if (callData->argc != 4) + THROW_GENERIC_ERROR("Qt.rect(): Invalid arguments"); - double x = ctx->args()[0].toNumber(); - double y = ctx->args()[1].toNumber(); - double w = ctx->args()[2].toNumber(); - double h = ctx->args()[3].toNumber(); + double x = callData->args[0].toNumber(); + double y = callData->args[1].toNumber(); + double w = callData->args[2].toNumber(); + double h = callData->args[3].toNumber(); - return ctx->engine()->fromVariant(QVariant::fromValue(QRectF(x, y, w, h))); + scope.result = scope.engine->fromVariant(QVariant::fromValue(QRectF(x, y, w, h))); } /*! \qmlmethod point Qt::point(int x, int y) Returns a Point with the specified \c x and \c y coordinates. */ -ReturnedValue QtObject::method_point(QV4::CallContext *ctx) +void QtObject::method_point(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (ctx->argc() != 2) - V4THROW_ERROR("Qt.point(): Invalid arguments"); + if (callData->argc != 2) + THROW_GENERIC_ERROR("Qt.point(): Invalid arguments"); - double x = ctx->args()[0].toNumber(); - double y = ctx->args()[1].toNumber(); + double x = callData->args[0].toNumber(); + double y = callData->args[1].toNumber(); - return ctx->engine()->fromVariant(QVariant::fromValue(QPointF(x, y))); + scope.result = scope.engine->fromVariant(QVariant::fromValue(QPointF(x, y))); } /*! \qmlmethod Qt::size(int width, int height) Returns a Size with the specified \c width and \c height. */ -ReturnedValue QtObject::method_size(QV4::CallContext *ctx) +void QtObject::method_size(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (ctx->argc() != 2) - V4THROW_ERROR("Qt.size(): Invalid arguments"); + if (callData->argc != 2) + THROW_GENERIC_ERROR("Qt.size(): Invalid arguments"); - double w = ctx->args()[0].toNumber(); - double h = ctx->args()[1].toNumber(); + double w = callData->args[0].toNumber(); + double h = callData->args[1].toNumber(); - return ctx->engine()->fromVariant(QVariant::fromValue(QSizeF(w, h))); + scope.result = scope.engine->fromVariant(QVariant::fromValue(QSizeF(w, h))); } /*! @@ -413,17 +419,17 @@ key-value pairs where valid keys are the \l{fontbasictypedocs}{font} type's subproperty names, and the values are valid values for each subproperty. Invalid keys will be ignored. */ -ReturnedValue QtObject::method_font(QV4::CallContext *ctx) +void QtObject::method_font(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (ctx->argc() != 1 || !ctx->args()[0].isObject()) - V4THROW_ERROR("Qt.font(): Invalid arguments"); + if (callData->argc != 1 || !callData->args[0].isObject()) + THROW_GENERIC_ERROR("Qt.font(): Invalid arguments"); - QV4::ExecutionEngine *v4 = ctx->d()->engine; + QV4::ExecutionEngine *v4 = scope.engine; bool ok = false; - QVariant v = QQml_valueTypeProvider()->createVariantFromJsObject(QMetaType::QFont, QQmlV4Handle(ctx->args()[0]), v4, &ok); + QVariant v = QQml_valueTypeProvider()->createVariantFromJsObject(QMetaType::QFont, QQmlV4Handle(callData->args[0]), v4, &ok); if (!ok) - V4THROW_ERROR("Qt.font(): Invalid argument: no valid font subproperties specified"); - return ctx->engine()->fromVariant(v); + THROW_GENERIC_ERROR("Qt.font(): Invalid argument: no valid font subproperties specified"); + scope.result = scope.engine->fromVariant(v); } @@ -432,73 +438,73 @@ ReturnedValue QtObject::method_font(QV4::CallContext *ctx) \qmlmethod Qt::vector2d(real x, real y) Returns a Vector2D with the specified \c x and \c y. */ -ReturnedValue QtObject::method_vector2d(QV4::CallContext *ctx) +void QtObject::method_vector2d(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (ctx->argc() != 2) - V4THROW_ERROR("Qt.vector2d(): Invalid arguments"); + if (callData->argc != 2) + THROW_GENERIC_ERROR("Qt.vector2d(): Invalid arguments"); float xy[3]; // qvector2d uses float internally - xy[0] = ctx->args()[0].toNumber(); - xy[1] = ctx->args()[1].toNumber(); + xy[0] = callData->args[0].toNumber(); + xy[1] = callData->args[1].toNumber(); const void *params[] = { xy }; - return ctx->engine()->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector2D, 1, params)); + scope.result = scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector2D, 1, params)); } /*! \qmlmethod Qt::vector3d(real x, real y, real z) Returns a Vector3D with the specified \c x, \c y and \c z. */ -ReturnedValue QtObject::method_vector3d(QV4::CallContext *ctx) +void QtObject::method_vector3d(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (ctx->argc() != 3) - V4THROW_ERROR("Qt.vector3d(): Invalid arguments"); + if (callData->argc != 3) + THROW_GENERIC_ERROR("Qt.vector3d(): Invalid arguments"); float xyz[3]; // qvector3d uses float internally - xyz[0] = ctx->args()[0].toNumber(); - xyz[1] = ctx->args()[1].toNumber(); - xyz[2] = ctx->args()[2].toNumber(); + xyz[0] = callData->args[0].toNumber(); + xyz[1] = callData->args[1].toNumber(); + xyz[2] = callData->args[2].toNumber(); const void *params[] = { xyz }; - return ctx->engine()->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector3D, 1, params)); + scope.result = scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector3D, 1, params)); } /*! \qmlmethod Qt::vector4d(real x, real y, real z, real w) Returns a Vector4D with the specified \c x, \c y, \c z and \c w. */ -ReturnedValue QtObject::method_vector4d(QV4::CallContext *ctx) +void QtObject::method_vector4d(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (ctx->argc() != 4) - V4THROW_ERROR("Qt.vector4d(): Invalid arguments"); + if (callData->argc != 4) + THROW_GENERIC_ERROR("Qt.vector4d(): Invalid arguments"); float xyzw[4]; // qvector4d uses float internally - xyzw[0] = ctx->args()[0].toNumber(); - xyzw[1] = ctx->args()[1].toNumber(); - xyzw[2] = ctx->args()[2].toNumber(); - xyzw[3] = ctx->args()[3].toNumber(); + xyzw[0] = callData->args[0].toNumber(); + xyzw[1] = callData->args[1].toNumber(); + xyzw[2] = callData->args[2].toNumber(); + xyzw[3] = callData->args[3].toNumber(); const void *params[] = { xyzw }; - return ctx->engine()->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector4D, 1, params)); + scope.result = scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector4D, 1, params)); } /*! \qmlmethod Qt::quaternion(real scalar, real x, real y, real z) Returns a Quaternion with the specified \c scalar, \c x, \c y, and \c z. */ -ReturnedValue QtObject::method_quaternion(QV4::CallContext *ctx) +void QtObject::method_quaternion(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (ctx->argc() != 4) - V4THROW_ERROR("Qt.quaternion(): Invalid arguments"); + if (callData->argc != 4) + THROW_GENERIC_ERROR("Qt.quaternion(): Invalid arguments"); qreal sxyz[4]; // qquaternion uses qreal internally - sxyz[0] = ctx->args()[0].toNumber(); - sxyz[1] = ctx->args()[1].toNumber(); - sxyz[2] = ctx->args()[2].toNumber(); - sxyz[3] = ctx->args()[3].toNumber(); + sxyz[0] = callData->args[0].toNumber(); + sxyz[1] = callData->args[1].toNumber(); + sxyz[2] = callData->args[2].toNumber(); + sxyz[3] = callData->args[3].toNumber(); const void *params[] = { sxyz }; - return ctx->engine()->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QQuaternion, 1, params)); + scope.result = scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QQuaternion, 1, params)); } /*! @@ -510,44 +516,47 @@ matrix values. Finally, the function may be called with no arguments and the resulting matrix will be the identity matrix. */ -ReturnedValue QtObject::method_matrix4x4(QV4::CallContext *ctx) +void QtObject::method_matrix4x4(const BuiltinFunction *, Scope &scope, CallData *callData) { - QV4::ExecutionEngine *v4 = ctx->d()->engine; + QV4::ExecutionEngine *v4 = scope.engine; - if (ctx->argc() == 0) - return ctx->engine()->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, 0, Q_NULLPTR)); + if (callData->argc == 0) { + scope.result = scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, 0, Q_NULLPTR)); + return; + } - if (ctx->argc() == 1 && ctx->args()[0].isObject()) { + if (callData->argc == 1 && callData->args[0].isObject()) { bool ok = false; - QVariant v = QQml_valueTypeProvider()->createVariantFromJsObject(QMetaType::QMatrix4x4, QQmlV4Handle(ctx->args()[0]), v4, &ok); + QVariant v = QQml_valueTypeProvider()->createVariantFromJsObject(QMetaType::QMatrix4x4, QQmlV4Handle(callData->args[0]), v4, &ok); if (!ok) - V4THROW_ERROR("Qt.matrix4x4(): Invalid argument: not a valid matrix4x4 values array"); - return ctx->engine()->fromVariant(v); + THROW_GENERIC_ERROR("Qt.matrix4x4(): Invalid argument: not a valid matrix4x4 values array"); + scope.result = scope.engine->fromVariant(v); + return; } - if (ctx->argc() != 16) - V4THROW_ERROR("Qt.matrix4x4(): Invalid arguments"); + if (callData->argc != 16) + THROW_GENERIC_ERROR("Qt.matrix4x4(): Invalid arguments"); qreal vals[16]; // qmatrix4x4 uses qreal internally - vals[0] = ctx->args()[0].toNumber(); - vals[1] = ctx->args()[1].toNumber(); - vals[2] = ctx->args()[2].toNumber(); - vals[3] = ctx->args()[3].toNumber(); - vals[4] = ctx->args()[4].toNumber(); - vals[5] = ctx->args()[5].toNumber(); - vals[6] = ctx->args()[6].toNumber(); - vals[7] = ctx->args()[7].toNumber(); - vals[8] = ctx->args()[8].toNumber(); - vals[9] = ctx->args()[9].toNumber(); - vals[10] = ctx->args()[10].toNumber(); - vals[11] = ctx->args()[11].toNumber(); - vals[12] = ctx->args()[12].toNumber(); - vals[13] = ctx->args()[13].toNumber(); - vals[14] = ctx->args()[14].toNumber(); - vals[15] = ctx->args()[15].toNumber(); + vals[0] = callData->args[0].toNumber(); + vals[1] = callData->args[1].toNumber(); + vals[2] = callData->args[2].toNumber(); + vals[3] = callData->args[3].toNumber(); + vals[4] = callData->args[4].toNumber(); + vals[5] = callData->args[5].toNumber(); + vals[6] = callData->args[6].toNumber(); + vals[7] = callData->args[7].toNumber(); + vals[8] = callData->args[8].toNumber(); + vals[9] = callData->args[9].toNumber(); + vals[10] = callData->args[10].toNumber(); + vals[11] = callData->args[11].toNumber(); + vals[12] = callData->args[12].toNumber(); + vals[13] = callData->args[13].toNumber(); + vals[14] = callData->args[14].toNumber(); + vals[15] = callData->args[15].toNumber(); const void *params[] = { vals }; - return ctx->engine()->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, 1, params)); + scope.result = scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, 1, params)); } /*! @@ -564,27 +573,29 @@ by factor and converts the color back to RGB. If \c factor is not supplied, returns a color 50% lighter than \c baseColor (factor 1.5). */ -ReturnedValue QtObject::method_lighter(QV4::CallContext *ctx) +void QtObject::method_lighter(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (ctx->argc() != 1 && ctx->argc() != 2) - V4THROW_ERROR("Qt.lighter(): Invalid arguments"); + if (callData->argc != 1 && callData->argc != 2) + THROW_GENERIC_ERROR("Qt.lighter(): Invalid arguments"); - QVariant v = ctx->engine()->toVariant(ctx->args()[0], -1); + QVariant v = scope.engine->toVariant(callData->args[0], -1); if (v.userType() == QVariant::String) { bool ok = false; v = QQmlStringConverters::colorFromString(v.toString(), &ok); if (!ok) { - return QV4::Encode::null(); + scope.result = QV4::Encode::null(); + return; } } else if (v.userType() != QVariant::Color) { - return QV4::Encode::null(); + scope.result = QV4::Encode::null(); + return; } qreal factor = 1.5; - if (ctx->argc() == 2) - factor = ctx->args()[1].toNumber(); + if (callData->argc == 2) + factor = callData->args[1].toNumber(); - return ctx->engine()->fromVariant(QQml_colorProvider()->lighter(v, factor)); + scope.result = scope.engine->fromVariant(QQml_colorProvider()->lighter(v, factor)); } /*! @@ -602,27 +613,29 @@ by factor and converts the color back to RGB. If \c factor is not supplied, returns a color 50% darker than \c baseColor (factor 2.0). */ -ReturnedValue QtObject::method_darker(QV4::CallContext *ctx) +void QtObject::method_darker(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (ctx->argc() != 1 && ctx->argc() != 2) - V4THROW_ERROR("Qt.darker(): Invalid arguments"); + if (callData->argc != 1 && callData->argc != 2) + THROW_GENERIC_ERROR("Qt.darker(): Invalid arguments"); - QVariant v = ctx->engine()->toVariant(ctx->args()[0], -1); + QVariant v = scope.engine->toVariant(callData->args[0], -1); if (v.userType() == QVariant::String) { bool ok = false; v = QQmlStringConverters::colorFromString(v.toString(), &ok); if (!ok) { - return QV4::Encode::null(); + scope.result = QV4::Encode::null(); + return; } } else if (v.userType() != QVariant::Color) { - return QV4::Encode::null(); + scope.result = QV4::Encode::null(); + return; } qreal factor = 2.0; - if (ctx->argc() == 2) - factor = ctx->args()[1].toNumber(); + if (callData->argc == 2) + factor = callData->args[1].toNumber(); - return ctx->engine()->fromVariant(QQml_colorProvider()->darker(v, factor)); + scope.result = scope.engine->fromVariant(QQml_colorProvider()->darker(v, factor)); } /*! @@ -649,36 +662,40 @@ ReturnedValue QtObject::method_darker(QV4::CallContext *ctx) Tint is most useful when a subtle change is intended to be conveyed due to some event; you can then use tinting to more effectively tune the visible color. */ -ReturnedValue QtObject::method_tint(QV4::CallContext *ctx) +void QtObject::method_tint(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (ctx->argc() != 2) - V4THROW_ERROR("Qt.tint(): Invalid arguments"); + if (callData->argc != 2) + THROW_GENERIC_ERROR("Qt.tint(): Invalid arguments"); // base color - QVariant v1 = ctx->engine()->toVariant(ctx->args()[0], -1); + QVariant v1 = scope.engine->toVariant(callData->args[0], -1); if (v1.userType() == QVariant::String) { bool ok = false; v1 = QQmlStringConverters::colorFromString(v1.toString(), &ok); if (!ok) { - return QV4::Encode::null(); + scope.result = QV4::Encode::null(); + return; } } else if (v1.userType() != QVariant::Color) { - return QV4::Encode::null(); + scope.result = QV4::Encode::null(); + return; } // tint color - QVariant v2 = ctx->engine()->toVariant(ctx->args()[1], -1); + QVariant v2 = scope.engine->toVariant(callData->args[1], -1); if (v2.userType() == QVariant::String) { bool ok = false; v2 = QQmlStringConverters::colorFromString(v2.toString(), &ok); if (!ok) { - return QV4::Encode::null(); + scope.result = QV4::Encode::null(); + return; } } else if (v2.userType() != QVariant::Color) { - return QV4::Encode::null(); + scope.result = QV4::Encode::null(); + return; } - return ctx->engine()->fromVariant(QQml_colorProvider()->tint(v1, v2)); + scope.result = scope.engine->fromVariant(QQml_colorProvider()->tint(v1, v2)); } /*! @@ -697,32 +714,31 @@ If \a format is not specified, \a date is formatted using \sa Locale */ -ReturnedValue QtObject::method_formatDate(QV4::CallContext *ctx) +void QtObject::method_formatDate(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (ctx->argc() < 1 || ctx->argc() > 2) - V4THROW_ERROR("Qt.formatDate(): Invalid arguments"); - QV4::Scope scope(ctx); + if (callData->argc < 1 || callData->argc > 2) + THROW_GENERIC_ERROR("Qt.formatDate(): Invalid arguments"); Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate; - QDate date = ctx->engine()->toVariant(ctx->args()[0], -1).toDateTime().date(); + QDate date = scope.engine->toVariant(callData->args[0], -1).toDateTime().date(); QString formattedDate; - if (ctx->argc() == 2) { - QV4::ScopedString s(scope, ctx->args()[1]); + if (callData->argc == 2) { + QV4::ScopedString s(scope, callData->args[1]); if (s) { QString format = s->toQString(); formattedDate = date.toString(format); - } else if (ctx->args()[1].isNumber()) { - quint32 intFormat = ctx->args()[1].asDouble(); + } else if (callData->args[1].isNumber()) { + quint32 intFormat = callData->args[1].asDouble(); Qt::DateFormat format = Qt::DateFormat(intFormat); formattedDate = date.toString(format); } else { - V4THROW_ERROR("Qt.formatDate(): Invalid date format"); + THROW_GENERIC_ERROR("Qt.formatDate(): Invalid date format"); } } else { formattedDate = date.toString(enumFormat); } - return ctx->d()->engine->newString(formattedDate)->asReturnedValue(); + scope.result = scope.engine->newString(formattedDate); } /*! @@ -740,38 +756,37 @@ If \a format is not specified, \a time is formatted using \sa Locale */ -ReturnedValue QtObject::method_formatTime(QV4::CallContext *ctx) +void QtObject::method_formatTime(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (ctx->argc() < 1 || ctx->argc() > 2) - V4THROW_ERROR("Qt.formatTime(): Invalid arguments"); - QV4::Scope scope(ctx); + if (callData->argc < 1 || callData->argc > 2) + THROW_GENERIC_ERROR("Qt.formatTime(): Invalid arguments"); - QVariant argVariant = ctx->engine()->toVariant(ctx->args()[0], -1); + QVariant argVariant = scope.engine->toVariant(callData->args[0], -1); QTime time; - if (ctx->args()[0].as<DateObject>() || (argVariant.type() == QVariant::String)) + if (callData->args[0].as<DateObject>() || (argVariant.type() == QVariant::String)) time = argVariant.toDateTime().time(); else // if (argVariant.type() == QVariant::Time), or invalid. time = argVariant.toTime(); Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate; QString formattedTime; - if (ctx->argc() == 2) { - QV4::ScopedString s(scope, ctx->args()[1]); + if (callData->argc == 2) { + QV4::ScopedString s(scope, callData->args[1]); if (s) { QString format = s->toQString(); formattedTime = time.toString(format); - } else if (ctx->args()[1].isNumber()) { - quint32 intFormat = ctx->args()[1].asDouble(); + } else if (callData->args[1].isNumber()) { + quint32 intFormat = callData->args[1].asDouble(); Qt::DateFormat format = Qt::DateFormat(intFormat); formattedTime = time.toString(format); } else { - V4THROW_ERROR("Qt.formatTime(): Invalid time format"); + THROW_GENERIC_ERROR("Qt.formatTime(): Invalid time format"); } } else { formattedTime = time.toString(enumFormat); } - return ctx->d()->engine->newString(formattedTime)->asReturnedValue(); + scope.result = scope.engine->newString(formattedTime); } /*! @@ -864,32 +879,31 @@ with the \a format values below to produce the following results: \sa Locale */ -ReturnedValue QtObject::method_formatDateTime(QV4::CallContext *ctx) +void QtObject::method_formatDateTime(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (ctx->argc() < 1 || ctx->argc() > 2) - V4THROW_ERROR("Qt.formatDateTime(): Invalid arguments"); - QV4::Scope scope(ctx); + if (callData->argc < 1 || callData->argc > 2) + THROW_GENERIC_ERROR("Qt.formatDateTime(): Invalid arguments"); Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate; - QDateTime dt = ctx->engine()->toVariant(ctx->args()[0], -1).toDateTime(); + QDateTime dt = scope.engine->toVariant(callData->args[0], -1).toDateTime(); QString formattedDt; - if (ctx->argc() == 2) { - QV4::ScopedString s(scope, ctx->args()[1]); + if (callData->argc == 2) { + QV4::ScopedString s(scope, callData->args[1]); if (s) { QString format = s->toQString(); formattedDt = dt.toString(format); - } else if (ctx->args()[1].isNumber()) { - quint32 intFormat = ctx->args()[1].asDouble(); + } else if (callData->args[1].isNumber()) { + quint32 intFormat = callData->args[1].asDouble(); Qt::DateFormat format = Qt::DateFormat(intFormat); formattedDt = dt.toString(format); } else { - V4THROW_ERROR("Qt.formatDateTime(): Invalid datetime format"); + THROW_GENERIC_ERROR("Qt.formatDateTime(): Invalid datetime format"); } } else { formattedDt = dt.toString(enumFormat); } - return ctx->d()->engine->newString(formattedDt)->asReturnedValue(); + scope.result = scope.engine->newString(formattedDt); } /*! @@ -903,90 +917,94 @@ ReturnedValue QtObject::method_formatDateTime(QV4::CallContext *ctx) still fail to launch or fail to open the requested URL. This result will not be reported back to the application. */ -ReturnedValue QtObject::method_openUrlExternally(QV4::CallContext *ctx) +void QtObject::method_openUrlExternally(const BuiltinFunction *b, Scope &scope, CallData *callData) { - if (ctx->argc() != 1) - return QV4::Encode(false); + if (callData->argc != 1) { + scope.result = QV4::Encode(false); + return; + } - QUrl url(Value::fromReturnedValue(method_resolvedUrl(ctx)).toQStringNoThrow()); - return ctx->engine()->fromVariant(QQml_guiProvider()->openUrlExternally(url)); + method_resolvedUrl(b, scope, callData); + QUrl url(scope.result.toQStringNoThrow()); + scope.result = scope.engine->fromVariant(QQml_guiProvider()->openUrlExternally(url)); } /*! \qmlmethod url Qt::resolvedUrl(url url) Returns \a url resolved relative to the URL of the caller. */ -ReturnedValue QtObject::method_resolvedUrl(QV4::CallContext *ctx) +void QtObject::method_resolvedUrl(const BuiltinFunction *, Scope &scope, CallData *callData) { - ExecutionEngine *v4 = ctx->engine(); + ExecutionEngine *v4 = scope.engine; - QUrl url = v4->toVariant(ctx->args()[0], -1).toUrl(); + QUrl url = v4->toVariant(callData->args[0], -1).toUrl(); QQmlEngine *e = v4->qmlEngine(); QQmlEnginePrivate *p = 0; if (e) p = QQmlEnginePrivate::get(e); if (p) { QQmlContextData *ctxt = v4->callingQmlContext(); if (ctxt) - return v4->newString(ctxt->resolvedUrl(url).toString())->asReturnedValue(); + scope.result = v4->newString(ctxt->resolvedUrl(url).toString()); else - return v4->newString(url.toString())->asReturnedValue(); + scope.result = v4->newString(url.toString()); + return; } - return v4->newString(e->baseUrl().resolved(url).toString())->asReturnedValue(); + scope.result = v4->newString(e->baseUrl().resolved(url).toString()); } /*! \qmlmethod list<string> Qt::fontFamilies() Returns a list of the font families available to the application. */ -ReturnedValue QtObject::method_fontFamilies(CallContext *ctx) +void QtObject::method_fontFamilies(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (ctx->argc() != 0) - V4THROW_ERROR("Qt.fontFamilies(): Invalid arguments"); + if (callData->argc != 0) + THROW_GENERIC_ERROR("Qt.fontFamilies(): Invalid arguments"); - return ctx->engine()->fromVariant(QVariant(QQml_guiProvider()->fontFamilies())); + scope.result = scope.engine->fromVariant(QVariant(QQml_guiProvider()->fontFamilies())); } /*! \qmlmethod string Qt::md5(data) Returns a hex string of the md5 hash of \c data. */ -ReturnedValue QtObject::method_md5(CallContext *ctx) +void QtObject::method_md5(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (ctx->argc() != 1) - V4THROW_ERROR("Qt.md5(): Invalid arguments"); + if (callData->argc != 1) + THROW_GENERIC_ERROR("Qt.md5(): Invalid arguments"); - QByteArray data = ctx->args()[0].toQStringNoThrow().toUtf8(); + QByteArray data = callData->args[0].toQStringNoThrow().toUtf8(); QByteArray result = QCryptographicHash::hash(data, QCryptographicHash::Md5); - return ctx->d()->engine->newString(QLatin1String(result.toHex()))->asReturnedValue(); + scope.result = scope.engine->newString(QLatin1String(result.toHex())); } /*! \qmlmethod string Qt::btoa(data) Binary to ASCII - this function returns a base64 encoding of \c data. */ -ReturnedValue QtObject::method_btoa(CallContext *ctx) +void QtObject::method_btoa(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (ctx->argc() != 1) - V4THROW_ERROR("Qt.btoa(): Invalid arguments"); + if (callData->argc != 1) + THROW_GENERIC_ERROR("Qt.btoa(): Invalid arguments"); - QByteArray data = ctx->args()[0].toQStringNoThrow().toUtf8(); + QByteArray data = callData->args[0].toQStringNoThrow().toUtf8(); - return ctx->d()->engine->newString(QLatin1String(data.toBase64()))->asReturnedValue(); + scope.result = scope.engine->newString(QLatin1String(data.toBase64())); } /*! \qmlmethod string Qt::atob(data) ASCII to binary - this function decodes the base64 encoded \a data string and returns it. */ -ReturnedValue QtObject::method_atob(CallContext *ctx) +void QtObject::method_atob(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (ctx->argc() != 1) - V4THROW_ERROR("Qt.atob(): Invalid arguments"); + if (callData->argc != 1) + THROW_GENERIC_ERROR("Qt.atob(): Invalid arguments"); - QByteArray data = ctx->args()[0].toQStringNoThrow().toLatin1(); + QByteArray data = callData->args[0].toQStringNoThrow().toLatin1(); - return ctx->d()->engine->newString(QString::fromUtf8(QByteArray::fromBase64(data)))->asReturnedValue(); + scope.result = scope.engine->newString(QString::fromUtf8(QByteArray::fromBase64(data))); } /*! @@ -998,10 +1016,10 @@ QQmlEngine::quit() signal to the QCoreApplication::quit() slot. \sa exit() */ -ReturnedValue QtObject::method_quit(CallContext *ctx) +void QtObject::method_quit(const BuiltinFunction *, Scope &scope, CallData *) { - QQmlEnginePrivate::get(ctx->engine()->qmlEngine())->sendQuit(); - return QV4::Encode::undefined(); + QQmlEnginePrivate::get(scope.engine->qmlEngine())->sendQuit(); + scope.result = Encode::undefined(); } /*! @@ -1015,15 +1033,15 @@ ReturnedValue QtObject::method_quit(CallContext *ctx) \sa quit() */ -ReturnedValue QtObject::method_exit(CallContext *ctx) +void QtObject::method_exit(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (ctx->argc() != 1) - V4THROW_ERROR("Qt.exit(): Invalid arguments"); + if (callData->argc != 1) + THROW_GENERIC_ERROR("Qt.exit(): Invalid arguments"); - int retCode = ctx->args()[0].toNumber(); + int retCode = callData->args[0].toNumber(); - QQmlEnginePrivate::get(ctx->engine()->qmlEngine())->sendExit(retCode); - return QV4::Encode::undefined(); + QQmlEnginePrivate::get(scope.engine->qmlEngine())->sendExit(retCode); + scope.result = QV4::Encode::undefined(); } /*! @@ -1050,11 +1068,10 @@ If this is the case, consider using \l{QtQml::Qt::createComponent()}{Qt.createCo See \l {Dynamic QML Object Creation from JavaScript} for more information on using this function. */ -ReturnedValue QtObject::method_createQmlObject(CallContext *ctx) +void QtObject::method_createQmlObject(const BuiltinFunction *, Scope &scope, CallData *callData) { - Scope scope(ctx); - if (ctx->argc() < 2 || ctx->argc() > 3) - V4THROW_ERROR("Qt.createQmlObject(): Invalid arguments"); + if (callData->argc < 2 || callData->argc > 3) + THROW_GENERIC_ERROR("Qt.createQmlObject(): Invalid arguments"); struct Error { static ReturnedValue create(QV4::ExecutionEngine *v4, const QList<QQmlError> &errors) { @@ -1085,7 +1102,7 @@ ReturnedValue QtObject::method_createQmlObject(CallContext *ctx) } }; - QV8Engine *v8engine = ctx->d()->engine->v8Engine; + QV8Engine *v8engine = scope.engine->v8Engine; QQmlEngine *engine = v8engine->engine(); QQmlContextData *context = scope.engine->callingQmlContext(); @@ -1097,13 +1114,13 @@ ReturnedValue QtObject::method_createQmlObject(CallContext *ctx) effectiveContext = context->asQQmlContext(); Q_ASSERT(effectiveContext); - QString qml = ctx->args()[0].toQStringNoThrow(); + QString qml = callData->args[0].toQStringNoThrow(); if (qml.isEmpty()) - return QV4::Encode::null(); + RETURN_RESULT(Encode::null()); QUrl url; - if (ctx->argc() > 2) - url = QUrl(ctx->args()[2].toQStringNoThrow()); + if (callData->argc > 2) + url = QUrl(callData->args[2].toQStringNoThrow()); else url = QUrl(QLatin1String("inline")); @@ -1111,11 +1128,11 @@ ReturnedValue QtObject::method_createQmlObject(CallContext *ctx) url = context->resolvedUrl(url); QObject *parentArg = 0; - QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, ctx->args()[1]); + QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, callData->args[1]); if (!!qobjectWrapper) parentArg = qobjectWrapper->object(); if (!parentArg) - V4THROW_ERROR("Qt.createQmlObject(): Missing parent object"); + THROW_GENERIC_ERROR("Qt.createQmlObject(): Missing parent object"); QQmlTypeData *typeData = QQmlEnginePrivate::get(engine)->typeLoader.getType( qml.toUtf8(), url, QQmlTypeLoader::Synchronous); @@ -1126,12 +1143,12 @@ ReturnedValue QtObject::method_createQmlObject(CallContext *ctx) componentPrivate->progress = 1.0; if (component.isError()) { - ScopedValue v(scope, Error::create(ctx->d()->engine, component.errors())); - return ctx->engine()->throwError(v); + ScopedValue v(scope, Error::create(scope.engine, component.errors())); + RETURN_RESULT(scope.engine->throwError(v)); } if (!component.isReady()) - V4THROW_ERROR("Qt.createQmlObject(): Component is not ready"); + THROW_GENERIC_ERROR("Qt.createQmlObject(): Component is not ready"); QObject *obj = component.beginCreate(effectiveContext); if (obj) { @@ -1150,13 +1167,14 @@ ReturnedValue QtObject::method_createQmlObject(CallContext *ctx) component.completeCreate(); if (component.isError()) { - ScopedValue v(scope, Error::create(ctx->d()->engine, component.errors())); - return ctx->engine()->throwError(v); + ScopedValue v(scope, Error::create(scope.engine, component.errors())); + scope.result = scope.engine->throwError(v); + return; } Q_ASSERT(obj); - return QV4::QObjectWrapper::wrap(ctx->d()->engine, obj); + scope.result = QV4::QObjectWrapper::wrap(scope.engine, obj); } /*! @@ -1203,14 +1221,12 @@ See \l {Dynamic QML Object Creation from JavaScript} for more information on usi To create a QML object from an arbitrary string of QML (instead of a file), use \l{QtQml::Qt::createQmlObject()}{Qt.createQmlObject()}. */ -ReturnedValue QtObject::method_createComponent(CallContext *ctx) +void QtObject::method_createComponent(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (ctx->argc() < 1 || ctx->argc() > 3) - return ctx->engine()->throwError(QStringLiteral("Qt.createComponent(): Invalid arguments")); + if (callData->argc < 1 || callData->argc > 3) + THROW_GENERIC_ERROR("Qt.createComponent(): Invalid arguments"); - Scope scope(ctx); - - QV8Engine *v8engine = ctx->d()->engine->v8Engine; + QV8Engine *v8engine = scope.engine->v8Engine; QQmlEngine *engine = v8engine->engine(); QQmlContextData *context = scope.engine->callingQmlContext(); @@ -1219,41 +1235,41 @@ ReturnedValue QtObject::method_createComponent(CallContext *ctx) if (context->isPragmaLibraryContext) effectiveContext = 0; - QString arg = ctx->args()[0].toQStringNoThrow(); + QString arg = callData->args[0].toQStringNoThrow(); if (arg.isEmpty()) - return QV4::Encode::null(); + RETURN_RESULT(QV4::Encode::null()); QQmlComponent::CompilationMode compileMode = QQmlComponent::PreferSynchronous; QObject *parentArg = 0; int consumedCount = 1; - if (ctx->argc() > 1) { - ScopedValue lastArg(scope, ctx->args()[ctx->argc()-1]); + if (callData->argc > 1) { + ScopedValue lastArg(scope, callData->args[callData->argc-1]); // The second argument could be the mode enum - if (ctx->args()[1].isInteger()) { - int mode = ctx->args()[1].integerValue(); + if (callData->args[1].isInteger()) { + int mode = callData->args[1].integerValue(); if (mode != int(QQmlComponent::PreferSynchronous) && mode != int(QQmlComponent::Asynchronous)) - return ctx->engine()->throwError(QStringLiteral("Qt.createComponent(): Invalid arguments")); + THROW_GENERIC_ERROR("Qt.createComponent(): Invalid arguments"); compileMode = QQmlComponent::CompilationMode(mode); consumedCount += 1; } else { // The second argument could be the parent only if there are exactly two args - if ((ctx->argc() != 2) || !(lastArg->isObject() || lastArg->isNull())) - return ctx->engine()->throwError(QStringLiteral("Qt.createComponent(): Invalid arguments")); + if ((callData->argc != 2) || !(lastArg->isObject() || lastArg->isNull())) + THROW_GENERIC_ERROR("Qt.createComponent(): Invalid arguments"); } - if (consumedCount < ctx->argc()) { + if (consumedCount < callData->argc) { if (lastArg->isObject()) { Scoped<QObjectWrapper> qobjectWrapper(scope, lastArg); if (qobjectWrapper) parentArg = qobjectWrapper->object(); if (!parentArg) - return ctx->engine()->throwError(QStringLiteral("Qt.createComponent(): Invalid parent object")); + THROW_GENERIC_ERROR("Qt.createComponent(): Invalid parent object"); } else if (lastArg->isNull()) { parentArg = 0; } else { - return ctx->engine()->throwError(QStringLiteral("Qt.createComponent(): Invalid parent object")); + THROW_GENERIC_ERROR("Qt.createComponent(): Invalid parent object"); } } } @@ -1264,7 +1280,7 @@ ReturnedValue QtObject::method_createComponent(CallContext *ctx) QQmlData::get(c, true)->explicitIndestructibleSet = false; QQmlData::get(c)->indestructible = false; - return QV4::QObjectWrapper::wrap(ctx->d()->engine, c); + scope.result = QV4::QObjectWrapper::wrap(scope.engine, c); } /*! @@ -1287,18 +1303,18 @@ ReturnedValue QtObject::method_createComponent(CallContext *ctx) \sa Locale */ -ReturnedValue QtObject::method_locale(CallContext *ctx) +void QtObject::method_locale(const BuiltinFunction *, Scope &scope, CallData *callData) { QString code; - if (ctx->argc() > 1) - V4THROW_ERROR("locale() requires 0 or 1 argument"); - if (ctx->argc() == 1 && !ctx->args()[0].isString()) - V4THROW_TYPE("locale(): argument (locale code) must be a string"); + if (callData->argc > 1) + THROW_GENERIC_ERROR("locale() requires 0 or 1 argument"); + if (callData->argc == 1 && !callData->args[0].isString()) + THROW_TYPE_ERROR_WITH_MESSAGE("locale(): argument (locale code) must be a string"); - if (ctx->argc() == 1) - code = ctx->args()[0].toQStringNoThrow(); + if (callData->argc == 1) + code = callData->args[0].toQStringNoThrow(); - return QQmlLocale::locale(ctx->engine(), code); + scope.result = QQmlLocale::locale(scope.engine, code); } void Heap::QQmlBindingFunction::init(const QV4::FunctionObject *originalFunction) @@ -1360,62 +1376,62 @@ DEFINE_OBJECT_VTABLE(QQmlBindingFunction); \since 5.0 */ -ReturnedValue QtObject::method_binding(CallContext *ctx) +void QtObject::method_binding(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (ctx->argc() != 1) - V4THROW_ERROR("binding() requires 1 argument"); - const QV4::FunctionObject *f = ctx->args()[0].as<FunctionObject>(); + if (callData->argc != 1) + THROW_GENERIC_ERROR("binding() requires 1 argument"); + const QV4::FunctionObject *f = callData->args[0].as<FunctionObject>(); if (!f) - V4THROW_TYPE("binding(): argument (binding expression) must be a function"); + THROW_TYPE_ERROR_WITH_MESSAGE("binding(): argument (binding expression) must be a function"); - return (ctx->d()->engine->memoryManager->allocObject<QQmlBindingFunction>(f))->asReturnedValue(); + scope.result = scope.engine->memoryManager->allocObject<QQmlBindingFunction>(f); } -ReturnedValue QtObject::method_get_platform(CallContext *ctx) +void QtObject::method_get_platform(const BuiltinFunction *, Scope &scope, CallData *callData) { // ### inefficient. Should be just a value based getter - Object *o = ctx->thisObject().as<Object>(); + Object *o = callData->thisObject.as<Object>(); if (!o) - return ctx->engine()->throwTypeError(); + THROW_TYPE_ERROR(); QtObject *qt = o->as<QtObject>(); if (!qt) - return ctx->engine()->throwTypeError(); + THROW_TYPE_ERROR(); if (!qt->d()->platform) // Only allocate a platform object once - qt->d()->platform = new QQmlPlatform(ctx->d()->engine->jsEngine()); + qt->d()->platform = new QQmlPlatform(scope.engine->jsEngine()); - return QV4::QObjectWrapper::wrap(ctx->d()->engine, qt->d()->platform); + scope.result = QV4::QObjectWrapper::wrap(scope.engine, qt->d()->platform); } -ReturnedValue QtObject::method_get_application(CallContext *ctx) +void QtObject::method_get_application(const BuiltinFunction *, Scope &scope, CallData *callData) { // ### inefficient. Should be just a value based getter - Object *o = ctx->thisObject().as<Object>(); + Object *o = callData->thisObject.as<Object>(); if (!o) - return ctx->engine()->throwTypeError(); + THROW_TYPE_ERROR(); QtObject *qt = o->as<QtObject>(); if (!qt) - return ctx->engine()->throwTypeError(); + THROW_TYPE_ERROR(); if (!qt->d()->application) // Only allocate an application object once - qt->d()->application = QQml_guiProvider()->application(ctx->d()->engine->jsEngine()); + qt->d()->application = QQml_guiProvider()->application(scope.engine->jsEngine()); - return QV4::QObjectWrapper::wrap(ctx->d()->engine, qt->d()->application); + scope.result = QV4::QObjectWrapper::wrap(scope.engine, qt->d()->application); } -ReturnedValue QtObject::method_get_inputMethod(CallContext *ctx) +void QtObject::method_get_inputMethod(const BuiltinFunction *, Scope &scope, CallData *) { QObject *o = QQml_guiProvider()->inputMethod(); - return QV4::QObjectWrapper::wrap(ctx->d()->engine, o); + scope.result = QV4::QObjectWrapper::wrap(scope.engine, o); } -ReturnedValue QtObject::method_get_styleHints(CallContext *ctx) +void QtObject::method_get_styleHints(const BuiltinFunction *, Scope &scope, CallData *) { QObject *o = QQml_guiProvider()->styleHints(); - return QV4::QObjectWrapper::wrap(ctx->d()->engine, o); + scope.result = QV4::QObjectWrapper::wrap(scope.engine, o); } @@ -1475,35 +1491,35 @@ static QString jsStack(QV4::ExecutionEngine *engine) { return stack; } -static QV4::ReturnedValue writeToConsole(ConsoleLogTypes logType, CallContext *ctx, - bool printStack = false) +static void writeToConsole(const BuiltinFunction *, Scope &scope, CallData *callData, + ConsoleLogTypes logType, bool printStack = false) { QLoggingCategory *loggingCategory = 0; QString result; - QV4::ExecutionEngine *v4 = ctx->d()->engine; + QV4::ExecutionEngine *v4 = scope.engine; int start = 0; - if (ctx->argc() > 0) { - if (const QObjectWrapper* wrapper = ctx->args()[0].as<QObjectWrapper>()) { + if (callData->argc > 0) { + if (const QObjectWrapper* wrapper = callData->args[0].as<QObjectWrapper>()) { if (QQmlLoggingCategory* category = qobject_cast<QQmlLoggingCategory*>(wrapper->object())) { if (category->category()) loggingCategory = category->category(); else - V4THROW_ERROR("A QmlLoggingCatgory was provided without a valid name"); + THROW_GENERIC_ERROR("A QmlLoggingCatgory was provided without a valid name"); start = 1; } } } - for (int i = start; i < ctx->argc(); ++i) { + for (int i = start; i < callData->argc; ++i) { if (i != start) result.append(QLatin1Char(' ')); - if (ctx->args()[i].as<ArrayObject>()) - result += QLatin1Char('[') + ctx->args()[i].toQStringNoThrow() + QLatin1Char(']'); + if (callData->args[i].as<ArrayObject>()) + result += QLatin1Char('[') + callData->args[i].toQStringNoThrow() + QLatin1Char(']'); else - result.append(ctx->args()[i].toQStringNoThrow()); + result.append(callData->args[i].toQStringNoThrow()); } if (printStack) @@ -1540,32 +1556,32 @@ static QV4::ReturnedValue writeToConsole(ConsoleLogTypes logType, CallContext *c break; } - return QV4::Encode::undefined(); + scope.result = QV4::Encode::undefined(); } DEFINE_OBJECT_VTABLE(ConsoleObject); -QV4::ReturnedValue ConsoleObject::method_error(CallContext *ctx) +void ConsoleObject::method_error(const BuiltinFunction *b, Scope &scope, CallData *callData) { - return writeToConsole(Error, ctx); + writeToConsole(b, scope, callData, Error); } -QV4::ReturnedValue ConsoleObject::method_log(CallContext *ctx) +void ConsoleObject::method_log(const BuiltinFunction *b, Scope &scope, CallData *callData) { //console.log //console.debug //print - return writeToConsole(Log, ctx); + writeToConsole(b, scope, callData, Log); } -QV4::ReturnedValue ConsoleObject::method_info(CallContext *ctx) +void ConsoleObject::method_info(const BuiltinFunction *b, Scope &scope, CallData *callData) { - return writeToConsole(Info, ctx); + writeToConsole(b, scope, callData, Info); } -QV4::ReturnedValue ConsoleObject::method_profile(CallContext *ctx) +void ConsoleObject::method_profile(const BuiltinFunction *, Scope &scope, CallData *) { - QV4::ExecutionEngine *v4 = ctx->d()->engine; + QV4::ExecutionEngine *v4 = scope.engine; QV4::StackFrame frame = v4->currentStackFrame(); const QByteArray baSource = frame.source.toUtf8(); @@ -1579,12 +1595,12 @@ QV4::ReturnedValue ConsoleObject::method_profile(CallContext *ctx) logger.debug("Profiling started."); } - return QV4::Encode::undefined(); + scope.result = QV4::Encode::undefined(); } -QV4::ReturnedValue ConsoleObject::method_profileEnd(CallContext *ctx) +void ConsoleObject::method_profileEnd(const BuiltinFunction *, Scope &scope, CallData *) { - QV4::ExecutionEngine *v4 = ctx->d()->engine; + QV4::ExecutionEngine *v4 = scope.engine; QV4::StackFrame frame = v4->currentStackFrame(); const QByteArray baSource = frame.source.toUtf8(); @@ -1599,46 +1615,46 @@ QV4::ReturnedValue ConsoleObject::method_profileEnd(CallContext *ctx) logger.debug("Profiling ended."); } - return QV4::Encode::undefined(); + scope.result = QV4::Encode::undefined(); } -QV4::ReturnedValue ConsoleObject::method_time(CallContext *ctx) +void ConsoleObject::method_time(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (ctx->argc() != 1) - V4THROW_ERROR("console.time(): Invalid arguments"); + if (callData->argc != 1) + THROW_GENERIC_ERROR("console.time(): Invalid arguments"); - QV8Engine *v8engine = ctx->d()->engine->v8Engine; + QV8Engine *v8engine = scope.engine->v8Engine; - QString name = ctx->args()[0].toQStringNoThrow(); + QString name = callData->args[0].toQStringNoThrow(); v8engine->startTimer(name); - return QV4::Encode::undefined(); + scope.result = QV4::Encode::undefined(); } -QV4::ReturnedValue ConsoleObject::method_timeEnd(CallContext *ctx) +void ConsoleObject::method_timeEnd(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (ctx->argc() != 1) - V4THROW_ERROR("console.timeEnd(): Invalid arguments"); + if (callData->argc != 1) + THROW_GENERIC_ERROR("console.timeEnd(): Invalid arguments"); - QV8Engine *v8engine = ctx->d()->engine->v8Engine; + QV8Engine *v8engine = scope.engine->v8Engine; - QString name = ctx->args()[0].toQStringNoThrow(); + QString name = callData->args[0].toQStringNoThrow(); bool wasRunning; qint64 elapsed = v8engine->stopTimer(name, &wasRunning); if (wasRunning) { qDebug("%s: %llims", qPrintable(name), elapsed); } - return QV4::Encode::undefined(); + scope.result = QV4::Encode::undefined(); } -QV4::ReturnedValue ConsoleObject::method_count(CallContext *ctx) +void ConsoleObject::method_count(const BuiltinFunction *, Scope &scope, CallData *callData) { // first argument: name to print. Ignore any additional arguments QString name; - if (ctx->argc() > 0) - name = ctx->args()[0].toQStringNoThrow(); + if (callData->argc > 0) + name = callData->args[0].toQStringNoThrow(); - QV4::ExecutionEngine *v4 = ctx->d()->engine; - QV8Engine *v8engine = ctx->d()->engine->v8Engine; + QV4::ExecutionEngine *v4 = scope.engine; + QV8Engine *v8engine = scope.engine->v8Engine; QV4::StackFrame frame = v4->currentStackFrame(); @@ -1651,15 +1667,15 @@ QV4::ReturnedValue ConsoleObject::method_count(CallContext *ctx) qPrintable(frame.function)) .debug("%s", qPrintable(message)); - return QV4::Encode::undefined(); + scope.result = QV4::Encode::undefined(); } -QV4::ReturnedValue ConsoleObject::method_trace(CallContext *ctx) +void ConsoleObject::method_trace(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (ctx->argc() != 0) - V4THROW_ERROR("console.trace(): Invalid arguments"); + if (callData->argc != 0) + THROW_GENERIC_ERROR("console.trace(): Invalid arguments"); - QV4::ExecutionEngine *v4 = ctx->d()->engine; + QV4::ExecutionEngine *v4 = scope.engine; QString stack = jsStack(v4); @@ -1668,28 +1684,28 @@ QV4::ReturnedValue ConsoleObject::method_trace(CallContext *ctx) frame.function.toUtf8().constData()) .debug("%s", qPrintable(stack)); - return QV4::Encode::undefined(); + scope.result = QV4::Encode::undefined(); } -QV4::ReturnedValue ConsoleObject::method_warn(CallContext *ctx) +void ConsoleObject::method_warn(const BuiltinFunction *b, Scope &scope, CallData *callData) { - return writeToConsole(Warn, ctx); + return writeToConsole(b, scope, callData, Warn); } -QV4::ReturnedValue ConsoleObject::method_assert(CallContext *ctx) +void ConsoleObject::method_assert(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (ctx->argc() == 0) - V4THROW_ERROR("console.assert(): Missing argument"); + if (callData->argc == 0) + THROW_GENERIC_ERROR("console.assert(): Missing argument"); - QV4::ExecutionEngine *v4 = ctx->d()->engine; + QV4::ExecutionEngine *v4 = scope.engine; - if (!ctx->args()[0].toBoolean()) { + if (!callData->args[0].toBoolean()) { QString message; - for (int i = 1; i < ctx->argc(); ++i) { + for (int i = 1; i < callData->argc; ++i) { if (i != 1) message.append(QLatin1Char(' ')); - message.append(ctx->args()[i].toQStringNoThrow()); + message.append(callData->args[i].toQStringNoThrow()); } QString stack = jsStack(v4); @@ -1700,17 +1716,17 @@ QV4::ReturnedValue ConsoleObject::method_assert(CallContext *ctx) .critical("%s\n%s",qPrintable(message), qPrintable(stack)); } - return QV4::Encode::undefined(); + scope.result = QV4::Encode::undefined(); } -QV4::ReturnedValue ConsoleObject::method_exception(CallContext *ctx) +void ConsoleObject::method_exception(const BuiltinFunction *b, Scope &scope, CallData *callData) { - if (ctx->argc() == 0) - V4THROW_ERROR("console.exception(): Missing argument"); + if (callData->argc == 0) + THROW_GENERIC_ERROR("console.exception(): Missing argument"); - writeToConsole(Error, ctx, true); + writeToConsole(b, scope, callData, Error, true); - return QV4::Encode::undefined(); + scope.result = QV4::Encode::undefined(); } @@ -1766,38 +1782,38 @@ void QV4::GlobalExtensions::init(Object *globalObject, QJSEngine::Extensions ext \sa {Internationalization and Localization with Qt Quick} */ -ReturnedValue GlobalExtensions::method_qsTranslate(CallContext *ctx) -{ - if (ctx->argc() < 2) - V4THROW_ERROR("qsTranslate() requires at least two arguments"); - if (!ctx->args()[0].isString()) - V4THROW_ERROR("qsTranslate(): first argument (context) must be a string"); - if (!ctx->args()[1].isString()) - V4THROW_ERROR("qsTranslate(): second argument (sourceText) must be a string"); - if ((ctx->argc() > 2) && !ctx->args()[2].isString()) - V4THROW_ERROR("qsTranslate(): third argument (disambiguation) must be a string"); - - QString context = ctx->args()[0].toQStringNoThrow(); - QString text = ctx->args()[1].toQStringNoThrow(); +void GlobalExtensions::method_qsTranslate(const BuiltinFunction *, Scope &scope, CallData *callData) +{ + if (callData->argc < 2) + THROW_GENERIC_ERROR("qsTranslate() requires at least two arguments"); + if (!callData->args[0].isString()) + THROW_GENERIC_ERROR("qsTranslate(): first argument (context) must be a string"); + if (!callData->args[1].isString()) + THROW_GENERIC_ERROR("qsTranslate(): second argument (sourceText) must be a string"); + if ((callData->argc > 2) && !callData->args[2].isString()) + THROW_GENERIC_ERROR("qsTranslate(): third argument (disambiguation) must be a string"); + + QString context = callData->args[0].toQStringNoThrow(); + QString text = callData->args[1].toQStringNoThrow(); QString comment; - if (ctx->argc() > 2) comment = ctx->args()[2].toQStringNoThrow(); + if (callData->argc > 2) comment = callData->args[2].toQStringNoThrow(); int i = 3; - if (ctx->argc() > i && ctx->args()[i].isString()) { + if (callData->argc > i && callData->args[i].isString()) { qWarning("qsTranslate(): specifying the encoding as fourth argument is deprecated"); ++i; } int n = -1; - if (ctx->argc() > i) - n = ctx->args()[i].toInt32(); + if (callData->argc > i) + n = callData->args[i].toInt32(); QString result = QCoreApplication::translate(context.toUtf8().constData(), text.toUtf8().constData(), comment.toUtf8().constData(), n); - return ctx->d()->engine->newString(result)->asReturnedValue(); + scope.result = scope.engine->newString(result); } /*! @@ -1822,11 +1838,12 @@ ReturnedValue GlobalExtensions::method_qsTranslate(CallContext *ctx) \sa {Internationalization and Localization with Qt Quick} */ -ReturnedValue GlobalExtensions::method_qsTranslateNoOp(CallContext *ctx) +void GlobalExtensions::method_qsTranslateNoOp(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (ctx->argc() < 2) - return QV4::Encode::undefined(); - return ctx->args()[1].asReturnedValue(); + if (callData->argc < 2) + scope.result = QV4::Encode::undefined(); + else + scope.result = callData->args[1]; } /*! @@ -1846,18 +1863,17 @@ ReturnedValue GlobalExtensions::method_qsTranslateNoOp(CallContext *ctx) \sa {Internationalization and Localization with Qt Quick} */ -ReturnedValue GlobalExtensions::method_qsTr(CallContext *ctx) -{ - if (ctx->argc() < 1) - V4THROW_ERROR("qsTr() requires at least one argument"); - if (!ctx->args()[0].isString()) - V4THROW_ERROR("qsTr(): first argument (sourceText) must be a string"); - if ((ctx->argc() > 1) && !ctx->args()[1].isString()) - V4THROW_ERROR("qsTr(): second argument (disambiguation) must be a string"); - if ((ctx->argc() > 2) && !ctx->args()[2].isNumber()) - V4THROW_ERROR("qsTr(): third argument (n) must be a number"); - - Scope scope(ctx); +void GlobalExtensions::method_qsTr(const BuiltinFunction *, Scope &scope, CallData *callData) +{ + if (callData->argc < 1) + THROW_GENERIC_ERROR("qsTr() requires at least one argument"); + if (!callData->args[0].isString()) + THROW_GENERIC_ERROR("qsTr(): first argument (sourceText) must be a string"); + if ((callData->argc > 1) && !callData->args[1].isString()) + THROW_GENERIC_ERROR("qsTr(): second argument (disambiguation) must be a string"); + if ((callData->argc > 2) && !callData->args[2].isNumber()) + THROW_GENERIC_ERROR("qsTr(): third argument (n) must be a number"); + QString context; if (QQmlContextData *ctxt = scope.engine->callingQmlContext()) { QString path = ctxt->urlString(); @@ -1866,7 +1882,7 @@ ReturnedValue GlobalExtensions::method_qsTr(CallContext *ctx) int length = lastDot - (lastSlash + 1); context = (lastSlash > -1) ? path.mid(lastSlash + 1, (length > -1) ? length : -1) : QString(); } else { - ExecutionContext *parentCtx = scope.engine->parentContext(ctx); + ExecutionContext *parentCtx = scope.engine->currentContext; // The first non-empty source URL in the call stack determines the translation context. while (!!parentCtx && context.isEmpty()) { if (QV4::CompiledData::CompilationUnit *unit = parentCtx->d()->compilationUnit) { @@ -1885,18 +1901,18 @@ ReturnedValue GlobalExtensions::method_qsTr(CallContext *ctx) } } - QString text = ctx->args()[0].toQStringNoThrow(); + QString text = callData->args[0].toQStringNoThrow(); QString comment; - if (ctx->argc() > 1) - comment = ctx->args()[1].toQStringNoThrow(); + if (callData->argc > 1) + comment = callData->args[1].toQStringNoThrow(); int n = -1; - if (ctx->argc() > 2) - n = ctx->args()[2].toInt32(); + if (callData->argc > 2) + n = callData->args[2].toInt32(); QString result = QCoreApplication::translate(context.toUtf8().constData(), text.toUtf8().constData(), comment.toUtf8().constData(), n); - return ctx->d()->engine->newString(result)->asReturnedValue(); + scope.result = scope.engine->newString(result); } /*! @@ -1921,11 +1937,12 @@ ReturnedValue GlobalExtensions::method_qsTr(CallContext *ctx) \sa {Internationalization and Localization with Qt Quick} */ -ReturnedValue GlobalExtensions::method_qsTrNoOp(CallContext *ctx) +void GlobalExtensions::method_qsTrNoOp(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (ctx->argc() < 1) - return QV4::Encode::undefined(); - return ctx->args()[0].asReturnedValue(); + if (callData->argc < 1) + scope.result = QV4::Encode::undefined(); + else + scope.result = callData->args[0]; } /*! @@ -1958,20 +1975,20 @@ ReturnedValue GlobalExtensions::method_qsTrNoOp(CallContext *ctx) \sa QT_TRID_NOOP(), {Internationalization and Localization with Qt Quick} */ -ReturnedValue GlobalExtensions::method_qsTrId(CallContext *ctx) +void GlobalExtensions::method_qsTrId(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (ctx->argc() < 1) - V4THROW_ERROR("qsTrId() requires at least one argument"); - if (!ctx->args()[0].isString()) - V4THROW_TYPE("qsTrId(): first argument (id) must be a string"); - if (ctx->argc() > 1 && !ctx->args()[1].isNumber()) - V4THROW_TYPE("qsTrId(): second argument (n) must be a number"); + if (callData->argc < 1) + THROW_GENERIC_ERROR("qsTrId() requires at least one argument"); + if (!callData->args[0].isString()) + THROW_TYPE_ERROR_WITH_MESSAGE("qsTrId(): first argument (id) must be a string"); + if (callData->argc > 1 && !callData->args[1].isNumber()) + THROW_TYPE_ERROR_WITH_MESSAGE("qsTrId(): second argument (n) must be a number"); int n = -1; - if (ctx->argc() > 1) - n = ctx->args()[1].toInt32(); + if (callData->argc > 1) + n = callData->args[1].toInt32(); - return ctx->d()->engine->newString(qtTrId(ctx->args()[0].toQStringNoThrow().toUtf8().constData(), n))->asReturnedValue(); + scope.result = scope.engine->newString(qtTrId(callData->args[0].toQStringNoThrow().toUtf8().constData(), n)); } /*! @@ -1990,41 +2007,41 @@ ReturnedValue GlobalExtensions::method_qsTrId(CallContext *ctx) \sa qsTrId(), {Internationalization and Localization with Qt Quick} */ -ReturnedValue GlobalExtensions::method_qsTrIdNoOp(CallContext *ctx) +void GlobalExtensions::method_qsTrIdNoOp(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (ctx->argc() < 1) - return QV4::Encode::undefined(); - return ctx->args()[0].asReturnedValue(); + if (callData->argc < 1) + scope.result = QV4::Encode::undefined(); + else + scope.result = callData->args[0]; } #endif // translation -QV4::ReturnedValue GlobalExtensions::method_gc(CallContext *ctx) +void GlobalExtensions::method_gc(const BuiltinFunction *, Scope &scope, CallData *) { - ctx->d()->engine->memoryManager->runGC(); + scope.engine->memoryManager->runGC(); - return QV4::Encode::undefined(); + scope.result = QV4::Encode::undefined(); } -ReturnedValue GlobalExtensions::method_string_arg(CallContext *ctx) +void GlobalExtensions::method_string_arg(const BuiltinFunction *, Scope &scope, CallData *callData) { - if (ctx->argc() != 1) - V4THROW_ERROR("String.arg(): Invalid arguments"); + if (callData->argc != 1) + THROW_GENERIC_ERROR("String.arg(): Invalid arguments"); - QString value = ctx->thisObject().toQString(); + QString value = callData->thisObject.toQString(); - QV4::Scope scope(ctx); - QV4::ScopedValue arg(scope, ctx->args()[0]); + QV4::ScopedValue arg(scope, callData->args[0]); if (arg->isInteger()) - return ctx->d()->engine->newString(value.arg(arg->integerValue()))->asReturnedValue(); + RETURN_RESULT(scope.engine->newString(value.arg(arg->integerValue()))); else if (arg->isDouble()) - return ctx->d()->engine->newString(value.arg(arg->doubleValue()))->asReturnedValue(); + RETURN_RESULT(scope.engine->newString(value.arg(arg->doubleValue()))); else if (arg->isBoolean()) - return ctx->d()->engine->newString(value.arg(arg->booleanValue()))->asReturnedValue(); + RETURN_RESULT(scope.engine->newString(value.arg(arg->booleanValue()))); - return ctx->d()->engine->newString(value.arg(arg->toQString()))->asReturnedValue(); + RETURN_RESULT(scope.engine->newString(value.arg(arg->toQString()))); } /*! @@ -2047,10 +2064,10 @@ be passed on to the function invoked. Note that if redundant calls are eliminated, then only the last set of arguments will be passed to the function. */ -ReturnedValue QtObject::method_callLater(CallContext *ctx) +void QtObject::method_callLater(const BuiltinFunction *b, Scope &scope, CallData *callData) { - QV8Engine *v8engine = ctx->engine()->v8Engine; - return v8engine->delayedCallQueue()->addUniquelyAndExecuteLater(ctx); + QV8Engine *v8engine = scope.engine->v8Engine; + v8engine->delayedCallQueue()->addUniquelyAndExecuteLater(b, scope, callData); } QT_END_NAMESPACE diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h index fe43532647..21613b7c10 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h +++ b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h @@ -93,45 +93,45 @@ struct QtObject : Object static ReturnedValue get(const Managed *m, String *name, bool *hasProperty); static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes); - static ReturnedValue method_isQtObject(CallContext *ctx); - static ReturnedValue method_rgba(CallContext *ctx); - static ReturnedValue method_hsla(CallContext *ctx); - static ReturnedValue method_hsva(CallContext *ctx); - static ReturnedValue method_colorEqual(CallContext *ctx); - static ReturnedValue method_font(CallContext *ctx); - static ReturnedValue method_rect(CallContext *ctx); - static ReturnedValue method_point(CallContext *ctx); - static ReturnedValue method_size(CallContext *ctx); - static ReturnedValue method_vector2d(CallContext *ctx); - static ReturnedValue method_vector3d(CallContext *ctx); - static ReturnedValue method_vector4d(CallContext *ctx); - static ReturnedValue method_quaternion(CallContext *ctx); - static ReturnedValue method_matrix4x4(CallContext *ctx); - static ReturnedValue method_lighter(CallContext *ctx); - static ReturnedValue method_darker(CallContext *ctx); - static ReturnedValue method_tint(CallContext *ctx); - static ReturnedValue method_formatDate(CallContext *ctx); - static ReturnedValue method_formatTime(CallContext *ctx); - static ReturnedValue method_formatDateTime(CallContext *ctx); - static ReturnedValue method_openUrlExternally(CallContext *ctx); - static ReturnedValue method_fontFamilies(CallContext *ctx); - static ReturnedValue method_md5(CallContext *ctx); - static ReturnedValue method_btoa(CallContext *ctx); - static ReturnedValue method_atob(CallContext *ctx); - static ReturnedValue method_quit(CallContext *ctx); - static ReturnedValue method_exit(CallContext *ctx); - static ReturnedValue method_resolvedUrl(CallContext *ctx); - static ReturnedValue method_createQmlObject(CallContext *ctx); - static ReturnedValue method_createComponent(CallContext *ctx); - static ReturnedValue method_locale(CallContext *ctx); - static ReturnedValue method_binding(CallContext *ctx); - - static ReturnedValue method_get_platform(CallContext *ctx); - static ReturnedValue method_get_application(CallContext *ctx); - static ReturnedValue method_get_inputMethod(CallContext *ctx); - static ReturnedValue method_get_styleHints(CallContext *ctx); - - static ReturnedValue method_callLater(CallContext *ctx); + static void method_isQtObject(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_rgba(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_hsla(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_hsva(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_colorEqual(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_font(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_rect(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_point(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_size(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_vector2d(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_vector3d(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_vector4d(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_quaternion(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_matrix4x4(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_lighter(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_darker(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_tint(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_formatDate(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_formatTime(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_formatDateTime(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_openUrlExternally(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_fontFamilies(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_md5(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_btoa(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_atob(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_quit(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_exit(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_resolvedUrl(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_createQmlObject(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_createComponent(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_locale(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_binding(const BuiltinFunction *, Scope &scope, CallData *callData); + + static void method_get_platform(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_get_application(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_get_inputMethod(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_get_styleHints(const BuiltinFunction *, Scope &scope, CallData *callData); + + static void method_callLater(const BuiltinFunction *, Scope &scope, CallData *callData); private: void addAll(); @@ -142,18 +142,18 @@ struct ConsoleObject : Object { V4_OBJECT2(ConsoleObject, Object) - static ReturnedValue method_error(CallContext *ctx); - static ReturnedValue method_log(CallContext *ctx); - static ReturnedValue method_info(CallContext *ctx); - static ReturnedValue method_profile(CallContext *ctx); - static ReturnedValue method_profileEnd(CallContext *ctx); - static ReturnedValue method_time(CallContext *ctx); - static ReturnedValue method_timeEnd(CallContext *ctx); - static ReturnedValue method_count(CallContext *ctx); - static ReturnedValue method_trace(CallContext *ctx); - static ReturnedValue method_warn(CallContext *ctx); - static ReturnedValue method_assert(CallContext *ctx); - static ReturnedValue method_exception(CallContext *ctx); + static void method_error(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_log(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_info(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_profile(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_profileEnd(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_time(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_timeEnd(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_count(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_trace(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_warn(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_assert(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_exception(const BuiltinFunction *, Scope &scope, CallData *callData); }; @@ -161,17 +161,17 @@ struct Q_QML_PRIVATE_EXPORT GlobalExtensions { static void init(Object *globalObject, QJSEngine::Extensions extensions); #if QT_CONFIG(translation) - static ReturnedValue method_qsTranslate(CallContext *ctx); - static ReturnedValue method_qsTranslateNoOp(CallContext *ctx); - static ReturnedValue method_qsTr(CallContext *ctx); - static ReturnedValue method_qsTrNoOp(CallContext *ctx); - static ReturnedValue method_qsTrId(CallContext *ctx); - static ReturnedValue method_qsTrIdNoOp(CallContext *ctx); + static void method_qsTranslate(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_qsTranslateNoOp(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_qsTr(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_qsTrNoOp(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_qsTrId(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_qsTrIdNoOp(const BuiltinFunction *, Scope &scope, CallData *callData); #endif - static ReturnedValue method_gc(CallContext *ctx); + static void method_gc(const BuiltinFunction *, Scope &scope, CallData *callData); // on String:prototype - static ReturnedValue method_string_arg(CallContext *ctx); + static void method_string_arg(const BuiltinFunction *, Scope &scope, CallData *callData); }; diff --git a/src/qml/qml/v8/qv4domerrors_p.h b/src/qml/qml/v8/qv4domerrors_p.h index faa9dd8bc7..a9bdbe01ae 100644 --- a/src/qml/qml/v8/qv4domerrors_p.h +++ b/src/qml/qml/v8/qv4domerrors_p.h @@ -74,11 +74,12 @@ QT_BEGIN_NAMESPACE #define DOMEXCEPTION_VALIDATION_ERR 16 #define DOMEXCEPTION_TYPE_MISMATCH_ERR 17 -#define V4THROW_DOM(error, string) { \ +#define THROW_DOM(error, string) { \ QV4::ScopedValue v(scope, scope.engine->newString(QStringLiteral(string))); \ QV4::ScopedObject ex(scope, scope.engine->newErrorObject(v)); \ ex->put(QV4::ScopedString(scope, scope.engine->newIdentifier(QStringLiteral("code"))), QV4::ScopedValue(scope, QV4::Primitive::fromInt32(error))); \ - return ctx->engine()->throwError(ex); \ + scope.result = scope.engine->throwError(ex); \ + return; \ } namespace QV4 { |