aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlscriptblob.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/qml/qqmlscriptblob.cpp')
-rw-r--r--src/qml/qml/qqmlscriptblob.cpp142
1 files changed, 66 insertions, 76 deletions
diff --git a/src/qml/qml/qqmlscriptblob.cpp b/src/qml/qml/qqmlscriptblob.cpp
index 7b7a842d04..fa9a41e801 100644
--- a/src/qml/qml/qqmlscriptblob.cpp
+++ b/src/qml/qml/qqmlscriptblob.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <private/qqmlengine_p.h>
#include <private/qqmlirbuilder_p.h>
@@ -68,14 +32,18 @@ QQmlRefPointer<QQmlScriptData> QQmlScriptBlob::scriptData() const
return m_scriptData;
}
+bool QQmlScriptBlob::isNative() const
+{
+ return m_scriptData && !m_scriptData->m_value.isEmpty();
+}
+
void QQmlScriptBlob::dataReceived(const SourceCodeData &data)
{
- if (diskCacheEnabled()) {
- QQmlRefPointer<QV4::ExecutableCompilationUnit> unit
- = QV4::ExecutableCompilationUnit::create();
+ if (readCacheFile()) {
+ auto unit = QQml::makeRefPointer<QV4::CompiledData::CompilationUnit>();
QString error;
if (unit->loadFromDisk(url(), data.sourceTimeStamp(), &error)) {
- initializeFromCompilationUnit(unit);
+ initializeFromCompilationUnit(std::move(unit));
return;
} else {
qCDebug(DBG_DISK_CACHE()) << "Error loading" << urlString() << "from disk cache:" << error;
@@ -97,7 +65,7 @@ void QQmlScriptBlob::dataReceived(const SourceCodeData &data)
return;
}
- QV4::CompiledData::CompilationUnit unit;
+ QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit;
if (m_isModule) {
QList<QQmlJS::DiagnosticMessage> diagnostics;
@@ -132,28 +100,26 @@ void QQmlScriptBlob::dataReceived(const SourceCodeData &data)
unit = std::move(irUnit.javaScriptCompilationUnit);
}
- auto executableUnit = QV4::ExecutableCompilationUnit::create(std::move(unit));
-
- if (diskCacheEnabled()) {
+ if (writeCacheFile()) {
QString errorString;
- if (executableUnit->saveToDisk(url(), &errorString)) {
+ if (unit->saveToDisk(url(), &errorString)) {
QString error;
- if (!executableUnit->loadFromDisk(url(), data.sourceTimeStamp(), &error)) {
+ if (!unit->loadFromDisk(url(), data.sourceTimeStamp(), &error)) {
// ignore error, keep using the in-memory compilation unit.
}
} else {
qCDebug(DBG_DISK_CACHE()) << "Error saving cached version of"
- << executableUnit->fileName() << "to disk:" << errorString;
+ << unit->fileName() << "to disk:" << errorString;
}
}
- initializeFromCompilationUnit(executableUnit);
+ initializeFromCompilationUnit(std::move(unit));
}
-void QQmlScriptBlob::initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *unit)
+void QQmlScriptBlob::initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *cachedUnit)
{
- initializeFromCompilationUnit(QV4::ExecutableCompilationUnit::create(
- QV4::CompiledData::CompilationUnit(unit->qmlData, unit->aotCompiledFunctions, urlString(), finalUrlString())));
+ initializeFromCompilationUnit(QQml::makeRefPointer<QV4::CompiledData::CompilationUnit>(
+ cachedUnit->qmlData, cachedUnit->aotCompiledFunctions, urlString(), finalUrlString()));
}
void QQmlScriptBlob::done()
@@ -162,15 +128,15 @@ void QQmlScriptBlob::done()
return;
// Check all script dependencies for errors
- for (int ii = 0; ii < m_scripts.count(); ++ii) {
+ for (int ii = 0; ii < m_scripts.size(); ++ii) {
const ScriptReference &script = m_scripts.at(ii);
Q_ASSERT(script.script->isCompleteOrError());
if (script.script->isError()) {
QList<QQmlError> errors = script.script->errors();
QQmlError error;
error.setUrl(url());
- error.setLine(qmlConvertSourceCoordinate<quint32, int>(script.location.line));
- error.setColumn(qmlConvertSourceCoordinate<quint32, int>(script.location.column));
+ error.setLine(qmlConvertSourceCoordinate<quint32, int>(script.location.line()));
+ error.setColumn(qmlConvertSourceCoordinate<quint32, int>(script.location.column()));
error.setDescription(QQmlTypeLoader::tr("Script %1 unavailable").arg(script.script->urlString()));
errors.prepend(error);
setError(errors);
@@ -183,7 +149,7 @@ void QQmlScriptBlob::done()
QSet<QString> ns;
- for (int scriptIndex = 0; scriptIndex < m_scripts.count(); ++scriptIndex) {
+ for (int scriptIndex = 0; scriptIndex < m_scripts.size(); ++scriptIndex) {
const ScriptReference &script = m_scripts.at(scriptIndex);
m_scriptData->scripts.append(script.script);
@@ -197,7 +163,7 @@ void QQmlScriptBlob::done()
m_scriptData->typeNameCache->add(script.qualifier, scriptIndex, script.nameSpace);
}
- m_importCache.populateCache(m_scriptData->typeNameCache.data());
+ m_importCache->populateCache(m_scriptData->typeNameCache.data());
}
m_scripts.clear();
}
@@ -218,28 +184,29 @@ void QQmlScriptBlob::scriptImported(const QQmlRefPointer<QQmlScriptBlob> &blob,
m_scripts << ref;
}
-void QQmlScriptBlob::initializeFromCompilationUnit(const QQmlRefPointer<QV4::ExecutableCompilationUnit> &unit)
+void QQmlScriptBlob::initializeFromCompilationUnit(
+ QQmlRefPointer<QV4::CompiledData::CompilationUnit> &&unit)
{
Q_ASSERT(!m_scriptData);
+ Q_ASSERT(unit);
+
m_scriptData.adopt(new QQmlScriptData());
m_scriptData->url = finalUrl();
m_scriptData->urlString = finalUrlString();
m_scriptData->m_precompiledScript = unit;
- m_importCache.setBaseUrl(finalUrl(), finalUrlString());
-
- QQmlRefPointer<QV4::ExecutableCompilationUnit> script = m_scriptData->m_precompiledScript;
+ m_importCache->setBaseUrl(finalUrl(), finalUrlString());
if (!m_isModule) {
QList<QQmlError> errors;
- for (quint32 i = 0, count = script->importCount(); i < count; ++i) {
- const QV4::CompiledData::Import *import = script->importAt(i);
+ for (quint32 i = 0, count = unit->importCount(); i < count; ++i) {
+ const QV4::CompiledData::Import *import = unit->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);
+ 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;
@@ -247,19 +214,42 @@ void QQmlScriptBlob::initializeFromCompilationUnit(const QQmlRefPointer<QV4::Exe
}
}
- auto *v4 = QQmlEnginePrivate::getV4Engine(typeLoader()->engine());
-
- v4->injectModule(unit);
+ const QStringList moduleRequests = unit->moduleRequests();
+ for (const QString &request: moduleRequests) {
+ const QUrl relativeRequest = QUrl(request);
+ if (m_typeLoader->injectedScript(relativeRequest))
+ continue;
- for (const QString &request: unit->moduleRequests()) {
- if (v4->moduleForUrl(QUrl(request), unit.data()))
+ const QUrl absoluteRequest = unit->finalUrl().resolved(relativeRequest);
+ QQmlRefPointer<QQmlScriptBlob> absoluteBlob = typeLoader()->getScript(absoluteRequest);
+ if (absoluteBlob->m_scriptData && absoluteBlob->m_scriptData->m_precompiledScript)
continue;
- const QUrl absoluteRequest = unit->finalUrl().resolved(QUrl(request));
- QQmlRefPointer<QQmlScriptBlob> blob = typeLoader()->getScript(absoluteRequest);
- addDependency(blob.data());
- scriptImported(blob, /* ### */QV4::CompiledData::Location(), /*qualifier*/QString(), /*namespace*/QString());
+ addDependency(absoluteBlob.data());
+ scriptImported(
+ absoluteBlob, /* ### */QV4::CompiledData::Location(), /*qualifier*/QString(),
+ /*namespace*/QString());
}
}
+
+/*!
+ \internal
+
+ This initializes a dummy script blob from a "native" ECMAScript module.
+ Native modules are just JavaScript values, possibly objects with members.
+
+ \sa QJSEngine::registerModule()
+ */
+void QQmlScriptBlob::initializeFromNative(const QV4::Value &value)
+{
+ Q_ASSERT(!m_scriptData);
+ m_scriptData.adopt(new QQmlScriptData());
+ m_scriptData->url = finalUrl();
+ m_scriptData->urlString = finalUrlString();
+ m_scriptData->m_loaded = true;
+ m_scriptData->m_value.set(QQmlEnginePrivate::getV4Engine(typeLoader()->engine()), value);
+ m_importCache->setBaseUrl(finalUrl(), finalUrlString());
+}
+
QT_END_NAMESPACE