summaryrefslogtreecommitdiffstats
path: root/src/declarative/qml/qmlcompiler.cpp
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2009-05-27 10:40:28 (GMT)
committerAaron Kennedy <aaron.kennedy@nokia.com>2009-05-27 10:40:28 (GMT)
commitc8f180e7023308b8a051b53943b9a088a7f0c427 (patch)
tree12fbbccc818670fd4c982bd5f42723477aab2833 /src/declarative/qml/qmlcompiler.cpp
parent0a6df63c7150f0010b08ce2ba08a492cd129a96f (diff)
downloadQt-c8f180e7023308b8a051b53943b9a088a7f0c427.zip
Qt-c8f180e7023308b8a051b53943b9a088a7f0c427.tar.gz
Qt-c8f180e7023308b8a051b53943b9a088a7f0c427.tar.bz2
Small cleanups
Diffstat (limited to 'src/declarative/qml/qmlcompiler.cpp')
-rw-r--r--src/declarative/qml/qmlcompiler.cpp175
1 files changed, 83 insertions, 92 deletions
diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp
index 09f4e0b..b9a848a 100644
--- a/src/declarative/qml/qmlcompiler.cpp
+++ b/src/declarative/qml/qmlcompiler.cpp
@@ -62,6 +62,7 @@
#include "private/qmlcustomparser_p_p.h"
#include <private/qmlcontext_p.h>
#include <private/qmlcomponent_p.h>
+#include "parser/javascriptast_p.h"
#include "qmlscriptparser_p.h"
@@ -516,6 +517,7 @@ bool QmlCompiler::compile(QmlEngine *engine,
}
output = 0;
+
return !isError();
}
@@ -542,7 +544,7 @@ void QmlCompiler::compileTree(Object *tree)
def.type = QmlInstruction::SetDefault;
output->bytecode << def;
- optimizeExpressions(0, output->bytecode.count() - 1, 0);
+ finalizeComponent(0);
}
bool QmlCompiler::compileObject(Object *obj, int ctxt)
@@ -588,6 +590,8 @@ bool QmlCompiler::compileObject(Object *obj, int ctxt)
begin.begin.castValue = parserStatusCast;
begin.line = obj->location.start.line;
output->bytecode << begin;
+
+ compileState.parserStatusCount++;
}
// Check if this is a custom parser type. Custom parser types allow
@@ -688,9 +692,14 @@ bool QmlCompiler::compileComponent(Object *obj, int ctxt)
if (!isValidId(val))
COMPILE_EXCEPTION("Invalid id property value");
- if (ids.contains(val))
+ if (compileState.ids.contains(val))
COMPILE_EXCEPTION("id is not unique");
- ids.insert(val);
+
+ IdReference reference;
+ reference.id = val;
+ reference.object = obj;
+ reference.instructionIdx = output->bytecode.count();
+ compileState.ids.insert(val, reference);
int pref = output->indexForString(val);
QmlInstruction id;
@@ -699,8 +708,6 @@ bool QmlCompiler::compileComponent(Object *obj, int ctxt)
id.setId.value = pref;
id.setId.save = -1;
- savedTypes.insert(output->bytecode.count(), -1);
-
output->bytecode << id;
}
@@ -724,16 +731,16 @@ bool QmlCompiler::compileComponentFromRoot(Object *obj, int ctxt)
init.line = obj->location.start.line;
output->bytecode << init;
- QSet<QString> oldIds = ids;
- ids.clear();
+ ComponentCompileState oldComponentCompileState = compileState;
+ compileState = ComponentCompileState();
if (obj)
COMPILE_CHECK(compileObject(obj, ctxt));
create.createComponent.count = output->bytecode.count() - count;
- int inc = optimizeExpressions(count, count - 1 + create.createComponent.count, count);
+ int inc = finalizeComponent(count);
create.createComponent.count += inc;
- ids = oldIds;
+ compileState = oldComponentCompileState;
return true;
}
@@ -950,41 +957,43 @@ bool QmlCompiler::compileIdProperty(QmlParser::Property *prop,
if (prop->values.count() > 1)
COMPILE_EXCEPTION2(prop, "The object id may only be set once");
- if (prop->values.count() == 1) {
- if (prop->values.at(0)->object)
- COMPILE_EXCEPTION("Cannot assign an object as an id");
- QString val = prop->values.at(0)->primitive();
- if (!isValidId(val))
- COMPILE_EXCEPTION(val << "is not a valid id");
- if (ids.contains(val))
- COMPILE_EXCEPTION("id is not unique");
- ids.insert(val);
+ if (prop->values.at(0)->object)
+ COMPILE_EXCEPTION("Cannot assign an object as an id");
+ QString val = prop->values.at(0)->primitive();
+ if (!isValidId(val))
+ COMPILE_EXCEPTION(val << "is not a valid id");
+ if (compileState.ids.contains(val))
+ COMPILE_EXCEPTION("id is not unique");
- int pref = output->indexForString(val);
+ int pref = output->indexForString(val);
- if (prop->type == QVariant::String) {
- QmlInstruction assign;
- assign.type = QmlInstruction::StoreString;
- assign.storeString.propertyIndex = prop->index;
- assign.storeString.value = pref;
- assign.line = prop->values.at(0)->location.start.line;
- output->bytecode << assign;
+ if (prop->type == QVariant::String) {
+ QmlInstruction assign;
+ assign.type = QmlInstruction::StoreString;
+ assign.storeString.propertyIndex = prop->index;
+ assign.storeString.value = pref;
+ assign.line = prop->values.at(0)->location.start.line;
+ output->bytecode << assign;
- prop->values.at(0)->type = Value::Id;
- } else {
- prop->values.at(0)->type = Value::Literal;
- }
+ prop->values.at(0)->type = Value::Id;
+ } else {
+ prop->values.at(0)->type = Value::Literal;
+ }
- QmlInstruction id;
- id.type = QmlInstruction::SetId;
- id.line = prop->values.at(0)->location.start.line;
- id.setId.value = pref;
- id.setId.save = -1;
- savedTypes.insert(output->bytecode.count(), obj->type);
- output->bytecode << id;
+ IdReference reference;
+ reference.id = val;
+ reference.object = obj;
+ reference.instructionIdx = output->bytecode.count();
+ compileState.ids.insert(val, reference);
- obj->id = val.toLatin1();
- }
+ QmlInstruction id;
+ id.type = QmlInstruction::SetId;
+ id.line = prop->values.at(0)->location.start.line;
+ id.setId.value = pref;
+ id.setId.save = -1;
+ output->bytecode << id;
+
+ obj->id = val.toLatin1();
return true;
}
@@ -1116,7 +1125,7 @@ bool QmlCompiler::compileListProperty(QmlParser::Property *prop,
COMPILE_EXCEPTION("Can only assign one binding to lists");
assignedBinding = true;
- COMPILE_CHECK(compileBinding(v->value.asScript(), prop, ctxt,
+ COMPILE_CHECK(compileBinding(v->value, prop, ctxt,
obj->metaObject(),
v->location.start.line));
v->type = Value::PropertyBinding;
@@ -1287,7 +1296,7 @@ bool QmlCompiler::compilePropertyLiteralAssignment(QmlParser::Property *prop,
if (v->value.isScript()) {
- COMPILE_CHECK(compileBinding(v->value.asScript(), prop, ctxt,
+ COMPILE_CHECK(compileBinding(v->value, prop, ctxt,
obj->metaObject(),
v->location.start.line));
@@ -1394,7 +1403,8 @@ bool QmlCompiler::compileDynamicMeta(QmlParser::Object *obj)
return true;
}
-bool QmlCompiler::compileBinding(const QString &bind, QmlParser::Property *prop,
+bool QmlCompiler::compileBinding(const QmlParser::Variant &bind,
+ QmlParser::Property *prop,
int ctxt, const QMetaObject *mo, qint64 line)
{
Q_ASSERT(mo);
@@ -1405,13 +1415,13 @@ bool QmlCompiler::compileBinding(const QString &bind, QmlParser::Property *prop,
COMPILE_EXCEPTION2(prop, "Cannot assign binding to read-only property");
QmlBasicScript bs;
- bs.compile(bind.toLatin1());
+ bs.compile(bind.asScript().toLatin1());
int bref;
if (bs.isValid()) {
bref = output->indexForByteArray(QByteArray(bs.compileData(), bs.compileDataSize()));
} else {
- bref = output->indexForString(bind);
+ bref = output->indexForString(bind.asScript());
}
QmlInstruction assign;
@@ -1426,49 +1436,28 @@ bool QmlCompiler::compileBinding(const QString &bind, QmlParser::Property *prop,
assign.assignBinding.property = prop->index;
assign.assignBinding.value = bref;
assign.assignBinding.category = QmlMetaProperty::propertyCategory(mp);
- savedTypes.insert(output->bytecode.count(), prop->type);
+ BindingReference reference;
+ reference.expression = bind;
+ reference.property = prop;
+ reference.instructionIdx = output->bytecode.count();
+ compileState.bindings << reference;
+
output->bytecode << assign;
return true;
}
-int QmlCompiler::optimizeExpressions(int start, int end, int patch)
+// Update the init instruction with final data, and optimize some simple
+// bindings
+int QmlCompiler::finalizeComponent(int patch)
{
- QHash<QString, int> ids;
int saveCount = 0;
int newInstrs = 0;
- int bindingsCount = 0;
- int parserStatusCount = 0;
- for (int ii = start; ii <= end; ++ii) {
- const QmlInstruction &instr = output->bytecode.at(ii);
-
- if (instr.type == QmlInstruction::CreateComponent) {
- ii += instr.createComponent.count - 1;
- continue;
- }
-
- if (instr.type == QmlInstruction::SetId) {
- QString id = output->primitives.at(instr.setId.value);
- ids.insert(id, ii);
- }
- }
-
- for (int ii = start; ii <= end; ++ii) {
- const QmlInstruction &instr = output->bytecode.at(ii);
-
- if (instr.type == QmlInstruction::CreateComponent) {
- ii += instr.createComponent.count - 1;
- continue;
- }
-
- if (instr.type == QmlInstruction::StoreBinding ||
- instr.type == QmlInstruction::StoreCompiledBinding) {
- ++bindingsCount;
- } else if (instr.type == QmlInstruction::BeginObject) {
- ++parserStatusCount;
- }
+ for (int ii = 0; ii < compileState.bindings.count(); ++ii) {
+ const BindingReference &binding = compileState.bindings.at(ii);
+ QmlInstruction &instr = output->bytecode[binding.instructionIdx];
if (instr.type == QmlInstruction::StoreCompiledBinding) {
QmlBasicScript s(output->datas.at(instr.assignBinding.value).constData());
@@ -1478,16 +1467,17 @@ int QmlCompiler::optimizeExpressions(int start, int end, int patch)
if (!slt.at(0).isUpper())
continue;
- if (ids.contains(slt) &&
+ if (compileState.ids.contains(slt) &&
instr.assignBinding.category == QmlMetaProperty::Object) {
- int id = ids[slt];
- int idType = savedTypes.value(id);
- int storeType = savedTypes.value(ii);
+ IdReference reference =
+ compileState.ids[slt];
+
+ const QMetaObject *idMo = reference.object->metaObject();
+ const QMetaObject *storeMo = QmlMetaType::rawMetaObjectForType(binding.property->type);
- const QMetaObject *idMo = (idType == -1)?&QmlComponent::staticMetaObject:output->types.at(idType).metaObject();
- const QMetaObject *storeMo =
- QmlMetaType::rawMetaObjectForType(storeType);
+ Q_ASSERT(idMo);
+ Q_ASSERT(storeMo);
bool canAssign = false;
while (!canAssign && idMo) {
@@ -1502,19 +1492,19 @@ int QmlCompiler::optimizeExpressions(int start, int end, int patch)
int saveId = -1;
- if (output->bytecode.at(id).setId.save != -1) {
- saveId = output->bytecode.at(id).setId.save;
+ int instructionIdx = reference.instructionIdx;
+ if (output->bytecode.at(instructionIdx).setId.save != -1) {
+ saveId = output->bytecode.at(instructionIdx).setId.save;
} else {
- output->bytecode[id].setId.save = saveCount;
+ output->bytecode[instructionIdx].setId.save = saveCount;
saveId = saveCount;
++saveCount;
}
int prop = instr.assignBinding.property;
- QmlInstruction &rwinstr = output->bytecode[ii];
- rwinstr.type = QmlInstruction::PushProperty;
- rwinstr.pushProperty.property = prop;
+ instr.type = QmlInstruction::PushProperty;
+ instr.pushProperty.property = prop;
QmlInstruction instr;
instr.type = QmlInstruction::StoreStackObject;
@@ -1529,8 +1519,9 @@ int QmlCompiler::optimizeExpressions(int start, int end, int patch)
}
output->bytecode[patch].init.dataSize = saveCount;
- output->bytecode[patch].init.bindingsSize = bindingsCount;
- output->bytecode[patch].init.parserStatusSize = parserStatusCount;;
+ output->bytecode[patch].init.bindingsSize = compileState.bindings.count();
+ output->bytecode[patch].init.parserStatusSize =
+ compileState.parserStatusCount;
return newInstrs;
}