aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlcompiler.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2013-10-24 14:51:02 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-10-31 10:50:38 +0100
commit34c85bb56c92316a6ce1c79d25f9653fec14791c (patch)
tree6d3d43de33fa53a1353c52506e989ae126f1361b /src/qml/qml/qqmlcompiler.cpp
parentbb7d26ebb0c2e7a9f06a030be8bfcd00e346e06f (diff)
Initial support for resolving meta-property access for the scope and context objects at QML compile time
This avoids having to do a string lookup for ids and in the import cache at run-time, before we can do a string hash lookup in the property cache. Instead we resolve final properties in the context and scope object at compile time and look them up at run-time using their index instead. The dependencies to these properties are also tracked separately and recorded in the compiled data. This is merely the initial patch. There's a lot left to do, such as having specialized getter and setters for specific property types. Setters are missing altogether right now and will fall back to name lookup. Change-Id: If3cb4e7c9454ef4850a615f0935b311c9395b165 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/qml/qml/qqmlcompiler.cpp')
-rw-r--r--src/qml/qml/qqmlcompiler.cpp60
1 files changed, 36 insertions, 24 deletions
diff --git a/src/qml/qml/qqmlcompiler.cpp b/src/qml/qml/qqmlcompiler.cpp
index 58495bb1bf..3f57d7c2ef 100644
--- a/src/qml/qml/qqmlcompiler.cpp
+++ b/src/qml/qml/qqmlcompiler.cpp
@@ -1336,7 +1336,7 @@ void QQmlCompiler::genObjectBody(QQmlScript::Object *obj)
} else if (v->type == Value::SignalExpression) {
Instruction::StoreSignal store;
- store.runtimeFunctionIndex = compileState->runtimeFunctionIndices.at(v->signalData.functionIndex);
+ store.runtimeFunctionIndex = compileState->jsCompileData[v->signalData.signalScopeObject].runtimeFunctionIndices.at(v->signalData.functionIndex);
store.handlerName = output->indexForString(prop->name().toString());
store.parameters = output->indexForString(obj->metatype->signalParameterStringForJS(prop->index));
store.signalIndex = prop->index;
@@ -1738,12 +1738,15 @@ bool QQmlCompiler::buildSignal(QQmlScript::Property *prop, QQmlScript::Object *o
//to ensure all parameters are available (see qqmlboundsignal constructor for more details)
prop->index = obj->metatype->originalClone(prop->index);
prop->values.first()->signalData.signalExpressionContextStack = ctxt.stack;
+ prop->values.first()->signalData.signalScopeObject = ctxt.object;
QList<QByteArray> parameters = obj->metatype->signalParameterNames(prop->index);
AST::FunctionDeclaration *funcDecl = convertSignalHandlerExpressionToFunctionDeclaration(unit->parser().jsEngine(), prop->values.first()->value.asAST(), propName.toString(), parameters);
- compileState->functionsToCompile.append(funcDecl);
- prop->values.first()->signalData.functionIndex = compileState->functionsToCompile.count() - 1;
+
+ ComponentCompileState::PerObjectCompileData *cd = &compileState->jsCompileData[ctxt.object];
+ cd->functionsToCompile.append(funcDecl);
+ prop->values.first()->signalData.functionIndex = cd->functionsToCompile.count() - 1;
QString errorString;
obj->metatype->signalParameterStringForJS(prop->index, &errorString);
@@ -3250,12 +3253,13 @@ bool QQmlCompiler::buildDynamicMeta(QQmlScript::Object *obj, DynamicMetaMode mod
vmd->methodCount++;
md = methodData;
- QQmlCompilerTypes::ComponentCompileState::CompiledMetaMethod cmm;
- cmm.obj = obj;
+ ComponentCompileState::PerObjectCompileData *cd = &compileState->jsCompileData[obj];
+
+ ComponentCompileState::CompiledMetaMethod cmm;
cmm.methodIndex = vmd->methodCount - 1;
- compileState->functionsToCompile.append(s->funcDecl);
- cmm.compiledFunctionIndex = compileState->functionsToCompile.count() - 1;
- compileState->compiledMetaMethods.append(cmm);
+ cd->functionsToCompile.append(s->funcDecl);
+ cmm.compiledFunctionIndex = cd->functionsToCompile.count() - 1;
+ cd->compiledMetaMethods.append(cmm);
}
if (aliasCount)
@@ -3641,18 +3645,19 @@ bool QQmlCompiler::completeComponentBuild()
node = new (pool) AST::ExpressionStatement(expr);
}
- compileState->functionsToCompile.append(node);
- binding.compiledIndex = compileState->functionsToCompile.count() - 1;
+ ComponentCompileState::PerObjectCompileData *cd = &compileState->jsCompileData[b->bindingContext.object];
+ cd->functionsToCompile.append(node);
+ binding.compiledIndex = cd->functionsToCompile.count() - 1;
if (componentStats)
componentStats->componentStat.scriptBindings.append(b->value->location);
}
- if (!compileState->functionsToCompile.isEmpty()) {
+ if (!compileState->jsCompileData.isEmpty()) {
const QString &sourceCode = jsEngine->code();
AST::UiProgram *qmlRoot = parser.qmlRoot();
- JSCodeGen jsCodeGen(unit->finalUrlString(), sourceCode, jsModule.data(), jsEngine, qmlRoot);
+ JSCodeGen jsCodeGen(unit->finalUrlString(), sourceCode, jsModule.data(), jsEngine, qmlRoot, output->importCache);
JSCodeGen::ObjectIdMapping idMapping;
if (compileState->ids.count() > 0) {
@@ -3665,21 +3670,28 @@ bool QQmlCompiler::completeComponentBuild()
}
}
- const QVector<int> runtimeFunctionIndices = jsCodeGen.generateJSCodeForFunctionsAndBindings(compileState->root->astNode,
- compileState->functionsToCompile,
- idMapping);
- compileState->runtimeFunctionIndices = runtimeFunctionIndices;
+ jsCodeGen.beginContextScope(idMapping, compileState->root->metatype);
- for (JSBindingReference *b = compileState->bindings.first(); b; b = b->nextReference) {
- JSBindingReference &binding = *b;
- binding.compiledIndex = runtimeFunctionIndices[binding.compiledIndex];
+ for (QHash<QQmlScript::Object *, ComponentCompileState::PerObjectCompileData>::Iterator it = compileState->jsCompileData.begin();
+ it != compileState->jsCompileData.end(); ++it) {
+ QQmlScript::Object *scopeObject = it.key();
+ ComponentCompileState::PerObjectCompileData *cd = &it.value();
+
+ jsCodeGen.beginObjectScope(scopeObject->metatype);
+
+ cd->runtimeFunctionIndices = jsCodeGen.generateJSCodeForFunctionsAndBindings(cd->functionsToCompile);
+
+ foreach (const QQmlCompilerTypes::ComponentCompileState::CompiledMetaMethod &cmm, cd->compiledMetaMethods) {
+ typedef QQmlVMEMetaData VMD;
+ VMD *vmd = (QQmlVMEMetaData *)scopeObject->synthdata.data();
+ VMD::MethodData &md = *(vmd->methodData() + cmm.methodIndex);
+ md.runtimeFunctionIndex = cd->runtimeFunctionIndices.at(cmm.compiledFunctionIndex);
+ }
}
- foreach (const QQmlCompilerTypes::ComponentCompileState::CompiledMetaMethod &cmm, compileState->compiledMetaMethods) {
- typedef QQmlVMEMetaData VMD;
- VMD *vmd = (QQmlVMEMetaData *)cmm.obj->synthdata.data();
- VMD::MethodData &md = *(vmd->methodData() + cmm.methodIndex);
- md.runtimeFunctionIndex = runtimeFunctionIndices.at(cmm.compiledFunctionIndex);
+ for (JSBindingReference *b = compileState->bindings.first(); b; b = b->nextReference) {
+ JSBindingReference &binding = *b;
+ binding.compiledIndex = compileState->jsCompileData[binding.bindingContext.object].runtimeFunctionIndices[binding.compiledIndex];
}
}