aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/qml')
-rw-r--r--src/qml/qml/ftw/qqmlthread.cpp1
-rw-r--r--src/qml/qml/qml.pri14
-rw-r--r--src/qml/qml/qqml.h6
-rw-r--r--src/qml/qml/qqmlabstractbinding_p.h1
-rw-r--r--src/qml/qml/qqmlabstracturlinterceptor.cpp4
-rw-r--r--src/qml/qml/qqmlbinding.cpp45
-rw-r--r--src/qml/qml/qqmlboundsignal.cpp26
-rw-r--r--src/qml/qml/qqmlboundsignal_p.h4
-rw-r--r--src/qml/qml/qqmlcompileddata.cpp2
-rw-r--r--src/qml/qml/qqmlcompiler_p.h14
-rw-r--r--src/qml/qml/qqmlcomponent.cpp17
-rw-r--r--src/qml/qml/qqmlcomponent.h1
-rw-r--r--src/qml/qml/qqmlcomponentattached_p.h1
-rw-r--r--src/qml/qml/qqmlcontext.h1
-rw-r--r--src/qml/qml/qqmlcontext_p.h2
-rw-r--r--src/qml/qml/qqmlcontextwrapper.cpp6
-rw-r--r--src/qml/qml/qqmlcustomparser.cpp9
-rw-r--r--src/qml/qml/qqmlcustomparser_p.h11
-rw-r--r--src/qml/qml/qqmldirparser.cpp38
-rw-r--r--src/qml/qml/qqmldirparser_p.h17
-rw-r--r--src/qml/qml/qqmlengine.cpp15
-rw-r--r--src/qml/qml/qqmlengine_p.h1
-rw-r--r--src/qml/qml/qqmlexpression.cpp36
-rw-r--r--src/qml/qml/qqmlexpression.h1
-rw-r--r--src/qml/qml/qqmlexpression_p.h2
-rw-r--r--src/qml/qml/qqmlextensionplugin.cpp10
-rw-r--r--src/qml/qml/qqmlfile.cpp11
-rw-r--r--src/qml/qml/qqmlfileselector.cpp6
-rw-r--r--src/qml/qml/qqmlimport.cpp36
-rw-r--r--src/qml/qml/qqmlimport_p.h3
-rw-r--r--src/qml/qml/qqmlincubator.cpp32
-rw-r--r--src/qml/qml/qqmljavascriptexpression.cpp1
-rw-r--r--src/qml/qml/qqmllistwrapper.cpp12
-rw-r--r--src/qml/qml/qqmllocale.cpp7
-rw-r--r--src/qml/qml/qqmlmetatype.cpp38
-rw-r--r--src/qml/qml/qqmlmetatype_p.h9
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp68
-rw-r--r--src/qml/qml/qqmlobjectcreator_p.h2
-rw-r--r--src/qml/qml/qqmlparserstatus.h1
-rw-r--r--src/qml/qml/qqmlplatform.cpp22
-rw-r--r--src/qml/qml/qqmlprivate.h31
-rw-r--r--src/qml/qml/qqmlproperty.cpp6
-rw-r--r--src/qml/qml/qqmlscript.cpp417
-rw-r--r--src/qml/qml/qqmlscript_p.h180
-rw-r--r--src/qml/qml/qqmlscriptstring.h1
-rw-r--r--src/qml/qml/qqmltypeloader.cpp466
-rw-r--r--src/qml/qml/qqmltypeloader_p.h68
-rw-r--r--src/qml/qml/qqmlvmemetaobject.cpp2
-rw-r--r--src/qml/qml/qqmlxmlhttprequest.cpp14
-rw-r--r--src/qml/qml/v8/qv8engine.cpp6
50 files changed, 662 insertions, 1062 deletions
diff --git a/src/qml/qml/ftw/qqmlthread.cpp b/src/qml/qml/ftw/qqmlthread.cpp
index c49463c913..700e5c3324 100644
--- a/src/qml/qml/ftw/qqmlthread.cpp
+++ b/src/qml/qml/ftw/qqmlthread.cpp
@@ -127,6 +127,7 @@ QQmlThreadPrivate::QQmlThreadPrivate(QQmlThread *q)
: q(q), m_threadProcessing(false), m_mainProcessing(false), m_shutdown(false),
m_mainThreadWaiting(false), mainSync(0), m_mainObject(this)
{
+ setObjectName(QStringLiteral("QQmlThread"));
}
bool QQmlThreadPrivate::event(QEvent *e)
diff --git a/src/qml/qml/qml.pri b/src/qml/qml/qml.pri
index 33d8be37d1..013f757c90 100644
--- a/src/qml/qml/qml.pri
+++ b/src/qml/qml/qml.pri
@@ -1,4 +1,12 @@
SOURCES += \
+ $$PWD/qqmldirparser.cpp \
+
+HEADERS += \
+ $$PWD/qqmldirparser_p.h \
+
+!qmldevtools_build {
+
+SOURCES += \
$$PWD/qqmlopenmetaobject.cpp \
$$PWD/qqmlvmemetaobject.cpp \
$$PWD/qqmlengine.cpp \
@@ -20,7 +28,6 @@ SOURCES += \
$$PWD/qqmltypeloader.cpp \
$$PWD/qqmlinfo.cpp \
$$PWD/qqmlerror.cpp \
- $$PWD/qqmlscript.cpp \
$$PWD/qqmlvaluetype.cpp \
$$PWD/qqmlaccessors.cpp \
$$PWD/qqmlxmlhttprequest.cpp \
@@ -32,7 +39,6 @@ SOURCES += \
$$PWD/qqmltypenamecache.cpp \
$$PWD/qqmlscriptstring.cpp \
$$PWD/qqmlnetworkaccessmanagerfactory.cpp \
- $$PWD/qqmldirparser.cpp \
$$PWD/qqmlextensionplugin.cpp \
$$PWD/qqmlimport.cpp \
$$PWD/qqmllist.cpp \
@@ -91,7 +97,6 @@ HEADERS += \
$$PWD/qqmllist_p.h \
$$PWD/qqmldata_p.h \
$$PWD/qqmlerror.h \
- $$PWD/qqmlscript_p.h \
$$PWD/qqmlvaluetype_p.h \
$$PWD/qqmlaccessors_p.h \
$$PWD/qqmlxmlhttprequest_p.h \
@@ -104,7 +109,6 @@ HEADERS += \
$$PWD/qqmlscriptstring.h \
$$PWD/qqmlguard_p.h \
$$PWD/qqmlnetworkaccessmanagerfactory.h \
- $$PWD/qqmldirparser_p.h \
$$PWD/qqmlextensioninterface.h \
$$PWD/qqmlimport_p.h \
$$PWD/qqmlextensionplugin.h \
@@ -135,3 +139,5 @@ HEADERS += \
include(ftw/ftw.pri)
include(v8/v8.pri)
+
+}
diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h
index 6479aedd1b..721f2cc5a8 100644
--- a/src/qml/qml/qqml.h
+++ b/src/qml/qml/qqml.h
@@ -91,13 +91,13 @@ class QQmlPropertyValueInterceptor;
const char *className = T::staticMetaObject.className(); \
const int nameLen = int(strlen(className)); \
QVarLengthArray<char,48> pointerName(nameLen+2); \
- memcpy(pointerName.data(), className, nameLen); \
+ memcpy(pointerName.data(), className, size_t(nameLen)); \
pointerName[nameLen] = '*'; \
pointerName[nameLen+1] = '\0'; \
const int listLen = int(strlen("QQmlListProperty<")); \
QVarLengthArray<char,64> listName(listLen + nameLen + 2); \
- memcpy(listName.data(), "QQmlListProperty<", listLen); \
- memcpy(listName.data()+listLen, className, nameLen); \
+ memcpy(listName.data(), "QQmlListProperty<", size_t(listLen)); \
+ memcpy(listName.data()+listLen, className, size_t(nameLen)); \
listName[listLen+nameLen] = '>'; \
listName[listLen+nameLen+1] = '\0';
diff --git a/src/qml/qml/qqmlabstractbinding_p.h b/src/qml/qml/qqmlabstractbinding_p.h
index 7354f9af1e..0bc0b6f199 100644
--- a/src/qml/qml/qqmlabstractbinding_p.h
+++ b/src/qml/qml/qqmlabstractbinding_p.h
@@ -149,7 +149,6 @@ private:
friend class QQmlComponentPrivate;
friend class QQmlValueTypeProxyBinding;
friend class QQmlPropertyPrivate;
- friend class QQmlVME;
friend class QtSharedPointer::ExternalRefCount<QQmlAbstractBinding>;
friend class QV4Bindings;
friend class QQmlObjectCreator;
diff --git a/src/qml/qml/qqmlabstracturlinterceptor.cpp b/src/qml/qml/qqmlabstracturlinterceptor.cpp
index 127dad86ce..3aea9c83cc 100644
--- a/src/qml/qml/qqmlabstracturlinterceptor.cpp
+++ b/src/qml/qml/qqmlabstracturlinterceptor.cpp
@@ -84,8 +84,8 @@
/*!
\fn QUrl QQmlAbstractUrlInterceptor::intercept(const QUrl& url, DataType type)
- A pure virtual function where you can intercept the url. The returned value is taken as the
- new value for the url. The type of url being intercepted is given by the type variable.
+ A pure virtual function where you can intercept the \a url. The returned value is taken as the
+ new value for the url. The type of url being intercepted is given by the \a type variable.
Your implementation of this function must be thread-safe, as it can be called from multiple threads
at the same time.
diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp
index 295461ba26..571d78312e 100644
--- a/src/qml/qml/qqmlbinding.cpp
+++ b/src/qml/qml/qqmlbinding.cpp
@@ -88,11 +88,8 @@ QQmlBinding::createBinding(Identifier id, QObject *obj, QQmlContext *ctxt)
if (QQmlCompiledData *cdata = typeData->compiledData()) {
QV4::ExecutionEngine *v4 = engine->v4engine();
QV4::Scope valueScope(v4);
- QV4::ScopedObject scopeObject(valueScope, QV4::QmlContextWrapper::qmlScope(v4->v8Engine, ctxtdata, obj));
- QV4::Scoped<QV4::QmlBindingWrapper> wrapper(valueScope, new (v4->memoryManager) QV4::QmlBindingWrapper(v4->rootContext, scopeObject));
- QV4::ExecutionContext *qmlContext = wrapper->context();
QV4::Function *runtimeFunction = cdata->compilationUnit->runtimeFunctions[cdata->customParserBindings[id]];
- QV4::ScopedValue function(valueScope, QV4::FunctionObject::creatScriptFunction(qmlContext, runtimeFunction));
+ QV4::ScopedValue function(valueScope, QV4::QmlBindingWrapper::createQmlCallableForFunction(ctxtdata, obj, runtimeFunction));
rv = new QQmlBinding(function, obj, ctxtdata);
}
@@ -128,31 +125,33 @@ QQmlBinding::QQmlBinding(const QQmlScriptString &script, QObject *obj, QQmlConte
return;
QString url;
- QString code;
-
- int id = scriptPrivate->bindingId;
- if (id >= 0) {
- QQmlContextData *ctxtdata = QQmlContextData::get(scriptPrivate->context);
- QQmlEnginePrivate *engine = QQmlEnginePrivate::get(scriptPrivate->context->engine());
- if (engine && ctxtdata && !ctxtdata->url.isEmpty()) {
- QQmlTypeData *typeData = engine->typeLoader.getType(ctxtdata->url);
- Q_ASSERT(typeData);
-
- if (QQmlCompiledData *cdata = typeData->compiledData()) {
- code = cdata->primitives.at(id);
- url = cdata->name;
- }
+ QV4::Function *runtimeFunction = 0;
+
+ QQmlContextData *ctxtdata = QQmlContextData::get(scriptPrivate->context);
+ QQmlEnginePrivate *engine = QQmlEnginePrivate::get(scriptPrivate->context->engine());
+ if (engine && ctxtdata && !ctxtdata->url.isEmpty()) {
+ QQmlTypeData *typeData = engine->typeLoader.getType(ctxtdata->url);
+ Q_ASSERT(typeData);
- typeData->release();
+ if (QQmlCompiledData *cdata = typeData->compiledData()) {
+ url = cdata->name;
+ if (scriptPrivate->bindingId != QQmlBinding::Invalid)
+ runtimeFunction = cdata->compilationUnit->runtimeFunctions.at(scriptPrivate->bindingId);
}
- } else
- code = scriptPrivate->script;
+
+ typeData->release();
+ }
setNotifyOnValueChanged(true);
QQmlAbstractExpression::setContext(QQmlContextData::get(ctxt ? ctxt : scriptPrivate->context));
setScopeObject(obj ? obj : scriptPrivate->scope);
- v4function = qmlBinding(context(), scopeObject(), code, url, scriptPrivate->lineNumber);
+ if (runtimeFunction) {
+ v4function = QV4::QmlBindingWrapper::createQmlCallableForFunction(ctxtdata, scopeObject(), runtimeFunction);
+ } else {
+ QString code = scriptPrivate->script;
+ v4function = qmlBinding(context(), scopeObject(), code, url, scriptPrivate->lineNumber);
+ }
}
QQmlBinding::QQmlBinding(const QString &str, QObject *obj, QQmlContextData *ctxt)
@@ -215,7 +214,7 @@ void QQmlBinding::update(QQmlPropertyPrivate::WriteFlags flags)
QV4::ScopedFunctionObject f(scope, v4function.value());
Q_ASSERT(f);
if (f->bindingKeyFlag) {
- QQmlSourceLocation loc = f->as<QQmlBindingFunction>()->bindingLocation;
+ QQmlSourceLocation loc = f->as<QV4::QQmlBindingFunction>()->bindingLocation;
url = loc.sourceFile;
lineNumber = loc.line;
columnNumber = loc.column;
diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp
index 6237459aac..876f367097 100644
--- a/src/qml/qml/qqmlboundsignal.cpp
+++ b/src/qml/qml/qqmlboundsignal.cpp
@@ -52,6 +52,7 @@
#include "qqmlglobal_p.h"
#include <private/qqmlprofiler_p.h>
#include <private/qv4debugservice_p.h>
+#include <private/qqmlcompiler_p.h>
#include "qqmlinfo.h"
#include <private/qv4value_inl_p.h>
@@ -59,6 +60,7 @@
#include <QtCore/qstringbuilder.h>
#include <QtCore/qdebug.h>
+
QT_BEGIN_NAMESPACE
static QQmlJavaScriptExpression::VTable QQmlBoundSignalExpression_jsvtable = {
@@ -105,6 +107,28 @@ QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index,
init(ctxt, scope);
}
+QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index, QQmlContextData *ctxt, QObject *scope, QV4::Function *runtimeFunction)
+ : QQmlJavaScriptExpression(&QQmlBoundSignalExpression_jsvtable),
+ m_target(target),
+ m_index(index),
+ m_extra(0)
+{
+ setExpressionFunctionValid(true);
+ setInvalidParameterName(false);
+
+ // It's important to call init first, because m_index gets remapped in case of cloned signals.
+ init(ctxt, scope);
+
+ QMetaMethod signal = QMetaObjectPrivate::signal(m_target->metaObject(), m_index);
+ QString error;
+ m_v8function = QV4::QmlBindingWrapper::createQmlCallableForFunction(ctxt, scope, runtimeFunction, signal.parameterNames(), &error);
+ if (!error.isEmpty()) {
+ qmlInfo(scopeObject()) << error;
+ setInvalidParameterName(true);
+ } else
+ setInvalidParameterName(false);
+}
+
void QQmlBoundSignalExpression::init(QQmlContextData *ctxt, QObject *scope)
{
setNotifyOnValueChanged(false);
@@ -221,7 +245,7 @@ void QQmlBoundSignalExpression::evaluate(void **a)
m_extra->m_parameterString.clear();
m_v8function = evalFunction(context(), scopeObject(), expression,
- m_extra->m_sourceLocation.sourceFile, m_extra->m_sourceLocation.line, &m_v8qmlscope);
+ m_extra->m_sourceLocation.sourceFile, m_extra->m_sourceLocation.line, &m_extra->m_v8qmlscope);
if (m_v8function.isNullOrUndefined()) {
ep->dereferenceScarceResources();
diff --git a/src/qml/qml/qqmlboundsignal_p.h b/src/qml/qml/qqmlboundsignal_p.h
index 6df6da4214..43ff71f682 100644
--- a/src/qml/qml/qqmlboundsignal_p.h
+++ b/src/qml/qml/qqmlboundsignal_p.h
@@ -78,6 +78,8 @@ public:
QQmlBoundSignalExpression(QObject *target, int index,
QQmlContextData *ctxt, QObject *scope, const QV4::ValueRef &function);
+ QQmlBoundSignalExpression(QObject *target, int index,
+ QQmlContextData *ctxt, QObject *scope, QV4::Function *runtimeFunction);
// "inherited" from QQmlJavaScriptExpression.
static QString expressionIdentifier(QQmlJavaScriptExpression *);
@@ -104,7 +106,6 @@ private:
bool invalidParameterName() const { return m_extra.flag2(); }
void setInvalidParameterName(bool v) { m_extra.setFlag2Value(v); }
- QV4::PersistentValue m_v8qmlscope;
QV4::PersistentValue m_v8function;
QObject *m_target;
@@ -119,6 +120,7 @@ private:
QString m_parameterString;
QString m_expression;
QQmlSourceLocation m_sourceLocation;
+ QV4::PersistentValue m_v8qmlscope;
};
// We store some flag bits in the following flag pointers.
diff --git a/src/qml/qml/qqmlcompileddata.cpp b/src/qml/qml/qqmlcompileddata.cpp
index 59c56bf513..a352e5ad1d 100644
--- a/src/qml/qml/qqmlcompileddata.cpp
+++ b/src/qml/qml/qqmlcompileddata.cpp
@@ -61,8 +61,6 @@ QQmlCompiledData::QQmlCompiledData(QQmlEngine *engine)
rootPropertyCache(0), compilationUnit(0), qmlUnit(0), totalBindingsCount(0), totalParserStatusCount(0)
{
Q_ASSERT(engine);
-
- bytecode.reserve(1024);
}
void QQmlCompiledData::destroy()
diff --git a/src/qml/qml/qqmlcompiler_p.h b/src/qml/qml/qqmlcompiler_p.h
index 98d308aa5c..f3b6f621ce 100644
--- a/src/qml/qml/qqmlcompiler_p.h
+++ b/src/qml/qml/qqmlcompiler_p.h
@@ -55,13 +55,11 @@
#include "qqml.h"
#include "qqmlerror.h"
-#include "qqmlscript_p.h"
#include "qqmlengine_p.h"
#include <private/qbitfield_p.h>
#include "qqmlpropertycache_p.h"
#include "qqmltypenamecache_p.h"
#include "qqmltypeloader_p.h"
-#include <private/qqmlcodegenerator_p.h>
#include "private/qv4identifier_p.h"
#include <private/qqmljsastfwd_p.h>
#include "qqmlcustomparser_p.h"
@@ -129,15 +127,10 @@ public:
QHash<int, TypeReference*> resolvedTypes;
QQmlPropertyCache *rootPropertyCache;
- QList<QString> primitives;
- QVector<QByteArray> datas;
- QByteArray bytecode;
+ QVector<QByteArray> metaObjects;
QVector<QQmlPropertyCache *> propertyCaches;
- QList<QVector<QQmlContextData::ObjectIdMapping> > contextCaches;
QList<QQmlScriptData *> scripts;
- QList<QUrl> urls;
- // --- new compiler
QV4::CompiledData::CompilationUnit *compilationUnit;
QV4::CompiledData::QmlUnit *qmlUnit;
// index in first hash is component index, hash inside maps from object index in that scope to integer id
@@ -156,11 +149,14 @@ public:
int totalObjectCount; // Number of objects explicitly instantiated
bool isComponent(int objectIndex) const { return objectIndexToIdPerComponent.contains(objectIndex); }
- bool isCompositeType() const { return !datas.at(qmlUnit->indexOfRootObject).isEmpty(); }
+ bool isCompositeType() const { return !metaObjects.at(qmlUnit->indexOfRootObject).isEmpty(); }
bool isInitialized() const { return hasEngine(); }
void initialize(QQmlEngine *);
+ QV4::Function *functionForBindingId(int bindingId) const
+ { return compilationUnit->runtimeFunctions[customParserBindings[bindingId]]; }
+
protected:
virtual void destroy(); // From QQmlRefCount
virtual void clear(); // From QQmlCleanup
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index 77d02e071f..39a7d8905d 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -51,7 +51,6 @@
#include "qqmlengine.h"
#include "qqmlbinding_p.h"
#include "qqmlglobal_p.h"
-#include "qqmlscript_p.h"
#include <private/qqmlenginedebugservice_p.h>
#include "qqmlincubator.h"
#include "qqmlincubator_p.h"
@@ -264,14 +263,14 @@ V8_DEFINE_EXTENSION(QQmlComponentExtension, componentExtension);
*/
/*!
- \qmlattachedsignal Component::onCompleted()
+ \qmlattachedsignal Component::completed()
Emitted after component "startup" has completed. This can be used to
execute script code at startup, once the full QML environment has been
established.
- The \c {Component::onCompleted} attached property can be declared on
- any object. The order of running the \c onCompleted scripts is
+ The corresponding handler is \c onCompleted. It can be declared on
+ any object. The order of running the \c onCompleted handlers is
undefined.
\qml
@@ -285,16 +284,16 @@ V8_DEFINE_EXTENSION(QQmlComponentExtension, componentExtension);
*/
/*!
- \qmlattachedsignal Component::onDestruction()
+ \qmlattachedsignal Component::destruction()
Emitted as the component begins destruction. This can be used to undo
- work done in the onCompleted signal, or other imperative code in your
- application.
+ work done in response to the \l {completed}{completed()} signal, or other
+ imperative code in your application.
- The \c {Component::onDestruction} attached property can be declared on
+ The corresponding handler is \c onDestruction. It can be declared on
any object. However, it applies to the destruction of the component as
a whole, and not the destruction of the specific object. The order of
- running the \c onDestruction scripts is undefined.
+ running the \c onDestruction handlers is undefined.
\qml
Rectangle {
diff --git a/src/qml/qml/qqmlcomponent.h b/src/qml/qml/qqmlcomponent.h
index 4aa0daf47e..9be1990adc 100644
--- a/src/qml/qml/qqmlcomponent.h
+++ b/src/qml/qml/qqmlcomponent.h
@@ -127,7 +127,6 @@ private:
QQmlComponent(QQmlEngine *, QQmlCompiledData *, int, QObject *parent);
Q_DISABLE_COPY(QQmlComponent)
- friend class QQmlVME;
friend class QQmlTypeData;
friend class QQmlObjectCreator;
};
diff --git a/src/qml/qml/qqmlcomponentattached_p.h b/src/qml/qml/qqmlcomponentattached_p.h
index ae416dcb1c..4fb77a1a4d 100644
--- a/src/qml/qml/qqmlcomponentattached_p.h
+++ b/src/qml/qml/qqmlcomponentattached_p.h
@@ -73,7 +73,6 @@ Q_SIGNALS:
void destruction();
private:
- friend class QQmlVME;
friend class QQmlContextData;
};
diff --git a/src/qml/qml/qqmlcontext.h b/src/qml/qml/qqmlcontext.h
index e191807cf4..828ae8c523 100644
--- a/src/qml/qml/qqmlcontext.h
+++ b/src/qml/qml/qqmlcontext.h
@@ -88,7 +88,6 @@ public:
QUrl baseUrl() const;
private:
- friend class QQmlVME;
friend class QQmlEngine;
friend class QQmlEnginePrivate;
friend class QQmlExpression;
diff --git a/src/qml/qml/qqmlcontext_p.h b/src/qml/qml/qqmlcontext_p.h
index 464bee82c0..2d544b1633 100644
--- a/src/qml/qml/qqmlcontext_p.h
+++ b/src/qml/qml/qqmlcontext_p.h
@@ -59,7 +59,6 @@
#include "qqmltypenamecache_p.h"
#include "qqmlnotifier_p.h"
#include "qqmllist.h"
-#include "qqmlscript_p.h"
#include <QtCore/qhash.h>
#include <QtQml/qjsvalue.h>
@@ -106,7 +105,6 @@ public:
static QObject *context_at(QQmlListProperty<QObject> *, int);
};
-class QQmlVME;
class QQmlComponentAttached;
class QQmlGuardedContextData;
class Q_QML_PRIVATE_EXPORT QQmlContextData
diff --git a/src/qml/qml/qqmlcontextwrapper.cpp b/src/qml/qml/qqmlcontextwrapper.cpp
index e72e90296f..a5574b706a 100644
--- a/src/qml/qml/qqmlcontextwrapper.cpp
+++ b/src/qml/qml/qqmlcontextwrapper.cpp
@@ -94,7 +94,7 @@ ReturnedValue QmlContextWrapper::urlScope(QV8Engine *v8, const QUrl &url)
context->isInternal = true;
context->isJSContext = true;
- Scoped<QmlContextWrapper> w(scope, new (v4->memoryManager) QmlContextWrapper(v8, context, 0));
+ Scoped<QmlContextWrapper> w(scope, new (v4->memoryManager) QmlContextWrapper(v8, context, 0, true));
w->isNullWrapper = true;
return w.asReturnedValue();
}
@@ -387,6 +387,7 @@ void QmlContextWrapper::registerQmlDependencies(ExecutionEngine *engine, const C
capture->captureProperty(&qmlContext->idValues[*idObjectDependency].bindings);
}
+ Q_ASSERT(qmlContext->contextObject);
const quint32 *contextPropertyDependency = compiledFunction->qmlContextPropertiesDependencyTable();
const int contextPropertyDependencyCount = compiledFunction->nDependingContextProperties;
for (int i = 0; i < contextPropertyDependencyCount; ++i) {
@@ -460,6 +461,9 @@ ReturnedValue QQmlIdObjectsArray::getIndexed(Managed *m, uint index, bool *hasPr
return Encode::undefined();
}
+ if (hasProperty)
+ *hasProperty = true;
+
ExecutionEngine *v4 = m->engine();
QQmlEnginePrivate *ep = v4->v8Engine->engine() ? QQmlEnginePrivate::get(v4->v8Engine->engine()) : 0;
if (ep)
diff --git a/src/qml/qml/qqmlcustomparser.cpp b/src/qml/qml/qqmlcustomparser.cpp
index 16e3abf3a0..75acbdb778 100644
--- a/src/qml/qml/qqmlcustomparser.cpp
+++ b/src/qml/qml/qqmlcustomparser.cpp
@@ -47,8 +47,6 @@
QT_BEGIN_NAMESPACE
-using namespace QQmlScript;
-
/*!
\class QQmlCustomParser
\brief The QQmlCustomParser class allows you to add new arbitrary types to QML.
@@ -102,7 +100,7 @@ void QQmlCustomParser::clearErrors()
An error is generated referring to the \a location in the source file.
*/
-void QQmlCustomParser::error(const CompiledData::Location &location, const QString &description)
+void QQmlCustomParser::error(const QV4::CompiledData::Location &location, const QString &description)
{
QQmlError error;
error.setLine(location.line);
@@ -144,11 +142,6 @@ QQmlBinding::Identifier QQmlCustomParser::bindingIdentifier(const QV4::CompiledD
return compiler->bindingIdentifier(binding, this);
}
-QQmlJS::AST::Node *QQmlCustomParser::astForBinding(int objectIndex, int scriptIndex) const
-{
- return compiler->astForBinding(objectIndex, scriptIndex);
-}
-
struct StaticQtMetaObject : public QObject
{
static const QMetaObject *get()
diff --git a/src/qml/qml/qqmlcustomparser_p.h b/src/qml/qml/qqmlcustomparser_p.h
index 8d98cf6423..2ce6375870 100644
--- a/src/qml/qml/qqmlcustomparser_p.h
+++ b/src/qml/qml/qqmlcustomparser_p.h
@@ -55,7 +55,6 @@
#include "qqmlmetatype_p.h"
#include "qqmlerror.h"
-#include "qqmlscript_p.h"
#include "qqmlbinding_p.h"
#include <QtCore/qbytearray.h>
@@ -63,6 +62,8 @@
QT_BEGIN_NAMESPACE
+class QQmlCompiledData;
+
struct QQmlCustomParserCompilerBackend
{
virtual ~QQmlCustomParserCompilerBackend() {}
@@ -72,8 +73,6 @@ struct QQmlCustomParserCompilerBackend
const QMetaObject *resolveType(const QString& name) const;
virtual QQmlBinding::Identifier bindingIdentifier(const QV4::CompiledData::Binding *, QQmlCustomParser *) { return QQmlBinding::Invalid; }
-
- virtual QQmlJS::AST::Node *astForBinding(int, int) const { return 0; }
};
class Q_QML_PRIVATE_EXPORT QQmlCustomParser
@@ -93,8 +92,8 @@ public:
void clearErrors();
Flags flags() const { return m_flags; }
- virtual QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, int objectIndex, const QList<const QV4::CompiledData::Binding *> &bindings) = 0;
- virtual void setCustomData(QObject *, const QByteArray &)=0;
+ virtual QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &bindings) = 0;
+ virtual void setCustomData(QObject *, const QByteArray &, QQmlCompiledData *cdata) = 0;
QList<QQmlError> errors() const { return exceptions; }
@@ -111,8 +110,6 @@ protected:
QQmlBinding::Identifier bindingIdentifier(const QV4::CompiledData::Binding *binding);
- QQmlJS::AST::Node *astForBinding(int objectIndex, int scriptIndex) const;
-
private:
QList<QQmlError> exceptions;
QQmlCustomParserCompilerBackend *compiler;
diff --git a/src/qml/qml/qqmldirparser.cpp b/src/qml/qml/qqmldirparser.cpp
index c1d0132c61..a2b4b5edd0 100644
--- a/src/qml/qml/qqmldirparser.cpp
+++ b/src/qml/qml/qqmldirparser.cpp
@@ -41,9 +41,7 @@
#include "qqmldirparser_p.h"
#include "qqmlerror.h"
-#include "qqmlglobal_p.h"
-#include <QtQml/qqmlfile.h>
#include <QtCore/QtDebug>
QT_BEGIN_NAMESPACE
@@ -281,10 +279,10 @@ bool QQmlDirParser::parse(const QString &source)
void QQmlDirParser::reportError(quint16 line, quint16 column, const QString &description)
{
- QQmlError error;
- error.setLine(line);
- error.setColumn(column);
- error.setDescription(description);
+ QQmlJS::DiagnosticMessage error;
+ error.loc.startLine = line;
+ error.loc.startColumn = column;
+ error.message = description;
_errors.append(error);
}
@@ -296,25 +294,41 @@ bool QQmlDirParser::hasError() const
return false;
}
+#if defined(QT_BUILD_QMLDEVTOOLS_LIB) || defined(QT_QMLDEVTOOLS_LIB)
+QList<QQmlJS::DiagnosticMessage> QQmlDirParser::errors(const QString &uri) const
+{
+ QList<QQmlJS::DiagnosticMessage> errors = _errors;
+ for (int i = 0; i < errors.size(); ++i) {
+ QQmlJS::DiagnosticMessage &msg = errors[i];
+ msg.message.replace(QLatin1String("$$URI$$"), uri);
+ }
+ return errors;
+}
+#else
void QQmlDirParser::setError(const QQmlError &e)
{
_errors.clear();
- _errors.append(e);
+ reportError(e.line(), e.column(), e.description());
}
QList<QQmlError> QQmlDirParser::errors(const QString &uri) const
{
QUrl url(uri);
- QList<QQmlError> errors = _errors;
- for (int i = 0; i < errors.size(); ++i) {
- QQmlError &e = errors[i];
- QString description = e.description();
+ QList<QQmlError> errors;
+ for (int i = 0; i < _errors.size(); ++i) {
+ const QQmlJS::DiagnosticMessage &msg = _errors.at(i);
+ QQmlError e;
+ QString description = msg.message;
description.replace(QLatin1String("$$URI$$"), uri);
e.setDescription(description);
e.setUrl(url);
+ e.setLine(msg.loc.startLine);
+ e.setColumn(msg.loc.startColumn);
+ errors << e;
}
return errors;
}
+#endif
QString QQmlDirParser::typeNamespace() const
{
@@ -331,7 +345,7 @@ QList<QQmlDirParser::Plugin> QQmlDirParser::plugins() const
return _plugins;
}
-QHash<QHashedStringRef,QQmlDirParser::Component> QQmlDirParser::components() const
+QHash<QString, QQmlDirParser::Component> QQmlDirParser::components() const
{
return _components;
}
diff --git a/src/qml/qml/qqmldirparser_p.h b/src/qml/qml/qqmldirparser_p.h
index e3607d1e72..bcdb366c6c 100644
--- a/src/qml/qml/qqmldirparser_p.h
+++ b/src/qml/qml/qqmldirparser_p.h
@@ -56,13 +56,14 @@
#include <QtCore/QUrl>
#include <QtCore/QHash>
#include <QtCore/QDebug>
-#include <private/qhashedstring_p.h>
+#include <private/qqmljsengine_p.h>
+#include <private/qtqmlglobal_p.h>
QT_BEGIN_NAMESPACE
class QQmlError;
class QQmlEngine;
-class Q_AUTOTEST_EXPORT QQmlDirParser
+class Q_QML_PRIVATE_EXPORT QQmlDirParser
{
Q_DISABLE_COPY(QQmlDirParser)
@@ -73,8 +74,12 @@ public:
bool parse(const QString &source);
bool hasError() const;
+#if defined(QT_BUILD_QMLDEVTOOLS_LIB) || defined(QT_QMLDEVTOOLS_LIB)
+ QList<QQmlJS::DiagnosticMessage> errors(const QString &uri) const;
+#else
void setError(const QQmlError &);
QList<QQmlError> errors(const QString &uri) const;
+#endif
QString typeNamespace() const;
void setTypeNamespace(const QString &s);
@@ -121,7 +126,7 @@ public:
int minorVersion;
};
- QHash<QHashedStringRef,Component> components() const;
+ QHash<QString,Component> components() const;
QList<Script> scripts() const;
QList<Plugin> plugins() const;
@@ -142,9 +147,9 @@ private:
void reportError(quint16 line, quint16 column, const QString &message);
private:
- QList<QQmlError> _errors;
+ QList<QQmlJS::DiagnosticMessage> _errors;
QString _typeNamespace;
- QHash<QHashedStringRef,Component> _components; // multi hash
+ QHash<QString,Component> _components; // multi hash
QList<Script> _scripts;
QList<Plugin> _plugins;
#ifdef QT_CREATOR
@@ -152,7 +157,7 @@ private:
#endif
};
-typedef QHash<QHashedStringRef,QQmlDirParser::Component> QQmlDirComponents;
+typedef QHash<QString,QQmlDirParser::Component> QQmlDirComponents;
typedef QList<QQmlDirParser::Script> QQmlDirScripts;
typedef QList<QQmlDirParser::Plugin> QQmlDirPlugins;
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index d927a8c628..d378d77bb0 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -109,7 +109,9 @@
#include <qlibrary.h>
#include <windows.h>
-#define CSIDL_APPDATA 0x001a // <username>\Application Data
+#ifndef CSIDL_APPDATA
+# define CSIDL_APPDATA 0x001a // <username>\Application Data
+#endif
#endif
Q_DECLARE_METATYPE(QQmlProperty)
@@ -2302,12 +2304,23 @@ static inline QString shellNormalizeFileName(const QString &name)
{
const QString nativeSeparatorName(QDir::toNativeSeparators(name));
const LPCTSTR nameC = reinterpret_cast<LPCTSTR>(nativeSeparatorName.utf16());
+// The correct declaration of the SHGetPathFromIDList symbol is
+// being used in mingw-w64 as of r6215, which is a v3 snapshot.
+#if defined(Q_CC_MINGW) && (!defined(__MINGW64_VERSION_MAJOR) || __MINGW64_VERSION_MAJOR < 3)
+ ITEMIDLIST file;
+ if (FAILED(SHParseDisplayName(nameC, NULL, &file, 0, NULL)))
+ return name;
+ TCHAR buffer[MAX_PATH];
+ if (!SHGetPathFromIDList(&file, buffer))
+ return name;
+#else
PIDLIST_ABSOLUTE file;
if (FAILED(SHParseDisplayName(nameC, NULL, &file, 0, NULL)))
return name;
TCHAR buffer[MAX_PATH];
if (!SHGetPathFromIDList(file, buffer))
return name;
+#endif
QString canonicalName = QString::fromWCharArray(buffer);
// Upper case drive letter
if (canonicalName.size() > 2 && canonicalName.at(1) == QLatin1Char(':'))
diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h
index 56c80dc2cd..5767ca90f0 100644
--- a/src/qml/qml/qqmlengine_p.h
+++ b/src/qml/qml/qqmlengine_p.h
@@ -69,6 +69,7 @@
#include "qqmldirparser_p.h"
#include <private/qintrusivelist_p.h>
#include <private/qrecyclepool_p.h>
+#include <private/qfieldlist_p.h>
#include <QtCore/qlist.h>
#include <QtCore/qpair.h>
diff --git a/src/qml/qml/qqmlexpression.cpp b/src/qml/qml/qqmlexpression.cpp
index b64dd9bd39..4dc3704bbb 100644
--- a/src/qml/qml/qqmlexpression.cpp
+++ b/src/qml/qml/qqmlexpression.cpp
@@ -78,17 +78,10 @@ void QQmlExpressionPrivate::init(QQmlContextData *ctxt, const QString &expr, QOb
expressionFunctionValid = false;
}
-void QQmlExpressionPrivate::init(QQmlContextData *ctxt, const QString &expr,
- QObject *me, const QString &srcUrl,
- quint16 lineNumber, quint16 columnNumber)
+void QQmlExpressionPrivate::init(QQmlContextData *ctxt, QV4::Function *runtimeFunction, QObject *me)
{
- url = srcUrl;
- line = lineNumber;
- column = columnNumber;
-
- expression = expr;
-
- expressionFunctionValid = false;
+ expressionFunctionValid = true;
+ function = QV4::QmlBindingWrapper::createQmlCallableForFunction(ctxt, me, runtimeFunction);
QQmlAbstractExpression::setContext(ctxt);
setScopeObject(me);
@@ -156,9 +149,9 @@ QQmlExpression::QQmlExpression(const QQmlScriptString &script, QQmlContext *ctxt
if (!ctxt && (!scriptPrivate->context || !scriptPrivate->context->isValid()))
return;
- bool defaultConstruction = true;
QQmlContextData *evalCtxtData = QQmlContextData::get(ctxt ? ctxt : scriptPrivate->context);
QObject *scopeObject = scope ? scope : scriptPrivate->scope;
+ QV4::Function *runtimeFunction = 0;
if (scriptPrivate->context) {
QQmlContextData *ctxtdata = QQmlContextData::get(scriptPrivate->context);
@@ -168,23 +161,22 @@ QQmlExpression::QQmlExpression(const QQmlScriptString &script, QQmlContext *ctxt
Q_ASSERT(typeData);
if (QQmlCompiledData *cdata = typeData->compiledData()) {
- int id = scriptPrivate->bindingId;
- if (id >= 0) {
- defaultConstruction = false;
- d->init(evalCtxtData, cdata->primitives.at(id), scopeObject,
- cdata->name, scriptPrivate->lineNumber, scriptPrivate->columnNumber);
- } else {
- d->url = cdata->name;
- d->line = scriptPrivate->lineNumber;
- d->column = scriptPrivate->columnNumber;
- }
+ d->url = cdata->name;
+ d->line = scriptPrivate->lineNumber;
+ d->column = scriptPrivate->columnNumber;
+
+ if (scriptPrivate->bindingId != QQmlBinding::Invalid)
+ runtimeFunction = cdata->compilationUnit->runtimeFunctions.at(scriptPrivate->bindingId);
}
typeData->release();
}
}
- if (defaultConstruction)
+ if (runtimeFunction) {
+ d->expression = scriptPrivate->script;
+ d->init(evalCtxtData, runtimeFunction, scopeObject);
+ } else
d->init(evalCtxtData, scriptPrivate->script, scopeObject);
}
diff --git a/src/qml/qml/qqmlexpression.h b/src/qml/qml/qqmlexpression.h
index b702a37ee0..185b9542c5 100644
--- a/src/qml/qml/qqmlexpression.h
+++ b/src/qml/qml/qqmlexpression.h
@@ -98,7 +98,6 @@ private:
Q_DECLARE_PRIVATE(QQmlExpression)
friend class QQmlDebugger;
friend class QQmlContext;
- friend class QQmlVME;
};
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlexpression_p.h b/src/qml/qml/qqmlexpression_p.h
index e84d193837..5488459962 100644
--- a/src/qml/qml/qqmlexpression_p.h
+++ b/src/qml/qml/qqmlexpression_p.h
@@ -77,7 +77,7 @@ public:
~QQmlExpressionPrivate();
void init(QQmlContextData *, const QString &, QObject *);
- void init(QQmlContextData *, const QString &, QObject *, const QString &, quint16, quint16);
+ void init(QQmlContextData *, QV4::Function *runtimeFunction, QObject *);
QVariant value(bool *isUndefined = 0);
diff --git a/src/qml/qml/qqmlextensionplugin.cpp b/src/qml/qml/qqmlextensionplugin.cpp
index 76de2dfe34..f3d1ba9d41 100644
--- a/src/qml/qml/qqmlextensionplugin.cpp
+++ b/src/qml/qml/qqmlextensionplugin.cpp
@@ -77,7 +77,7 @@ QT_BEGIN_NAMESPACE
as a new QML element. It provides the current time through \c hour and \c minute
properties, like this:
- \snippet plugins/plugin.cpp 0
+ \snippet qmlextensionplugins/plugin.cpp 0
\dots
To make this class available as a QML type, create a plugin that registers
@@ -85,7 +85,7 @@ QT_BEGIN_NAMESPACE
module will be named \c TimeExample (as defined in the project
file further below).
- \snippet plugins/plugin.cpp plugin
+ \snippet qmlextensionplugins/plugin.cpp plugin
This registers the \c TimeModel class with the 1.0 version of this
plugin library, as a QML type called \c Time. The Q_ASSERT statement
@@ -109,14 +109,14 @@ QT_BEGIN_NAMESPACE
should be bundled with the plugin, so it needs to be specified in the \c qmldir
file:
- \quotefile plugins/imports/TimeExample/qmldir
+ \quotefile qmlextensionplugins/imports/TimeExample/qmldir
Once the project is built and installed, the new \c Time element can be
used by any QML component that imports the \c TimeExample module:
- \snippet plugins/plugins.qml 0
+ \snippet qmlextensionplugins/plugins.qml 0
- The full source code is available in the \l {qml/plugins}{plugins example}.
+ The full source code is available in the \l {qml/qmlextensionplugins}{plugins example}.
The \l {Writing QML Extensions with C++} tutorial also contains a chapter
on creating QML plugins.
diff --git a/src/qml/qml/qqmlfile.cpp b/src/qml/qml/qqmlfile.cpp
index be9b011dda..6728fa10a7 100644
--- a/src/qml/qml/qqmlfile.cpp
+++ b/src/qml/qml/qqmlfile.cpp
@@ -666,18 +666,13 @@ QString QQmlFile::urlToLocalFileOrQrc(const QUrl& url)
static QString toLocalFile(const QString &url)
{
- if (!url.startsWith(QLatin1String("file://"), Qt::CaseInsensitive))
+ const QUrl file(url);
+ if (!file.isLocalFile())
return QString();
- QString file = url.mid(7);
-
//XXX TODO: handle windows hostnames: "//servername/path/to/file.txt"
- // magic for drives on windows
- if (file.length() > 2 && file.at(0) == QLatin1Char('/') && file.at(2) == QLatin1Char(':'))
- file.remove(0, 1);
-
- return file;
+ return file.toLocalFile();
}
/*!
diff --git a/src/qml/qml/qqmlfileselector.cpp b/src/qml/qml/qqmlfileselector.cpp
index a18b8327b1..187c3656c6 100644
--- a/src/qml/qml/qqmlfileselector.cpp
+++ b/src/qml/qml/qqmlfileselector.cpp
@@ -152,8 +152,8 @@ void QQmlFileSelector::setSelector(QFileSelector *selector)
}
/*!
- Adds extra selectors to the current QFileSelector being used. Use this when
- extra selectors are all you need to avoid having to create your own
+ Adds extra selectors contained in \a strings to the current QFileSelector being used.
+ Use this when extra selectors are all you need to avoid having to create your own
QFileSelector instance.
*/
void QQmlFileSelector::setExtraSelectors(QStringList &strings)
@@ -163,7 +163,7 @@ void QQmlFileSelector::setExtraSelectors(QStringList &strings)
}
/*!
- Gets the QQmlFileSelector currently active on the target engine.
+ Gets the QQmlFileSelector currently active on the target \a engine.
*/
QQmlFileSelector* QQmlFileSelector::get(QQmlEngine* engine)
{
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index cae8365598..c0b21a943f 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -296,7 +296,7 @@ public:
QQmlImportNamespace::Import *addImportToNamespace(QQmlImportNamespace *nameSpace,
const QString &uri, const QString &url,
- int vmaj, int vmin, QQmlScript::Import::Type type,
+ int vmaj, int vmin, QV4::CompiledData::Import::ImportType type,
QList<QQmlError> *errors, bool lowPrecedence = false);
bool populatePluginPairVector(QVector<StaticPluginPair> &result, const QString &uri,
@@ -624,12 +624,13 @@ bool QQmlImportNamespace::Import::resolveType(QQmlTypeLoader *typeLoader,
}
}
- QQmlDirComponents::ConstIterator it = qmlDirComponents.find(type), end = qmlDirComponents.end();
+ const QString typeStr = type.toString();
+ QQmlDirComponents::ConstIterator it = qmlDirComponents.find(typeStr), end = qmlDirComponents.end();
if (it != end) {
QString componentUrl;
bool isCompositeSingleton = false;
QQmlDirComponents::ConstIterator candidate = end;
- for ( ; it != end && it.key() == type; ++it) {
+ for ( ; it != end && it.key() == typeStr; ++it) {
const QQmlDirParser::Component &c = *it;
// importing version -1 means import ALL versions
@@ -1211,7 +1212,7 @@ QQmlImportNamespace *QQmlImportsPrivate::importNamespace(const QString &prefix)
QQmlImportNamespace::Import *QQmlImportsPrivate::addImportToNamespace(QQmlImportNamespace *nameSpace,
const QString &uri, const QString &url, int vmaj, int vmin,
- QQmlScript::Import::Type type,
+ QV4::CompiledData::Import::ImportType type,
QList<QQmlError> *errors, bool lowPrecedence)
{
Q_ASSERT(nameSpace);
@@ -1224,7 +1225,7 @@ QQmlImportNamespace::Import *QQmlImportsPrivate::addImportToNamespace(QQmlImport
import->url = url;
import->majversion = vmaj;
import->minversion = vmin;
- import->isLibrary = (type == QQmlScript::Import::Library);
+ import->isLibrary = (type == QV4::CompiledData::Import::ImportLibrary);
if (lowPrecedence)
nameSpace->imports.append(import);
@@ -1245,7 +1246,7 @@ bool QQmlImportsPrivate::addLibraryImport(const QString& uri, const QString &pre
QQmlImportNamespace *nameSpace = importNamespace(prefix);
Q_ASSERT(nameSpace);
- QQmlImportNamespace::Import *inserted = addImportToNamespace(nameSpace, uri, qmldirUrl, vmaj, vmin, QQmlScript::Import::Library, errors);
+ QQmlImportNamespace::Import *inserted = addImportToNamespace(nameSpace, uri, qmldirUrl, vmaj, vmin, QV4::CompiledData::Import::ImportLibrary, errors);
Q_ASSERT(inserted);
if (!incomplete) {
@@ -1375,7 +1376,7 @@ bool QQmlImportsPrivate::addFileImport(const QString& uri, const QString &prefix
if (!url.endsWith(Slash) && !url.endsWith(Backslash))
url += Slash;
- QQmlImportNamespace::Import *inserted = addImportToNamespace(nameSpace, importUri, url, vmaj, vmin, QQmlScript::Import::File, errors, isImplicitImport);
+ QQmlImportNamespace::Import *inserted = addImportToNamespace(nameSpace, importUri, url, vmaj, vmin, QV4::CompiledData::Import::ImportFile, errors, isImplicitImport);
Q_ASSERT(inserted);
if (!incomplete && !qmldirIdentifier.isEmpty()) {
@@ -1578,8 +1579,7 @@ QQmlImportDatabase::QQmlImportDatabase(QQmlEngine *e)
QQmlImportDatabase::~QQmlImportDatabase()
{
- qDeleteAll(qmldirCache);
- qmldirCache.clear();
+ clearDirCache();
}
/*!
@@ -1814,7 +1814,7 @@ void QQmlImportDatabase::setImportPathList(const QStringList &paths)
fileImportPath = paths;
// Our existing cached paths may have been invalidated
- qmldirCache.clear();
+ clearDirCache();
}
/*!
@@ -2024,4 +2024,20 @@ bool QQmlImportDatabase::importDynamicPlugin(const QString &filePath, const QStr
#endif
}
+void QQmlImportDatabase::clearDirCache()
+{
+ QStringHash<QmldirCache *>::ConstIterator itr = qmldirCache.begin();
+ while (itr != qmldirCache.end()) {
+ QmldirCache *cache = *itr;
+ do {
+ QmldirCache *nextCache = cache->next;
+ delete cache;
+ cache = nextCache;
+ } while (cache);
+
+ ++itr;
+ }
+ qmldirCache.clear();
+}
+
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlimport_p.h b/src/qml/qml/qqmlimport_p.h
index b19e777852..3c9452963c 100644
--- a/src/qml/qml/qqmlimport_p.h
+++ b/src/qml/qml/qqmlimport_p.h
@@ -47,8 +47,8 @@
#include <QtCore/qset.h>
#include <QtCore/qstringlist.h>
#include <private/qqmldirparser_p.h>
-#include <private/qqmlscript_p.h>
#include <private/qqmlmetatype_p.h>
+#include <private/qhashedstring_p.h>
//
// W A R N I N G
@@ -174,6 +174,7 @@ private:
const QString &typeNamespace, QList<QQmlError> *errors);
bool registerPluginTypes(QObject *instance, const QString &basePath,
const QString &uri, const QString &typeNamespace, QList<QQmlError> *errors);
+ void clearDirCache();
struct QmldirCache {
int versionMajor;
diff --git a/src/qml/qml/qqmlincubator.cpp b/src/qml/qml/qqmlincubator.cpp
index 4c9c99f1f6..4cdeb19719 100644
--- a/src/qml/qml/qqmlincubator.cpp
+++ b/src/qml/qml/qqmlincubator.cpp
@@ -169,6 +169,20 @@ void QQmlIncubatorPrivate::clear()
nextWaitingFor.remove();
waitingOnMe = 0;
}
+
+ // if we're waiting on any incubators then they should be cleared too.
+ while (waitingFor.first()) {
+ QQmlIncubator * i = static_cast<QQmlIncubatorPrivate*>(waitingFor.first())->q;
+ if (i)
+ i->clear();
+ }
+
+ bool guardOk = vmeGuard.isOK();
+
+ vmeGuard.clear();
+ if (creator && guardOk)
+ creator->clear();
+ creator.reset(0);
}
/*!
@@ -393,7 +407,7 @@ void QQmlIncubationController::incubateFor(int msecs)
/*!
Incubate objects while the bool pointed to by \a flag is true, or until there are no
-more objects to incubate, or up to msecs if msecs is not zero.
+more objects to incubate, or up to \a msecs if \a msecs is not zero.
Generally this method is used in conjunction with a thread or a UNIX signal that sets
the bool pointed to by \a flag to false when it wants incubation to be interrupted.
@@ -562,20 +576,6 @@ void QQmlIncubator::clear()
d->clear();
- // if we're waiting on any incubators then they should be cleared too.
- while (d->waitingFor.first()) {
- QQmlIncubator * i = static_cast<QQmlIncubatorPrivate*>(d->waitingFor.first())->q;
- if (i)
- i->clear();
- }
-
- bool guardOk = d->vmeGuard.isOK();
-
- d->vmeGuard.clear();
- if (d->creator && guardOk)
- d->creator->clear();
- d->creator.reset(0);
-
Q_ASSERT(d->compiledData == 0);
Q_ASSERT(d->waitingOnMe.data() == 0);
Q_ASSERT(d->waitingFor.isEmpty());
@@ -687,7 +687,7 @@ void QQmlIncubator::statusChanged(Status status)
}
/*!
-Called after the object is first created, but before property bindings are
+Called after the \a object is first created, but before property bindings are
evaluated and, if applicable, QQmlParserStatus::componentComplete() is
called. This is equivalent to the point between QQmlComponent::beginCreate()
and QQmlComponent::endCreate(), and can be used to assign initial values
diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp
index b233b6e98c..560a4c8afd 100644
--- a/src/qml/qml/qqmljavascriptexpression.cpp
+++ b/src/qml/qml/qqmljavascriptexpression.cpp
@@ -218,7 +218,6 @@ void QQmlJavaScriptExpression::GuardCapture::captureProperty(QQmlNotifier *n)
}
/*! \internal
- \reimp
\a n is in the signal index range (see QObjectPrivate::signalIndex()).
*/
diff --git a/src/qml/qml/qqmllistwrapper.cpp b/src/qml/qml/qqmllistwrapper.cpp
index 0d60fee5d0..fd50e2dbbc 100644
--- a/src/qml/qml/qqmllistwrapper.cpp
+++ b/src/qml/qml/qqmllistwrapper.cpp
@@ -129,13 +129,21 @@ ReturnedValue QmlListWrapper::getIndexed(Managed *m, uint index, bool *hasProper
QV4::ExecutionEngine *e = m->engine();
QmlListWrapper *w = m->as<QmlListWrapper>();
- if (!w)
+ if (!w) {
+ if (hasProperty)
+ *hasProperty = false;
return e->currentContext()->throwTypeError();
+ }
quint32 count = w->property.count ? w->property.count(&w->property) : 0;
- if (index < count && w->property.at)
+ if (index < count && w->property.at) {
+ if (hasProperty)
+ *hasProperty = true;
return QV4::QObjectWrapper::wrap(e, w->property.at(&w->property, index));
+ }
+ if (hasProperty)
+ *hasProperty = false;
return Primitive::undefinedValue().asReturnedValue();
}
diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp
index fc9e2fc42a..178280b27c 100644
--- a/src/qml/qml/qqmllocale.cpp
+++ b/src/qml/qml/qqmllocale.cpp
@@ -290,8 +290,11 @@ QV4::ReturnedValue QQmlDateExtension::method_fromLocaleTimeString(QV4::CallConte
tm = r->locale.toTime(dateString, enumFormat);
}
- QDateTime dt = QDateTime::currentDateTime();
- dt.setTime(tm);
+ QDateTime dt;
+ if (tm.isValid()) {
+ dt = QDateTime::currentDateTime();
+ dt.setTime(tm);
+ }
return QV4::Encode(engine->newDateObject(dt));
}
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index 90d3ca3308..42f67f3345 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -106,6 +106,7 @@ struct QQmlMetaTypeData
QBitArray lists;
QList<QQmlPrivate::AutoParentFunction> parentFunctions;
+ QQmlPrivate::QmlUnitCacheLookupFunction lookupCachedQmlUnit;
QSet<QString> protectedNamespaces;
@@ -142,6 +143,7 @@ static uint qHash(const QQmlMetaTypeData::VersionedUri &v)
}
QQmlMetaTypeData::QQmlMetaTypeData()
+ : lookupCachedQmlUnit(0)
{
}
@@ -1344,6 +1346,15 @@ int registerCompositeType(const QQmlPrivate::RegisterCompositeType &type)
return index;
}
+int registerQmlUnitCacheHook(const QQmlPrivate::RegisterQmlUnitCacheHook &hookRegistration)
+{
+ if (hookRegistration.version > 0)
+ qFatal("qmlRegisterType(): Cannot mix incompatible QML versions.");
+ QWriteLocker lock(metaTypeDataLock());
+ QQmlMetaTypeData *data = metaTypeData();
+ data->lookupCachedQmlUnit = hookRegistration.lookupCachedQmlUnit;
+ return 0;
+}
/*
This method is "over generalized" to allow us to (potentially) register more types of things in
@@ -1363,6 +1374,8 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data)
return registerCompositeType(*reinterpret_cast<RegisterCompositeType *>(data));
} else if (type == CompositeSingletonRegistration) {
return registerCompositeSingletonType(*reinterpret_cast<RegisterCompositeSingletonType *>(data));
+ } else if (type == QmlUnitCacheHookRegistration) {
+ return registerQmlUnitCacheHook(*reinterpret_cast<RegisterQmlUnitCacheHook *>(data));
}
return -1;
}
@@ -1865,26 +1878,13 @@ QList<QQmlType*> QQmlMetaType::qmlSingletonTypes()
return retn;
}
-int QQmlMetaType::QQuickAnchorLineMetaTypeId()
+const QQmlPrivate::CachedQmlUnit *QQmlMetaType::findCachedCompilationUnit(const QUrl &uri)
{
- static int id = 0;
- if (!id) {
- id = QMetaType::type("QQuickAnchorLine");
- }
- return id;
-}
-
-QQmlMetaType::CompareFunction QQmlMetaType::anchorLineCompareFunction = 0;
-
-void QQmlMetaType::setQQuickAnchorLineCompareFunction(CompareFunction fun)
-{
- anchorLineCompareFunction = fun;
-}
-
-bool QQmlMetaType::QQuickAnchorLineCompare(const void *p1, const void *p2)
-{
- Q_ASSERT(anchorLineCompareFunction != 0);
- return anchorLineCompareFunction(p1, p2);
+ QReadLocker lock(metaTypeDataLock());
+ QQmlMetaTypeData *data = metaTypeData();
+ if (data->lookupCachedQmlUnit)
+ return data->lookupCachedQmlUnit(uri);
+ return 0;
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h
index 019e6b8821..715ff80c46 100644
--- a/src/qml/qml/qqmlmetatype_p.h
+++ b/src/qml/qml/qqmlmetatype_p.h
@@ -120,10 +120,7 @@ public:
static QList<QQmlPrivate::AutoParentFunction> parentFunctions();
- static int QQuickAnchorLineMetaTypeId();
- typedef bool (*CompareFunction)(const void *, const void *);
- static void setQQuickAnchorLineCompareFunction(CompareFunction);
- static bool QQuickAnchorLineCompare(const void *p1, const void *p2);
+ static const QQmlPrivate::CachedQmlUnit *findCachedCompilationUnit(const QUrl &uri);
static bool namespaceContainsRegistrations(const QString &);
@@ -133,9 +130,6 @@ public:
static QStringList typeRegistrationFailures();
static QReadWriteLock *typeRegistrationLock();
-
-private:
- static CompareFunction anchorLineCompareFunction;
};
struct QQmlMetaTypeData;
@@ -240,6 +234,7 @@ private:
friend int registerInterface(const QQmlPrivate::RegisterInterface &);
friend int registerCompositeType(const QQmlPrivate::RegisterCompositeType &);
friend int registerCompositeSingletonType(const QQmlPrivate::RegisterCompositeSingletonType &);
+ friend int registerQmlUnitCacheHook(const QQmlPrivate::RegisterQmlUnitCacheHook &);
friend Q_QML_EXPORT void qmlClearTypeRegistrations();
QQmlType(int, const QQmlPrivate::RegisterInterface &);
QQmlType(int, const QString &, const QQmlPrivate::RegisterSingletonType &);
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index 50fe5861a6..2ebf90c9be 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -85,7 +85,7 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QQmlCompile
, compiledData(compiledData)
, resolvedTypes(compiledData->resolvedTypes)
, propertyCaches(compiledData->propertyCaches)
- , vmeMetaObjectData(compiledData->datas)
+ , vmeMetaObjectData(compiledData->metaObjects)
, activeVMEDataForRootContext(activeVMEDataForRootContext)
{
init(parentContext);
@@ -98,7 +98,10 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QQmlCompile
sharedState->allCreatedObjects.allocate(compiledData->totalObjectCount);
sharedState->creationContext = creationContext;
sharedState->rootContext = 0;
- sharedState->profiler.profiler = QQmlEnginePrivate::get(engine)->profiler;
+
+ QQmlProfiler *profiler = QQmlEnginePrivate::get(engine)->profiler;
+ Q_QML_PROFILE_IF_ENABLED(profiler,
+ sharedState->profiler.init(profiler, compiledData->totalParserStatusCount));
}
QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QQmlCompiledData *compiledData, QQmlObjectCreatorSharedState *inheritedSharedState)
@@ -106,7 +109,7 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QQmlCompile
, compiledData(compiledData)
, resolvedTypes(compiledData->resolvedTypes)
, propertyCaches(compiledData->propertyCaches)
- , vmeMetaObjectData(compiledData->datas)
+ , vmeMetaObjectData(compiledData->metaObjects)
, activeVMEDataForRootContext(0)
{
init(parentContext);
@@ -213,7 +216,7 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
context->importedScripts = sharedState->creationContext->importedScripts;
}
- QObject *instance = createInstance(objectToCreate, parent);
+ QObject *instance = createInstance(objectToCreate, parent, /*isContextObject*/true);
if (instance) {
QQmlData *ddata = QQmlData::get(instance);
Q_ASSERT(ddata);
@@ -221,12 +224,8 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
ddata->compiledData->release();
ddata->compiledData = compiledData;
ddata->compiledData->addref();
-
- context->contextObject = instance;
}
- Q_QML_VME_PROFILE(sharedState->profiler, stop());
-
phase = CreatingObjectsPhase2;
if (interrupt && interrupt->shouldInterrupt())
@@ -241,6 +240,7 @@ bool QQmlObjectCreator::populateDeferredProperties(QObject *instance)
{
QQmlData *declarativeData = QQmlData::get(instance);
context = declarativeData->deferredData->context;
+ sharedState->rootContext = context;
const int objectIndex = declarativeData->deferredData->deferredIdx;
const QV4::CompiledData::Object *obj = qmlUnit->objectAt(objectIndex);
@@ -704,7 +704,7 @@ void QQmlObjectCreator::setupBindings(const QBitArray &bindingsToSkip)
if (!name.isEmpty()) {
if (binding->flags & QV4::CompiledData::Binding::IsSignalHandlerExpression
|| binding->flags & QV4::CompiledData::Binding::IsSignalHandlerObject)
- property = PropertyResolver(_propertyCache).signal(name, /*notInRevision*/0, _qobject, context);
+ property = QmlIR::PropertyResolver(_propertyCache).signal(name, /*notInRevision*/0, _qobject, context);
else
property = _propertyCache->property(name, _qobject, context);
} else
@@ -745,7 +745,7 @@ bool QQmlObjectCreator::setPropertyBinding(QQmlPropertyData *property, const QV4
// ### resolve this at compile time
if (property && property->propType == qMetaTypeId<QQmlScriptString>()) {
QQmlScriptString ss(binding->valueAsScriptString(&qmlUnit->header), context->asQQmlContext(), _scopeObject);
- ss.d.data()->bindingId = QQmlBinding::Invalid;
+ ss.d.data()->bindingId = binding->value.compiledScriptIndex;
ss.d.data()->lineNumber = binding->location.line;
ss.d.data()->columnNumber = binding->location.column;
ss.d.data()->isStringLiteral = binding->type == QV4::CompiledData::Binding::Type_String;
@@ -820,7 +820,7 @@ bool QQmlObjectCreator::setPropertyBinding(QQmlPropertyData *property, const QV4
QV4::Function *runtimeFunction = compiledData->compilationUnit->runtimeFunctions[binding->value.compiledScriptIndex];
QV4::Scope scope(_qmlContext);
- QV4::ScopedFunctionObject function(scope, QV4::FunctionObject::creatScriptFunction(_qmlContext, runtimeFunction, /*createProto*/ false));
+ QV4::ScopedFunctionObject function(scope, QV4::FunctionObject::createScriptFunction(_qmlContext, runtimeFunction, /*createProto*/ false));
if (binding->flags & QV4::CompiledData::Binding::IsSignalHandlerExpression) {
int signalIndex = _propertyCache->methodIndexToSignalIndex(property->coreIndex);
@@ -998,7 +998,7 @@ void QQmlObjectCreator::setupFunctions()
if (!property->isVMEFunction())
continue;
- function = QV4::FunctionObject::creatScriptFunction(_qmlContext, runtimeFunction);
+ function = QV4::FunctionObject::createScriptFunction(_qmlContext, runtimeFunction);
_vmeMetaObject->setVmeMethod(property->coreIndex, function);
}
}
@@ -1013,8 +1013,9 @@ void QQmlObjectCreator::recordError(const QV4::CompiledData::Location &location,
errors << error;
}
-QObject *QQmlObjectCreator::createInstance(int index, QObject *parent)
+QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isContextObject)
{
+ QQmlObjectCreationProfiler profiler(sharedState->profiler.profiler);
ActiveOCRestorer ocRestorer(this, QQmlEnginePrivate::get(engine));
bool isComponent = false;
@@ -1024,21 +1025,23 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent)
QQmlParserStatus *parserStatus = 0;
bool installPropertyCache = true;
+ const QV4::CompiledData::Object *obj = qmlUnit->objectAt(index);
if (compiledData->isComponent(index)) {
isComponent = true;
QQmlComponent *component = new QQmlComponent(engine, compiledData, index, parent);
+ Q_QML_OC_PROFILE(sharedState->profiler, profiler.update(QStringLiteral("<component>"),
+ context->url, obj->location.line, obj->location.column));
QQmlComponentPrivate::get(component)->creationContext = context;
instance = component;
ddata = QQmlData::get(instance, /*create*/true);
} else {
- const QV4::CompiledData::Object *obj = qmlUnit->objectAt(index);
-
QQmlCompiledData::TypeReference *typeRef = resolvedTypes.value(obj->inheritedTypeNameIndex);
Q_ASSERT(typeRef);
installPropertyCache = !typeRef->isFullyDynamicType;
QQmlType *type = typeRef->type;
if (type) {
- Q_QML_VME_PROFILE(sharedState->profiler, start(type->qmlTypeName(), context->url, obj->location.line, obj->location.column));
+ Q_QML_OC_PROFILE(sharedState->profiler, profiler.update(type->qmlTypeName(),
+ context->url, obj->location.line, obj->location.column));
instance = type->create();
if (!instance) {
recordError(obj->location, tr("Unable to create object of type %1").arg(stringAt(obj->inheritedTypeNameIndex)));
@@ -1060,23 +1063,23 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent)
sharedState->allCreatedObjects.push(instance);
} else {
Q_ASSERT(typeRef->component);
+ Q_QML_OC_PROFILE(sharedState->profiler, profiler.update(typeRef->component->name,
+ context->url, obj->location.line, obj->location.column));
if (typeRef->component->qmlUnit->isSingleton())
{
recordError(obj->location, tr("Composite Singleton Type %1 is not creatable").arg(stringAt(obj->inheritedTypeNameIndex)));
return 0;
}
- Q_QML_VME_PROFILE(sharedState->profiler, startBackground(typeRef->component->name));
+
QQmlObjectCreator subCreator(context, typeRef->component, sharedState.data());
instance = subCreator.create();
- Q_QML_VME_PROFILE(sharedState->profiler, foreground(context->url, obj->location.line, obj->location.column));
if (!instance) {
errors += subCreator.errors;
return 0;
}
}
- // ### use no-event variant
if (parent)
- instance->setParent(parent);
+ QQml_setParent_noEvent(instance, parent);
ddata = QQmlData::get(instance, /*create*/true);
ddata->lineNumber = obj->location.line;
@@ -1102,6 +1105,9 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent)
if (parserStatus) {
parserStatus->classBegin();
+ // push() the profiler state here, together with the parserStatus, as we'll pop() them
+ // together, too.
+ Q_QML_OC_PROFILE(sharedState->profiler, sharedState->profiler.push(profiler));
sharedState->allParserStatusCallbacks.push(parserStatus);
parserStatus->d = &sharedState->allParserStatusCallbacks.top();
}
@@ -1110,11 +1116,16 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent)
if (idEntry != objectIndexToId.constEnd())
context->setIdProperty(idEntry.value(), instance);
+ // Register the context object in the context early on in order for pending binding
+ // initialization to find it available.
+ if (isContextObject)
+ context->contextObject = instance;
+
QBitArray bindingsToSkip;
if (customParser) {
QHash<int, QQmlCompiledData::CustomParserData>::ConstIterator entry = compiledData->customParserData.find(index);
if (entry != compiledData->customParserData.constEnd()) {
- customParser->setCustomData(instance, entry->compilationArtifact);
+ customParser->setCustomData(instance, entry->compilationArtifact, compiledData);
bindingsToSkip = entry->bindings;
}
}
@@ -1122,7 +1133,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent)
if (isComponent)
return instance;
- QQmlRefPointer<QQmlPropertyCache> cache = propertyCaches.value(index);
+ QQmlRefPointer<QQmlPropertyCache> cache = propertyCaches.at(index);
Q_ASSERT(!cache.isNull());
if (installPropertyCache) {
if (ddata->propertyCache)
@@ -1183,7 +1194,7 @@ QQmlContextData *QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interru
if (QQmlVME::componentCompleteEnabled()) { // the qml designer does the component complete later
QQmlTrace trace("VME Component Complete");
while (!sharedState->allParserStatusCallbacks.isEmpty()) {
- Q_QML_VME_PROFILE(sharedState->profiler, pop());
+ QQmlObjectCompletionProfiler profiler(&sharedState->profiler);
QQmlParserStatus *status = sharedState->allParserStatusCallbacks.pop();
if (status && status->d) {
@@ -1194,7 +1205,6 @@ QQmlContextData *QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interru
if (watcher.hasRecursed() || interrupt.shouldInterrupt())
return 0;
}
- Q_QML_VME_PROFILE(sharedState->profiler, clear());
}
{
@@ -1243,20 +1253,12 @@ void QQmlObjectCreator::clear()
while (!sharedState->allCreatedObjects.isEmpty())
delete sharedState->allCreatedObjects.pop();
- // If profiling is switched off during a VME run and then switched back on
- // before or during the next run background ranges from the first run will
- // be reported in the second run because we don't clear() here. We accept
- // that as the collected data will be incomplete anyway and because not
- // calling clear() here is benefitial for the non-profiling case.
- Q_QML_VME_PROFILE(sharedState->profiler, clear(true));
-
phase = Done;
}
bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject *bindingTarget, QQmlPropertyData *valueTypeProperty, const QBitArray &bindingsToSkip)
{
const QV4::CompiledData::Object *obj = qmlUnit->objectAt(index);
- Q_QML_VME_PROFILE(sharedState->profiler, push());
QQmlData *declarativeData = QQmlData::get(instance, /*create*/true);
@@ -1270,7 +1272,7 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject *
QV4::Scope valueScope(v4);
QV4::ScopedValue scopeObjectProtector(valueScope);
- QQmlRefPointer<QQmlPropertyCache> cache = propertyCaches.value(index);
+ QQmlRefPointer<QQmlPropertyCache> cache = propertyCaches.at(index);
QQmlVMEMetaObject *vmeMetaObject = 0;
const QByteArray data = vmeMetaObjectData.value(index);
diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h
index 9fd52a9f48..379a3b2970 100644
--- a/src/qml/qml/qqmlobjectcreator_p.h
+++ b/src/qml/qml/qqmlobjectcreator_p.h
@@ -96,7 +96,7 @@ private:
void init(QQmlContextData *parentContext);
- QObject *createInstance(int index, QObject *parent = 0);
+ QObject *createInstance(int index, QObject *parent = 0, bool isContextObject = false);
bool populateInstance(int index, QObject *instance,
QObject *bindingTarget, QQmlPropertyData *valueTypeProperty,
diff --git a/src/qml/qml/qqmlparserstatus.h b/src/qml/qml/qqmlparserstatus.h
index 4e611f82b1..92b320ec0c 100644
--- a/src/qml/qml/qqmlparserstatus.h
+++ b/src/qml/qml/qqmlparserstatus.h
@@ -58,7 +58,6 @@ public:
virtual void componentComplete()=0;
private:
- friend class QQmlVME;
friend class QQmlComponent;
friend class QQmlComponentPrivate;
friend class QQmlEnginePrivate;
diff --git a/src/qml/qml/qqmlplatform.cpp b/src/qml/qml/qqmlplatform.cpp
index 04862379be..8ee4a542de 100644
--- a/src/qml/qml/qqmlplatform.cpp
+++ b/src/qml/qml/qqmlplatform.cpp
@@ -60,23 +60,27 @@ QQmlPlatform::~QQmlPlatform()
QString QQmlPlatform::os()
{
#if defined(Q_OS_ANDROID)
- return QLatin1String("android");
+ return QStringLiteral("android");
#elif defined(Q_OS_BLACKBERRY)
- return QLatin1String("blackberry");
+ return QStringLiteral("blackberry");
#elif defined(Q_OS_IOS)
- return QLatin1String("ios");
+ return QStringLiteral("ios");
#elif defined(Q_OS_MAC)
- return QLatin1String("osx");
+ return QStringLiteral("osx");
#elif defined(Q_OS_WINCE)
- return QLatin1String("wince");
+ return QStringLiteral("wince");
+#elif defined(Q_OS_WINPHONE)
+ return QStringLiteral("winphone");
+#elif defined(Q_OS_WINRT)
+ return QStringLiteral("winrt");
#elif defined(Q_OS_WIN)
- return QLatin1String("windows");
+ return QStringLiteral("windows");
#elif defined(Q_OS_LINUX)
- return QLatin1String("linux");
+ return QStringLiteral("linux");
#elif defined(Q_OS_UNIX)
- return QLatin1String("unix");
+ return QStringLiteral("unix");
#else
- return QLatin1String("unknown");
+ return QStringLiteral("unknown");
#endif
}
diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h
index 90e7961e6b..5460c99f1d 100644
--- a/src/qml/qml/qqmlprivate.h
+++ b/src/qml/qml/qqmlprivate.h
@@ -61,6 +61,22 @@
QT_BEGIN_NAMESPACE
+namespace QQmlPrivate {
+struct CachedQmlUnit;
+}
+
+namespace QV4 {
+struct ExecutionEngine;
+namespace CompiledData {
+struct QmlUnit;
+struct CompilationUnit;
+}
+typedef CompiledData::CompilationUnit *(*CompilationUnitFactoryFunction)();
+}
+namespace QmlIR {
+struct Document;
+typedef void (*IRLoaderFunction)(Document *, const QQmlPrivate::CachedQmlUnit *);
+}
typedef QObject *(*QQmlAttachedPropertiesFunc)(QObject *);
@@ -268,13 +284,26 @@ namespace QQmlPrivate
const char *typeName;
};
+ struct CachedQmlUnit {
+ const QV4::CompiledData::QmlUnit *qmlData;
+ QV4::CompilationUnitFactoryFunction createCompilationUnit;
+ QmlIR::IRLoaderFunction loadIR;
+ };
+
+ typedef const CachedQmlUnit *(*QmlUnitCacheLookupFunction)(const QUrl &url);
+ struct RegisterQmlUnitCacheHook {
+ int version;
+ QmlUnitCacheLookupFunction lookupCachedQmlUnit;
+ };
+
enum RegistrationType {
TypeRegistration = 0,
InterfaceRegistration = 1,
AutoParentRegistration = 2,
SingletonRegistration = 3,
CompositeRegistration = 4,
- CompositeSingletonRegistration = 5
+ CompositeSingletonRegistration = 5,
+ QmlUnitCacheHookRegistration = 6
};
int Q_QML_EXPORT qmlregister(RegistrationType, void *);
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp
index 0bbcafda54..1075b53c5e 100644
--- a/src/qml/qml/qqmlproperty.cpp
+++ b/src/qml/qml/qqmlproperty.cpp
@@ -1403,6 +1403,12 @@ bool QQmlPropertyPrivate::write(QObject *object,
v = value;
if (v.convert(propertyType)) {
ok = true;
+ } else if (v.isValid() && value.isNull()) {
+ // For historical reasons converting a null QVariant to another type will do the trick
+ // but return false anyway. This is caught with the above condition and considered a
+ // successful conversion.
+ Q_ASSERT(v.userType() == propertyType);
+ ok = true;
} else if ((uint)propertyType >= QVariant::UserType && variantType == QVariant::String) {
QQmlMetaType::StringConverter con = QQmlMetaType::customStringConverter(propertyType);
if (con) {
diff --git a/src/qml/qml/qqmlscript.cpp b/src/qml/qml/qqmlscript.cpp
deleted file mode 100644
index cf56d5701d..0000000000
--- a/src/qml/qml/qqmlscript.cpp
+++ /dev/null
@@ -1,417 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qqmlscript_p.h"
-
-#include <private/qqmljsengine_p.h>
-#include <private/qqmljsparser_p.h>
-#include <private/qqmljslexer_p.h>
-#include <private/qqmljsmemorypool_p.h>
-#include <private/qqmljsastvisitor_p.h>
-#include <private/qqmljsast_p.h>
-
-#include <QStack>
-#include <QStringList>
-#include <QCoreApplication>
-#include <QtDebug>
-
-QT_BEGIN_NAMESPACE
-
-using namespace QQmlJS;
-using namespace QQmlScript;
-
-static void replaceWithSpace(QString &str, int idx, int n)
-{
- QChar *data = str.data() + idx;
- const QChar space(QLatin1Char(' '));
- for (int ii = 0; ii < n; ++ii)
- *data++ = space;
-}
-
-static QQmlScript::LocationSpan
-locationFromLexer(const QQmlJS::Lexer &lex, int startLine, int startColumn, int startOffset)
-{
- QQmlScript::LocationSpan l;
-
- l.start.line = startLine; l.start.column = startColumn;
- l.end.line = lex.tokenEndLine(); l.end.column = lex.tokenEndColumn();
- l.range.offset = startOffset;
- l.range.length = lex.tokenOffset() + lex.tokenLength() - startOffset;
-
- return l;
-}
-
-/*
-Searches for ".pragma <value>" declarations within \a script. Currently supported pragmas
-are:
- library
-*/
-QQmlScript::Object::ScriptBlock::Pragmas QQmlScript::Parser::extractPragmas(QString &script)
-{
- QQmlScript::Object::ScriptBlock::Pragmas rv = QQmlScript::Object::ScriptBlock::None;
-
- const QString pragma(QLatin1String("pragma"));
- const QString library(QLatin1String("library"));
-
- QQmlJS::Lexer l(0);
- l.setCode(script, 0);
-
- int token = l.lex();
-
- while (true) {
- if (token != QQmlJSGrammar::T_DOT)
- return rv;
-
- int startOffset = l.tokenOffset();
- int startLine = l.tokenStartLine();
-
- token = l.lex();
-
- if (token != QQmlJSGrammar::T_PRAGMA ||
- l.tokenStartLine() != startLine ||
- script.mid(l.tokenOffset(), l.tokenLength()) != pragma)
- return rv;
-
- token = l.lex();
-
- if (token != QQmlJSGrammar::T_IDENTIFIER ||
- l.tokenStartLine() != startLine)
- return rv;
-
- QString pragmaValue = script.mid(l.tokenOffset(), l.tokenLength());
- int endOffset = l.tokenLength() + l.tokenOffset();
-
- token = l.lex();
- if (l.tokenStartLine() == startLine)
- return rv;
-
- if (pragmaValue == library) {
- rv |= QQmlScript::Object::ScriptBlock::Shared;
- replaceWithSpace(script, startOffset, endOffset - startOffset);
- } else {
- return rv;
- }
- }
- return rv;
-}
-
-#define CHECK_LINE if (l.tokenStartLine() != startLine) return rv;
-#define CHECK_TOKEN(t) if (token != QQmlJSGrammar:: t) return rv;
-
-static const int uriTokens[] = {
- QQmlJSGrammar::T_IDENTIFIER,
- QQmlJSGrammar::T_PROPERTY,
- QQmlJSGrammar::T_SIGNAL,
- QQmlJSGrammar::T_READONLY,
- QQmlJSGrammar::T_ON,
- QQmlJSGrammar::T_BREAK,
- QQmlJSGrammar::T_CASE,
- QQmlJSGrammar::T_CATCH,
- QQmlJSGrammar::T_CONTINUE,
- QQmlJSGrammar::T_DEFAULT,
- QQmlJSGrammar::T_DELETE,
- QQmlJSGrammar::T_DO,
- QQmlJSGrammar::T_ELSE,
- QQmlJSGrammar::T_FALSE,
- QQmlJSGrammar::T_FINALLY,
- QQmlJSGrammar::T_FOR,
- QQmlJSGrammar::T_FUNCTION,
- QQmlJSGrammar::T_IF,
- QQmlJSGrammar::T_IN,
- QQmlJSGrammar::T_INSTANCEOF,
- QQmlJSGrammar::T_NEW,
- QQmlJSGrammar::T_NULL,
- QQmlJSGrammar::T_RETURN,
- QQmlJSGrammar::T_SWITCH,
- QQmlJSGrammar::T_THIS,
- QQmlJSGrammar::T_THROW,
- QQmlJSGrammar::T_TRUE,
- QQmlJSGrammar::T_TRY,
- QQmlJSGrammar::T_TYPEOF,
- QQmlJSGrammar::T_VAR,
- QQmlJSGrammar::T_VOID,
- QQmlJSGrammar::T_WHILE,
- QQmlJSGrammar::T_CONST,
- QQmlJSGrammar::T_DEBUGGER,
- QQmlJSGrammar::T_RESERVED_WORD,
- QQmlJSGrammar::T_WITH,
-
- QQmlJSGrammar::EOF_SYMBOL
-};
-static inline bool isUriToken(int token)
-{
- const int *current = uriTokens;
- while (*current != QQmlJSGrammar::EOF_SYMBOL) {
- if (*current == token)
- return true;
- ++current;
- }
- return false;
-}
-
-static void extractVersion(QStringRef string, int *maj, int *min)
-{
- *maj = -1; *min = -1;
-
- if (!string.isEmpty()) {
-
- int dot = string.indexOf(QLatin1Char('.'));
-
- if (dot < 0) {
- *maj = string.toInt();
- *min = 0;
- } else {
- *maj = string.left(dot).toInt();
- *min = string.mid(dot + 1).toInt();
- }
- }
-}
-
-QQmlScript::Parser::JavaScriptMetaData QQmlScript::Parser::extractMetaData(QString &script, QQmlError *error)
-{
- Q_ASSERT(error);
-
- JavaScriptMetaData rv;
-
- QQmlScript::Object::ScriptBlock::Pragmas &pragmas = rv.pragmas;
-
- const QString js(QLatin1String(".js"));
- const QString library(QLatin1String("library"));
-
- QQmlJS::Lexer l(0);
- l.setCode(script, 0);
-
- int token = l.lex();
-
- while (true) {
- if (token != QQmlJSGrammar::T_DOT)
- return rv;
-
- int startOffset = l.tokenOffset();
- int startLine = l.tokenStartLine();
- int startColumn = l.tokenStartColumn();
-
- QQmlError importError;
- importError.setLine(startLine + 1); // 0-based, adjust to be 1-based
-
- token = l.lex();
-
- CHECK_LINE;
-
- if (token == QQmlJSGrammar::T_IMPORT) {
-
- // .import <URI> <Version> as <Identifier>
- // .import <file.js> as <Identifier>
-
- token = l.lex();
-
- CHECK_LINE;
-
- if (token == QQmlJSGrammar::T_STRING_LITERAL) {
-
- QString file = l.tokenText();
-
- if (!file.endsWith(js)) {
- importError.setDescription(QCoreApplication::translate("QQmlParser","Imported file must be a script"));
- importError.setColumn(l.tokenStartColumn());
- *error = importError;
- return rv;
- }
-
- bool invalidImport = false;
-
- token = l.lex();
-
- if ((token != QQmlJSGrammar::T_AS) || (l.tokenStartLine() != startLine)) {
- invalidImport = true;
- } else {
- token = l.lex();
-
- if ((token != QQmlJSGrammar::T_IDENTIFIER) || (l.tokenStartLine() != startLine))
- invalidImport = true;
- }
-
-
- if (invalidImport) {
- importError.setDescription(QCoreApplication::translate("QQmlParser","File import requires a qualifier"));
- importError.setColumn(l.tokenStartColumn());
- *error = importError;
- return rv;
- }
-
- int endOffset = l.tokenLength() + l.tokenOffset();
-
- QString importId = script.mid(l.tokenOffset(), l.tokenLength());
-
- QQmlScript::LocationSpan location =
- locationFromLexer(l, startLine, startColumn, startOffset);
-
- token = l.lex();
-
- if (!importId.at(0).isUpper() || (l.tokenStartLine() == startLine)) {
- importError.setDescription(QCoreApplication::translate("QQmlParser","Invalid import qualifier"));
- importError.setColumn(l.tokenStartColumn());
- *error = importError;
- return rv;
- }
-
- replaceWithSpace(script, startOffset, endOffset - startOffset);
-
- Import import;
- import.type = Import::Script;
- import.uri = file;
- import.qualifier = importId;
- import.location = location;
-
- rv.imports << import;
- } else {
- // URI
- QString uri;
-
- while (true) {
- if (!isUriToken(token)) {
- importError.setDescription(QCoreApplication::translate("QQmlParser","Invalid module URI"));
- importError.setColumn(l.tokenStartColumn());
- *error = importError;
- return rv;
- }
-
- uri.append(l.tokenText());
-
- token = l.lex();
- CHECK_LINE;
- if (token != QQmlJSGrammar::T_DOT)
- break;
-
- uri.append(QLatin1Char('.'));
-
- token = l.lex();
- CHECK_LINE;
- }
-
- if (token != QQmlJSGrammar::T_NUMERIC_LITERAL) {
- importError.setDescription(QCoreApplication::translate("QQmlParser","Module import requires a version"));
- importError.setColumn(l.tokenStartColumn());
- *error = importError;
- return rv;
- }
-
- int vmaj, vmin;
- extractVersion(QStringRef(&script, l.tokenOffset(), l.tokenLength()),
- &vmaj, &vmin);
-
- bool invalidImport = false;
-
- token = l.lex();
-
- if ((token != QQmlJSGrammar::T_AS) || (l.tokenStartLine() != startLine)) {
- invalidImport = true;
- } else {
- token = l.lex();
-
- if ((token != QQmlJSGrammar::T_IDENTIFIER) || (l.tokenStartLine() != startLine))
- invalidImport = true;
- }
-
-
- if (invalidImport) {
- importError.setDescription(QCoreApplication::translate("QQmlParser","Module import requires a qualifier"));
- importError.setColumn(l.tokenStartColumn());
- *error = importError;
- return rv;
- }
-
- int endOffset = l.tokenLength() + l.tokenOffset();
-
- QString importId = script.mid(l.tokenOffset(), l.tokenLength());
-
- QQmlScript::LocationSpan location =
- locationFromLexer(l, startLine, startColumn, startOffset);
-
- token = l.lex();
-
- if (!importId.at(0).isUpper() || (l.tokenStartLine() == startLine)) {
- importError.setDescription(QCoreApplication::translate("QQmlParser","Invalid import qualifier"));
- importError.setColumn(l.tokenStartColumn());
- *error = importError;
- return rv;
- }
-
- replaceWithSpace(script, startOffset, endOffset - startOffset);
-
- Import import;
- import.type = Import::Library;
- import.uri = uri;
- import.majorVersion = vmaj;
- import.minorVersion = vmin;
- import.qualifier = importId;
- import.location = location;
-
- rv.imports << import;
- }
- } else if (token == QQmlJSGrammar::T_PRAGMA) {
- token = l.lex();
-
- CHECK_TOKEN(T_IDENTIFIER);
- CHECK_LINE;
-
- QString pragmaValue = script.mid(l.tokenOffset(), l.tokenLength());
- int endOffset = l.tokenLength() + l.tokenOffset();
-
- if (pragmaValue == library) {
- pragmas |= QQmlScript::Object::ScriptBlock::Shared;
- replaceWithSpace(script, startOffset, endOffset - startOffset);
- } else {
- return rv;
- }
-
- token = l.lex();
- if (l.tokenStartLine() == startLine)
- return rv;
-
- } else {
- return rv;
- }
- }
- return rv;
-}
-
-QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlscript_p.h b/src/qml/qml/qqmlscript_p.h
deleted file mode 100644
index 15446c089f..0000000000
--- a/src/qml/qml/qqmlscript_p.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#ifndef QQMLSCRIPT_P_H
-#define QQMLSCRIPT_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtQml/qqmlerror.h>
-
-#include <private/qfieldlist_p.h>
-#include <private/qhashfield_p.h>
-#include <private/qqmlpool_p.h>
-#include <private/qqmlpropertycache_p.h>
-
-#include <QtCore/QList>
-#include <QtCore/QUrl>
-
-QT_BEGIN_NAMESPACE
-
-
-class QByteArray;
-class QQmlPropertyCache;
-namespace QQmlJS { class Engine; namespace AST { class Node; class StringLiteral; class UiProgram; class FunctionDeclaration; } }
-
-namespace QQmlScript {
-
-struct Location
-{
- Location() : line(0), column(0) {}
- quint16 line;
- quint16 column;
-
- inline bool operator<(const Location &other) {
- return line < other.line ||
- (line == other.line && column < other.column);
- }
-};
-
-struct LocationRange
-{
- LocationRange() : offset(0), length(0) {}
- quint32 offset;
- quint32 length;
-};
-
-struct LocationSpan
-{
- Location start;
- Location end;
- LocationRange range;
-
- bool operator<(LocationSpan &o) const {
- return (start.line < o.start.line) ||
- (start.line == o.start.line && start.column < o.start.column);
- }
-};
-
-class Import
-{
-public:
- Import() : type(Library), majorVersion(-1), minorVersion(-1) {}
-
- enum Type { Library, File, Script };
- Type type;
-
- QString uri;
- QString qualifier;
-
- int majorVersion;
- int minorVersion;
-
- QQmlScript::LocationSpan location;
-};
-
-class Pragma
-{
-public:
- Pragma() : type(Singleton) {}
-
- enum Type { Singleton };
- Type type;
-
- QQmlScript::LocationSpan location;
-};
-
-class Object;
-class TypeReference : public QQmlPool::Class
-{
-public:
- // type as it has been referenced in Qml
- QString name;
-};
-
-class Object : public QQmlPool::Class
-{
-public:
- // Script blocks that were nested under this object
- struct ScriptBlock {
- enum Pragma {
- None = 0x00000000,
- Shared = 0x00000001
- };
- Q_DECLARE_FLAGS(Pragmas, Pragma)
-
- QString code;
- QString file;
- Pragmas pragmas;
- };
-};
-
-class Q_QML_PRIVATE_EXPORT Parser
-{
-public:
- class JavaScriptMetaData {
- public:
- JavaScriptMetaData()
- : pragmas(QQmlScript::Object::ScriptBlock::None) {}
-
- QQmlScript::Object::ScriptBlock::Pragmas pragmas;
- QList<Import> imports;
- };
-
- static QQmlScript::Object::ScriptBlock::Pragmas extractPragmas(QString &);
- static JavaScriptMetaData extractMetaData(QString &, QQmlError *error);
-};
-
-}
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlScript::Object::ScriptBlock::Pragmas)
-
-QT_END_NAMESPACE
-
-#endif // QQMLSCRIPT_P_H
diff --git a/src/qml/qml/qqmlscriptstring.h b/src/qml/qml/qqmlscriptstring.h
index 9817fdc92c..2c10df6efc 100644
--- a/src/qml/qml/qqmlscriptstring.h
+++ b/src/qml/qml/qqmlscriptstring.h
@@ -77,7 +77,6 @@ private:
friend class QQmlObjectCreator;
friend class QQmlScriptStringPrivate;
- friend class QQmlVME;
friend class QQmlExpression;
friend class QQmlBinding;
};
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index 5c48304b56..7fc08bd114 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -51,7 +51,6 @@
#include <private/qqmlcomponent_p.h>
#include <private/qqmlprofiler_p.h>
#include <private/qqmlmemoryprofiler_p.h>
-#include <private/qqmlcodegenerator_p.h>
#include <private/qqmltypecompiler_p.h>
#include <QtCore/qdir.h>
@@ -148,6 +147,7 @@ public:
void loadAsync(QQmlDataBlob *b);
void loadWithStaticData(QQmlDataBlob *b, const QByteArray &);
void loadWithStaticDataAsync(QQmlDataBlob *b, const QByteArray &);
+ void loadWithCachedUnit(QQmlDataBlob *b, const QQmlPrivate::CachedQmlUnit *unit);
void callCompleted(QQmlDataBlob *b);
void callDownloadProgressChanged(QQmlDataBlob *b, qreal p);
void initializeEngine(QQmlExtensionInterface *, const char *);
@@ -158,6 +158,7 @@ protected:
private:
void loadThread(QQmlDataBlob *b);
void loadWithStaticDataThread(QQmlDataBlob *b, const QByteArray &);
+ void loadWithCachedUnitThread(QQmlDataBlob *b, const QQmlPrivate::CachedQmlUnit *unit);
void callCompletedMain(QQmlDataBlob *b);
void callDownloadProgressChangedMain(QQmlDataBlob *b, qreal p);
void initializeEngineMain(QQmlExtensionInterface *iface, const char *uri);
@@ -778,6 +779,12 @@ void QQmlDataLoaderThread::loadWithStaticDataAsync(QQmlDataBlob *b, const QByteA
postMethodToThread(&This::loadWithStaticDataThread, b, d);
}
+void QQmlDataLoaderThread::loadWithCachedUnit(QQmlDataBlob *b, const QQmlPrivate::CachedQmlUnit *unit)
+{
+ b->addref();
+ callMethodInThread(&This::loadWithCachedUnitThread, b, unit);
+}
+
void QQmlDataLoaderThread::callCompleted(QQmlDataBlob *b)
{
b->addref();
@@ -816,6 +823,12 @@ void QQmlDataLoaderThread::loadWithStaticDataThread(QQmlDataBlob *b, const QByte
b->release();
}
+void QQmlDataLoaderThread::loadWithCachedUnitThread(QQmlDataBlob *b, const QQmlPrivate::CachedQmlUnit *unit)
+{
+ m_loader->loadWithCachedUnitThread(b, unit);
+ b->release();
+}
+
void QQmlDataLoaderThread::callCompletedMain(QQmlDataBlob *b)
{
QML_MEMORY_SCOPE_URL(b->url());
@@ -966,6 +979,28 @@ void QQmlDataLoader::loadWithStaticData(QQmlDataBlob *blob, const QByteArray &da
}
}
+void QQmlDataLoader::loadWithCachedUnit(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit)
+{
+#ifdef DATABLOB_DEBUG
+ qWarning("QQmlDataLoader::loadWithUnitFcatory(%s, data): %s thread", qPrintable(blob->m_url.toString()),
+ m_thread->isThisThread()?"Compile":"Engine");
+#endif
+
+ blob->startLoading(this);
+
+ if (m_thread->isThisThread()) {
+ unlock();
+ loadWithCachedUnitThread(blob, unit);
+ lock();
+ } else {
+ unlock();
+ m_thread->loadWithCachedUnit(blob, unit);
+ lock();
+ if (!blob->isCompleteOrError())
+ blob->m_data.setIsAsync(true);
+ }
+}
+
void QQmlDataLoader::loadWithStaticDataThread(QQmlDataBlob *blob, const QByteArray &data)
{
ASSERT_LOADTHREAD();
@@ -973,6 +1008,13 @@ void QQmlDataLoader::loadWithStaticDataThread(QQmlDataBlob *blob, const QByteArr
setData(blob, data);
}
+void QQmlDataLoader::loadWithCachedUnitThread(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit)
+{
+ ASSERT_LOADTHREAD();
+
+ setCachedUnit(blob, unit);
+}
+
void QQmlDataLoader::loadThread(QQmlDataBlob *blob)
{
ASSERT_LOADTHREAD();
@@ -1166,6 +1208,24 @@ void QQmlDataLoader::setData(QQmlDataBlob *blob, const QQmlDataBlob::Data &d)
blob->tryDone();
}
+void QQmlDataLoader::setCachedUnit(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit)
+{
+ QML_MEMORY_SCOPE_URL(blob->url());
+ blob->m_inCallback = true;
+
+ blob->initializeFromCachedUnit(unit);
+
+ if (!blob->isError() && !blob->isWaiting())
+ blob->allDependenciesDone();
+
+ if (blob->status() != QQmlDataBlob::Error)
+ blob->m_data.setStatus(QQmlDataBlob::WaitingForDependencies);
+
+ blob->m_inCallback = false;
+
+ blob->tryDone();
+}
+
void QQmlDataLoader::shutdownThread()
{
if (!m_thread->isShutdown())
@@ -1173,7 +1233,7 @@ void QQmlDataLoader::shutdownThread()
}
QQmlTypeLoader::Blob::Blob(const QUrl &url, QQmlDataBlob::Type type, QQmlTypeLoader *loader)
- : QQmlDataBlob(url, type), m_typeLoader(loader), m_imports(loader), m_isSingleton(false)
+ : QQmlDataBlob(url, type), m_typeLoader(loader), m_importCache(loader), m_isSingleton(false)
{
}
@@ -1183,7 +1243,7 @@ QQmlTypeLoader::Blob::~Blob()
m_qmldirs.at(ii)->release();
}
-bool QQmlTypeLoader::Blob::fetchQmldir(const QUrl &url, const QQmlScript::Import *import, int priority, QList<QQmlError> *errors)
+bool QQmlTypeLoader::Blob::fetchQmldir(const QUrl &url, const QV4::CompiledData::Import *import, int priority, QList<QQmlError> *errors)
{
QQmlQmldirData *data = typeLoader()->getQmldir(url);
@@ -1204,17 +1264,17 @@ bool QQmlTypeLoader::Blob::fetchQmldir(const QUrl &url, const QQmlScript::Import
return true;
}
-bool QQmlTypeLoader::Blob::updateQmldir(QQmlQmldirData *data, const QQmlScript::Import *import, QList<QQmlError> *errors)
+bool QQmlTypeLoader::Blob::updateQmldir(QQmlQmldirData *data, const QV4::CompiledData::Import *import, QList<QQmlError> *errors)
{
QString qmldirIdentifier = data->url().toString();
QString qmldirUrl = qmldirIdentifier.left(qmldirIdentifier.lastIndexOf(QLatin1Char('/')) + 1);
typeLoader()->setQmldirContent(qmldirIdentifier, data->content());
- if (!m_imports.updateQmldirContent(typeLoader()->importDatabase(), import->uri, import->qualifier, qmldirIdentifier, qmldirUrl, errors))
+ if (!m_importCache.updateQmldirContent(typeLoader()->importDatabase(), stringAt(import->uriIndex), stringAt(import->qualifierIndex), qmldirIdentifier, qmldirUrl, errors))
return false;
- QHash<const QQmlScript::Import *, int>::iterator it = m_unresolvedImports.find(import);
+ QHash<const QV4::CompiledData::Import *, int>::iterator it = m_unresolvedImports.find(import);
if (it != m_unresolvedImports.end()) {
*it = data->priority();
}
@@ -1222,7 +1282,8 @@ bool QQmlTypeLoader::Blob::updateQmldir(QQmlQmldirData *data, const QQmlScript::
// Release this reference at destruction
m_qmldirs << data;
- if (!import->qualifier.isEmpty()) {
+ const QString &importQualifier = stringAt(import->qualifierIndex);
+ if (!importQualifier.isEmpty()) {
// Does this library contain any qualified scripts?
QUrl libraryUrl(qmldirUrl);
const QmldirContent *qmldir = typeLoader()->qmldirContent(qmldirIdentifier, qmldirUrl);
@@ -1231,43 +1292,45 @@ bool QQmlTypeLoader::Blob::updateQmldir(QQmlQmldirData *data, const QQmlScript::
QQmlScriptBlob *blob = typeLoader()->getScript(scriptUrl);
addDependency(blob);
- scriptImported(blob, import->location.start, script.nameSpace, import->qualifier);
+ scriptImported(blob, import->location, script.nameSpace, importQualifier);
}
}
return true;
}
-bool QQmlTypeLoader::Blob::addImport(const QQmlScript::Import &import, QList<QQmlError> *errors)
+bool QQmlTypeLoader::Blob::addImport(const QV4::CompiledData::Import *import, QList<QQmlError> *errors)
{
Q_ASSERT(errors);
QQmlImportDatabase *importDatabase = typeLoader()->importDatabase();
- if (import.type == QQmlScript::Import::Script) {
- QUrl scriptUrl = finalUrl().resolved(QUrl(import.uri));
+ const QString &importUri = stringAt(import->uriIndex);
+ const QString &importQualifier = stringAt(import->qualifierIndex);
+ if (import->type == QV4::CompiledData::Import::ImportScript) {
+ QUrl scriptUrl = finalUrl().resolved(QUrl(importUri));
QQmlScriptBlob *blob = typeLoader()->getScript(scriptUrl);
addDependency(blob);
- scriptImported(blob, import.location.start, import.qualifier, QString());
- } else if (import.type == QQmlScript::Import::Library) {
+ scriptImported(blob, import->location, importQualifier, QString());
+ } else if (import->type == QV4::CompiledData::Import::ImportLibrary) {
QString qmldirFilePath;
QString qmldirUrl;
- if (QQmlMetaType::isLockedModule(import.uri, import.majorVersion)) {
+ if (QQmlMetaType::isLockedModule(importUri, import->majorVersion)) {
//Locked modules are checked first, to save on filesystem checks
- if (!m_imports.addLibraryImport(importDatabase, import.uri, import.qualifier, import.majorVersion,
- import.minorVersion, QString(), QString(), false, errors))
+ if (!m_importCache.addLibraryImport(importDatabase, importUri, importQualifier, import->majorVersion,
+ import->minorVersion, QString(), QString(), false, errors))
return false;
- } else if (m_imports.locateQmldir(importDatabase, import.uri, import.majorVersion, import.minorVersion,
+ } else if (m_importCache.locateQmldir(importDatabase, importUri, import->majorVersion, import->minorVersion,
&qmldirFilePath, &qmldirUrl)) {
// This is a local library import
- if (!m_imports.addLibraryImport(importDatabase, import.uri, import.qualifier, import.majorVersion,
- import.minorVersion, qmldirFilePath, qmldirUrl, false, errors))
+ if (!m_importCache.addLibraryImport(importDatabase, importUri, importQualifier, import->majorVersion,
+ import->minorVersion, qmldirFilePath, qmldirUrl, false, errors))
return false;
- if (!import.qualifier.isEmpty()) {
+ if (!importQualifier.isEmpty()) {
// Does this library contain any qualified scripts?
QUrl libraryUrl(qmldirUrl);
const QmldirContent *qmldir = typeLoader()->qmldirContent(qmldirFilePath, qmldirUrl);
@@ -1276,34 +1339,34 @@ bool QQmlTypeLoader::Blob::addImport(const QQmlScript::Import &import, QList<QQm
QQmlScriptBlob *blob = typeLoader()->getScript(scriptUrl);
addDependency(blob);
- scriptImported(blob, import.location.start, script.nameSpace, import.qualifier);
+ scriptImported(blob, import->location, script.nameSpace, importQualifier);
}
}
} else {
// Is this a module?
- if (QQmlMetaType::isAnyModule(import.uri)) {
- if (!m_imports.addLibraryImport(importDatabase, import.uri, import.qualifier, import.majorVersion,
- import.minorVersion, QString(), QString(), false, errors))
+ if (QQmlMetaType::isAnyModule(importUri)) {
+ if (!m_importCache.addLibraryImport(importDatabase, importUri, importQualifier, import->majorVersion,
+ import->minorVersion, QString(), QString(), false, errors))
return false;
} else {
// We haven't yet resolved this import
- m_unresolvedImports.insert(&import, 0);
+ m_unresolvedImports.insert(import, 0);
// Query any network import paths for this library
QStringList remotePathList = importDatabase->importPathList(QQmlImportDatabase::Remote);
if (!remotePathList.isEmpty()) {
// Add this library and request the possible locations for it
- if (!m_imports.addLibraryImport(importDatabase, import.uri, import.qualifier, import.majorVersion,
- import.minorVersion, QString(), QString(), true, errors))
+ if (!m_importCache.addLibraryImport(importDatabase, importUri, importQualifier, import->majorVersion,
+ import->minorVersion, QString(), QString(), true, errors))
return false;
// Probe for all possible locations
int priority = 0;
for (int version = QQmlImports::FullyVersioned; version <= QQmlImports::Unversioned; ++version) {
foreach (const QString &path, remotePathList) {
- QString qmldirUrl = QQmlImports::completeQmldirPath(import.uri, path, import.majorVersion, import.minorVersion,
+ QString qmldirUrl = QQmlImports::completeQmldirPath(importUri, path, import->majorVersion, import->minorVersion,
static_cast<QQmlImports::ImportVersion>(version));
- if (!fetchQmldir(QUrl(qmldirUrl), &import, ++priority, errors))
+ if (!fetchQmldir(QUrl(qmldirUrl), import, ++priority, errors))
return false;
}
}
@@ -1311,25 +1374,25 @@ bool QQmlTypeLoader::Blob::addImport(const QQmlScript::Import &import, QList<QQm
}
}
} else {
- Q_ASSERT(import.type == QQmlScript::Import::File);
+ Q_ASSERT(import->type == QV4::CompiledData::Import::ImportFile);
bool incomplete = false;
QUrl qmldirUrl;
- if (import.qualifier.isEmpty()) {
- qmldirUrl = finalUrl().resolved(QUrl(import.uri + QLatin1String("/qmldir")));
+ if (importQualifier.isEmpty()) {
+ qmldirUrl = finalUrl().resolved(QUrl(importUri + QLatin1String("/qmldir")));
if (!QQmlImports::isLocal(qmldirUrl)) {
// This is a remote file; the import is currently incomplete
incomplete = true;
}
}
- if (!m_imports.addFileImport(importDatabase, import.uri, import.qualifier, import.majorVersion,
- import.minorVersion, incomplete, errors))
+ if (!m_importCache.addFileImport(importDatabase, importUri, importQualifier, import->majorVersion,
+ import->minorVersion, incomplete, errors))
return false;
if (incomplete) {
- if (!fetchQmldir(qmldirUrl, &import, 1, errors))
+ if (!fetchQmldir(qmldirUrl, import, 1, errors))
return false;
}
}
@@ -1337,11 +1400,11 @@ bool QQmlTypeLoader::Blob::addImport(const QQmlScript::Import &import, QList<QQm
return true;
}
-bool QQmlTypeLoader::Blob::addPragma(const QQmlScript::Pragma &pragma, QList<QQmlError> *errors)
+bool QQmlTypeLoader::Blob::addPragma(const QmlIR::Pragma &pragma, QList<QQmlError> *errors)
{
Q_ASSERT(errors);
- if (pragma.type == QQmlScript::Pragma::Singleton) {
+ if (pragma.type == QmlIR::Pragma::PragmaSingleton) {
QUrl myUrl = finalUrl();
QQmlType *ret = QQmlMetaType::qmlType(myUrl, true);
@@ -1349,8 +1412,8 @@ bool QQmlTypeLoader::Blob::addPragma(const QQmlScript::Pragma &pragma, QList<QQm
QQmlError error;
error.setDescription(QQmlTypeLoader::tr("No matching type found, pragma Singleton files cannot be used by QQmlComponent."));
error.setUrl(myUrl);
- error.setLine(pragma.location.start.line);
- error.setColumn(pragma.location.start.column);
+ error.setLine(pragma.location.line);
+ error.setColumn(pragma.location.column);
errors->prepend(error);
return false;
}
@@ -1359,8 +1422,8 @@ bool QQmlTypeLoader::Blob::addPragma(const QQmlScript::Pragma &pragma, QList<QQm
QQmlError error;
error.setDescription(QQmlTypeLoader::tr("pragma Singleton used with a non composite singleton type %1").arg(ret->qmlTypeName()));
error.setUrl(myUrl);
- error.setLine(pragma.location.start.line);
- error.setColumn(pragma.location.start.column);
+ error.setLine(pragma.location.line);
+ error.setColumn(pragma.location.column);
errors->prepend(error);
return false;
}
@@ -1371,8 +1434,8 @@ bool QQmlTypeLoader::Blob::addPragma(const QQmlScript::Pragma &pragma, QList<QQm
QQmlError error;
error.setDescription(QLatin1String("Invalid pragma"));
error.setUrl(finalUrl());
- error.setLine(pragma.location.start.line);
- error.setColumn(pragma.location.start.column);
+ error.setLine(pragma.location.line);
+ error.setColumn(pragma.location.column);
errors->prepend(error);
return false;
}
@@ -1395,15 +1458,15 @@ void QQmlTypeLoader::Blob::dependencyComplete(QQmlDataBlob *blob)
if (blob->type() == QQmlDataBlob::QmldirFile) {
QQmlQmldirData *data = static_cast<QQmlQmldirData *>(blob);
- const QQmlScript::Import *import = data->import();
+ const QV4::CompiledData::Import *import = data->import();
QList<QQmlError> errors;
if (!qmldirDataAvailable(data, &errors)) {
Q_ASSERT(errors.size());
QQmlError error(errors.takeFirst());
- error.setUrl(m_imports.baseUrl());
- error.setLine(import->location.start.line);
- error.setColumn(import->location.start.column);
+ error.setUrl(m_importCache.baseUrl());
+ error.setLine(import->location.line);
+ error.setColumn(import->location.column);
errors.prepend(error); // put it back on the list after filling out information.
setError(errors);
}
@@ -1414,7 +1477,7 @@ bool QQmlTypeLoader::Blob::qmldirDataAvailable(QQmlQmldirData *data, QList<QQmlE
{
bool resolve = true;
- const QQmlScript::Import *import = data->import();
+ const QV4::CompiledData::Import *import = data->import();
data->setImport(0);
int priority = data->priority();
@@ -1422,7 +1485,7 @@ bool QQmlTypeLoader::Blob::qmldirDataAvailable(QQmlQmldirData *data, QList<QQmlE
if (import) {
// Do we need to resolve this import?
- QHash<const QQmlScript::Import *, int>::iterator it = m_unresolvedImports.find(import);
+ QHash<const QV4::CompiledData::Import *, int>::iterator it = m_unresolvedImports.find(import);
if (it != m_unresolvedImports.end()) {
resolve = (*it == 0) || (*it > priority);
}
@@ -1537,7 +1600,11 @@ QQmlTypeData *QQmlTypeLoader::getType(const QUrl &url, Mode mode)
typeData = new QQmlTypeData(url, this);
// TODO: if (compiledData == 0), is it safe to omit this insertion?
m_typeCache.insert(url, typeData);
- QQmlDataLoader::load(typeData, mode);
+ if (const QQmlPrivate::CachedQmlUnit *cachedUnit = QQmlMetaType::findCachedCompilationUnit(url)) {
+ QQmlDataLoader::loadWithCachedUnit(typeData, cachedUnit);
+ } else {
+ QQmlDataLoader::load(typeData, mode);
+ }
}
typeData->addref();
@@ -1575,7 +1642,12 @@ QQmlScriptBlob *QQmlTypeLoader::getScript(const QUrl &url)
if (!scriptBlob) {
scriptBlob = new QQmlScriptBlob(url, this);
m_scriptCache.insert(url, scriptBlob);
- QQmlDataLoader::load(scriptBlob);
+
+ if (const QQmlPrivate::CachedQmlUnit *cachedUnit = QQmlMetaType::findCachedCompilationUnit(url)) {
+ QQmlDataLoader::loadWithCachedUnit(scriptBlob, cachedUnit);
+ } else {
+ QQmlDataLoader::load(scriptBlob);
+ }
}
scriptBlob->addref();
@@ -1985,7 +2057,6 @@ QQmlTypeData::~QQmlTypeData()
if (m_compiledData)
m_compiledData->release();
- delete m_implicitImport;
}
const QList<QQmlTypeData::ScriptReference> &QQmlTypeData::resolvedScripts() const
@@ -2045,7 +2116,7 @@ void QQmlTypeData::done()
const TypeReference &type = *it;
Q_ASSERT(!type.typeData || type.typeData->isCompleteOrError());
if (type.typeData && type.typeData->isError()) {
- QString typeName = parsedQML->jsGenerator.strings.at(it.key());
+ QString typeName = m_document->stringAt(it.key());
QList<QQmlError> errors = type.typeData->errors();
QQmlError error;
@@ -2092,7 +2163,8 @@ void QQmlTypeData::done()
if (!isError())
compile();
- parsedQML.reset();
+ m_document.reset();
+ m_implicitImport = 0;
}
void QQmlTypeData::completed()
@@ -2108,14 +2180,14 @@ bool QQmlTypeData::loadImplicitImport()
{
m_implicitImportLoaded = true; // Even if we hit an error, count as loaded (we'd just keep hitting the error)
- m_imports.setBaseUrl(finalUrl(), finalUrlString());
+ m_importCache.setBaseUrl(finalUrl(), finalUrlString());
QQmlImportDatabase *importDatabase = typeLoader()->importDatabase();
// For local urls, add an implicit import "." as most overridden lookup.
// This will also trigger the loading of the qmldir and the import of any native
// types from available plugins.
QList<QQmlError> implicitImportErrors;
- m_imports.addImplicitImport(importDatabase, &implicitImportErrors);
+ m_importCache.addImplicitImport(importDatabase, &implicitImportErrors);
if (!implicitImportErrors.isEmpty()) {
setError(implicitImportErrors);
@@ -2133,14 +2205,37 @@ void QQmlTypeData::dataReceived(const Data &data)
if (data.isFile()) preparseData = data.asFile()->metaData(QLatin1String("qml:preparse"));
QQmlEngine *qmlEngine = typeLoader()->engine();
- parsedQML.reset(new QtQml::ParsedQML(QV8Engine::getV4(qmlEngine)->debugger != 0));
- QQmlCodeGenerator compiler(QV8Engine::get(qmlEngine)->illegalNames());
- if (!compiler.generateFromQml(code, finalUrl(), finalUrlString(), parsedQML.data())) {
- setError(compiler.errors);
+ m_document.reset(new QmlIR::Document(QV8Engine::getV4(qmlEngine)->debugger != 0));
+ QmlIR::IRBuilder compiler(QV8Engine::get(qmlEngine)->illegalNames());
+ if (!compiler.generateFromQml(code, finalUrlString(), finalUrlString(), m_document.data())) {
+ QList<QQmlError> errors;
+ foreach (const QQmlJS::DiagnosticMessage &msg, compiler.errors) {
+ QQmlError e;
+ e.setUrl(finalUrl());
+ e.setLine(msg.loc.startLine);
+ e.setColumn(msg.loc.startColumn);
+ e.setDescription(msg.message);
+ errors << e;
+ }
+ setError(errors);
return;
}
- m_imports.setBaseUrl(finalUrl(), finalUrlString());
+ continueLoadFromIR();
+}
+
+void QQmlTypeData::initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *unit)
+{
+ QQmlEngine *qmlEngine = typeLoader()->engine();
+ m_document.reset(new QmlIR::Document(QV8Engine::getV4(qmlEngine)->debugger != 0));
+ unit->loadIR(m_document.data(), unit);
+ continueLoadFromIR();
+}
+
+void QQmlTypeData::continueLoadFromIR()
+{
+ m_document->collectTypeReferences();
+ m_importCache.setBaseUrl(finalUrl(), finalUrlString());
// For remote URLs, we don't delay the loading of the implicit import
// because the loading probably requires an asynchronous fetch of the
@@ -2151,9 +2246,10 @@ void QQmlTypeData::dataReceived(const Data &data)
if (!loadImplicitImport())
return;
// This qmldir is for the implicit import
- m_implicitImport = new QQmlScript::Import;
- m_implicitImport->uri = QLatin1String(".");
- m_implicitImport->qualifier = QString();
+ QQmlJS::MemoryPool *pool = m_document->jsParserEngine.pool();
+ m_implicitImport = pool->New<QV4::CompiledData::Import>();
+ m_implicitImport->uriIndex = m_document->registerString(QLatin1String("."));
+ m_implicitImport->qualifierIndex = 0; // empty string
m_implicitImport->majorVersion = -1;
m_implicitImport->minorVersion = -1;
QList<QQmlError> errors;
@@ -2167,62 +2263,21 @@ void QQmlTypeData::dataReceived(const Data &data)
QList<QQmlError> errors;
- // ### convert to use new data structure once old compiler is gone.
- if (m_newImports.isEmpty()) {
- m_newImports.reserve(parsedQML->imports.size());
- foreach (QV4::CompiledData::Import *i, parsedQML->imports) {
- QQmlScript::Import import;
- import.uri = parsedQML->stringAt(i->uriIndex);
- import.qualifier = parsedQML->stringAt(i->qualifierIndex);
- import.majorVersion = i->majorVersion;
- import.minorVersion = i->minorVersion;
- import.location.start.line = i->location.line;
- import.location.start.column = i->location.column;
-
- switch (i->type) {
- case QV4::CompiledData::Import::ImportFile: import.type = QQmlScript::Import::File; break;
- case QV4::CompiledData::Import::ImportLibrary: import.type = QQmlScript::Import::Library; break;
- case QV4::CompiledData::Import::ImportScript: import.type = QQmlScript::Import::Script; break;
- default: break;
- }
-
-
- m_newImports << import;
- }
- }
-
- foreach (const QQmlScript::Import &import, m_newImports) {
+ foreach (const QV4::CompiledData::Import *import, m_document->imports) {
if (!addImport(import, &errors)) {
Q_ASSERT(errors.size());
QQmlError error(errors.takeFirst());
- error.setUrl(m_imports.baseUrl());
- error.setLine(import.location.start.line);
- error.setColumn(import.location.start.column);
+ error.setUrl(m_importCache.baseUrl());
+ error.setLine(import->location.line);
+ error.setColumn(import->location.column);
errors.prepend(error); // put it back on the list after filling out information.
setError(errors);
return;
}
}
- // ### convert to use new data structure once old compiler is gone.
- if (m_newPragmas.isEmpty()) {
- m_newPragmas.reserve(parsedQML->pragmas.size());
- foreach (QtQml::Pragma *p, parsedQML->pragmas) {
- QQmlScript::Pragma pragma;
- pragma.location.start.line = p->location.line;
- pragma.location.start.column = p->location.column;
-
- switch (p->type) {
- case QtQml::Pragma::PragmaSingleton: pragma.type = QQmlScript::Pragma::Singleton; break;
- default: break;
- }
-
- m_newPragmas << pragma;
- }
- }
-
- foreach (const QQmlScript::Pragma &pragma, m_newPragmas) {
- if (!addPragma(pragma, &errors)) {
+ foreach (QmlIR::Pragma *pragma, m_document->pragmas) {
+ if (!addPragma(*pragma, &errors)) {
Q_ASSERT(errors.size());
setError(errors);
return;
@@ -2235,16 +2290,16 @@ void QQmlTypeData::allDependenciesDone()
if (!m_typesResolved) {
// Check that all imports were resolved
QList<QQmlError> errors;
- QHash<const QQmlScript::Import *, int>::const_iterator it = m_unresolvedImports.constBegin(), end = m_unresolvedImports.constEnd();
+ QHash<const QV4::CompiledData::Import *, int>::const_iterator it = m_unresolvedImports.constBegin(), end = m_unresolvedImports.constEnd();
for ( ; it != end; ++it) {
if (*it == 0) {
// This import was not resolved
- foreach (const QQmlScript::Import *import, m_unresolvedImports.keys()) {
+ foreach (const QV4::CompiledData::Import *import, m_unresolvedImports.keys()) {
QQmlError error;
- error.setDescription(QQmlTypeLoader::tr("module \"%1\" is not installed").arg(import->uri));
- error.setUrl(m_imports.baseUrl());
- error.setLine(import->location.start.line);
- error.setColumn(import->location.start.column);
+ error.setDescription(QQmlTypeLoader::tr("module \"%1\" is not installed").arg(stringAt(import->uriIndex)));
+ error.setUrl(m_importCache.baseUrl());
+ error.setLine(import->location.line);
+ error.setColumn(import->location.column);
errors.prepend(error);
}
}
@@ -2267,6 +2322,11 @@ void QQmlTypeData::downloadProgressChanged(qreal p)
}
}
+QString QQmlTypeData::stringAt(int index) const
+{
+ return m_document->jsGenerator.stringTable.stringForIndex(index);
+}
+
void QQmlTypeData::compile()
{
Q_ASSERT(m_compiledData == 0);
@@ -2277,7 +2337,7 @@ void QQmlTypeData::compile()
QQmlCompilingProfiler prof(QQmlEnginePrivate::get(typeLoader()->engine())->profiler, m_compiledData->name);
- QQmlTypeCompiler compiler(QQmlEnginePrivate::get(typeLoader()->engine()), m_compiledData, this, parsedQML.data());
+ QQmlTypeCompiler compiler(QQmlEnginePrivate::get(typeLoader()->engine()), m_compiledData, this, m_document.data());
if (!compiler.compile()) {
setError(compiler.compilationErrors());
m_compiledData->release();
@@ -2288,7 +2348,7 @@ void QQmlTypeData::compile()
void QQmlTypeData::resolveTypes()
{
// Add any imported scripts to our resolved set
- foreach (const QQmlImports::ScriptReference &script, m_imports.resolvedScripts())
+ foreach (const QQmlImports::ScriptReference &script, m_importCache.resolvedScripts())
{
QQmlScriptBlob *blob = typeLoader()->getScript(script.location);
addDependency(blob);
@@ -2309,13 +2369,12 @@ void QQmlTypeData::resolveTypes()
}
// Lets handle resolved composite singleton types
- foreach (const QQmlImports::CompositeSingletonReference &csRef, m_imports.resolvedCompositeSingletons()) {
+ foreach (const QQmlImports::CompositeSingletonReference &csRef, m_importCache.resolvedCompositeSingletons()) {
TypeReference ref;
- QQmlScript::TypeReference parserRef;
- parserRef.name = csRef.typeName;
+ QString typeName = csRef.typeName;
if (!csRef.prefix.isEmpty()) {
- parserRef.name.prepend(csRef.prefix + QLatin1Char('.'));
+ typeName.prepend(csRef.prefix + QLatin1Char('.'));
// Add a reference to the enclosing namespace
m_namespaces.insert(csRef.prefix);
}
@@ -2323,7 +2382,7 @@ void QQmlTypeData::resolveTypes()
int majorVersion = -1;
int minorVersion = -1;
- if (!resolveType(&parserRef, majorVersion, minorVersion, ref))
+ if (!resolveType(typeName, majorVersion, minorVersion, ref))
return;
if (ref.type->isCompositeSingleton()) {
@@ -2335,15 +2394,7 @@ void QQmlTypeData::resolveTypes()
}
}
- QV4::CompiledData::TypeReferenceMap typeReferences;
- QStringList names;
- if (parsedQML) {
- typeReferences = parsedQML->typeReferences;
- names = parsedQML->jsGenerator.strings;
- } else {
- // ### collect from available QV4::CompiledData::QmlUnit
- }
- for (QV4::CompiledData::TypeReferenceMap::ConstIterator unresolvedRef = typeReferences.constBegin(), end = typeReferences.constEnd();
+ for (QV4::CompiledData::TypeReferenceMap::ConstIterator unresolvedRef = m_document->typeReferences.constBegin(), end = m_document->typeReferences.constEnd();
unresolvedRef != end; ++unresolvedRef) {
TypeReference ref; // resolved reference
@@ -2355,15 +2406,15 @@ void QQmlTypeData::resolveTypes()
QQmlImportNamespace *typeNamespace = 0;
QList<QQmlError> errors;
- const QString name = names.at(unresolvedRef.key());
- bool typeFound = m_imports.resolveType(name, &ref.type,
+ 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_imports.resolveType(name, &ref.type,
+ typeFound = m_importCache.resolveType(name, &ref.type,
&majorVersion, &minorVersion, &typeNamespace, &errors);
} else {
return; //loadImplicitImport() hit an error, and called setError already
@@ -2385,7 +2436,7 @@ void QQmlTypeData::resolveTypes()
// Description should come from error provided by addImport() function.
error.setDescription(QQmlTypeLoader::tr("Unreported error adding script import to import database"));
}
- error.setUrl(m_imports.baseUrl());
+ error.setUrl(m_importCache.baseUrl());
error.setDescription(QQmlTypeLoader::tr("%1 %2").arg(name).arg(error.description()));
}
@@ -2413,19 +2464,19 @@ void QQmlTypeData::resolveTypes()
}
}
-bool QQmlTypeData::resolveType(const QQmlScript::TypeReference *parserRef, int &majorVersion, int &minorVersion, TypeReference &ref)
+bool QQmlTypeData::resolveType(const QString &typeName, int &majorVersion, int &minorVersion, TypeReference &ref)
{
QQmlImportNamespace *typeNamespace = 0;
QList<QQmlError> errors;
- bool typeFound = m_imports.resolveType(parserRef->name, &ref.type,
+ bool typeFound = m_importCache.resolveType(typeName, &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_imports.resolveType(parserRef->name, &ref.type,
+ typeFound = m_importCache.resolveType(typeName, &ref.type,
&majorVersion, &minorVersion, &typeNamespace, &errors);
} else {
return false; //loadImplicitImport() hit an error, and called setError already
@@ -2438,7 +2489,7 @@ bool QQmlTypeData::resolveType(const QQmlScript::TypeReference *parserRef, int &
// - type with unknown namespace (UnknownNamespace.SomeType {})
QQmlError error;
if (typeNamespace) {
- error.setDescription(QQmlTypeLoader::tr("Namespace %1 cannot be used as a type").arg(parserRef->name));
+ error.setDescription(QQmlTypeLoader::tr("Namespace %1 cannot be used as a type").arg(typeName));
} else {
if (errors.size()) {
error = errors.takeFirst();
@@ -2447,8 +2498,8 @@ bool QQmlTypeData::resolveType(const QQmlScript::TypeReference *parserRef, int &
// Description should come from error provided by addImport() function.
error.setDescription(QQmlTypeLoader::tr("Unreported error adding script import to import database"));
}
- error.setUrl(m_imports.baseUrl());
- error.setDescription(QQmlTypeLoader::tr("%1 %2").arg(parserRef->name).arg(error.description()));
+ error.setUrl(m_importCache.baseUrl());
+ error.setDescription(QQmlTypeLoader::tr("%1 %2").arg(typeName).arg(error.description()));
}
errors.prepend(error);
@@ -2459,7 +2510,7 @@ bool QQmlTypeData::resolveType(const QQmlScript::TypeReference *parserRef, int &
return true;
}
-void QQmlTypeData::scriptImported(QQmlScriptBlob *blob, const QQmlScript::Location &location, const QString &qualifier, const QString &/*nameSpace*/)
+void QQmlTypeData::scriptImported(QQmlScriptBlob *blob, const QV4::CompiledData::Location &location, const QString &qualifier, const QString &/*nameSpace*/)
{
ScriptReference ref;
ref.script = blob;
@@ -2471,7 +2522,6 @@ void QQmlTypeData::scriptImported(QQmlScriptBlob *blob, const QQmlScript::Locati
QQmlScriptData::QQmlScriptData()
: importCache(0)
- , pragmas(QQmlScript::Object::ScriptBlock::None)
, m_loaded(false)
, m_precompiledScript(0)
, m_program(0)
@@ -2517,7 +2567,7 @@ QV4::PersistentValue QQmlScriptData::scriptValueForContext(QQmlContextData *pare
QV4::ExecutionEngine *v4 = QV8Engine::getV4(parentCtxt->engine);
QV4::Scope scope(v4);
- bool shared = pragmas & QQmlScript::Object::ScriptBlock::Shared;
+ bool shared = m_precompiledScript->data->flags & QV4::CompiledData::Unit::IsSharedLibrary;
QQmlContextData *effectiveCtxt = parentCtxt;
if (shared)
@@ -2621,11 +2671,6 @@ QQmlScriptBlob::~QQmlScriptBlob()
}
}
-QQmlScript::Object::ScriptBlock::Pragmas QQmlScriptBlob::pragmas() const
-{
- return m_metadata.pragmas;
-}
-
QQmlScriptData *QQmlScriptBlob::scriptData() const
{
return m_scriptData;
@@ -2633,36 +2678,49 @@ QQmlScriptData *QQmlScriptBlob::scriptData() const
void QQmlScriptBlob::dataReceived(const Data &data)
{
- m_source = QString::fromUtf8(data.data(), data.size());
+ QString source = QString::fromUtf8(data.data(), data.size());
- m_scriptData = new QQmlScriptData();
- m_scriptData->url = finalUrl();
- m_scriptData->urlString = finalUrlString();
+ QV4::ExecutionEngine *v4 = QV8Engine::getV4(m_typeLoader->engine());
+ QmlIR::Document irUnit(v4->debugger != 0);
+ QQmlJS::DiagnosticMessage metaDataError;
+ irUnit.extractScriptMetaData(source, &metaDataError);
+ if (!metaDataError.message.isEmpty()) {
+ QQmlError e;
+ e.setUrl(finalUrl());
+ e.setLine(metaDataError.loc.startLine);
+ e.setColumn(metaDataError.loc.startColumn);
+ e.setDescription(metaDataError.message);
+ setError(e);
+ return;
+ }
- QQmlError metaDataError;
- m_metadata = QQmlScript::Parser::extractMetaData(m_source, &metaDataError);
- if (metaDataError.isValid()) {
- metaDataError.setUrl(finalUrl());
- setError(metaDataError);
+ QList<QQmlError> errors;
+ QV4::CompiledData::CompilationUnit *unit = QV4::Script::precompile(&irUnit.jsModule, &irUnit.jsGenerator, v4, finalUrl(), source, &errors);
+ if (unit)
+ unit->ref();
+ source.clear();
+ if (!errors.isEmpty()) {
+ if (unit)
+ unit->deref();
+ setError(errors);
return;
}
+ irUnit.javaScriptCompilationUnit = unit;
- m_imports.setBaseUrl(finalUrl(), finalUrlString());
+ QmlIR::QmlUnitGenerator qmlGenerator;
+ QV4::CompiledData::QmlUnit *qmlUnit = qmlGenerator.generate(irUnit);
+ Q_ASSERT(!unit->data);
+ Q_ASSERT((void*)qmlUnit == (void*)&qmlUnit->header);
+ // The js unit owns the data and will free the qml unit.
+ unit->data = &qmlUnit->header;
- QList<QQmlError> errors;
+ initializeFromCompilationUnit(unit);
+ unit->deref();
+}
- foreach (const QQmlScript::Import &import, m_metadata.imports) {
- if (!addImport(import, &errors)) {
- Q_ASSERT(errors.size());
- QQmlError error(errors.takeFirst());
- error.setUrl(m_imports.baseUrl());
- error.setLine(import.location.start.line);
- error.setColumn(import.location.start.column);
- errors.prepend(error); // put it back on the list after filling out information.
- setError(errors);
- return;
- }
- }
+void QQmlScriptBlob::initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *unit)
+{
+ initializeFromCompilationUnit(unit->createCompilationUnit());
}
void QQmlScriptBlob::done()
@@ -2704,23 +2762,15 @@ void QQmlScriptBlob::done()
m_scriptData->importCache->add(script.qualifier, scriptIndex, script.nameSpace);
}
- m_imports.populateCache(m_scriptData->importCache);
-
- m_scriptData->pragmas = m_metadata.pragmas;
+ m_importCache.populateCache(m_scriptData->importCache);
+}
- QList<QQmlError> errors;
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(m_typeLoader->engine());
- m_scriptData->m_precompiledScript = QV4::Script::precompile(v4, m_scriptData->url, m_source, &errors);
- if (m_scriptData->m_precompiledScript)
- m_scriptData->m_precompiledScript->ref();
- m_source.clear();
- if (!errors.isEmpty()) {
- setError(errors);
- return;
- }
+QString QQmlScriptBlob::stringAt(int index) const
+{
+ return m_scriptData->m_precompiledScript->data->stringAt(index);
}
-void QQmlScriptBlob::scriptImported(QQmlScriptBlob *blob, const QQmlScript::Location &location, const QString &qualifier, const QString &nameSpace)
+void QQmlScriptBlob::scriptImported(QQmlScriptBlob *blob, const QV4::CompiledData::Location &location, const QString &qualifier, const QString &nameSpace)
{
ScriptReference ref;
ref.script = blob;
@@ -2731,6 +2781,37 @@ void QQmlScriptBlob::scriptImported(QQmlScriptBlob *blob, const QQmlScript::Loca
m_scripts << ref;
}
+void QQmlScriptBlob::initializeFromCompilationUnit(QV4::CompiledData::CompilationUnit *unit)
+{
+ Q_ASSERT(!m_scriptData);
+ m_scriptData = new QQmlScriptData();
+ m_scriptData->url = finalUrl();
+ m_scriptData->urlString = finalUrlString();
+ m_scriptData->m_precompiledScript = unit;
+ if (m_scriptData->m_precompiledScript)
+ m_scriptData->m_precompiledScript->ref();
+
+ m_importCache.setBaseUrl(finalUrl(), finalUrlString());
+
+ Q_ASSERT(m_scriptData->m_precompiledScript->data->flags & QV4::CompiledData::Unit::IsQml);
+ const QV4::CompiledData::QmlUnit *qmlUnit = reinterpret_cast<const QV4::CompiledData::QmlUnit*>(m_scriptData->m_precompiledScript->data);
+
+ QList<QQmlError> errors;
+ for (quint32 i = 0; i < qmlUnit->nImports; ++i) {
+ const QV4::CompiledData::Import *import = qmlUnit->importAt(i);
+ if (!addImport(import, &errors)) {
+ Q_ASSERT(errors.size());
+ QQmlError error(errors.takeFirst());
+ error.setUrl(m_importCache.baseUrl());
+ error.setLine(import->location.line);
+ error.setColumn(import->location.column);
+ errors.prepend(error); // put it back on the list after filling out information.
+ setError(errors);
+ return;
+ }
+ }
+}
+
QQmlQmldirData::QQmlQmldirData(const QUrl &url, QQmlTypeLoader *loader)
: QQmlTypeLoader::Blob(url, QmldirFile, loader), m_import(0), m_priority(0)
{
@@ -2741,12 +2822,12 @@ const QString &QQmlQmldirData::content() const
return m_content;
}
-const QQmlScript::Import *QQmlQmldirData::import() const
+const QV4::CompiledData::Import *QQmlQmldirData::import() const
{
return m_import;
}
-void QQmlQmldirData::setImport(const QQmlScript::Import *import)
+void QQmlQmldirData::setImport(const QV4::CompiledData::Import *import)
{
m_import = import;
}
@@ -2766,6 +2847,11 @@ void QQmlQmldirData::dataReceived(const Data &data)
m_content = QString::fromUtf8(data.data(), data.size());
}
+void QQmlQmldirData::initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *)
+{
+ Q_UNIMPLEMENTED();
+}
+
QT_END_NAMESPACE
#include "qqmltypeloader.moc"
diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h
index 9cd28a03ce..b09ac15861 100644
--- a/src/qml/qml/qqmltypeloader_p.h
+++ b/src/qml/qml/qqmltypeloader_p.h
@@ -62,12 +62,12 @@
#include <QtQml/qqmlabstracturlinterceptor.h>
#include <private/qhashedstring_p.h>
-#include <private/qqmlscript_p.h>
#include <private/qqmlimport_p.h>
#include <private/qqmlcleanup_p.h>
#include <private/qqmldirparser_p.h>
#include <private/qqmlbundle_p.h>
#include <private/qflagpointer_p.h>
+#include <private/qqmlirbuilder_p.h>
#include <private/qv4value_inl_p.h>
#include <private/qv4script_p.h>
@@ -84,8 +84,8 @@ class QQmlTypeData;
class QQmlDataLoader;
class QQmlExtensionInterface;
-namespace QtQml {
-struct ParsedQML;
+namespace QmlIR {
+struct Document;
}
class Q_QML_PRIVATE_EXPORT QQmlDataBlob : public QQmlRefCount
@@ -155,6 +155,7 @@ protected:
// Callbacks made in load thread
virtual void dataReceived(const Data &) = 0;
+ virtual void initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit*) = 0;
virtual void done();
virtual void networkError(QNetworkReply::NetworkError);
virtual void dependencyError(QQmlDataBlob *);
@@ -228,6 +229,7 @@ public:
void load(QQmlDataBlob *, Mode = PreferSynchronous);
void loadWithStaticData(QQmlDataBlob *, const QByteArray &, Mode = PreferSynchronous);
+ void loadWithCachedUnit(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit);
QQmlEngine *engine() const;
void initializeEngine(QQmlExtensionInterface *, const char *);
@@ -242,6 +244,7 @@ private:
void loadThread(QQmlDataBlob *);
void loadWithStaticDataThread(QQmlDataBlob *, const QByteArray &);
+ void loadWithCachedUnitThread(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit);
void networkReplyFinished(QNetworkReply *);
void networkReplyProgress(QNetworkReply *, qint64, qint64);
@@ -250,6 +253,7 @@ private:
void setData(QQmlDataBlob *, const QByteArray &);
void setData(QQmlDataBlob *, QQmlFile *);
void setData(QQmlDataBlob *, const QQmlDataBlob::Data &);
+ void setCachedUnit(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit);
QQmlEngine *m_engine;
QQmlDataLoaderThread *m_thread;
@@ -275,28 +279,30 @@ public:
~Blob();
QQmlTypeLoader *typeLoader() const { return m_typeLoader; }
- const QQmlImports &imports() const { return m_imports; }
+ const QQmlImports &imports() const { return m_importCache; }
protected:
- bool addImport(const QQmlScript::Import &import, QList<QQmlError> *errors);
- bool addPragma(const QQmlScript::Pragma &pragma, QList<QQmlError> *errors);
+ bool addImport(const QV4::CompiledData::Import *import, QList<QQmlError> *errors);
+ bool addPragma(const QmlIR::Pragma &pragma, QList<QQmlError> *errors);
- bool fetchQmldir(const QUrl &url, const QQmlScript::Import *import, int priority, QList<QQmlError> *errors);
- bool updateQmldir(QQmlQmldirData *data, const QQmlScript::Import *import, QList<QQmlError> *errors);
+ bool fetchQmldir(const QUrl &url, const QV4::CompiledData::Import *import, int priority, QList<QQmlError> *errors);
+ bool updateQmldir(QQmlQmldirData *data, const QV4::CompiledData::Import *import, QList<QQmlError> *errors);
private:
virtual bool qmldirDataAvailable(QQmlQmldirData *, QList<QQmlError> *);
- virtual void scriptImported(QQmlScriptBlob *, const QQmlScript::Location &, const QString &, const QString &) {}
+ virtual void scriptImported(QQmlScriptBlob *, const QV4::CompiledData::Location &, const QString &, const QString &) {}
virtual void dependencyError(QQmlDataBlob *);
virtual void dependencyComplete(QQmlDataBlob *);
protected:
+ virtual QString stringAt(int) const { return QString(); }
+
QQmlTypeLoader *m_typeLoader;
- QQmlImports m_imports;
+ QQmlImports m_importCache;
bool m_isSingleton;
- QHash<const QQmlScript::Import *, int> m_unresolvedImports;
+ QHash<const QV4::CompiledData::Import*, int> m_unresolvedImports;
QList<QQmlQmldirData *> m_qmldirs;
};
@@ -398,7 +404,7 @@ public:
{
TypeReference() : type(0), majorVersion(0), minorVersion(0), typeData(0), needsCreation(true) {}
- QQmlScript::Location location;
+ QV4::CompiledData::Location location;
QQmlType *type;
int majorVersion;
int minorVersion;
@@ -411,7 +417,7 @@ public:
{
ScriptReference() : script(0) {}
- QQmlScript::Location location;
+ QV4::CompiledData::Location location;
QString qualifier;
QQmlScriptBlob *script;
};
@@ -445,19 +451,21 @@ protected:
virtual void done();
virtual void completed();
virtual void dataReceived(const Data &);
+ virtual void initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *unit);
virtual void allDependenciesDone();
virtual void downloadProgressChanged(qreal);
+ virtual QString stringAt(int index) const;
+
private:
+ void continueLoadFromIR();
void resolveTypes();
void compile();
- bool resolveType(const QQmlScript::TypeReference *parserRef, int &majorVersion, int &minorVersion, TypeReference &ref);
+ bool resolveType(const QString &typeName, int &majorVersion, int &minorVersion, TypeReference &ref);
- virtual void scriptImported(QQmlScriptBlob *blob, const QQmlScript::Location &location, const QString &qualifier, const QString &nameSpace);
+ virtual void scriptImported(QQmlScriptBlob *blob, const QV4::CompiledData::Location &location, const QString &qualifier, const QString &nameSpace);
- QScopedPointer<QtQml::ParsedQML> parsedQML;
- QList<QQmlScript::Import> m_newImports;
- QList<QQmlScript::Pragma> m_newPragmas;
+ QScopedPointer<QmlIR::Document> m_document;
QList<ScriptReference> m_scripts;
@@ -472,7 +480,7 @@ private:
QList<TypeDataCallback *> m_callbacks;
- QQmlScript::Import *m_implicitImport;
+ QV4::CompiledData::Import *m_implicitImport;
bool m_implicitImportLoaded;
bool loadImplicitImport();
};
@@ -498,7 +506,6 @@ public:
QString urlString;
QQmlTypeNameCache *importCache;
QList<QQmlScriptBlob *> scripts;
- QQmlScript::Object::ScriptBlock::Pragmas pragmas;
QV4::PersistentValue scriptValueForContext(QQmlContextData *parentCtxt);
@@ -506,7 +513,6 @@ protected:
virtual void clear(); // From QQmlCleanup
private:
- friend class QQmlVME;
friend class QQmlScriptBlob;
void initialize(QQmlEngine *);
@@ -531,25 +537,24 @@ public:
{
ScriptReference() : script(0) {}
- QQmlScript::Location location;
+ QV4::CompiledData::Location location;
QString qualifier;
QString nameSpace;
QQmlScriptBlob *script;
};
- QQmlScript::Object::ScriptBlock::Pragmas pragmas() const;
-
QQmlScriptData *scriptData() const;
protected:
virtual void dataReceived(const Data &);
+ virtual void initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *unit);
virtual void done();
-private:
- virtual void scriptImported(QQmlScriptBlob *blob, const QQmlScript::Location &location, const QString &qualifier, const QString &nameSpace);
+ virtual QString stringAt(int index) const;
- QString m_source;
- QQmlScript::Parser::JavaScriptMetaData m_metadata;
+private:
+ virtual void scriptImported(QQmlScriptBlob *blob, const QV4::CompiledData::Location &location, const QString &qualifier, const QString &nameSpace);
+ void initializeFromCompilationUnit(QV4::CompiledData::CompilationUnit *unit);
QList<ScriptReference> m_scripts;
QQmlScriptData *m_scriptData;
@@ -565,18 +570,19 @@ private:
public:
const QString &content() const;
- const QQmlScript::Import *import() const;
- void setImport(const QQmlScript::Import *);
+ const QV4::CompiledData::Import *import() const;
+ void setImport(const QV4::CompiledData::Import *);
int priority() const;
void setPriority(int);
protected:
virtual void dataReceived(const Data &);
+ virtual void initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit*);
private:
QString m_content;
- const QQmlScript::Import *m_import;
+ const QV4::CompiledData::Import *m_import;
int m_priority;
};
diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp
index e599c37c0c..1ff95a245d 100644
--- a/src/qml/qml/qqmlvmemetaobject.cpp
+++ b/src/qml/qml/qqmlvmemetaobject.cpp
@@ -615,7 +615,7 @@ QQmlVMEMetaObject::QQmlVMEMetaObject(QObject *obj,
QQmlVMEMetaData::MethodData *data = metaData->methodData() + index;
QV4::Function *runtimeFunction = compilationUnit->runtimeFunctions[data->runtimeFunctionIndex];
- o = QV4::FunctionObject::creatScriptFunction(qmlBindingContext, runtimeFunction);
+ o = QV4::FunctionObject::createScriptFunction(qmlBindingContext, runtimeFunction);
v8methods[index] = o;
}
}
diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp
index e2cdac16c0..d89dc92b68 100644
--- a/src/qml/qml/qqmlxmlhttprequest.cpp
+++ b/src/qml/qml/qqmlxmlhttprequest.cpp
@@ -905,8 +905,11 @@ ReturnedValue NamedNodeMap::getIndexed(Managed *m, uint index, bool *hasProperty
{
QV4::ExecutionEngine *v4 = m->engine();
NamedNodeMap *r = m->as<NamedNodeMap>();
- if (!r)
+ if (!r) {
+ if (hasProperty)
+ *hasProperty = false;
return v4->currentContext()->throwTypeError();
+ }
QV8Engine *engine = v4->v8Engine;
@@ -960,8 +963,11 @@ ReturnedValue NodeList::getIndexed(Managed *m, uint index, bool *hasProperty)
{
QV4::ExecutionEngine *v4 = m->engine();
NodeList *r = m->as<NodeList>();
- if (!r)
+ if (!r) {
+ if (hasProperty)
+ *hasProperty = false;
return v4->currentContext()->throwTypeError();
+ }
QV8Engine *engine = v4->v8Engine;
@@ -1388,7 +1394,8 @@ void QQmlXMLHttpRequest::error(QNetworkReply::NetworkError error)
error == QNetworkReply::ContentNotFoundError ||
error == QNetworkReply::AuthenticationRequiredError ||
error == QNetworkReply::ContentReSendError ||
- error == QNetworkReply::UnknownContentError) {
+ error == QNetworkReply::UnknownContentError ||
+ error == QNetworkReply::ProtocolInvalidOperationError) {
m_state = Loading;
dispatchCallback(me);
} else {
@@ -1650,6 +1657,7 @@ struct QQmlXMLHttpRequestCtor : public FunctionObject
QQmlXMLHttpRequestCtor *c = that->as<QQmlXMLHttpRequestCtor>();
if (c->proto)
c->proto->mark(e);
+ FunctionObject::markObjects(that, e);
}
static ReturnedValue construct(Managed *that, QV4::CallData *)
{
diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp
index 61b466a5db..8305649177 100644
--- a/src/qml/qml/v8/qv8engine.cpp
+++ b/src/qml/qml/v8/qv8engine.cpp
@@ -601,7 +601,11 @@ QV4::ReturnedValue QV8Engine::variantMapToJS(const QVariantMap &vmap)
for (it = vmap.constBegin(); it != vmap.constEnd(); ++it) {
s = m_v4Engine->newIdentifier(it.key());
v = variantToJS(it.value());
- o->insertMember(s, v);
+ uint idx = s->asArrayIndex();
+ if (idx < UINT_MAX)
+ o->arraySet(idx, v);
+ else
+ o->insertMember(s, v);
}
return o.asReturnedValue();
}