diff options
-rw-r--r-- | src/qml/qml/qqmlbinding.cpp | 10 | ||||
-rw-r--r-- | src/qml/qml/qqmlcompiler.cpp | 25 | ||||
-rw-r--r-- | src/qml/qml/qqmlcompiler_p.h | 5 | ||||
-rw-r--r-- | src/qml/qml/qqmlcustomparser.cpp | 3 |
4 files changed, 35 insertions, 8 deletions
diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp index 557267d808..9e2fb07066 100644 --- a/src/qml/qml/qqmlbinding.cpp +++ b/src/qml/qml/qqmlbinding.cpp @@ -50,6 +50,7 @@ #include <private/qqmltrace_p.h> #include <private/qqmlexpression_p.h> #include <private/qqmlscriptstring_p.h> +#include <private/qqmlcontextwrapper_p.h> #include <QVariant> #include <QtCore/qdebug.h> @@ -85,7 +86,14 @@ QQmlBinding::createBinding(Identifier id, QObject *obj, QQmlContext *ctxt, Q_ASSERT(typeData); if (QQmlCompiledData *cdata = typeData->compiledData()) { - rv = new QQmlBinding(cdata->primitives.at(id), obj, ctxtdata, url, lineNumber, 0); + QV4::ExecutionEngine *v4 = engine->v4engine(); + QV4::Scope valueScope(v4); + QV4::ScopedObject scopeObject(valueScope, QV4::QmlContextWrapper::qmlScope(v4->v8Engine, ctxtdata, obj)); + QV4::Scoped<QV4::QmlBindingWrapper> wrapper(valueScope, new (v4->memoryManager) QV4::QmlBindingWrapper(v4->rootContext, scopeObject)); + QV4::ExecutionContext *qmlContext = wrapper->context(); + QV4::Function *runtimeFunction = cdata->compilationUnit->runtimeFunctions[cdata->customParserBindings[id]]; + QV4::ScopedValue function(valueScope, QV4::FunctionObject::creatScriptFunction(qmlContext, runtimeFunction)); + rv = new QQmlBinding(function, obj, ctxtdata, url, lineNumber, 0); } typeData->release(); diff --git a/src/qml/qml/qqmlcompiler.cpp b/src/qml/qml/qqmlcompiler.cpp index 54fd002f7b..150ea549be 100644 --- a/src/qml/qml/qqmlcompiler.cpp +++ b/src/qml/qml/qqmlcompiler.cpp @@ -2682,9 +2682,24 @@ const QMetaObject *QQmlCompiler::resolveType(const QString& name) const return qmltype->metaObject(); } -int QQmlCompiler::bindingIdentifier(const Variant &value) +int QQmlCompiler::bindingIdentifier(const QString &name, const Variant &value, const BindingContext &ctxt) { - return output->indexForString(value.asScript()); + JSBindingReference *reference = pool->New<JSBindingReference>(); + reference->expression = value; + reference->property = pool->New<Property>(); + reference->property->setName(name); + reference->value = 0; + reference->bindingContext = ctxt; + reference->bindingContext.owner++; + + const int id = output->customParserBindings.count(); + output->customParserBindings.append(0); // Filled in later. + reference->customParserBindingsIndex = id; + + compileState->totalBindingsCount++; + compileState->bindings.prepend(reference); + + return id; } // Ensures that the dynamic meta specification on obj is valid @@ -3648,7 +3663,7 @@ bool QQmlCompiler::completeComponentBuild() binding.compiledIndex = cd->functionsToCompile.count() - 1; cd->expressionNames.insert(binding.compiledIndex, binding.property->name().toString().prepend(QStringLiteral("expression for "))); - if (componentStats) + if (componentStats && b->value) componentStats->componentStat.scriptBindings.append(b->value->location); } @@ -3697,6 +3712,10 @@ bool QQmlCompiler::completeComponentBuild() for (JSBindingReference *b = compileState->bindings.first(); b; b = b->nextReference) { JSBindingReference &binding = *b; binding.compiledIndex = compileState->jsCompileData[binding.bindingContext.object].runtimeFunctionIndices[binding.compiledIndex]; + if (!binding.value) { // Must be a binding requested from custom parser + Q_ASSERT(binding.customParserBindingsIndex >= 0 && binding.customParserBindingsIndex < output->customParserBindings.count()); + output->customParserBindings[binding.customParserBindingsIndex] = binding.compiledIndex; + } } } diff --git a/src/qml/qml/qqmlcompiler_p.h b/src/qml/qml/qqmlcompiler_p.h index 05c877d98b..443a80d95c 100644 --- a/src/qml/qml/qqmlcompiler_p.h +++ b/src/qml/qml/qqmlcompiler_p.h @@ -150,6 +150,7 @@ public: // index in first hash is component index, hash inside maps from object index in that scope to integer id QHash<int, QHash<int, int> > objectIndexToIdPerComponent; QHash<int, int> objectIndexToIdForRoot; + QVector<int> customParserBindings; // index is binding identifier, value is compiled function index. bool isComponent(int objectIndex) const { return objectIndexToIdPerComponent.contains(objectIndex); } bool isCompositeType() const { return !datas.at(qmlUnit->indexOfRootObject).isEmpty(); } @@ -231,7 +232,7 @@ namespace QQmlCompilerTypes { QQmlScript::Value *value; int compiledIndex : 16; - int sharedIndex : 16; + int customParserBindingsIndex : 16; BindingContext bindingContext; @@ -340,7 +341,7 @@ public: int evaluateEnum(const QHashedStringRef &scope, const QByteArray& enumValue, bool *ok) const; // for QQmlCustomParser::evaluateEnum const QMetaObject *resolveType(const QString& name) const; // for QQmlCustomParser::resolveType - int bindingIdentifier(const QQmlScript::Variant& value); // for QQmlCustomParser::bindingIndex + int bindingIdentifier(const QString &name, const QQmlScript::Variant& value, const QQmlCompilerTypes::BindingContext &ctxt); // for QQmlCustomParser::bindingIndex private: typedef QQmlCompiledData::Instruction Instruction; diff --git a/src/qml/qml/qqmlcustomparser.cpp b/src/qml/qml/qqmlcustomparser.cpp index eba2e14e51..19e49009ce 100644 --- a/src/qml/qml/qqmlcustomparser.cpp +++ b/src/qml/qml/qqmlcustomparser.cpp @@ -313,8 +313,7 @@ const QMetaObject *QQmlCustomParser::resolveType(const QString& name) const */ QQmlBinding::Identifier QQmlCustomParser::bindingIdentifier(const QQmlScript::Variant &value, const QString& name) { - Q_UNUSED(name); - return compiler->bindingIdentifier(value); + return compiler->bindingIdentifier(name, value, QQmlCompilerTypes::BindingContext(object)); } QT_END_NAMESPACE |