diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2009-06-10 04:16:19 (GMT) |
---|---|---|
committer | Aaron Kennedy <aaron.kennedy@nokia.com> | 2009-06-10 04:16:19 (GMT) |
commit | b14a89473a51bee7cc2f313b88a8bc1e87a454d8 (patch) | |
tree | ed19f68437ab3d63570b7dc374357f898811d72a /src/declarative | |
parent | 1ef0d84c8e5d706e60e487fc801f90bbf5fddaa6 (diff) | |
download | Qt-b14a89473a51bee7cc2f313b88a8bc1e87a454d8.zip Qt-b14a89473a51bee7cc2f313b88a8bc1e87a454d8.tar.gz Qt-b14a89473a51bee7cc2f313b88a8bc1e87a454d8.tar.bz2 |
Improve bindings startup performance
Diffstat (limited to 'src/declarative')
-rw-r--r-- | src/declarative/qml/qml.pri | 3 | ||||
-rw-r--r-- | src/declarative/qml/qmlbasicscript.cpp | 166 | ||||
-rw-r--r-- | src/declarative/qml/qmlbasicscript_p.h | 11 | ||||
-rw-r--r-- | src/declarative/qml/qmlcompiler.cpp | 55 | ||||
-rw-r--r-- | src/declarative/qml/qmlcompiler_p.h | 44 | ||||
-rw-r--r-- | src/declarative/qml/qmlengine.cpp | 28 | ||||
-rw-r--r-- | src/declarative/qml/qmlengine_p.h | 12 | ||||
-rw-r--r-- | src/declarative/qml/qmlexpression.h | 2 | ||||
-rw-r--r-- | src/declarative/qml/qmlvme.cpp | 4 | ||||
-rw-r--r-- | src/declarative/qml/qpodvector_p.h | 124 |
10 files changed, 356 insertions, 93 deletions
diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri index c61200e..efe4d3f 100644 --- a/src/declarative/qml/qml.pri +++ b/src/declarative/qml/qml.pri @@ -63,7 +63,8 @@ HEADERS += qml/qmlparser_p.h \ qml/qmldeclarativedata_p.h \ qml/qmlerror.h \ qml/qmlscriptparser_p.h \ - qml/qmlbasicscript_p.h + qml/qmlbasicscript_p.h \ + qml/qpodvector_p.h # for qtscript debugger QT += scripttools diff --git a/src/declarative/qml/qmlbasicscript.cpp b/src/declarative/qml/qmlbasicscript.cpp index 7bd898c..d8e65bf 100644 --- a/src/declarative/qml/qmlbasicscript.cpp +++ b/src/declarative/qml/qmlbasicscript.cpp @@ -22,11 +22,19 @@ QT_BEGIN_NAMESPACE +using namespace JavaScript; + struct ScriptInstruction { enum { Load, // fetch Fetch, // fetch + LoadIdObject, // fetch + FetchConstant, // constant + FetchD0Constant, // constant + FetchD1Constant, // constant + + Add, // NA Subtract, // NA Multiply, // NA @@ -47,6 +55,11 @@ struct ScriptInstruction { struct { bool value; } boolean; + struct { + short idx; + short notify; + int type; + } constant; }; }; @@ -249,9 +262,14 @@ struct QmlBasicScriptCompiler { QmlBasicScriptCompiler() : script(0), stateSize(0) {} + QmlBasicScript *script; int stateSize; + QmlParser::Object *context; + QmlParser::Object *component; + QHash<QString, QPair<QmlParser::Object *, int> > ids; + bool compile(JavaScript::AST::Node *); bool compileExpression(JavaScript::AST::Node *); @@ -259,7 +277,7 @@ struct QmlBasicScriptCompiler bool tryConstant(JavaScript::AST::Node *); bool parseConstant(JavaScript::AST::Node *); bool tryName(JavaScript::AST::Node *); - bool parseName(JavaScript::AST::Node *); + bool parseName(JavaScript::AST::Node *, QmlParser::Object ** = 0); bool tryBinaryExpression(JavaScript::AST::Node *); bool compileBinaryExpression(JavaScript::AST::Node *); @@ -437,19 +455,18 @@ bool QmlBasicScript::isValid() const return d != 0; } -/*! - Compile \a v and return true if the compilation is successful, otherwise - returns false. - */ -bool QmlBasicScript::compile(const QmlParser::Variant &v) +bool QmlBasicScript::compile(const Expression &expression) { - if (!v.asAST()) return false; + if (!expression.expression.asAST()) return false; - QByteArray expr = v.asScript().toLatin1(); + QByteArray expr = expression.expression.asScript().toLatin1(); const char *src = expr.constData(); QmlBasicScriptCompiler bsc; bsc.script = this; + bsc.context = expression.context; + bsc.component = expression.component; + bsc.ids = expression.ids; if (d) { if (flags & QmlBasicScriptPrivate::OwnData) @@ -458,7 +475,7 @@ bool QmlBasicScript::compile(const QmlParser::Variant &v) flags = 0; } - if (bsc.compile(v.asAST())) { + if (bsc.compile(expression.expression.asAST())) { int len = ::strlen(src); flags = QmlBasicScriptPrivate::OwnData; int size = sizeof(QmlBasicScriptPrivate) + @@ -483,7 +500,6 @@ bool QmlBasicScriptCompiler::compile(JavaScript::AST::Node *node) return compileExpression(node); } -using namespace JavaScript; bool QmlBasicScriptCompiler::tryConstant(JavaScript::AST::Node *node) { if (node->kind == AST::Node::Kind_TrueLiteral || @@ -524,10 +540,11 @@ bool QmlBasicScriptCompiler::tryName(JavaScript::AST::Node *node) node->kind == AST::Node::Kind_FieldMemberExpression; } -bool QmlBasicScriptCompiler::parseName(AST::Node *node) +bool QmlBasicScriptCompiler::parseName(AST::Node *node, + QmlParser::Object **type) { bool load = false; - + QmlParser::Object *loadedType = 0; QString name; if (node->kind == AST::Node::Kind_IdentifierExpression) { name = static_cast<AST::IdentifierExpression *>(node)->name->asString(); @@ -535,7 +552,7 @@ bool QmlBasicScriptCompiler::parseName(AST::Node *node) } else if (node->kind == AST::Node::Kind_FieldMemberExpression) { AST::FieldMemberExpression *expr = static_cast<AST::FieldMemberExpression *>(node); - if (!parseName(expr->base)) + if (!parseName(expr->base, &loadedType)) return false; name = expr->name->asString(); @@ -543,18 +560,72 @@ bool QmlBasicScriptCompiler::parseName(AST::Node *node) return false; } - int nref = data.count(); - data.append(name.toUtf8()); - data.append('\0'); ScriptInstruction instr; - if (load) - instr.type = ScriptInstruction::Load; - else - instr.type = ScriptInstruction::Fetch; - instr.fetch.idx = nref; - bytecode.append(instr); - ++stateSize; + if (load) { + if (ids.contains(name)) { + instr.type = ScriptInstruction::LoadIdObject; + instr.fetch.idx = ids.value(name).second; + + if (type) + *type = ids.value(name).first; + + } else { + int d0Idx = context->metaObject()->indexOfProperty(name.toUtf8().constData()); + int d1Idx = -1; + if (d0Idx == -1) + d1Idx = component->metaObject()->indexOfProperty(name.toUtf8().constData()); + if (d0Idx != -1) { + + instr.type = ScriptInstruction::FetchD0Constant; + instr.constant.idx = d0Idx; + QMetaProperty prop = context->metaObject()->property(d0Idx); + instr.constant.notify = prop.notifySignalIndex(); + instr.constant.type = prop.userType(); + + } else if (d1Idx != -1) { + + instr.type = ScriptInstruction::FetchD1Constant; + instr.constant.idx = d1Idx; + QMetaProperty prop = component->metaObject()->property(d1Idx); + instr.constant.notify = prop.notifySignalIndex(); + instr.constant.type = prop.userType(); + + } else { + + int nref = data.count(); + data.append(name.toUtf8()); + data.append('\0'); + instr.type = ScriptInstruction::Load; + instr.fetch.idx = nref; + ++stateSize; + + } + } + + } else { + + int idx = -1; + if (loadedType) + idx = loadedType->metaObject()->indexOfProperty(name.toUtf8().constData()); + if (idx != -1) { + instr.type = ScriptInstruction::FetchConstant; + instr.constant.idx = idx; + QMetaProperty prop = loadedType->metaObject()->property(idx); + instr.constant.notify = prop.notifySignalIndex(); + instr.constant.type = prop.userType(); + } else { + int nref = data.count(); + data.append(name.toUtf8()); + data.append('\0'); + instr.type = ScriptInstruction::Fetch; + instr.fetch.idx = nref; + ++stateSize; + } + + } + + bytecode.append(instr); return true; } @@ -679,12 +750,16 @@ QVariant QmlBasicScript::run(QmlContext *context, void *voidCache, CacheState *c { if (!isValid()) return QVariant(); + + QmlContextPrivate *contextPrivate = context->d_func(); + QmlEnginePrivate *enginePrivate = context->engine()->d_func(); QmlBasicScriptNodeCache *dataCache = reinterpret_cast<QmlBasicScriptNodeCache *>(voidCache); int dataCacheItem; - QStack<QVariant> stack; + QStack<QVariant> stack; + bool resetting = false; bool hasReset = false; @@ -702,6 +777,49 @@ QVariant QmlBasicScript::run(QmlContext *context, void *voidCache, CacheState *c const ScriptInstruction &instr = d->instructions()[idx]; switch(instr.type) { + case ScriptInstruction::LoadIdObject: + { + stack.push(contextPrivate->propertyValues.at(instr.fetch.idx)); + enginePrivate->capturedProperties << + QmlEnginePrivate::CapturedProperty(context, contextPrivate->notifyIndex + instr.fetch.idx); + state = Reset; + } + break; + + case ScriptInstruction::FetchD0Constant: + { + QObject *obj = contextPrivate->defaultObjects.at(0); + + stack.push(fetch_value(obj, instr.constant.idx, instr.constant.type)); + enginePrivate->capturedProperties << + QmlEnginePrivate::CapturedProperty(obj, instr.constant.notify); + state = Reset; + } + break; + + case ScriptInstruction::FetchD1Constant: + { + QObject *obj = contextPrivate->defaultObjects.at(1); + + stack.push(fetch_value(obj, instr.constant.idx, instr.constant.type)); + enginePrivate->capturedProperties << + QmlEnginePrivate::CapturedProperty(obj, instr.constant.notify); + state = Reset; + } + break; + + case ScriptInstruction::FetchConstant: + { + QVariant o = stack.pop(); + QObject *obj = qvariant_cast<QObject *>(o); + + stack.push(fetch_value(obj, instr.constant.idx, instr.constant.type)); + enginePrivate->capturedProperties << + QmlEnginePrivate::CapturedProperty(obj, instr.constant.notify); + state = Reset; + } + break; + case ScriptInstruction::Load: // either an object or a property case ScriptInstruction::Fetch: // can only be a property { diff --git a/src/declarative/qml/qmlbasicscript_p.h b/src/declarative/qml/qmlbasicscript_p.h index 1117e11..43c0d36 100644 --- a/src/declarative/qml/qmlbasicscript_p.h +++ b/src/declarative/qml/qmlbasicscript_p.h @@ -38,7 +38,16 @@ public: QByteArray expression() const; - bool compile(const QmlParser::Variant &); + struct Expression + { + QmlParser::Object *component; + QmlParser::Object *context; + QmlParser::Property *property; + QmlParser::Variant expression; + QHash<QString, QPair<QmlParser::Object *, int> > ids; + }; + + bool compile(const Expression &); bool isValid() const; void clear(); diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp index b28d7dd..fe3da57 100644 --- a/src/declarative/qml/qmlcompiler.cpp +++ b/src/declarative/qml/qmlcompiler.cpp @@ -533,6 +533,8 @@ bool QmlCompiler::compile(QmlEngine *engine, void QmlCompiler::compileTree(Object *tree) { + compileState.root = tree; + QmlInstruction init; init.type = QmlInstruction::Init; init.line = 0; @@ -557,7 +559,7 @@ void QmlCompiler::compileTree(Object *tree) finalizeComponent(0); } -bool QmlCompiler::compileObject(Object *obj, int ctxt) +bool QmlCompiler::compileObject(Object *obj, const BindingContext &ctxt) { Q_ASSERT (obj->type != -1); obj->metatype = output->types.at(obj->type).metaObject(); @@ -567,7 +569,7 @@ bool QmlCompiler::compileObject(Object *obj, int ctxt) return true; } - ctxt = 0; + BindingContext objCtxt(obj); int createInstrIdx = output->bytecode.count(); // Create the object @@ -617,7 +619,7 @@ bool QmlCompiler::compileObject(Object *obj, int ctxt) if (isCustomParser) { // Custom parser types don't support signal properties if (testProperty(prop, obj)) { - COMPILE_CHECK(compileProperty(prop, obj, ctxt)); + COMPILE_CHECK(compileProperty(prop, obj, objCtxt)); } else { customProps << QmlCustomParserNodePrivate::fromProperty(prop); } @@ -625,7 +627,7 @@ bool QmlCompiler::compileObject(Object *obj, int ctxt) if (isSignalPropertyName(prop->name)) { COMPILE_CHECK(compileSignal(prop,obj)); } else { - COMPILE_CHECK(compileProperty(prop, obj, ctxt)); + COMPILE_CHECK(compileProperty(prop, obj, objCtxt)); } } @@ -637,12 +639,12 @@ bool QmlCompiler::compileObject(Object *obj, int ctxt) if (isCustomParser) { if (testProperty(prop, obj)) { - COMPILE_CHECK(compileProperty(prop, obj, ctxt)); + COMPILE_CHECK(compileProperty(prop, obj, objCtxt)); } else { customProps << QmlCustomParserNodePrivate::fromProperty(prop); } } else { - COMPILE_CHECK(compileProperty(prop, obj, ctxt)); + COMPILE_CHECK(compileProperty(prop, obj, objCtxt)); } } @@ -673,7 +675,7 @@ bool QmlCompiler::compileObject(Object *obj, int ctxt) return true; } -bool QmlCompiler::compileComponent(Object *obj, int ctxt) +bool QmlCompiler::compileComponent(Object *obj, const BindingContext &ctxt) { Property *idProp = 0; if (obj->properties.count() > 1 || @@ -709,6 +711,7 @@ bool QmlCompiler::compileComponent(Object *obj, int ctxt) reference.id = val; reference.object = obj; reference.instructionIdx = output->bytecode.count(); + reference.idx = compileState.ids.count(); compileState.ids.insert(val, reference); int pref = output->indexForString(val); @@ -724,7 +727,7 @@ bool QmlCompiler::compileComponent(Object *obj, int ctxt) return true; } -bool QmlCompiler::compileComponentFromRoot(Object *obj, int ctxt) +bool QmlCompiler::compileComponentFromRoot(Object *obj, const BindingContext &ctxt) { output->bytecode.push_back(QmlInstruction()); QmlInstruction &create = output->bytecode.last(); @@ -743,6 +746,7 @@ bool QmlCompiler::compileComponentFromRoot(Object *obj, int ctxt) ComponentCompileState oldComponentCompileState = compileState; compileState = ComponentCompileState(); + compileState.root = obj; if (obj) COMPILE_CHECK(compileObject(obj, ctxt)); @@ -753,7 +757,7 @@ bool QmlCompiler::compileComponentFromRoot(Object *obj, int ctxt) } -bool QmlCompiler::compileFetchedObject(Object *obj, int ctxt) +bool QmlCompiler::compileFetchedObject(Object *obj, const BindingContext &ctxt) { Q_ASSERT(obj->metatype); @@ -871,7 +875,7 @@ bool QmlCompiler::testProperty(QmlParser::Property *prop, return false; } -bool QmlCompiler::compileProperty(Property *prop, Object *obj, int ctxt) +bool QmlCompiler::compileProperty(Property *prop, Object *obj, const BindingContext &ctxt) { if (prop->values.isEmpty() && !prop->value) COMPILE_EXCEPTION2(prop, "Empty property assignment"); @@ -992,6 +996,7 @@ bool QmlCompiler::compileIdProperty(QmlParser::Property *prop, reference.id = val; reference.object = obj; reference.instructionIdx = output->bytecode.count(); + reference.idx = compileState.ids.count(); compileState.ids.insert(val, reference); QmlInstruction id; @@ -1012,7 +1017,7 @@ bool QmlCompiler::compileIdProperty(QmlParser::Property *prop, // } // GridView is an attached property object. bool QmlCompiler::compileAttachedProperty(QmlParser::Property *prop, - int ctxt) + const BindingContext &ctxt) { Q_ASSERT(prop->value); int id = QmlMetaType::attachedPropertiesFuncId(prop->name); @@ -1024,7 +1029,7 @@ bool QmlCompiler::compileAttachedProperty(QmlParser::Property *prop, fetch.fetchAttached.id = id; output->bytecode << fetch; - COMPILE_CHECK(compileFetchedObject(prop->value, ctxt + 1)); + COMPILE_CHECK(compileFetchedObject(prop->value, ctxt.incr())); QmlInstruction pop; pop.type = QmlInstruction::PopFetchedObject; @@ -1040,7 +1045,7 @@ bool QmlCompiler::compileAttachedProperty(QmlParser::Property *prop, // } // font is a nested property. size is not. bool QmlCompiler::compileNestedProperty(QmlParser::Property *prop, - int ctxt) + const BindingContext &ctxt) { Q_ASSERT(prop->type != 0); Q_ASSERT(prop->index != -1); @@ -1057,7 +1062,7 @@ bool QmlCompiler::compileNestedProperty(QmlParser::Property *prop, fetch.line = prop->location.start.line; output->bytecode << fetch; - COMPILE_CHECK(compileFetchedObject(prop->value, ctxt + 1)); + COMPILE_CHECK(compileFetchedObject(prop->value, ctxt.incr())); QmlInstruction pop; pop.type = QmlInstruction::PopFetchedObject; @@ -1074,7 +1079,7 @@ bool QmlCompiler::compileNestedProperty(QmlParser::Property *prop, // QmlList<T *> * types can accept a list of objects bool QmlCompiler::compileListProperty(QmlParser::Property *prop, QmlParser::Object *obj, - int ctxt) + const BindingContext &ctxt) { Q_ASSERT(QmlMetaType::isList(prop->type) || QmlMetaType::isQmlList(prop->type)); @@ -1166,7 +1171,7 @@ bool QmlCompiler::compileListProperty(QmlParser::Property *prop, // We allow assignming multiple values to single value properties bool QmlCompiler::compilePropertyAssignment(QmlParser::Property *prop, QmlParser::Object *obj, - int ctxt) + const BindingContext &ctxt) { for (int ii = 0; ii < prop->values.count(); ++ii) { Value *v = prop->values.at(ii); @@ -1187,7 +1192,7 @@ bool QmlCompiler::compilePropertyAssignment(QmlParser::Property *prop, // Compile assigning a single object instance to a regular property bool QmlCompiler::compilePropertyObjectAssignment(QmlParser::Property *prop, QmlParser::Value *v, - int ctxt) + const BindingContext &ctxt) { Q_ASSERT(prop->index != -1); Q_ASSERT(v->object->type != -1); @@ -1296,7 +1301,7 @@ bool QmlCompiler::compilePropertyObjectAssignment(QmlParser::Property *prop, bool QmlCompiler::compilePropertyLiteralAssignment(QmlParser::Property *prop, QmlParser::Object *obj, QmlParser::Value *v, - int ctxt) + const BindingContext &ctxt) { Q_ASSERT(prop->index != -1); @@ -1409,7 +1414,7 @@ bool QmlCompiler::compileDynamicMeta(QmlParser::Object *obj) bool QmlCompiler::compileBinding(QmlParser::Value *value, QmlParser::Property *prop, - int ctxt) + const BindingContext &ctxt) { Q_ASSERT(prop->index); Q_ASSERT(prop->parent); @@ -1491,7 +1496,15 @@ void QmlCompiler::finalizeComponent(int patch) void QmlCompiler::finalizeBinding(const BindingReference &binding) { QmlBasicScript bs; - bs.compile(binding.expression); + QmlBasicScript::Expression expr; + expr.component = compileState.root; + expr.context = binding.bindingContext.object; + expr.property = binding.property; + expr.expression = binding.expression; + foreach (const IdReference &id, compileState.ids) + expr.ids.insert(id.id, qMakePair(id.object, id.idx)); + + bs.compile(expr); QmlInstruction &instr = output->bytecode[binding.instructionIdx]; instr.line = binding.value->location.start.line; @@ -1553,7 +1566,7 @@ void QmlCompiler::finalizeBinding(const BindingReference &binding) bref = output->indexForString(binding.expression.asScript()); } - instr.assignBinding.context = binding.bindingContext; + instr.assignBinding.context = binding.bindingContext.stack; if (bs.isValid()) instr.type = QmlInstruction::StoreCompiledBinding; diff --git a/src/declarative/qml/qmlcompiler_p.h b/src/declarative/qml/qmlcompiler_p.h index 6b6e1e2..6b6d8cb 100644 --- a/src/declarative/qml/qmlcompiler_p.h +++ b/src/declarative/qml/qmlcompiler_p.h @@ -125,41 +125,55 @@ public: private: void reset(QmlCompiledComponent *, bool); + struct BindingContext { + BindingContext() + : stack(0), object(0) {} + BindingContext(QmlParser::Object *o) + : stack(0), object(o) {} + BindingContext incr() const { + BindingContext rv(object); + rv.stack = stack + 1; + return rv; + } + int stack; + QmlParser::Object *object; + }; + void compileTree(QmlParser::Object *tree); - bool compileObject(QmlParser::Object *obj, int); - bool compileComponent(QmlParser::Object *obj, int); - bool compileComponentFromRoot(QmlParser::Object *obj, int); - bool compileFetchedObject(QmlParser::Object *obj, int); + bool compileObject(QmlParser::Object *obj, const BindingContext &); + bool compileComponent(QmlParser::Object *obj, const BindingContext &); + bool compileComponentFromRoot(QmlParser::Object *obj, const BindingContext &); + bool compileFetchedObject(QmlParser::Object *obj, const BindingContext &); bool compileSignal(QmlParser::Property *prop, QmlParser::Object *obj); bool testProperty(QmlParser::Property *prop, QmlParser::Object *obj); int signalByName(const QMetaObject *, const QByteArray &name); - bool compileProperty(QmlParser::Property *prop, QmlParser::Object *obj, int); + bool compileProperty(QmlParser::Property *prop, QmlParser::Object *obj, const BindingContext &); bool compileIdProperty(QmlParser::Property *prop, QmlParser::Object *obj); bool compileAttachedProperty(QmlParser::Property *prop, - int ctxt); + const BindingContext &ctxt); bool compileNestedProperty(QmlParser::Property *prop, - int ctxt); + const BindingContext &ctxt); bool compileListProperty(QmlParser::Property *prop, QmlParser::Object *obj, - int ctxt); + const BindingContext &ctxt); bool compilePropertyAssignment(QmlParser::Property *prop, QmlParser::Object *obj, - int ctxt); + const BindingContext &ctxt); bool compilePropertyObjectAssignment(QmlParser::Property *prop, QmlParser::Value *value, - int ctxt); + const BindingContext &ctxt); bool compilePropertyLiteralAssignment(QmlParser::Property *prop, QmlParser::Object *obj, QmlParser::Value *value, - int ctxt); + const BindingContext &ctxt); bool compileStoreInstruction(QmlInstruction &instr, const QMetaProperty &prop, QmlParser::Value *value); bool compileDynamicMeta(QmlParser::Object *obj); bool compileBinding(QmlParser::Value *, QmlParser::Property *prop, - int ctxt); + const BindingContext &ctxt); void finalizeComponent(int patch); struct BindingReference; @@ -169,6 +183,7 @@ private: QString id; QmlParser::Object *object; int instructionIdx; + int idx; }; struct BindingReference { @@ -176,17 +191,18 @@ private: QmlParser::Property *property; QmlParser::Value *value; int instructionIdx; - int bindingContext; + BindingContext bindingContext; }; struct ComponentCompileState { - ComponentCompileState() : parserStatusCount(0), savedObjects(0), pushedProperties(0) {} + ComponentCompileState() : parserStatusCount(0), savedObjects(0), pushedProperties(0), root(0) {} QHash<QString, IdReference> ids; int parserStatusCount; int savedObjects; int pushedProperties; QList<BindingReference> bindings; + QmlParser::Object *root; }; ComponentCompileState compileState; diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp index 73b9245..66781ce 100644 --- a/src/declarative/qml/qmlengine.cpp +++ b/src/declarative/qml/qmlengine.cpp @@ -219,30 +219,11 @@ QmlContext *QmlEnginePrivate::setCurrentBindContext(QmlContext *c) return old; } -QmlEnginePrivate::CapturedProperty::CapturedProperty(QObject *obj, int n) -: object(obj), notifyIndex(n) -{ -} - QmlEnginePrivate::CapturedProperty::CapturedProperty(const QmlMetaProperty &p) -: object(p.object()), name(p.name()), notifyIndex(p.property().notifySignalIndex()) -{ -} - -QmlEnginePrivate::CapturedProperty::CapturedProperty(const CapturedProperty &o) -: object(o.object), name(o.name), notifyIndex(o.notifyIndex) +: object(p.object()), notifyIndex(p.property().notifySignalIndex()) { } -QmlEnginePrivate::CapturedProperty & -QmlEnginePrivate::CapturedProperty::operator=(const CapturedProperty &o) -{ - object = o.object; - name = o.name; - notifyIndex = o.notifyIndex; - return *this; -} - //////////////////////////////////////////////////////////////////// typedef QHash<QPair<const QMetaObject *, QString>, bool> FunctionCache; Q_GLOBAL_STATIC(FunctionCache, functionCache); @@ -1224,8 +1205,9 @@ QVariant QmlExpression::value() QMetaObject::connect(prop.object, prop.notifyIndex, d->proxy, changedIndex); } else { - QString warn = QLatin1String("Expression depends on property without a NOTIFY signal: [") + QLatin1String(prop.object->metaObject()->className()) + QLatin1String("].") + prop.name; - log.addWarning(warn); + // ### FIXME + //QString warn = QLatin1String("Expression depends on property without a NOTIFY signal: [") + QLatin1String(prop.object->metaObject()->className()) + QLatin1String("].") + prop.name; + //log.addWarning(warn); } } d->addLog(log); @@ -1305,7 +1287,7 @@ void QmlExpression::setTrackChange(bool trackChange) Set the location of this expression to \a line of \a fileName. This information is used by the script engine. */ -void QmlExpression::setSourceLocation(const QString &fileName, int line) +void QmlExpression::setSourceLocation(const QUrl &fileName, int line) { d->fileName = fileName; d->line = line; diff --git a/src/declarative/qml/qmlengine_p.h b/src/declarative/qml/qmlengine_p.h index d7249e4..a1028e6 100644 --- a/src/declarative/qml/qmlengine_p.h +++ b/src/declarative/qml/qmlengine_p.h @@ -52,6 +52,7 @@ #include <private/qobject_p.h> #include <private/qmlclassfactory_p.h> #include <private/qmlcompositetypemanager_p.h> +#include <private/qpodvector_p.h> #include <QtDeclarative/qml.h> #include <private/qmlbasicscript_p.h> #include <QtDeclarative/qmlcontext.h> @@ -90,16 +91,14 @@ public: QScriptValue propertyObject(const QScriptString &propName, QObject *, uint id = 0); struct CapturedProperty { - CapturedProperty(QObject *, int); + CapturedProperty(QObject *o, int n) + : object(o), notifyIndex(n) {} CapturedProperty(const QmlMetaProperty &); - CapturedProperty(const CapturedProperty &); - CapturedProperty &operator=(const CapturedProperty &); QObject *object; - QString name; int notifyIndex; }; - QList<CapturedProperty> capturedProperties; + QPODVector<CapturedProperty> capturedProperties; QmlContext *rootContext; QmlContext *currentBindContext; @@ -280,7 +279,8 @@ public: BindExpressionProxy *proxy; QObject *me; bool trackChange; - QString fileName; + + QUrl fileName; int line; quint32 id; diff --git a/src/declarative/qml/qmlexpression.h b/src/declarative/qml/qmlexpression.h index 651fd9c..15d026a 100644 --- a/src/declarative/qml/qmlexpression.h +++ b/src/declarative/qml/qmlexpression.h @@ -77,7 +77,7 @@ public: bool trackChange() const; void setTrackChange(bool); - void setSourceLocation(const QString &fileName, int line); + void setSourceLocation(const QUrl &fileName, int line); QObject *scopeObject() const; diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp index f00d282..9ed7e95 100644 --- a/src/declarative/qml/qmlvme.cpp +++ b/src/declarative/qml/qmlvme.cpp @@ -695,7 +695,7 @@ case QmlInstruction::StoreDouble: QFx_setParent_noEvent(bind, target); bind->setTarget(mp); - bind->setSourceLocation(comp->url.toString(), instr.line); + bind->setSourceLocation(comp->url, instr.line); } break; @@ -719,7 +719,7 @@ case QmlInstruction::StoreDouble: QFx_setParent_noEvent(bind, target); bind->setTarget(mp); - bind->setSourceLocation(comp->url.toString(), instr.line); + bind->setSourceLocation(comp->url, instr.line); } break; diff --git a/src/declarative/qml/qpodvector_p.h b/src/declarative/qml/qpodvector_p.h new file mode 100644 index 0000000..55c04e7 --- /dev/null +++ b/src/declarative/qml/qpodvector_p.h @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QPODVECTOR_P_H +#define QPODVECTOR_P_H + +#include <QtCore/qglobal.h> + +QT_BEGIN_NAMESPACE + +template<class T> +class QPODVector +{ +public: + QPODVector() + : m_count(0), m_capacity(0), m_data(0) {} + + const T &at(int idx) { + return m_data[idx]; + } + + T &operator[](int idx) { + return m_data[idx]; + } + + void clear() { + m_count = 0; + } + + void prepend(const T &v) { + insert(0, v); + } + + void append(const T &v) { + insert(m_count, v); + } + + void insert(int idx, const T &v) { + if (m_count == m_capacity) { + m_capacity += 1024; + m_data = (T *)realloc(m_data, m_capacity * sizeof(T)); + } + int moveCount = m_count - idx; + if (moveCount) + ::memmove(m_data + idx + 1, m_data + idx, moveCount * sizeof(T)); + m_count++; + m_data[idx] = v; + } + + void insertBlank(int idx, int count) { + int newSize = m_count + count; + if (newSize >= m_capacity) { + m_capacity = (newSize + 1023) & 0xFFFFFC00; + m_data = (T *)realloc(m_data, m_capacity * sizeof(T)); + } + + int moveCount = m_count - idx; + if (moveCount) + ::memmove(m_data + idx + count, m_data + idx, + moveCount * sizeof(T)); + m_count = newSize; + } + + void remove(int idx, int count = 1) { + int moveCount = m_count - (idx + count); + if (moveCount) + ::memmove(m_data + idx, m_data + idx + count, + moveCount * sizeof(T)); + m_count -= count; + } + + int count() const { + return m_count; + } + + QPODVector<T> &operator<<(const T &v) { append(v); return *this; } +private: + QPODVector(const QPODVector &); + QPODVector &operator=(const QPODVector &); + int m_count; + int m_capacity; + T *m_data; +}; +QT_END_NAMESPACE + +#endif |