diff options
author | Erik Verbruggen <erik.verbruggen@qt.io> | 2018-04-10 15:23:30 +0200 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@qt.io> | 2018-04-10 14:15:24 +0000 |
commit | f2633df1be25acdf1a5444bbd301955ae3412297 (patch) | |
tree | c55cb9973368cbf1eb06839d139a801c2891dea4 /src/qml/compiler/qv4compilerscanfunctions.cpp | |
parent | 51b73e0bb68812d78315af032546750d04656c02 (diff) |
Fix leak of compiler contexts
Repeatedly entering a context that was entered before would result in
leaking the previously entered context. This can happen when compiling
child objects in a QML file, which is done recursively. So before
compiling the bindings/function in the child object, first the global
context and then the QML context are entered.
The fix is to re-use the global context, as it's the same anyway for all
objects in the same module. And we can remove entering the QML context,
because nothing is in there, and we don't put anything in it ever.
Change-Id: Ib1c4259d2dec22df46e96edb65bc3d377e52e671
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/compiler/qv4compilerscanfunctions.cpp')
-rw-r--r-- | src/qml/compiler/qv4compilerscanfunctions.cpp | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/src/qml/compiler/qv4compilerscanfunctions.cpp b/src/qml/compiler/qv4compilerscanfunctions.cpp index 89f602b409..92df98f201 100644 --- a/src/qml/compiler/qv4compilerscanfunctions.cpp +++ b/src/qml/compiler/qv4compilerscanfunctions.cpp @@ -73,13 +73,20 @@ void ScanFunctions::operator()(Node *node) calcEscapingVariables(); } +void ScanFunctions::enterGlobalEnvironment(CompilationMode compilationMode) +{ + enterEnvironment(astNodeForGlobalEnvironment, compilationMode); +} + void ScanFunctions::enterEnvironment(Node *node, CompilationMode compilationMode) { - Context *e = _cg->_module->newContext(node, _context, compilationMode); - if (!e->isStrict) - e->isStrict = _cg->_strictMode; - _contextStack.append(e); - _context = e; + Context *c = _cg->_module->contextMap.value(node); + if (!c) + c = _cg->_module->newContext(node, _context, compilationMode); + if (!c->isStrict) + c->isStrict = _cg->_strictMode; + _contextStack.append(c); + _context = c; } void ScanFunctions::leaveEnvironment() @@ -440,7 +447,7 @@ void ScanFunctions::calcEscapingVariables() { Module *m = _cg->_module; - for (Context *inner : m->contextMap) { + for (Context *inner : qAsConst(m->contextMap)) { for (const QString &var : qAsConst(inner->usedVariables)) { Context *c = inner; while (c) { @@ -468,7 +475,7 @@ void ScanFunctions::calcEscapingVariables() static const bool showEscapingVars = qEnvironmentVariableIsSet("QV4_SHOW_ESCAPING_VARS"); if (showEscapingVars) { qDebug() << "==== escaping variables ===="; - for (Context *c : m->contextMap) { + for (Context *c : qAsConst(m->contextMap)) { qDebug() << "Context" << c->name << ":"; qDebug() << " Arguments escape" << c->argumentsCanEscape; for (auto it = c->members.constBegin(); it != c->members.constEnd(); ++it) { |