diff options
| author | Andrei Golubev <andrei.golubev@qt.io> | 2021-06-21 12:02:04 +0200 |
|---|---|---|
| committer | Andrei Golubev <andrei.golubev@qt.io> | 2021-06-21 16:51:17 +0200 |
| commit | 2c730b211b94be90f15e706777336bdae6d1dc59 (patch) | |
| tree | 4cfd2e976d21f9f46ea5889bcbccc49c1ee068bc /src/qml/jsruntime/qv4engine.cpp | |
| parent | 562ba78426d32c43bdaadaf782a31e9e0121425d (diff) | |
QV4Engine: Do not use currentContext() when calling JavaScript from C++
This turns out to be not quite valid since context hierarchy is
afffected. It was fine before since all the generated classes either
had the same context or a dead-simple hierarchy + the tests for
comprehensive usage were lacking. The problems arise when contexts are
meant to be different for unrelated JS calls e.g. in property bindings
with non-trivial cross-context dependencies (e.g. derived property
uses both neighbor property and base class property in a binding)
As a drive by, simplify QQmlEnginePrivate::executeRuntimeFunction():
* Expect function index to always be valid (in range), it's a very bad
otherwise anyway
* Use QQmlData::outerContext directly as a context argument for
callInContext(). This is what was done anyhow, just through a
QQmlContext -> QQmlContextData conversion, which is actually needless
Change-Id: I8ac6b181363a5d03e468c2b6f35db2dac188ea8b
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4engine.cpp')
| -rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index da3f3226f6..7e87b8be75 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -2112,7 +2112,11 @@ void ExecutionEngine::callInContext(Function *function, QObject *self, QMetaType *types) { QV4::Scope scope(this); - ExecutionContext *ctx = currentStackFrame ? currentContext() : scriptContext(); + // NB: always use scriptContext() here as this method ignores whether + // there's already a stack frame. the method is called from C++ (through + // QQmlEngine::executeRuntimeFunction()) and thus the caller must ensure + // correct setup + QV4::ExecutionContext *ctx = scriptContext(); QV4::Scoped<QV4::QmlContext> qmlContext(scope, QV4::QmlContext::create(ctx, ctxtdata, self)); if (!args) { Q_ASSERT(argc == 0); |
