aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2014-10-04 17:18:15 +0200
committerSimon Hausmann <simon.hausmann@digia.com>2014-10-09 17:41:39 +0200
commit9e71faae038de4c41c206f1321da1b37ab6ca8b1 (patch)
treebf8c38eecd7654b4178379778c218f7552a752d9 /src/qml/jsruntime
parent8c3d661163fc7517569f1a70ab70c2b23de25406 (diff)
Fix QQmlExpression/QQmlScriptString/QQmlBinding crashes
In the QQmlScriptString we store the binding id and it is an index into the runtimeFunctions array of the compilation unit. However we don't store the compilation unit and instead in QQmlBinding and QQmlExpression try to retrieve it from the cache via the context url (we have the context after all). That turns out to be not a reliable way, as sometimes the URL might slightly differ from the originally compiled cache (qrc:/// turning to qrc:/ maybe). Consequently the type is (unnecessarily) compiled again and unfortunately not _linked_, therefore the runtime functions array is empty. Another option is that when the component was created from a QByteArray, then no entry exists in the cache in the first place. This patch addresses the problem by storing a reference to the compilation unit in the QQmlContextData. That we can safely retrieve and it'll make sure the compilation unit also stays alive. In the process of that the manual reference counting was switched over to QQmlRefCount and QQmlRefPointer for QV4::CompilationUnit. Task-number: QTBUG-41193 Change-Id: I9111f9a3b65618e453954abcd789c039e65a94f7 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/qml/jsruntime')
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp6
-rw-r--r--src/qml/jsruntime/qv4profiling_p.h10
-rw-r--r--src/qml/jsruntime/qv4script.cpp13
-rw-r--r--src/qml/jsruntime/qv4script_p.h2
4 files changed, 13 insertions, 18 deletions
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp
index cddc45aaf5..84b0eb17af 100644
--- a/src/qml/jsruntime/qv4functionobject.cpp
+++ b/src/qml/jsruntime/qv4functionobject.cpp
@@ -108,7 +108,7 @@ FunctionObject::Data::Data(InternalClass *ic)
FunctionObject::Data::~Data()
{
if (function)
- function->compilationUnit->deref();
+ function->compilationUnit->release();
}
void FunctionObject::init(String *n, bool createProto)
@@ -226,7 +226,7 @@ ReturnedValue FunctionCtor::construct(Managed *that, CallData *callData)
QV4::Compiler::JSUnitGenerator jsGenerator(&module);
QScopedPointer<EvalInstructionSelection> isel(v4->iselFactory->create(QQmlEnginePrivate::get(v4), v4->executableAllocator, &module, &jsGenerator));
- QV4::CompiledData::CompilationUnit *compilationUnit = isel->compile();
+ QQmlRefPointer<QV4::CompiledData::CompilationUnit> compilationUnit = isel->compile();
QV4::Function *vmf = compilationUnit->linkToEngine(v4);
return FunctionObject::createScriptFunction(v4->rootContext, vmf)->asReturnedValue();
@@ -416,7 +416,7 @@ SimpleScriptFunction::Data::Data(ExecutionContext *scope, Function *function, bo
setVTable(staticVTable());
this->function = function;
- function->compilationUnit->ref();
+ function->compilationUnit->addref();
Q_ASSERT(function);
Q_ASSERT(function->code);
diff --git a/src/qml/jsruntime/qv4profiling_p.h b/src/qml/jsruntime/qv4profiling_p.h
index 8224f8a851..7c66ee0049 100644
--- a/src/qml/jsruntime/qv4profiling_p.h
+++ b/src/qml/jsruntime/qv4profiling_p.h
@@ -80,23 +80,23 @@ public:
FunctionCall(Function *function, qint64 start, qint64 end) :
m_function(function), m_start(start), m_end(end)
- { m_function->compilationUnit->ref(); }
+ { m_function->compilationUnit->addref(); }
FunctionCall(const FunctionCall &other) :
m_function(other.m_function), m_start(other.m_start), m_end(other.m_end)
- { m_function->compilationUnit->ref(); }
+ { m_function->compilationUnit->addref(); }
~FunctionCall()
- { m_function->compilationUnit->deref(); }
+ { m_function->compilationUnit->release(); }
FunctionCall &operator=(const FunctionCall &other) {
if (&other != this) {
if (m_function)
- m_function->compilationUnit->deref();
+ m_function->compilationUnit->release();
m_function = other.m_function;
m_start = other.m_start;
m_end = other.m_end;
- m_function->compilationUnit->ref();
+ m_function->compilationUnit->addref();
}
return *this;
}
diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp
index 8e91c0e6a5..fa4b4b1894 100644
--- a/src/qml/jsruntime/qv4script.cpp
+++ b/src/qml/jsruntime/qv4script.cpp
@@ -62,7 +62,7 @@ QmlBindingWrapper::Data::Data(ExecutionContext *scope, Function *f, Object *qml)
setVTable(staticVTable());
function = f;
if (function)
- function->compilationUnit->ref();
+ function->compilationUnit->addref();
needsActivation = function ? function->needsActivation() : false;
Scope s(scope);
@@ -163,14 +163,9 @@ struct CompilationUnitHolder : public Object
: Object::Data(engine)
, unit(unit)
{
- unit->ref();
setVTable(staticVTable());
}
- ~Data()
- {
- unit->deref();
- }
- QV4::CompiledData::CompilationUnit *unit;
+ QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit;
};
V4_OBJECT(Object)
@@ -264,7 +259,7 @@ void Script::parse()
QScopedPointer<EvalInstructionSelection> isel(v4->iselFactory->create(QQmlEnginePrivate::get(v4), v4->executableAllocator, &module, &jsGenerator));
if (inheritContext)
isel->setUseFastLookups(false);
- QV4::CompiledData::CompilationUnit *compilationUnit = isel->compile();
+ QQmlRefPointer<QV4::CompiledData::CompilationUnit> compilationUnit = isel->compile();
vmFunction = compilationUnit->linkToEngine(v4);
ScopedObject holder(valueScope, v4->memoryManager->alloc<CompilationUnitHolder>(v4, compilationUnit));
compilationUnitHolder = holder.asReturnedValue();
@@ -313,7 +308,7 @@ Function *Script::function()
return vmFunction;
}
-QV4::CompiledData::CompilationUnit *Script::precompile(IR::Module *module, Compiler::JSUnitGenerator *unitGenerator, ExecutionEngine *engine, const QUrl &url, const QString &source, QList<QQmlError> *reportedErrors)
+QQmlRefPointer<QV4::CompiledData::CompilationUnit> Script::precompile(IR::Module *module, Compiler::JSUnitGenerator *unitGenerator, ExecutionEngine *engine, const QUrl &url, const QString &source, QList<QQmlError> *reportedErrors)
{
using namespace QQmlJS;
using namespace QQmlJS::AST;
diff --git a/src/qml/jsruntime/qv4script_p.h b/src/qml/jsruntime/qv4script_p.h
index 28ac5f3e01..ed93ce49ae 100644
--- a/src/qml/jsruntime/qv4script_p.h
+++ b/src/qml/jsruntime/qv4script_p.h
@@ -122,7 +122,7 @@ struct Q_QML_EXPORT Script {
Function *function();
- static QV4::CompiledData::CompilationUnit *precompile(IR::Module *module, Compiler::JSUnitGenerator *unitGenerator, ExecutionEngine *engine, const QUrl &url, const QString &source, QList<QQmlError> *reportedErrors = 0);
+ static QQmlRefPointer<CompiledData::CompilationUnit> precompile(IR::Module *module, Compiler::JSUnitGenerator *unitGenerator, ExecutionEngine *engine, const QUrl &url, const QString &source, QList<QQmlError> *reportedErrors = 0);
static ReturnedValue evaluate(ExecutionEngine *engine, const QString &script, Object *scopeObject);
};