From a129444bb0156c936900dbd2f12bd9f427ff366c Mon Sep 17 00:00:00 2001 From: Qt by Nokia Date: Wed, 27 Apr 2011 14:13:26 +0200 Subject: Initial import from qtquick2. Branched from the monolithic repo, Qt qtquick2 branch, at commit a4a585d2ee907746682846ae6e8a48e19deef469 --- src/declarative/qml/qdeclarativecompiler.cpp | 149 +++++++++++++++------------ 1 file changed, 81 insertions(+), 68 deletions(-) (limited to 'src/declarative/qml/qdeclarativecompiler.cpp') diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index f57f842004..d325ac48dd 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -63,7 +63,7 @@ #include "private/qdeclarativeglobal_p.h" #include "private/qdeclarativescriptparser_p.h" #include "private/qdeclarativebinding_p.h" -#include "private/qdeclarativecompiledbindings_p.h" +#include "private/qdeclarativev4compiler_p.h" #include "private/qdeclarativeglobalscriptclass_p.h" #include @@ -79,7 +79,6 @@ QT_BEGIN_NAMESPACE DEFINE_BOOL_CONFIG_OPTION(compilerDump, QML_COMPILER_DUMP); DEFINE_BOOL_CONFIG_OPTION(compilerStatDump, QML_COMPILER_STATS); -DEFINE_BOOL_CONFIG_OPTION(bindingsDump, QML_BINDINGS_DUMP); using namespace QDeclarativeParser; @@ -201,6 +200,9 @@ bool QDeclarativeCompiler::testLiteralAssignment(const QMetaProperty &prop, case QVariant::String: if (!v->value.isString()) COMPILE_EXCEPTION(v, tr("Invalid property assignment: string expected")); break; + case QVariant::ByteArray: + if (!v->value.isString()) COMPILE_EXCEPTION(v, tr("Invalid property assignment: byte array expected")); + break; case QVariant::Url: if (!v->value.isString()) COMPILE_EXCEPTION(v, tr("Invalid property assignment: url expected")); break; @@ -320,16 +322,20 @@ bool QDeclarativeCompiler::testLiteralAssignment(const QMetaProperty &prop, void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, QDeclarativeParser::Value *v) { - QString string = v->value.asString(); - QDeclarativeInstruction instr; instr.line = v->location.start.line; if (prop.isEnumType()) { int value; - if (prop.isFlagType()) { - value = prop.enumerator().keysToValue(string.toUtf8().constData()); - } else - value = prop.enumerator().keyToValue(string.toUtf8().constData()); + if (v->value.isNumber()) { + // Preresolved enum + value = (int)v->value.asNumber(); + } else { + // Must be a string + if (prop.isFlagType()) { + value = prop.enumerator().keysToValue(v->value.asString().toUtf8().constData()); + } else + value = prop.enumerator().keyToValue(v->value.asString().toUtf8().constData()); + } instr.type = QDeclarativeInstruction::StoreInteger; instr.storeInteger.propertyIndex = prop.propertyIndex(); @@ -338,6 +344,8 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, return; } + QString string = v->value.asString(); + int type = prop.userType(); switch(type) { case -1: @@ -371,6 +379,13 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, instr.storeString.value = output->indexForString(string); } break; + case QVariant::ByteArray: + { + instr.type = QDeclarativeInstruction::StoreByteArray; + instr.storeByteArray.propertyIndex = prop.propertyIndex(); + instr.storeByteArray.value = output->indexForByteArray(string.toLatin1()); + } + break; case QVariant::Url: { instr.type = QDeclarativeInstruction::StoreUrl; @@ -642,6 +657,31 @@ void QDeclarativeCompiler::compileTree(QDeclarativeParser::Object *tree) compileState.root = tree; componentStat.lineNumber = tree->location.start.line; + // Build global import scripts + QStringList importedScriptIndexes; + + foreach (const QDeclarativeTypeData::ScriptReference &script, unit->resolvedScripts()) { + importedScriptIndexes.append(script.qualifier); + + QDeclarativeInstruction import; + import.type = QDeclarativeInstruction::StoreImportedScript; + import.line = 0; + import.storeScript.value = output->scripts.count(); + + QDeclarativeScriptData *scriptData = script.script->scriptData(); + scriptData->addref(); + output->scripts << scriptData; + output->bytecode << import; + } + + // We generate the importCache before we build the tree so that + // it can be used in the binding compiler. Given we "expect" the + // QML compilation to succeed, this isn't a waste. + output->importCache = new QDeclarativeTypeNameCache(engine); + for (int ii = 0; ii < importedScriptIndexes.count(); ++ii) + output->importCache->add(importedScriptIndexes.at(ii), ii); + unit->imports().populateCache(output->importCache, engine); + if (!buildObject(tree, BindingContext()) || !completeComponentBuild()) return; @@ -657,38 +697,6 @@ void QDeclarativeCompiler::compileTree(QDeclarativeParser::Object *tree) init.init.compiledBinding = output->indexForByteArray(compileState.compiledBindingData); output->bytecode << init; - // Build global import scripts - QHash importedScripts; - QStringList importedScriptIndexes; - - foreach (const QDeclarativeTypeData::ScriptReference &script, unit->resolvedScripts()) { - QString scriptCode = script.script->scriptSource(); - Object::ScriptBlock::Pragmas pragmas = script.script->pragmas(); - - Q_ASSERT(!importedScripts.contains(script.qualifier)); - - if (!scriptCode.isEmpty()) { - Object::ScriptBlock &scriptBlock = importedScripts[script.qualifier]; - - scriptBlock.code = scriptCode; - scriptBlock.file = script.script->finalUrl().toString(); - scriptBlock.pragmas = pragmas; - } - } - - for (QHash::Iterator iter = importedScripts.begin(); - iter != importedScripts.end(); ++iter) { - - importedScriptIndexes.append(iter.key()); - - QDeclarativeInstruction import; - import.type = QDeclarativeInstruction::StoreImportedScript; - import.line = 0; - import.storeScript.value = output->scripts.count(); - output->scripts << *iter; - output->bytecode << import; - } - genObject(tree); QDeclarativeInstruction def; @@ -696,13 +704,6 @@ void QDeclarativeCompiler::compileTree(QDeclarativeParser::Object *tree) def.type = QDeclarativeInstruction::SetDefault; output->bytecode << def; - output->importCache = new QDeclarativeTypeNameCache(engine); - - for (int ii = 0; ii < importedScriptIndexes.count(); ++ii) - output->importCache->add(importedScriptIndexes.at(ii), ii); - - unit->imports().populateCache(output->importCache, engine); - Q_ASSERT(tree->metatype); if (tree->metadata.isEmpty()) { @@ -1283,6 +1284,7 @@ bool QDeclarativeCompiler::buildComponentFromRoot(QDeclarativeParser::Object *ob compileState = ComponentCompileState(); compileState.root = obj; + compileState.nested = true; componentStat = ComponentStat(); componentStat.lineNumber = obj->location.start.line; @@ -1442,8 +1444,6 @@ bool QDeclarativeCompiler::buildProperty(QDeclarativeParser::Property *prop, unit->imports().resolveType(prop->name, &type, 0, 0, 0, &typeNamespace); if (typeNamespace) { - // ### We might need to indicate that this property is a namespace - // for the DOM API COMPILE_CHECK(buildPropertyInNamespace(typeNamespace, prop, obj, ctxt)); return true; @@ -2227,20 +2227,35 @@ bool QDeclarativeCompiler::testQualifiedEnumAssignment(const QMetaProperty &prop objTypeName = objType->qmlTypeName(); } - if (!type || objTypeName != type->qmlTypeName()) + if (!type) return true; QString enumValue = parts.at(1); - int value; - if (prop.isFlagType()) { - value = prop.enumerator().keysToValue(enumValue.toUtf8().constData()); - } else - value = prop.enumerator().keyToValue(enumValue.toUtf8().constData()); + int value = -1; + + if (objTypeName == type->qmlTypeName()) { + // When these two match, we can short cut the search + if (prop.isFlagType()) { + value = prop.enumerator().keysToValue(enumValue.toUtf8().constData()); + } else { + value = prop.enumerator().keyToValue(enumValue.toUtf8().constData()); + } + } else { + // Otherwise we have to search the whole type + // This matches the logic in QDeclarativeTypeNameScriptClass + QByteArray enumName = enumValue.toUtf8(); + const QMetaObject *metaObject = type->baseMetaObject(); + for (int ii = metaObject->enumeratorCount() - 1; value == -1 && ii >= 0; --ii) { + QMetaEnum e = metaObject->enumerator(ii); + value = e.keyToValue(enumName.constData()); + } + } + if (value == -1) return true; v->type = Value::Literal; - v->value = QDeclarativeParser::Variant(enumValue); + v->value = QDeclarativeParser::Variant((double)value); *isAssignment = true; return true; @@ -2412,7 +2427,7 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn newClassName.append("_QML_"); int idx = classIndexCounter()->fetchAndAddRelaxed(1); newClassName.append(QByteArray::number(idx)); - if (compileState.root == obj) { + if (compileState.root == obj && !compileState.nested) { QString path = output->url.path(); int lastSlash = path.lastIndexOf(QLatin1Char('/')); if (lastSlash > -1) { @@ -2888,25 +2903,26 @@ bool QDeclarativeCompiler::completeComponentBuild() COMPILE_CHECK(buildDynamicMeta(aliasObject, ResolveAliases)); } - QDeclarativeBindingCompiler::Expression expr; + QDeclarativeV4Compiler::Expression expr; expr.component = compileState.root; expr.ids = compileState.ids; + expr.importCache = output->importCache; + expr.imports = unit->imports(); - QDeclarativeBindingCompiler bindingCompiler; + QDeclarativeV4Compiler bindingCompiler; for (QHash::Iterator iter = compileState.bindings.begin(); iter != compileState.bindings.end(); ++iter) { BindingReference &binding = *iter; - expr.context = binding.bindingContext.object; - expr.property = binding.property; - expr.expression = binding.expression; - expr.imports = unit->imports(); - // ### We don't currently optimize for bindings on alias's - because // of the solution to QTBUG-13719 if (!binding.property->isAlias) { + expr.context = binding.bindingContext.object; + expr.property = binding.property; + expr.expression = binding.expression; + int index = bindingCompiler.compile(expr, enginePrivate); if (index != -1) { binding.dataType = BindingReference::Experimental; @@ -2947,11 +2963,8 @@ bool QDeclarativeCompiler::completeComponentBuild() componentStat.scriptBindings.append(iter.key()->location); } - if (bindingCompiler.isValid()) { + if (bindingCompiler.isValid()) compileState.compiledBindingData = bindingCompiler.program(); - if (bindingsDump()) - QDeclarativeBindingCompiler::dump(compileState.compiledBindingData); - } saveComponentState(); -- cgit v1.2.3 From cff3c25ee616a7aee7bf1c0f983a190415668f5f Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Thu, 5 May 2011 11:07:59 +1000 Subject: Only include line numbers when necessary The mandatory line number bloats QML instructions for no reason. Moving it inline actually increases the instruction size further, but that will come down again once variable sized instruction support is added. Change-Id: I0ace03a50371ef57946edbb7c8e0e8c2fa4fdd76 --- src/declarative/qml/qdeclarativecompiler.cpp | 48 ++++++++-------------------- 1 file changed, 14 insertions(+), 34 deletions(-) (limited to 'src/declarative/qml/qdeclarativecompiler.cpp') diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index d325ac48dd..13a5d8769b 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -323,7 +323,6 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, QDeclarativeParser::Value *v) { QDeclarativeInstruction instr; - instr.line = v->location.start.line; if (prop.isEnumType()) { int value; if (v->value.isNumber()) { @@ -539,6 +538,7 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, instr.type = QDeclarativeInstruction::AssignCustomType; instr.assignCustomType.propertyIndex = prop.propertyIndex(); instr.assignCustomType.valueIndex = index; + instr.assignCustomType.line = v->location.start.line; QDeclarativeCompiledData::CustomTypeData data; data.index = output->indexForString(string); @@ -665,7 +665,6 @@ void QDeclarativeCompiler::compileTree(QDeclarativeParser::Object *tree) QDeclarativeInstruction import; import.type = QDeclarativeInstruction::StoreImportedScript; - import.line = 0; import.storeScript.value = output->scripts.count(); QDeclarativeScriptData *scriptData = script.script->scriptData(); @@ -687,7 +686,6 @@ void QDeclarativeCompiler::compileTree(QDeclarativeParser::Object *tree) QDeclarativeInstruction init; init.type = QDeclarativeInstruction::Init; - init.line = 0; init.init.bindingsSize = compileState.bindings.count(); init.init.parserStatusSize = compileState.parserStatusCount; init.init.contextCache = genContextCache(); @@ -700,7 +698,6 @@ void QDeclarativeCompiler::compileTree(QDeclarativeParser::Object *tree) genObject(tree); QDeclarativeInstruction def; - init.line = 0; def.type = QDeclarativeInstruction::SetDefault; output->bytecode << def; @@ -911,10 +908,10 @@ void QDeclarativeCompiler::genObject(QDeclarativeParser::Object *obj) QDeclarativeInstruction create; create.type = QDeclarativeInstruction::CreateSimpleObject; - create.line = obj->location.start.line; create.createSimple.create = output->types.at(obj->type).type->createFunction(); create.createSimple.typeSize = output->types.at(obj->type).type->createSize(); create.createSimple.type = obj->type; + create.createSimple.line = obj->location.start.line; create.createSimple.column = obj->location.start.column; output->bytecode << create; @@ -922,7 +919,7 @@ void QDeclarativeCompiler::genObject(QDeclarativeParser::Object *obj) QDeclarativeInstruction create; create.type = QDeclarativeInstruction::CreateObject; - create.line = obj->location.start.line; + create.create.line = obj->location.start.line; create.create.column = obj->location.start.column; create.create.data = -1; if (!obj->custom.isEmpty()) @@ -944,7 +941,6 @@ void QDeclarativeCompiler::genObject(QDeclarativeParser::Object *obj) if (!obj->metadata.isEmpty()) { QDeclarativeInstruction meta; meta.type = QDeclarativeInstruction::StoreMetaObject; - meta.line = 0; meta.storeMeta.data = output->indexForByteArray(obj->metadata); meta.storeMeta.aliasData = output->indexForByteArray(obj->synthdata); meta.storeMeta.propertyCache = output->propertyCaches.count(); @@ -979,7 +975,6 @@ void QDeclarativeCompiler::genObject(QDeclarativeParser::Object *obj) if (!obj->id.isEmpty()) { QDeclarativeInstruction id; id.type = QDeclarativeInstruction::SetId; - id.line = 0; id.setId.value = output->indexForString(obj->id); id.setId.index = obj->idIndex; output->bytecode << id; @@ -990,7 +985,6 @@ void QDeclarativeCompiler::genObject(QDeclarativeParser::Object *obj) QDeclarativeInstruction begin; begin.type = QDeclarativeInstruction::BeginObject; begin.begin.castValue = obj->parserStatusCast; - begin.line = obj->location.start.line; output->bytecode << begin; } @@ -1022,7 +1016,6 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj) if (seenDefer) { QDeclarativeInstruction defer; defer.type = QDeclarativeInstruction::Defer; - defer.line = 0; defer.defer.deferCount = 0; int deferIdx = output->bytecode.count(); output->bytecode << defer; @@ -1055,7 +1048,7 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj) QDeclarativeInstruction assign; assign.type = QDeclarativeInstruction::AssignSignalObject; - assign.line = v->location.start.line; + assign.assignSignalObject.line = v->location.start.line; assign.assignSignalObject.signal = output->indexForByteArray(prop->name); output->bytecode << assign; @@ -1066,12 +1059,12 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj) QDeclarativeInstruction store; store.type = QDeclarativeInstruction::StoreSignal; - store.line = v->location.start.line; store.storeSignal.signalIndex = prop->index; store.storeSignal.value = output->indexForString(v->value.asScript().trimmed()); store.storeSignal.context = ctxt.stack; store.storeSignal.name = output->indexForByteArray(prop->name); + store.storeSignal.line = v->location.start.line; output->bytecode << store; } @@ -1081,15 +1074,14 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj) foreach(Property *prop, obj->attachedProperties) { QDeclarativeInstruction fetch; fetch.type = QDeclarativeInstruction::FetchAttached; - fetch.line = prop->location.start.line; fetch.fetchAttached.id = prop->index; + fetch.fetchAttached.line = prop->location.start.line; output->bytecode << fetch; genObjectBody(prop->value); QDeclarativeInstruction pop; pop.type = QDeclarativeInstruction::PopFetchedObject; - pop.line = prop->location.start.line; output->bytecode << pop; } @@ -1097,13 +1089,12 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj) QDeclarativeInstruction fetch; fetch.type = QDeclarativeInstruction::FetchObject; fetch.fetch.property = prop->index; - fetch.line = prop->location.start.line; + fetch.fetch.line = prop->location.start.line; output->bytecode << fetch; if (!prop->value->metadata.isEmpty()) { QDeclarativeInstruction meta; meta.type = QDeclarativeInstruction::StoreMetaObject; - meta.line = 0; meta.storeMeta.data = output->indexForByteArray(prop->value->metadata); meta.storeMeta.aliasData = output->indexForByteArray(prop->value->synthdata); meta.storeMeta.propertyCache = -1; @@ -1114,7 +1105,6 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj) QDeclarativeInstruction pop; pop.type = QDeclarativeInstruction::PopFetchedObject; - pop.line = prop->location.start.line; output->bytecode << pop; } @@ -1143,7 +1133,6 @@ void QDeclarativeCompiler::genValueTypeProperty(QDeclarativeParser::Object *obj, fetch.fetchValue.property = prop->index; fetch.fetchValue.type = prop->type; fetch.fetchValue.bindingSkipList = 0; - fetch.line = prop->location.start.line; if (obj->type == -1 || output->types.at(obj->type).component) { // We only have to do this if this is a composite type. If it is a builtin @@ -1167,7 +1156,6 @@ void QDeclarativeCompiler::genValueTypeProperty(QDeclarativeParser::Object *obj, pop.fetchValue.property = prop->index; pop.fetchValue.type = prop->type; pop.fetchValue.bindingSkipList = 0; - pop.line = prop->location.start.line; output->bytecode << pop; } @@ -1178,7 +1166,7 @@ void QDeclarativeCompiler::genComponent(QDeclarativeParser::Object *obj) QDeclarativeInstruction create; create.type = QDeclarativeInstruction::CreateComponent; - create.line = root->location.start.line; + create.createComponent.line = root->location.start.line; create.createComponent.column = root->location.start.column; create.createComponent.endLine = root->location.end.line; output->bytecode << create; @@ -1196,13 +1184,11 @@ void QDeclarativeCompiler::genComponent(QDeclarativeParser::Object *obj) init.init.compiledBinding = -1; else init.init.compiledBinding = output->indexForByteArray(compileState.compiledBindingData); - init.line = obj->location.start.line; output->bytecode << init; genObject(root); QDeclarativeInstruction def; - init.line = 0; def.type = QDeclarativeInstruction::SetDefault; output->bytecode << def; @@ -1214,7 +1200,6 @@ void QDeclarativeCompiler::genComponent(QDeclarativeParser::Object *obj) if (!obj->id.isEmpty()) { QDeclarativeInstruction id; id.type = QDeclarativeInstruction::SetId; - id.line = 0; id.setId.value = output->indexForString(obj->id); id.setId.index = obj->idIndex; output->bytecode << id; @@ -1608,7 +1593,6 @@ void QDeclarativeCompiler::genListProperty(QDeclarativeParser::Property *prop, QDeclarativeInstruction fetch; fetch.type = QDeclarativeInstruction::FetchQList; - fetch.line = prop->location.start.line; fetch.fetchQmlList.property = prop->index; bool listTypeIsInterface = QDeclarativeMetaType::isInterface(listType); fetch.fetchQmlList.type = listType; @@ -1623,12 +1607,11 @@ void QDeclarativeCompiler::genListProperty(QDeclarativeParser::Property *prop, if (listTypeIsInterface) { QDeclarativeInstruction assign; assign.type = QDeclarativeInstruction::AssignObjectList; - assign.line = prop->location.start.line; + assign.assignObjectList.line = prop->location.start.line; output->bytecode << assign; } else { QDeclarativeInstruction store; store.type = QDeclarativeInstruction::StoreObjectQList; - store.line = prop->location.start.line; output->bytecode << store; } @@ -1642,7 +1625,6 @@ void QDeclarativeCompiler::genListProperty(QDeclarativeParser::Property *prop, QDeclarativeInstruction pop; pop.type = QDeclarativeInstruction::PopQList; - pop.line = prop->location.start.line; output->bytecode << pop; } @@ -1665,7 +1647,7 @@ void QDeclarativeCompiler::genPropertyAssignment(QDeclarativeParser::Property *p QDeclarativeInstruction store; store.type = QDeclarativeInstruction::StoreInterface; - store.line = v->object->location.start.line; + store.storeObject.line = v->object->location.start.line; store.storeObject.propertyIndex = prop->index; output->bytecode << store; @@ -1673,7 +1655,7 @@ void QDeclarativeCompiler::genPropertyAssignment(QDeclarativeParser::Property *p QDeclarativeInstruction store; store.type = QDeclarativeInstruction::StoreVariantObject; - store.line = v->object->location.start.line; + store.storeObject.line = v->object->location.start.line; store.storeObject.propertyIndex = prop->index; output->bytecode << store; @@ -1681,7 +1663,7 @@ void QDeclarativeCompiler::genPropertyAssignment(QDeclarativeParser::Property *p QDeclarativeInstruction store; store.type = QDeclarativeInstruction::StoreObject; - store.line = v->object->location.start.line; + store.storeObject.line = v->object->location.start.line; store.storeObject.propertyIndex = prop->index; output->bytecode << store; @@ -1711,7 +1693,6 @@ void QDeclarativeCompiler::genPropertyAssignment(QDeclarativeParser::Property *p QDeclarativeInstruction store; store.type = QDeclarativeInstruction::StoreValueSource; - store.line = v->object->location.start.line; if (valueTypeProperty) { store.assignValueSource.property = genValueTypeData(prop, valueTypeProperty); store.assignValueSource.owner = 1; @@ -1728,7 +1709,6 @@ void QDeclarativeCompiler::genPropertyAssignment(QDeclarativeParser::Property *p QDeclarativeInstruction store; store.type = QDeclarativeInstruction::StoreValueInterceptor; - store.line = v->object->location.start.line; if (valueTypeProperty) { store.assignValueInterceptor.property = genValueTypeData(prop, valueTypeProperty); store.assignValueInterceptor.owner = 1; @@ -2835,7 +2815,7 @@ void QDeclarativeCompiler::genBindingAssignment(QDeclarativeParser::Value *bindi ((prop->index & 0xFF) << 24); else store.assignBinding.property = prop->index; - store.line = binding->location.start.line; + store.assignBinding.line = binding->location.start.line; output->bytecode << store; return; } @@ -2848,7 +2828,7 @@ void QDeclarativeCompiler::genBindingAssignment(QDeclarativeParser::Value *bindi store.assignBinding.value = output->indexForByteArray(ref.compiledData); store.assignBinding.context = ref.bindingContext.stack; store.assignBinding.owner = ref.bindingContext.owner; - store.line = binding->location.start.line; + store.assignBinding.line = binding->location.start.line; Q_ASSERT(ref.bindingContext.owner == 0 || (ref.bindingContext.owner != 0 && valueTypeProperty)); -- cgit v1.2.3 From cb661b8fd32b20b4a90b13fa49e2a21f41b2e87d Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Thu, 5 May 2011 13:48:29 +1000 Subject: Support variable length instructions in QML bytecode Reviewed-by: Martin Jones Change-Id: Ib04b8d46a78723d3a734e14d22a2f2256c1627c2 --- src/declarative/qml/qdeclarativecompiler.cpp | 219 ++++++++++++++------------- 1 file changed, 115 insertions(+), 104 deletions(-) (limited to 'src/declarative/qml/qdeclarativecompiler.cpp') diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index 13a5d8769b..d8aa938943 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -336,10 +336,10 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, value = prop.enumerator().keyToValue(v->value.asString().toUtf8().constData()); } - instr.type = QDeclarativeInstruction::StoreInteger; + instr.setType(QDeclarativeInstruction::StoreInteger); instr.storeInteger.propertyIndex = prop.propertyIndex(); instr.storeInteger.value = value; - output->bytecode << instr; + output->addInstruction(instr); return; } @@ -352,20 +352,20 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, if (v->value.isNumber()) { double n = v->value.asNumber(); if (double(int(n)) == n) { - instr.type = QDeclarativeInstruction::StoreVariantInteger; + instr.setType(QDeclarativeInstruction::StoreVariantInteger); instr.storeInteger.propertyIndex = prop.propertyIndex(); instr.storeInteger.value = int(n); } else { - instr.type = QDeclarativeInstruction::StoreVariantDouble; + instr.setType(QDeclarativeInstruction::StoreVariantDouble); instr.storeDouble.propertyIndex = prop.propertyIndex(); instr.storeDouble.value = n; } } else if(v->value.isBoolean()) { - instr.type = QDeclarativeInstruction::StoreVariantBool; + instr.setType(QDeclarativeInstruction::StoreVariantBool); instr.storeBool.propertyIndex = prop.propertyIndex(); instr.storeBool.value = v->value.asBoolean(); } else { - instr.type = QDeclarativeInstruction::StoreVariant; + instr.setType(QDeclarativeInstruction::StoreVariant); instr.storeString.propertyIndex = prop.propertyIndex(); instr.storeString.value = output->indexForString(string); } @@ -373,21 +373,21 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, break; case QVariant::String: { - instr.type = QDeclarativeInstruction::StoreString; + instr.setType(QDeclarativeInstruction::StoreString); instr.storeString.propertyIndex = prop.propertyIndex(); instr.storeString.value = output->indexForString(string); } break; case QVariant::ByteArray: { - instr.type = QDeclarativeInstruction::StoreByteArray; + instr.setType(QDeclarativeInstruction::StoreByteArray); instr.storeByteArray.propertyIndex = prop.propertyIndex(); instr.storeByteArray.value = output->indexForByteArray(string.toLatin1()); } break; case QVariant::Url: { - instr.type = QDeclarativeInstruction::StoreUrl; + instr.setType(QDeclarativeInstruction::StoreUrl); QUrl u = string.isEmpty() ? QUrl() : output->url.resolved(QUrl(string)); instr.storeUrl.propertyIndex = prop.propertyIndex(); instr.storeUrl.value = output->indexForUrl(u); @@ -395,28 +395,28 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, break; case QVariant::UInt: { - instr.type = QDeclarativeInstruction::StoreInteger; + instr.setType(QDeclarativeInstruction::StoreInteger); instr.storeInteger.propertyIndex = prop.propertyIndex(); instr.storeInteger.value = uint(v->value.asNumber()); } break; case QVariant::Int: { - instr.type = QDeclarativeInstruction::StoreInteger; + instr.setType(QDeclarativeInstruction::StoreInteger); instr.storeInteger.propertyIndex = prop.propertyIndex(); instr.storeInteger.value = int(v->value.asNumber()); } break; case QMetaType::Float: { - instr.type = QDeclarativeInstruction::StoreFloat; + instr.setType(QDeclarativeInstruction::StoreFloat); instr.storeFloat.propertyIndex = prop.propertyIndex(); instr.storeFloat.value = float(v->value.asNumber()); } break; case QVariant::Double: { - instr.type = QDeclarativeInstruction::StoreDouble; + instr.setType(QDeclarativeInstruction::StoreDouble); instr.storeDouble.propertyIndex = prop.propertyIndex(); instr.storeDouble.value = v->value.asNumber(); } @@ -424,7 +424,7 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, case QVariant::Color: { QColor c = QDeclarativeStringConverters::colorFromString(string); - instr.type = QDeclarativeInstruction::StoreColor; + instr.setType(QDeclarativeInstruction::StoreColor); instr.storeColor.propertyIndex = prop.propertyIndex(); instr.storeColor.value = c.rgba(); } @@ -433,7 +433,7 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, case QVariant::Date: { QDate d = QDeclarativeStringConverters::dateFromString(string); - instr.type = QDeclarativeInstruction::StoreDate; + instr.setType(QDeclarativeInstruction::StoreDate); instr.storeDate.propertyIndex = prop.propertyIndex(); instr.storeDate.value = d.toJulianDay(); } @@ -444,7 +444,7 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, int data[] = { time.hour(), time.minute(), time.second(), time.msec() }; int index = output->indexForInt(data, 4); - instr.type = QDeclarativeInstruction::StoreTime; + instr.setType(QDeclarativeInstruction::StoreTime); instr.storeTime.propertyIndex = prop.propertyIndex(); instr.storeTime.valueIndex = index; } @@ -458,7 +458,7 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, dateTime.time().second(), dateTime.time().msec() }; int index = output->indexForInt(data, 5); - instr.type = QDeclarativeInstruction::StoreDateTime; + instr.setType(QDeclarativeInstruction::StoreDateTime); instr.storeDateTime.propertyIndex = prop.propertyIndex(); instr.storeDateTime.valueIndex = index; } @@ -473,9 +473,9 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, float data[] = { float(point.x()), float(point.y()) }; int index = output->indexForFloat(data, 2); if (type == QVariant::PointF) - instr.type = QDeclarativeInstruction::StorePointF; + instr.setType(QDeclarativeInstruction::StorePointF); else - instr.type = QDeclarativeInstruction::StorePoint; + instr.setType(QDeclarativeInstruction::StorePoint); instr.storeRealPair.propertyIndex = prop.propertyIndex(); instr.storeRealPair.valueIndex = index; } @@ -488,9 +488,9 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, float data[] = { float(size.width()), float(size.height()) }; int index = output->indexForFloat(data, 2); if (type == QVariant::SizeF) - instr.type = QDeclarativeInstruction::StoreSizeF; + instr.setType(QDeclarativeInstruction::StoreSizeF); else - instr.type = QDeclarativeInstruction::StoreSize; + instr.setType(QDeclarativeInstruction::StoreSize); instr.storeRealPair.propertyIndex = prop.propertyIndex(); instr.storeRealPair.valueIndex = index; } @@ -504,9 +504,9 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, float(rect.width()), float(rect.height()) }; int index = output->indexForFloat(data, 4); if (type == QVariant::RectF) - instr.type = QDeclarativeInstruction::StoreRectF; + instr.setType(QDeclarativeInstruction::StoreRectF); else - instr.type = QDeclarativeInstruction::StoreRect; + instr.setType(QDeclarativeInstruction::StoreRect); instr.storeRect.propertyIndex = prop.propertyIndex(); instr.storeRect.valueIndex = index; } @@ -514,7 +514,7 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, case QVariant::Bool: { bool b = v->value.asBoolean(); - instr.type = QDeclarativeInstruction::StoreBool; + instr.setType(QDeclarativeInstruction::StoreBool); instr.storeBool.propertyIndex = prop.propertyIndex(); instr.storeBool.value = b; } @@ -526,7 +526,7 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, QDeclarativeStringConverters::vector3DFromString(string, &ok); float data[] = { float(vector.x()), float(vector.y()), float(vector.z()) }; int index = output->indexForFloat(data, 3); - instr.type = QDeclarativeInstruction::StoreVector3D; + instr.setType(QDeclarativeInstruction::StoreVector3D); instr.storeRealPair.propertyIndex = prop.propertyIndex(); instr.storeRealPair.valueIndex = index; } @@ -535,7 +535,7 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, { int t = prop.userType(); int index = output->customTypeData.count(); - instr.type = QDeclarativeInstruction::AssignCustomType; + instr.setType(QDeclarativeInstruction::AssignCustomType); instr.assignCustomType.propertyIndex = prop.propertyIndex(); instr.assignCustomType.valueIndex = index; instr.assignCustomType.line = v->location.start.line; @@ -547,7 +547,7 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, } break; } - output->bytecode << instr; + output->addInstruction(instr); } /*! @@ -664,13 +664,13 @@ void QDeclarativeCompiler::compileTree(QDeclarativeParser::Object *tree) importedScriptIndexes.append(script.qualifier); QDeclarativeInstruction import; - import.type = QDeclarativeInstruction::StoreImportedScript; + import.setType(QDeclarativeInstruction::StoreImportedScript); import.storeScript.value = output->scripts.count(); QDeclarativeScriptData *scriptData = script.script->scriptData(); scriptData->addref(); output->scripts << scriptData; - output->bytecode << import; + output->addInstruction(import); } // We generate the importCache before we build the tree so that @@ -685,7 +685,7 @@ void QDeclarativeCompiler::compileTree(QDeclarativeParser::Object *tree) return; QDeclarativeInstruction init; - init.type = QDeclarativeInstruction::Init; + init.setType(QDeclarativeInstruction::Init); init.init.bindingsSize = compileState.bindings.count(); init.init.parserStatusSize = compileState.parserStatusCount; init.init.contextCache = genContextCache(); @@ -693,13 +693,17 @@ void QDeclarativeCompiler::compileTree(QDeclarativeParser::Object *tree) init.init.compiledBinding = -1; else init.init.compiledBinding = output->indexForByteArray(compileState.compiledBindingData); - output->bytecode << init; + output->addInstruction(init); genObject(tree); QDeclarativeInstruction def; - def.type = QDeclarativeInstruction::SetDefault; - output->bytecode << def; + def.setType(QDeclarativeInstruction::SetDefault); + output->addInstruction(def); + + QDeclarativeInstruction done; + done.setType(QDeclarativeInstruction::Done); + output->addInstruction(done); Q_ASSERT(tree->metatype); @@ -907,18 +911,18 @@ void QDeclarativeCompiler::genObject(QDeclarativeParser::Object *obj) !output->types.at(obj->type).type->isExtendedType() && obj != compileState.root) { QDeclarativeInstruction create; - create.type = QDeclarativeInstruction::CreateSimpleObject; + create.setType(QDeclarativeInstruction::CreateSimpleObject); create.createSimple.create = output->types.at(obj->type).type->createFunction(); create.createSimple.typeSize = output->types.at(obj->type).type->createSize(); create.createSimple.type = obj->type; create.createSimple.line = obj->location.start.line; create.createSimple.column = obj->location.start.column; - output->bytecode << create; + output->addInstruction(create); } else { QDeclarativeInstruction create; - create.type = QDeclarativeInstruction::CreateObject; + create.setType(QDeclarativeInstruction::CreateObject); create.create.line = obj->location.start.line; create.create.column = obj->location.start.column; create.create.data = -1; @@ -933,14 +937,14 @@ void QDeclarativeCompiler::genObject(QDeclarativeParser::Object *obj) } else { create.create.bindingBits = -1; } - output->bytecode << create; + output->addInstruction(create); } // Setup the synthesized meta object if necessary if (!obj->metadata.isEmpty()) { QDeclarativeInstruction meta; - meta.type = QDeclarativeInstruction::StoreMetaObject; + meta.setType(QDeclarativeInstruction::StoreMetaObject); meta.storeMeta.data = output->indexForByteArray(obj->metadata); meta.storeMeta.aliasData = output->indexForByteArray(obj->synthdata); meta.storeMeta.propertyCache = output->propertyCaches.count(); @@ -965,7 +969,7 @@ void QDeclarativeCompiler::genObject(QDeclarativeParser::Object *obj) } output->propertyCaches << propertyCache; - output->bytecode << meta; + output->addInstruction(meta); } else if (obj == unitRoot) { output->rootPropertyCache = tr.createPropertyCache(engine); output->rootPropertyCache->addref(); @@ -974,18 +978,18 @@ void QDeclarativeCompiler::genObject(QDeclarativeParser::Object *obj) // Set the object id if (!obj->id.isEmpty()) { QDeclarativeInstruction id; - id.type = QDeclarativeInstruction::SetId; + id.setType(QDeclarativeInstruction::SetId); id.setId.value = output->indexForString(obj->id); id.setId.index = obj->idIndex; - output->bytecode << id; + output->addInstruction(id); } // Begin the class if (tr.type && obj->parserStatusCast != -1) { QDeclarativeInstruction begin; - begin.type = QDeclarativeInstruction::BeginObject; + begin.setType(QDeclarativeInstruction::BeginObject); begin.begin.castValue = obj->parserStatusCast; - output->bytecode << begin; + output->addInstruction(begin); } genObjectBody(obj); @@ -996,12 +1000,12 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj) typedef QPair PropPair; foreach(const PropPair &prop, obj->scriptStringProperties) { QDeclarativeInstruction ss; - ss.type = QDeclarativeInstruction::StoreScriptString; + ss.setType(QDeclarativeInstruction::StoreScriptString); ss.storeScriptString.propertyIndex = prop.first->index; ss.storeScriptString.value = output->indexForString(prop.first->values.at(0)->value.asScript()); ss.storeScriptString.scope = prop.second; - output->bytecode << ss; + output->addInstruction(ss); } bool seenDefer = false; @@ -1015,18 +1019,18 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj) } if (seenDefer) { QDeclarativeInstruction defer; - defer.type = QDeclarativeInstruction::Defer; + defer.setType(QDeclarativeInstruction::Defer); defer.defer.deferCount = 0; - int deferIdx = output->bytecode.count(); - output->bytecode << defer; + int deferIdx = output->addInstruction(defer); + int nextInstructionIndex = output->nextInstructionIndex(); QDeclarativeInstruction init; - init.type = QDeclarativeInstruction::Init; + init.setType(QDeclarativeInstruction::Init); init.init.bindingsSize = compileState.bindings.count(); // XXX - bigger than necessary init.init.parserStatusSize = compileState.parserStatusCount; // XXX - bigger than necessary init.init.contextCache = -1; init.init.compiledBinding = -1; - output->bytecode << init; + output->addInstruction(init); foreach(Property *prop, obj->valueProperties) { if (!prop->isDeferred) @@ -1034,8 +1038,11 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj) genValueProperty(prop, obj); } - output->bytecode[deferIdx].defer.deferCount = - output->bytecode.count() - deferIdx - 1; + QDeclarativeInstruction done; + done.setType(QDeclarativeInstruction::Done); + output->addInstruction(done); + + output->instruction(deferIdx)->defer.deferCount = output->nextInstructionIndex() - nextInstructionIndex; } foreach(Property *prop, obj->signalProperties) { @@ -1047,25 +1054,25 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj) genObject(v->object); QDeclarativeInstruction assign; - assign.type = QDeclarativeInstruction::AssignSignalObject; + assign.setType(QDeclarativeInstruction::AssignSignalObject); assign.assignSignalObject.line = v->location.start.line; assign.assignSignalObject.signal = output->indexForByteArray(prop->name); - output->bytecode << assign; + output->addInstruction(assign); } else if (v->type == Value::SignalExpression) { BindingContext ctxt = compileState.signalExpressions.value(v); QDeclarativeInstruction store; - store.type = QDeclarativeInstruction::StoreSignal; + store.setType(QDeclarativeInstruction::StoreSignal); store.storeSignal.signalIndex = prop->index; store.storeSignal.value = output->indexForString(v->value.asScript().trimmed()); store.storeSignal.context = ctxt.stack; store.storeSignal.name = output->indexForByteArray(prop->name); store.storeSignal.line = v->location.start.line; - output->bytecode << store; + output->addInstruction(store); } @@ -1073,39 +1080,39 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj) foreach(Property *prop, obj->attachedProperties) { QDeclarativeInstruction fetch; - fetch.type = QDeclarativeInstruction::FetchAttached; + fetch.setType(QDeclarativeInstruction::FetchAttached); fetch.fetchAttached.id = prop->index; fetch.fetchAttached.line = prop->location.start.line; - output->bytecode << fetch; + output->addInstruction(fetch); genObjectBody(prop->value); QDeclarativeInstruction pop; - pop.type = QDeclarativeInstruction::PopFetchedObject; - output->bytecode << pop; + pop.setType(QDeclarativeInstruction::PopFetchedObject); + output->addInstruction(pop); } foreach(Property *prop, obj->groupedProperties) { QDeclarativeInstruction fetch; - fetch.type = QDeclarativeInstruction::FetchObject; + fetch.setType(QDeclarativeInstruction::FetchObject); fetch.fetch.property = prop->index; fetch.fetch.line = prop->location.start.line; - output->bytecode << fetch; + output->addInstruction(fetch); if (!prop->value->metadata.isEmpty()) { QDeclarativeInstruction meta; - meta.type = QDeclarativeInstruction::StoreMetaObject; + meta.setType(QDeclarativeInstruction::StoreMetaObject); meta.storeMeta.data = output->indexForByteArray(prop->value->metadata); meta.storeMeta.aliasData = output->indexForByteArray(prop->value->synthdata); meta.storeMeta.propertyCache = -1; - output->bytecode << meta; + output->addInstruction(meta); } genObjectBody(prop->value); QDeclarativeInstruction pop; - pop.type = QDeclarativeInstruction::PopFetchedObject; - output->bytecode << pop; + pop.setType(QDeclarativeInstruction::PopFetchedObject); + output->addInstruction(pop); } foreach(Property *prop, obj->valueTypeProperties) { @@ -1129,7 +1136,7 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj) void QDeclarativeCompiler::genValueTypeProperty(QDeclarativeParser::Object *obj,QDeclarativeParser::Property *prop) { QDeclarativeInstruction fetch; - fetch.type = QDeclarativeInstruction::FetchValueType; + fetch.setType(QDeclarativeInstruction::FetchValueType); fetch.fetchValue.property = prop->index; fetch.fetchValue.type = prop->type; fetch.fetchValue.bindingSkipList = 0; @@ -1145,18 +1152,18 @@ void QDeclarativeCompiler::genValueTypeProperty(QDeclarativeParser::Object *obj, } } - output->bytecode << fetch; + output->addInstruction(fetch); foreach(Property *vprop, prop->value->valueProperties) { genPropertyAssignment(vprop, prop->value, prop); } QDeclarativeInstruction pop; - pop.type = QDeclarativeInstruction::PopValueType; + pop.setType(QDeclarativeInstruction::PopValueType); pop.fetchValue.property = prop->index; pop.fetchValue.type = prop->type; pop.fetchValue.bindingSkipList = 0; - output->bytecode << pop; + output->addInstruction(pop); } void QDeclarativeCompiler::genComponent(QDeclarativeParser::Object *obj) @@ -1165,18 +1172,18 @@ void QDeclarativeCompiler::genComponent(QDeclarativeParser::Object *obj) Q_ASSERT(root); QDeclarativeInstruction create; - create.type = QDeclarativeInstruction::CreateComponent; + create.setType(QDeclarativeInstruction::CreateComponent); create.createComponent.line = root->location.start.line; create.createComponent.column = root->location.start.column; create.createComponent.endLine = root->location.end.line; - output->bytecode << create; - int count = output->bytecode.count(); + int createInstruction = output->addInstruction(create); + int nextInstructionIndex = output->nextInstructionIndex(); ComponentCompileState oldCompileState = compileState; compileState = componentState(root); QDeclarativeInstruction init; - init.type = QDeclarativeInstruction::Init; + init.setType(QDeclarativeInstruction::Init); init.init.bindingsSize = compileState.bindings.count(); init.init.parserStatusSize = compileState.parserStatusCount; init.init.contextCache = genContextCache(); @@ -1184,25 +1191,29 @@ void QDeclarativeCompiler::genComponent(QDeclarativeParser::Object *obj) init.init.compiledBinding = -1; else init.init.compiledBinding = output->indexForByteArray(compileState.compiledBindingData); - output->bytecode << init; + output->addInstruction(init); genObject(root); QDeclarativeInstruction def; - def.type = QDeclarativeInstruction::SetDefault; - output->bytecode << def; + def.setType(QDeclarativeInstruction::SetDefault); + output->addInstruction(def); + + QDeclarativeInstruction done; + done.setType(QDeclarativeInstruction::Done); + output->addInstruction(done); - output->bytecode[count - 1].createComponent.count = - output->bytecode.count() - count; + output->instruction(createInstruction)->createComponent.count = + output->nextInstructionIndex() - nextInstructionIndex; compileState = oldCompileState; if (!obj->id.isEmpty()) { QDeclarativeInstruction id; - id.type = QDeclarativeInstruction::SetId; + id.setType(QDeclarativeInstruction::SetId); id.setId.value = output->indexForString(obj->id); id.setId.index = obj->idIndex; - output->bytecode << id; + output->addInstruction(id); } } @@ -1592,11 +1603,11 @@ void QDeclarativeCompiler::genListProperty(QDeclarativeParser::Property *prop, int listType = enginePrivate->listType(prop->type); QDeclarativeInstruction fetch; - fetch.type = QDeclarativeInstruction::FetchQList; + fetch.setType(QDeclarativeInstruction::FetchQList); fetch.fetchQmlList.property = prop->index; bool listTypeIsInterface = QDeclarativeMetaType::isInterface(listType); fetch.fetchQmlList.type = listType; - output->bytecode << fetch; + output->addInstruction(fetch); for (int ii = 0; ii < prop->values.count(); ++ii) { QDeclarativeParser::Value *v = prop->values.at(ii); @@ -1606,13 +1617,13 @@ void QDeclarativeCompiler::genListProperty(QDeclarativeParser::Property *prop, genObject(v->object); if (listTypeIsInterface) { QDeclarativeInstruction assign; - assign.type = QDeclarativeInstruction::AssignObjectList; + assign.setType(QDeclarativeInstruction::AssignObjectList); assign.assignObjectList.line = prop->location.start.line; - output->bytecode << assign; + output->addInstruction(assign); } else { QDeclarativeInstruction store; - store.type = QDeclarativeInstruction::StoreObjectQList; - output->bytecode << store; + store.setType(QDeclarativeInstruction::StoreObjectQList); + output->addInstruction(store); } } else if (v->type == Value::PropertyBinding) { @@ -1624,8 +1635,8 @@ void QDeclarativeCompiler::genListProperty(QDeclarativeParser::Property *prop, } QDeclarativeInstruction pop; - pop.type = QDeclarativeInstruction::PopQList; - output->bytecode << pop; + pop.setType(QDeclarativeInstruction::PopQList); + output->addInstruction(pop); } void QDeclarativeCompiler::genPropertyAssignment(QDeclarativeParser::Property *prop, @@ -1646,26 +1657,26 @@ void QDeclarativeCompiler::genPropertyAssignment(QDeclarativeParser::Property *p if (QDeclarativeMetaType::isInterface(prop->type)) { QDeclarativeInstruction store; - store.type = QDeclarativeInstruction::StoreInterface; + store.setType(QDeclarativeInstruction::StoreInterface); store.storeObject.line = v->object->location.start.line; store.storeObject.propertyIndex = prop->index; - output->bytecode << store; + output->addInstruction(store); } else if (prop->type == -1) { QDeclarativeInstruction store; - store.type = QDeclarativeInstruction::StoreVariantObject; + store.setType(QDeclarativeInstruction::StoreVariantObject); store.storeObject.line = v->object->location.start.line; store.storeObject.propertyIndex = prop->index; - output->bytecode << store; + output->addInstruction(store); } else { QDeclarativeInstruction store; - store.type = QDeclarativeInstruction::StoreObject; + store.setType(QDeclarativeInstruction::StoreObject); store.storeObject.line = v->object->location.start.line; store.storeObject.propertyIndex = prop->index; - output->bytecode << store; + output->addInstruction(store); } } else if (v->type == Value::PropertyBinding) { @@ -1692,7 +1703,7 @@ void QDeclarativeCompiler::genPropertyAssignment(QDeclarativeParser::Property *p genObject(v->object); QDeclarativeInstruction store; - store.type = QDeclarativeInstruction::StoreValueSource; + store.setType(QDeclarativeInstruction::StoreValueSource); if (valueTypeProperty) { store.assignValueSource.property = genValueTypeData(prop, valueTypeProperty); store.assignValueSource.owner = 1; @@ -1702,13 +1713,13 @@ void QDeclarativeCompiler::genPropertyAssignment(QDeclarativeParser::Property *p } QDeclarativeType *valueType = toQmlType(v->object); store.assignValueSource.castValue = valueType->propertyValueSourceCast(); - output->bytecode << store; + output->addInstruction(store); } else if (v->type == Value::ValueInterceptor) { genObject(v->object); QDeclarativeInstruction store; - store.type = QDeclarativeInstruction::StoreValueInterceptor; + store.setType(QDeclarativeInstruction::StoreValueInterceptor); if (valueTypeProperty) { store.assignValueInterceptor.property = genValueTypeData(prop, valueTypeProperty); store.assignValueInterceptor.owner = 1; @@ -1718,7 +1729,7 @@ void QDeclarativeCompiler::genPropertyAssignment(QDeclarativeParser::Property *p } QDeclarativeType *valueType = toQmlType(v->object); store.assignValueInterceptor.castValue = valueType->propertyValueInterceptorCast(); - output->bytecode << store; + output->addInstruction(store); } } @@ -2805,7 +2816,7 @@ void QDeclarativeCompiler::genBindingAssignment(QDeclarativeParser::Value *bindi const BindingReference &ref = compileState.bindings.value(binding); if (ref.dataType == BindingReference::Experimental) { QDeclarativeInstruction store; - store.type = QDeclarativeInstruction::StoreCompiledBinding; + store.setType(QDeclarativeInstruction::StoreCompiledBinding); store.assignBinding.value = ref.compiledIndex; store.assignBinding.context = ref.bindingContext.stack; store.assignBinding.owner = ref.bindingContext.owner; @@ -2816,15 +2827,15 @@ void QDeclarativeCompiler::genBindingAssignment(QDeclarativeParser::Value *bindi else store.assignBinding.property = prop->index; store.assignBinding.line = binding->location.start.line; - output->bytecode << store; + output->addInstruction(store); return; } QDeclarativeInstruction store; if (!prop->isAlias) - store.type = QDeclarativeInstruction::StoreBinding; + store.setType(QDeclarativeInstruction::StoreBinding); else - store.type = QDeclarativeInstruction::StoreBindingOnAlias; + store.setType(QDeclarativeInstruction::StoreBindingOnAlias); store.assignBinding.value = output->indexForByteArray(ref.compiledData); store.assignBinding.context = ref.bindingContext.stack; store.assignBinding.owner = ref.bindingContext.owner; @@ -2838,7 +2849,7 @@ void QDeclarativeCompiler::genBindingAssignment(QDeclarativeParser::Value *bindi store.assignBinding.property = genPropertyData(prop); } - output->bytecode << store; + output->addInstruction(store); } int QDeclarativeCompiler::genContextCache() -- cgit v1.2.3 From 21521c2d28e7c00e859fd2a28263b716d550c0fc Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Thu, 5 May 2011 14:16:27 +1000 Subject: Inline static data for basic types into the QML instruction The following types are now entirely inline: QPoint, QPointF QSize, QSizeF QRect, QRectF QVector3D, QTime, QDateTime CustomTypeData Reviewed-by: Martin Jones Change-Id: I7024d136c77f8fb23ef6a6abb23ddfe0f9f8a1ca --- src/declarative/qml/qdeclarativecompiler.cpp | 110 +++++++++++++-------------- 1 file changed, 55 insertions(+), 55 deletions(-) (limited to 'src/declarative/qml/qdeclarativecompiler.cpp') diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index d8aa938943..31a9f668ef 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -441,74 +441,84 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, case QVariant::Time: { QTime time = QDeclarativeStringConverters::timeFromString(string); - int data[] = { time.hour(), time.minute(), - time.second(), time.msec() }; - int index = output->indexForInt(data, 4); instr.setType(QDeclarativeInstruction::StoreTime); instr.storeTime.propertyIndex = prop.propertyIndex(); - instr.storeTime.valueIndex = index; + instr.storeTime.time = *(QDeclarativeInstruction::instr_storeTime::QTime *)&time; } break; case QVariant::DateTime: { QDateTime dateTime = QDeclarativeStringConverters::dateTimeFromString(string); - int data[] = { dateTime.date().toJulianDay(), - dateTime.time().hour(), - dateTime.time().minute(), - dateTime.time().second(), - dateTime.time().msec() }; - int index = output->indexForInt(data, 5); + QTime time = dateTime.time(); instr.setType(QDeclarativeInstruction::StoreDateTime); instr.storeDateTime.propertyIndex = prop.propertyIndex(); - instr.storeDateTime.valueIndex = index; + instr.storeDateTime.date = dateTime.date().toJulianDay(); + instr.storeDateTime.time = *(QDeclarativeInstruction::instr_storeTime::QTime *)&time; } break; #endif // QT_NO_DATESTRING case QVariant::Point: + { + bool ok; + QPoint point = QDeclarativeStringConverters::pointFFromString(string, &ok).toPoint(); + instr.setType(QDeclarativeInstruction::StorePoint); + instr.storePoint.propertyIndex = prop.propertyIndex(); + instr.storePoint.point.xp = point.x(); + instr.storePoint.point.yp = point.y(); + } + break; case QVariant::PointF: { bool ok; - QPointF point = - QDeclarativeStringConverters::pointFFromString(string, &ok); - float data[] = { float(point.x()), float(point.y()) }; - int index = output->indexForFloat(data, 2); - if (type == QVariant::PointF) - instr.setType(QDeclarativeInstruction::StorePointF); - else - instr.setType(QDeclarativeInstruction::StorePoint); - instr.storeRealPair.propertyIndex = prop.propertyIndex(); - instr.storeRealPair.valueIndex = index; + QPointF point = QDeclarativeStringConverters::pointFFromString(string, &ok); + instr.setType(QDeclarativeInstruction::StorePointF); + instr.storePointF.propertyIndex = prop.propertyIndex(); + instr.storePointF.point.xp = point.x(); + instr.storePointF.point.yp = point.y(); } break; case QVariant::Size: + { + bool ok; + QSize size = QDeclarativeStringConverters::sizeFFromString(string, &ok).toSize(); + instr.setType(QDeclarativeInstruction::StoreSize); + instr.storeSize.propertyIndex = prop.propertyIndex(); + instr.storeSize.size.wd = size.width(); + instr.storeSize.size.ht = size.height(); + } + break; case QVariant::SizeF: { bool ok; QSizeF size = QDeclarativeStringConverters::sizeFFromString(string, &ok); - float data[] = { float(size.width()), float(size.height()) }; - int index = output->indexForFloat(data, 2); - if (type == QVariant::SizeF) - instr.setType(QDeclarativeInstruction::StoreSizeF); - else - instr.setType(QDeclarativeInstruction::StoreSize); - instr.storeRealPair.propertyIndex = prop.propertyIndex(); - instr.storeRealPair.valueIndex = index; + instr.setType(QDeclarativeInstruction::StoreSizeF); + instr.storeSizeF.propertyIndex = prop.propertyIndex(); + instr.storeSizeF.size.wd = size.width(); + instr.storeSizeF.size.ht = size.height(); } break; case QVariant::Rect: + { + bool ok; + QRect rect = QDeclarativeStringConverters::rectFFromString(string, &ok).toRect(); + instr.setType(QDeclarativeInstruction::StoreRect); + instr.storeRect.propertyIndex = prop.propertyIndex(); + instr.storeRect.rect.x1 = rect.left(); + instr.storeRect.rect.y1 = rect.top(); + instr.storeRect.rect.x2 = rect.right(); + instr.storeRect.rect.y2 = rect.bottom(); + } + break; case QVariant::RectF: { bool ok; QRectF rect = QDeclarativeStringConverters::rectFFromString(string, &ok); - float data[] = { float(rect.x()), float(rect.y()), - float(rect.width()), float(rect.height()) }; - int index = output->indexForFloat(data, 4); - if (type == QVariant::RectF) - instr.setType(QDeclarativeInstruction::StoreRectF); - else - instr.setType(QDeclarativeInstruction::StoreRect); - instr.storeRect.propertyIndex = prop.propertyIndex(); - instr.storeRect.valueIndex = index; + instr.setType(QDeclarativeInstruction::StoreRectF); + instr.storeRectF.propertyIndex = prop.propertyIndex(); + instr.storeRectF.rect.xp = rect.left(); + instr.storeRectF.rect.yp = rect.top(); + instr.storeRectF.rect.w = rect.width(); + instr.storeRectF.rect.h = rect.height(); } break; case QVariant::Bool: @@ -522,28 +532,21 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, case QVariant::Vector3D: { bool ok; - QVector3D vector = - QDeclarativeStringConverters::vector3DFromString(string, &ok); - float data[] = { float(vector.x()), float(vector.y()), float(vector.z()) }; - int index = output->indexForFloat(data, 3); + QVector3D vector = QDeclarativeStringConverters::vector3DFromString(string, &ok); instr.setType(QDeclarativeInstruction::StoreVector3D); - instr.storeRealPair.propertyIndex = prop.propertyIndex(); - instr.storeRealPair.valueIndex = index; + instr.storeVector3D.propertyIndex = prop.propertyIndex(); + instr.storeVector3D.vector.xp = vector.x(); + instr.storeVector3D.vector.yp = vector.y(); + instr.storeVector3D.vector.zp = vector.z(); } break; default: { int t = prop.userType(); - int index = output->customTypeData.count(); instr.setType(QDeclarativeInstruction::AssignCustomType); instr.assignCustomType.propertyIndex = prop.propertyIndex(); - instr.assignCustomType.valueIndex = index; - instr.assignCustomType.line = v->location.start.line; - - QDeclarativeCompiledData::CustomTypeData data; - data.index = output->indexForString(string); - data.type = t; - output->customTypeData << data; + instr.assignCustomType.primitive = output->indexForString(string); + instr.assignCustomType.type = t; } break; } @@ -557,9 +560,6 @@ void QDeclarativeCompiler::reset(QDeclarativeCompiledData *data) { data->types.clear(); data->primitives.clear(); - data->floatData.clear(); - data->intData.clear(); - data->customTypeData.clear(); data->datas.clear(); data->bytecode.clear(); } -- cgit v1.2.3 From 9605fc786482bdd208cc3bfe92f318f7c314329c Mon Sep 17 00:00:00 2001 From: Chris Adams Date: Mon, 23 May 2011 15:22:37 +1000 Subject: Support change slots for properties starting with '_' According to ECMA-262r3, property names may begin with a letter, underscore ('_'), dollar sign ('$'), or unicode escape sequence. We previously supported Change slots for properties only if the property name began with a letter; this patch adds support for properties which begin with one or more underscore. Task-number: QTBUG-17950 Reviewed-by: Aaron Kennedy Change-Id: I6f28bde18a38e32c2131e0990fe0f69bda36f90e --- src/declarative/qml/qdeclarativecompiler.cpp | 32 ++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) (limited to 'src/declarative/qml/qdeclarativecompiler.cpp') diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index 31a9f668ef..3a686be9ec 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -122,13 +122,26 @@ bool QDeclarativeCompiler::isAttachedPropertyName(const QByteArray &name) /*! Returns true if \a name refers to a signal property, false otherwise. - Signal property names are those that start with "on", followed by a capital - letter. + Signal property names are those that start with "on", followed by a first + character which is either a capital letter or one or more underscores followed + by a capital letter, which is then followed by other allowed characters. + + Note that although ECMA-262r3 supports dollarsigns and escaped unicode + character codes in property names, for simplicity and performance reasons + QML only supports letters, numbers and underscores. */ bool QDeclarativeCompiler::isSignalPropertyName(const QByteArray &name) { - return name.length() >= 3 && name.startsWith("on") && - 'A' <= name.at(2) && 'Z' >= name.at(2); + if (name.length() < 3) return false; + if (!name.startsWith("on")) return false; + int ns = name.size(); + for (int i = 2; i < ns; ++i) { + char curr = name.at(i); + if (curr == '_') continue; + if (curr >= 'A' && curr <= 'Z') return true; + return false; + } + return false; // consists solely of underscores - invalid. } /*! @@ -1340,8 +1353,15 @@ bool QDeclarativeCompiler::buildSignal(QDeclarativeParser::Property *prop, QDecl QByteArray name = prop->name; Q_ASSERT(name.startsWith("on")); name = name.mid(2); - if(name[0] >= 'A' && name[0] <= 'Z') - name[0] = name[0] - 'A' + 'a'; + + // Note that the property name could start with any alpha or '_' or '$' character, + // so we need to do the lower-casing of the first alpha character. + for (int firstAlphaIndex = 0; firstAlphaIndex < name.size(); ++firstAlphaIndex) { + if (name[firstAlphaIndex] >= 'A' && name[firstAlphaIndex] <= 'Z') { + name[firstAlphaIndex] = name[firstAlphaIndex] - 'A' + 'a'; + break; + } + } bool notInRevision = false; int sigIdx = indexOfSignal(obj, name, ¬InRevision); -- cgit v1.2.3