aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/jsruntime/qv4include.cpp2
-rw-r--r--src/qml/jsruntime/qv4qmlcontext.cpp53
-rw-r--r--src/qml/jsruntime/qv4qmlcontext_p.h5
-rw-r--r--src/qml/types/qquickworkerscript.cpp55
-rw-r--r--tests/auto/qml/qquickworkerscript/data/script_global.js5
-rw-r--r--tests/auto/qml/qquickworkerscript/data/script_global2.js6
-rw-r--r--tests/auto/qml/qquickworkerscript/data/worker_global.qml5
-rw-r--r--tests/auto/qml/qquickworkerscript/data/worker_global2.qml5
-rw-r--r--tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp42
9 files changed, 24 insertions, 154 deletions
diff --git a/src/qml/jsruntime/qv4include.cpp b/src/qml/jsruntime/qv4include.cpp
index d0d66c9b9a..e3e16fa070 100644
--- a/src/qml/jsruntime/qv4include.cpp
+++ b/src/qml/jsruntime/qv4include.cpp
@@ -207,7 +207,7 @@ QV4::ReturnedValue QV4Include::method_include(const QV4::FunctionObject *b, cons
QQmlContextData *context = scope.engine->callingQmlContext();
- if (!context || !context->isJSContext)
+ if ((!context || !context->isJSContext) && scope.engine->qmlEngine())
RETURN_RESULT(scope.engine->throwError(QString::fromUtf8("Qt.include(): Can only be called from JavaScript files")));
QV4::ScopedValue callbackFunction(scope, QV4::Primitive::undefinedValue());
diff --git a/src/qml/jsruntime/qv4qmlcontext.cpp b/src/qml/jsruntime/qv4qmlcontext.cpp
index c8ef87b979..b69081d378 100644
--- a/src/qml/jsruntime/qv4qmlcontext.cpp
+++ b/src/qml/jsruntime/qv4qmlcontext.cpp
@@ -65,8 +65,6 @@ DEFINE_MANAGED_VTABLE(QmlContext);
void Heap::QQmlContextWrapper::init(QQmlContextData *context, QObject *scopeObject)
{
Object::init();
- readOnly = true;
- isNullWrapper = false;
this->context = new QQmlContextDataRef(context);
this->scopeObject.init(scopeObject);
}
@@ -89,9 +87,6 @@ ReturnedValue QQmlContextWrapper::virtualGet(const Managed *m, PropertyKey id, c
QV4::ExecutionEngine *v4 = resource->engine();
QV4::Scope scope(v4);
- if (resource->d()->isNullWrapper)
- return Object::virtualGet(m, id, receiver, hasProperty);
-
if (v4->callingQmlContext() != *resource->d()->context)
return Object::virtualGet(m, id, receiver, hasProperty);
@@ -274,18 +269,6 @@ bool QQmlContextWrapper::virtualPut(Managed *m, PropertyKey id, const Value &val
if (member < UINT_MAX)
return wrapper->putValue(member, value);
- if (wrapper->d()->isNullWrapper) {
- if (wrapper && wrapper->d()->readOnly) {
- QString error = QLatin1String("Invalid write to global property \"") + id.toQString() +
- QLatin1Char('"');
- ScopedString e(scope, v4->newString(error));
- v4->throwError(e);
- return false;
- }
-
- return Object::virtualPut(m, id, value, receiver);
- }
-
// It's possible we could delay the calculation of the "actual" context (in the case
// of sub contexts) until it is definitely needed.
QQmlContextData *context = wrapper->getContext();
@@ -321,14 +304,10 @@ bool QQmlContextWrapper::virtualPut(Managed *m, PropertyKey id, const Value &val
expressionContext->unresolvedNames = true;
- if (wrapper->d()->readOnly) {
- QString error = QLatin1String("Invalid write to global property \"") + name->toQString() +
- QLatin1Char('"');
- v4->throwError(error);
- return false;
- }
-
- return Object::virtualPut(m, id, value, receiver);
+ QString error = QLatin1String("Invalid write to global property \"") + name->toQString() +
+ QLatin1Char('"');
+ v4->throwError(error);
+ return false;
}
void Heap::QmlContext::init(QV4::ExecutionContext *outerContext, QV4::QQmlContextWrapper *qml)
@@ -339,30 +318,6 @@ void Heap::QmlContext::init(QV4::ExecutionContext *outerContext, QV4::QQmlContex
this->activation.set(internalClass->engine, qml->d());
}
-Heap::QmlContext *QmlContext::createWorkerContext(ExecutionContext *parent, const QUrl &source, Value *sendFunction)
-{
- Scope scope(parent);
-
- QQmlContextData *context = new QQmlContextData;
- context->baseUrl = source;
- context->baseUrlString = source.toString();
- context->isInternal = true;
- context->isJSContext = true;
-
- Scoped<QQmlContextWrapper> qml(scope, scope.engine->memoryManager->allocate<QQmlContextWrapper>(context, (QObject*)nullptr));
- qml->d()->isNullWrapper = true;
-
- qml->setReadOnly(false);
- QV4::ScopedObject api(scope, scope.engine->newObject());
- api->put(QV4::ScopedString(scope, scope.engine->newString(QStringLiteral("sendMessage"))), *sendFunction);
- qml->QV4::Object::put(QV4::ScopedString(scope, scope.engine->newString(QStringLiteral("WorkerScript"))), api);
- qml->setReadOnly(true);
-
- Heap::QmlContext *c = scope.engine->memoryManager->alloc<QmlContext>(parent, qml);
- Q_ASSERT(c->vtable() == staticVTable());
- return c;
-}
-
Heap::QmlContext *QmlContext::create(ExecutionContext *parent, QQmlContextData *context, QObject *scopeObject)
{
Scope scope(parent);
diff --git a/src/qml/jsruntime/qv4qmlcontext_p.h b/src/qml/jsruntime/qv4qmlcontext_p.h
index b9061a3f58..4fe34a0a06 100644
--- a/src/qml/jsruntime/qv4qmlcontext_p.h
+++ b/src/qml/jsruntime/qv4qmlcontext_p.h
@@ -69,8 +69,6 @@ namespace Heap {
struct QQmlContextWrapper : Object {
void init(QQmlContextData *context, QObject *scopeObject);
void destroy();
- bool readOnly;
- bool isNullWrapper;
QQmlContextDataRef *context;
QQmlQPointer<QObject> scopeObject;
@@ -96,8 +94,6 @@ struct Q_QML_EXPORT QQmlContextWrapper : Object
inline QObject *getScopeObject() const { return d()->scopeObject; }
inline QQmlContextData *getContext() const { return *d()->context; }
- void setReadOnly(bool b) { d()->readOnly = b; }
-
static ReturnedValue virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty);
static bool virtualPut(Managed *m, PropertyKey id, const Value &value, Value *receiver);
};
@@ -107,7 +103,6 @@ struct Q_QML_EXPORT QmlContext : public ExecutionContext
V4_MANAGED(QmlContext, ExecutionContext)
V4_INTERNALCLASS(QmlContext)
- static Heap::QmlContext *createWorkerContext(QV4::ExecutionContext *parent, const QUrl &source, Value *sendFunction);
static Heap::QmlContext *create(QV4::ExecutionContext *parent, QQmlContextData *context, QObject *scopeObject);
QObject *qmlScope() const {
diff --git a/src/qml/types/qquickworkerscript.cpp b/src/qml/types/qquickworkerscript.cpp
index 9fc374acb0..706982ba97 100644
--- a/src/qml/types/qquickworkerscript.cpp
+++ b/src/qml/types/qquickworkerscript.cpp
@@ -145,7 +145,7 @@ public:
WorkerEngine(QQuickWorkerScriptEnginePrivate *parent);
~WorkerEngine() override;
- void init();
+ void init(int id);
#if QT_CONFIG(qml_network)
QNetworkAccessManager *networkAccessManager() override;
@@ -173,16 +173,14 @@ public:
QWaitCondition m_wait;
struct WorkerScript {
- WorkerScript(QQuickWorkerScriptEnginePrivate *parent);
+ WorkerScript(int id, QQuickWorkerScriptEnginePrivate *parent);
~WorkerScript();
QV4::ExecutionEngine *v4() const { return QV8Engine::getV4(workerEngine.data()); }
QScopedPointer<WorkerEngine> workerEngine;
int id;
QUrl source;
- bool initialized;
QQuickWorkerScript *owner;
- QV4::PersistentValue qmlContext;
};
QHash<int, WorkerScript *> workers;
@@ -221,17 +219,17 @@ QQuickWorkerScriptEnginePrivate::WorkerEngine::~WorkerEngine()
delete m_v4Engine;
}
-void QQuickWorkerScriptEnginePrivate::WorkerEngine::init()
+void QQuickWorkerScriptEnginePrivate::WorkerEngine::init(int id)
{
initQmlGlobalObject();
#define CALL_ONMESSAGE_SCRIPT \
- "(function(object, message) { "\
+ "(function(message) { "\
"var isfunction = false; "\
"try { "\
- "isfunction = object.WorkerScript.onMessage instanceof Function; "\
+ "isfunction = WorkerScript.onMessage instanceof Function; "\
"} catch (e) {}" \
"if (isfunction) "\
- "object.WorkerScript.onMessage(message); "\
+ "WorkerScript.onMessage(message); "\
"})"
#define SEND_MESSAGE_CREATE_SCRIPT \
@@ -256,6 +254,12 @@ void QQuickWorkerScriptEnginePrivate::WorkerEngine::init()
jsCallData->args[0] = function;
*jsCallData->thisObject = m_v4Engine->global();
createsend.set(scope.engine, createsendconstructor->call(jsCallData));
+
+
+ QV4::ScopedValue v(scope, sendFunction(id));
+ QV4::ScopedObject api(scope, scope.engine->newObject());
+ api->put(QV4::ScopedString(scope, scope.engine->newString(QStringLiteral("sendMessage"))), v);
+ m_v4Engine->globalObject->put(QV4::ScopedString(scope, scope.engine->newString(QStringLiteral("WorkerScript"))), api);
}
// Requires handle and context scope
@@ -316,20 +320,6 @@ QV4::ReturnedValue QQuickWorkerScriptEnginePrivate::method_sendMessage(const QV4
return QV4::Encode::undefined();
}
-QV4::ReturnedValue QQuickWorkerScriptEnginePrivate::getWorker(WorkerScript *script)
-{
- if (!script->initialized) {
- script->initialized = true;
-
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(script->workerEngine.get());
- QV4::Scope scope(v4);
- QV4::ScopedValue v(scope, script->workerEngine->sendFunction(script->id));
- script->qmlContext.set(v4, QV4::QmlContext::createWorkerContext(v4->rootContext(), script->source, v));
- }
-
- return script->qmlContext.value();
-}
-
bool QQuickWorkerScriptEnginePrivate::event(QEvent *event)
{
if (event->type() == (QEvent::Type)WorkerDataEvent::WorkerData) {
@@ -367,13 +357,10 @@ void QQuickWorkerScriptEnginePrivate::processMessage(int id, const QByteArray &d
QV4::ScopedFunctionObject f(scope, script->workerEngine->onmessage.value());
QV4::ScopedValue value(scope, QV4::Serialize::deserialize(data, v4));
- QV4::Scoped<QV4::QmlContext> qmlContext(scope, script->qmlContext.value());
- Q_ASSERT(!!qmlContext);
- QV4::JSCallData jsCallData(scope, 2);
+ QV4::JSCallData jsCallData(scope, 1);
*jsCallData->thisObject = v4->global();
- jsCallData->args[0] = qmlContext->d()->qml(); // ###
- jsCallData->args[1] = value;
+ jsCallData->args[0] = value;
f->call(jsCallData);
if (scope.hasException()) {
QQmlError error = scope.engine->catchExceptionAsQmlError();
@@ -398,11 +385,8 @@ void QQuickWorkerScriptEnginePrivate::processLoad(int id, const QUrl &url)
script->source = url;
- QV4::Scoped<QV4::QmlContext> qmlContext(scope, getWorker(script));
- Q_ASSERT(!!qmlContext);
-
QString error;
- program.reset(QV4::Script::createFromFileOrCache(v4, qmlContext, fileName, url, &error));
+ program.reset(QV4::Script::createFromFileOrCache(v4, /*qml context*/nullptr, fileName, url, &error));
if (program.isNull()) {
if (!error.isEmpty())
qWarning().nospace() << error;
@@ -512,11 +496,11 @@ QQuickWorkerScriptEngine::~QQuickWorkerScriptEngine()
d->deleteLater();
}
-QQuickWorkerScriptEnginePrivate::WorkerScript::WorkerScript(QQuickWorkerScriptEnginePrivate *parent)
-: id(-1), initialized(false), owner(nullptr)
+QQuickWorkerScriptEnginePrivate::WorkerScript::WorkerScript(int id, QQuickWorkerScriptEnginePrivate *parent)
+: id(id), owner(nullptr)
{
workerEngine.reset(new QQuickWorkerScriptEnginePrivate::WorkerEngine(parent));
- workerEngine->init();
+ workerEngine->init(id);
}
QQuickWorkerScriptEnginePrivate::WorkerScript::~WorkerScript()
@@ -526,9 +510,8 @@ QQuickWorkerScriptEnginePrivate::WorkerScript::~WorkerScript()
int QQuickWorkerScriptEngine::registerWorkerScript(QQuickWorkerScript *owner)
{
typedef QQuickWorkerScriptEnginePrivate::WorkerScript WorkerScript;
- WorkerScript *script = new WorkerScript(d);
+ WorkerScript *script = new WorkerScript(d->m_nextId++, d);
- script->id = d->m_nextId++;
script->owner = owner;
d->m_lock.lock();
diff --git a/tests/auto/qml/qquickworkerscript/data/script_global.js b/tests/auto/qml/qquickworkerscript/data/script_global.js
deleted file mode 100644
index cce4f2ceca..0000000000
--- a/tests/auto/qml/qquickworkerscript/data/script_global.js
+++ /dev/null
@@ -1,5 +0,0 @@
-WorkerScript.onMessage = function(msg) {
- world = "World"
- WorkerScript.sendMessage(msg + " " + world)
-}
-
diff --git a/tests/auto/qml/qquickworkerscript/data/script_global2.js b/tests/auto/qml/qquickworkerscript/data/script_global2.js
deleted file mode 100644
index 0867f7ee76..0000000000
--- a/tests/auto/qml/qquickworkerscript/data/script_global2.js
+++ /dev/null
@@ -1,6 +0,0 @@
-world = "World"
-
-WorkerScript.onMessage = function(msg) {
- WorkerScript.sendMessage(msg + " " + world)
-}
-
diff --git a/tests/auto/qml/qquickworkerscript/data/worker_global.qml b/tests/auto/qml/qquickworkerscript/data/worker_global.qml
deleted file mode 100644
index 546afd2f39..0000000000
--- a/tests/auto/qml/qquickworkerscript/data/worker_global.qml
+++ /dev/null
@@ -1,5 +0,0 @@
-import QtQuick 2.0
-
-BaseWorker {
- source: "script_global.js"
-}
diff --git a/tests/auto/qml/qquickworkerscript/data/worker_global2.qml b/tests/auto/qml/qquickworkerscript/data/worker_global2.qml
deleted file mode 100644
index 42cad3852b..0000000000
--- a/tests/auto/qml/qquickworkerscript/data/worker_global2.qml
+++ /dev/null
@@ -1,5 +0,0 @@
-import QtQuick 2.0
-
-BaseWorker {
- source: "script_global2.js"
-}
diff --git a/tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp b/tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp
index e8a4be6faf..e21a53b4f3 100644
--- a/tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp
+++ b/tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp
@@ -57,7 +57,6 @@ private slots:
void scriptError_onCall();
void script_function();
void script_var();
- void script_global();
void stressDispose();
private:
@@ -311,47 +310,6 @@ void tst_QQuickWorkerScript::script_var()
delete worker;
}
-void tst_QQuickWorkerScript::script_global()
-{
- {
- QQmlComponent component(&m_engine, testFileUrl("worker_global.qml"));
- QQuickWorkerScript *worker = qobject_cast<QQuickWorkerScript*>(component.create());
- QVERIFY(worker != nullptr);
-
- QString value("Hello");
-
- QtMessageHandler previousMsgHandler = qInstallMessageHandler(qquickworkerscript_warningsHandler);
-
- QVERIFY(QMetaObject::invokeMethod(worker, "testSend", Q_ARG(QVariant, value)));
-
- QTRY_COMPARE(qquickworkerscript_lastWarning,
- testFileUrl("script_global.js").toString() + QLatin1String(":2: Invalid write to global property \"world\""));
-
- qInstallMessageHandler(previousMsgHandler);
-
- qApp->processEvents();
- delete worker;
- }
-
- qquickworkerscript_lastWarning = QString();
-
- {
- QtMessageHandler previousMsgHandler = qInstallMessageHandler(qquickworkerscript_warningsHandler);
-
- QQmlComponent component(&m_engine, testFileUrl("worker_global2.qml"));
- QQuickWorkerScript *worker = qobject_cast<QQuickWorkerScript*>(component.create());
- QVERIFY(worker != nullptr);
-
- QTRY_COMPARE(qquickworkerscript_lastWarning,
- testFileUrl("script_global2.js").toString() + QLatin1String(":1: Invalid write to global property \"world\""));
-
- qInstallMessageHandler(previousMsgHandler);
-
- qApp->processEvents();
- delete worker;
- }
-}
-
// Rapidly create and destroy worker scripts to test resources are being disposed
// in the correct isolate
void tst_QQuickWorkerScript::stressDispose()