aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp7
-rw-r--r--src/qml/qml/qqmltypeloader.cpp133
-rw-r--r--src/qml/qml/qqmltypeloader_p.h5
-rw-r--r--src/qml/qml/qqmlvme.cpp106
-rw-r--r--src/qml/qml/qqmlvme_p.h1
5 files changed, 144 insertions, 108 deletions
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index 5d29a57441..55858e0b12 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -527,6 +527,13 @@ QObject *QmlObjectCreator::create(int subComponentIndex, QObject *parent)
}
context->setIdPropertyData(mapping);
+ if (subComponentIndex == -1) {
+ foreach (QQmlScriptData *script, compiledData->scripts)
+ context->importedScripts << script->scriptValueForContext(context);
+ } else if (parentContext) {
+ context->importedScripts = parentContext->importedScripts;
+ }
+
QObject *instance = createInstance(objectToCreate, parent);
if (instance) {
QQmlData *ddata = QQmlData::get(instance);
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index 07639aa6ba..52b42e85a3 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -41,6 +41,8 @@
#include "qqmltypeloader_p.h"
#include "qqmlabstracturlinterceptor.h"
+#include "qqmlcontextwrapper_p.h"
+#include "qqmlexpression_p.h"
#include <private/qqmlengine_p.h>
#include <private/qqmlglobal_p.h>
@@ -2306,6 +2308,28 @@ void QQmlTypeData::compile()
}
}
+ // Collect imported scripts
+ m_compiledData->scripts.reserve(m_scripts.count());
+ for (int scriptIndex = 0; scriptIndex < m_scripts.count(); ++scriptIndex) {
+ const ScriptReference &script = m_scripts.at(scriptIndex);
+
+ QString qualifier = script.qualifier;
+ QString enclosingNamespace;
+
+ const int lastDotIndex = qualifier.lastIndexOf(QLatin1Char('.'));
+ if (lastDotIndex != -1) {
+ enclosingNamespace = qualifier.left(lastDotIndex);
+ qualifier = qualifier.mid(lastDotIndex+1);
+ }
+
+ m_compiledData->importCache->add(qualifier, scriptIndex, enclosingNamespace);
+ QQmlScriptData *scriptData = script.script->scriptData();
+ scriptData->addref();
+ m_compiledData->scripts << scriptData;
+ }
+
+ // Compile JS binding expressions and signal handlers
+
JSCodeGen jsCodeGen;
jsCodeGen.generateJSCodeForFunctionsAndBindings(finalUrlString(), parsedQML.data());
@@ -2315,6 +2339,8 @@ void QQmlTypeData::compile()
isel->setUseFastLookups(false);
QV4::CompiledData::CompilationUnit *jsUnit = isel->compile(/*generated unit data*/false);
+ // Generate QML compiled type data structures
+
QmlUnitGenerator qmlGenerator;
QV4::CompiledData::QmlUnit *qmlUnit = qmlGenerator.generate(*parsedQML.data());
@@ -2331,6 +2357,8 @@ void QQmlTypeData::compile()
QList<QQmlError> errors;
+ // Build property caches and VME meta object data
+
m_compiledData->datas.reserve(qmlUnit->nObjects);
m_compiledData->propertyCaches.reserve(qmlUnit->nObjects);
@@ -2366,6 +2394,8 @@ void QQmlTypeData::compile()
}
}
+ // Resolve component boundaries and aliases
+
if (errors.isEmpty()) {
// Scan for components, determine their scopes and resolve aliases within the scope.
QQmlComponentAndAliasResolver resolver(m_compiledData->url, m_compiledData->qmlUnit, m_compiledData->resolvedTypes, m_compiledData->propertyCaches,
@@ -2621,6 +2651,109 @@ QQmlScriptData::~QQmlScriptData()
}
}
+void QQmlScriptData::initialize(QQmlEngine *engine)
+{
+ Q_ASSERT(!m_program);
+ Q_ASSERT(engine);
+ Q_ASSERT(!hasEngine());
+
+ QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
+ QV8Engine *v8engine = ep->v8engine();
+ QV4::ExecutionEngine *v4 = QV8Engine::getV4(v8engine);
+
+ m_program = new QV4::Script(v4, QV4::ObjectRef::null(), m_precompiledScript);
+
+ addToEngine(engine);
+
+ addref();
+}
+
+QV4::PersistentValue QQmlScriptData::scriptValueForContext(QQmlContextData *parentCtxt)
+{
+ if (m_loaded)
+ return m_value;
+
+ QV4::PersistentValue rv;
+
+ Q_ASSERT(parentCtxt && parentCtxt->engine);
+ QQmlEnginePrivate *ep = QQmlEnginePrivate::get(parentCtxt->engine);
+ QV8Engine *v8engine = ep->v8engine();
+ QV4::ExecutionEngine *v4 = QV8Engine::getV4(parentCtxt->engine);
+ QV4::Scope scope(v4);
+
+ bool shared = pragmas & QQmlScript::Object::ScriptBlock::Shared;
+
+ QQmlContextData *effectiveCtxt = parentCtxt;
+ if (shared)
+ effectiveCtxt = 0;
+
+ // Create the script context if required
+ QQmlContextData *ctxt = new QQmlContextData;
+ ctxt->isInternal = true;
+ ctxt->isJSContext = true;
+ if (shared)
+ ctxt->isPragmaLibraryContext = true;
+ else
+ ctxt->isPragmaLibraryContext = parentCtxt->isPragmaLibraryContext;
+ ctxt->url = url;
+ ctxt->urlString = urlString;
+
+ // For backward compatibility, if there are no imports, we need to use the
+ // imports from the parent context. See QTBUG-17518.
+ if (!importCache->isEmpty()) {
+ ctxt->imports = importCache;
+ } else if (effectiveCtxt) {
+ ctxt->imports = effectiveCtxt->imports;
+ ctxt->importedScripts = effectiveCtxt->importedScripts;
+ }
+
+ if (ctxt->imports) {
+ ctxt->imports->addref();
+ }
+
+ if (effectiveCtxt) {
+ ctxt->setParent(effectiveCtxt, true);
+ } else {
+ ctxt->engine = parentCtxt->engine; // Fix for QTBUG-21620
+ }
+
+ for (int ii = 0; ii < scripts.count(); ++ii) {
+ ctxt->importedScripts << scripts.at(ii)->scriptData()->scriptValueForContext(ctxt);
+ }
+
+ if (!hasEngine())
+ initialize(parentCtxt->engine);
+
+ if (!m_program) {
+ if (shared)
+ m_loaded = true;
+ return QV4::PersistentValue();
+ }
+
+ QV4::ScopedValue qmlglobal(scope, QV4::QmlContextWrapper::qmlScope(v8engine, ctxt, 0));
+ QV4::QmlContextWrapper::takeContextOwnership(qmlglobal);
+
+ QV4::ExecutionContext *ctx = QV8Engine::getV4(v8engine)->current;
+ try {
+ m_program->qml = qmlglobal;
+ m_program->run();
+ } catch (QV4::Exception &e) {
+ e.accept(ctx);
+ QQmlError error;
+ QQmlExpressionPrivate::exceptionToError(e, error);
+ if (error.isValid())
+ ep->warning(error);
+ }
+
+ rv = qmlglobal;
+ if (shared) {
+ m_value = rv;
+ m_loaded = true;
+ }
+
+ return rv;
+}
+
void QQmlScriptData::clear()
{
if (importCache) {
diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h
index f6eea6c248..b9bf056cb3 100644
--- a/src/qml/qml/qqmltypeloader_p.h
+++ b/src/qml/qml/qqmltypeloader_p.h
@@ -508,8 +508,7 @@ public:
QList<QQmlScriptBlob *> scripts;
QQmlScript::Object::ScriptBlock::Pragmas pragmas;
- bool isInitialized() const { return hasEngine(); }
- void initialize(QQmlEngine *);
+ QV4::PersistentValue scriptValueForContext(QQmlContextData *parentCtxt);
protected:
virtual void clear(); // From QQmlCleanup
@@ -518,6 +517,8 @@ private:
friend class QQmlVME;
friend class QQmlScriptBlob;
+ void initialize(QQmlEngine *);
+
bool m_loaded;
QV4::CompiledData::CompilationUnit *m_precompiledScript;
QV4::Script *m_program;
diff --git a/src/qml/qml/qqmlvme.cpp b/src/qml/qml/qqmlvme.cpp
index 5bf679d7a3..21bffee7a7 100644
--- a/src/qml/qml/qqmlvme.cpp
+++ b/src/qml/qml/qqmlvme.cpp
@@ -768,7 +768,7 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
QML_END_INSTR(StoreSignal)
QML_BEGIN_INSTR(StoreImportedScript)
- CTXT->importedScripts << run(CTXT, SCRIPTS.at(instr.value));
+ CTXT->importedScripts << SCRIPTS.at(instr.value)->scriptValueForContext(CTXT);
QML_END_INSTR(StoreImportedScript)
QML_BEGIN_INSTR(StoreScriptString)
@@ -1077,110 +1077,6 @@ void QQmlVME::reset()
creationContext = 0;
}
-// Must be called with a handle scope and context
-void QQmlScriptData::initialize(QQmlEngine *engine)
-{
- Q_ASSERT(!m_program);
- Q_ASSERT(engine);
- Q_ASSERT(!hasEngine());
-
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
- QV8Engine *v8engine = ep->v8engine();
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(v8engine);
-
- m_program = new QV4::Script(v4, QV4::ObjectRef::null(), m_precompiledScript);
-
- addToEngine(engine);
-
- addref();
-}
-
-QV4::PersistentValue QQmlVME::run(QQmlContextData *parentCtxt, QQmlScriptData *script)
-{
- if (script->m_loaded)
- return script->m_value;
-
- QV4::PersistentValue rv;
-
- Q_ASSERT(parentCtxt && parentCtxt->engine);
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(parentCtxt->engine);
- QV8Engine *v8engine = ep->v8engine();
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(parentCtxt->engine);
- QV4::Scope scope(v4);
-
- bool shared = script->pragmas & QQmlScript::Object::ScriptBlock::Shared;
-
- QQmlContextData *effectiveCtxt = parentCtxt;
- if (shared)
- effectiveCtxt = 0;
-
- // Create the script context if required
- QQmlContextData *ctxt = new QQmlContextData;
- ctxt->isInternal = true;
- ctxt->isJSContext = true;
- if (shared)
- ctxt->isPragmaLibraryContext = true;
- else
- ctxt->isPragmaLibraryContext = parentCtxt->isPragmaLibraryContext;
- ctxt->url = script->url;
- ctxt->urlString = script->urlString;
-
- // For backward compatibility, if there are no imports, we need to use the
- // imports from the parent context. See QTBUG-17518.
- if (!script->importCache->isEmpty()) {
- ctxt->imports = script->importCache;
- } else if (effectiveCtxt) {
- ctxt->imports = effectiveCtxt->imports;
- ctxt->importedScripts = effectiveCtxt->importedScripts;
- }
-
- if (ctxt->imports) {
- ctxt->imports->addref();
- }
-
- if (effectiveCtxt) {
- ctxt->setParent(effectiveCtxt, true);
- } else {
- ctxt->engine = parentCtxt->engine; // Fix for QTBUG-21620
- }
-
- for (int ii = 0; ii < script->scripts.count(); ++ii) {
- ctxt->importedScripts << run(ctxt, script->scripts.at(ii)->scriptData());
- }
-
- if (!script->isInitialized())
- script->initialize(parentCtxt->engine);
-
- if (!script->m_program) {
- if (shared)
- script->m_loaded = true;
- return QV4::PersistentValue();
- }
-
- QV4::ScopedValue qmlglobal(scope, QV4::QmlContextWrapper::qmlScope(v8engine, ctxt, 0));
- QV4::QmlContextWrapper::takeContextOwnership(qmlglobal);
-
- QV4::ExecutionContext *ctx = QV8Engine::getV4(v8engine)->current;
- try {
- script->m_program->qml = qmlglobal;
- script->m_program->run();
- } catch (QV4::Exception &e) {
- e.accept(ctx);
- QQmlError error;
- QQmlExpressionPrivate::exceptionToError(e, error);
- if (error.isValid())
- ep->warning(error);
- }
-
- rv = qmlglobal;
- if (shared) {
- script->m_value = rv;
- script->m_loaded = true;
- }
-
- return rv;
-}
-
#ifdef QML_THREADED_VME_INTERPRETER
void *const *QQmlVME::instructionJumpTable()
{
diff --git a/src/qml/qml/qqmlvme_p.h b/src/qml/qml/qqmlvme_p.h
index 09e3237aee..5e76143cca 100644
--- a/src/qml/qml/qqmlvme_p.h
+++ b/src/qml/qml/qqmlvme_p.h
@@ -151,7 +151,6 @@ private:
, void *const**storeJumpTable = 0
#endif
);
- QV4::PersistentValue run(QQmlContextData *, QQmlScriptData *);
#ifdef QML_THREADED_VME_INTERPRETER
static void *const*instructionJumpTable();