summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/declarative/qml/qml.pri3
-rw-r--r--src/declarative/qml/qmlbasicscript.cpp166
-rw-r--r--src/declarative/qml/qmlbasicscript_p.h11
-rw-r--r--src/declarative/qml/qmlcompiler.cpp127
-rw-r--r--src/declarative/qml/qmlcompiler_p.h46
-rw-r--r--src/declarative/qml/qmlengine.cpp28
-rw-r--r--src/declarative/qml/qmlengine_p.h12
-rw-r--r--src/declarative/qml/qmlexpression.h2
-rw-r--r--src/declarative/qml/qmlinstruction.cpp2
-rw-r--r--src/declarative/qml/qmlinstruction_p.h10
-rw-r--r--src/declarative/qml/qmlvme.cpp314
-rw-r--r--src/declarative/qml/qpodvector_p.h124
12 files changed, 471 insertions, 374 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 8b4be2b..d29ac1f 100644
--- a/src/declarative/qml/qmlcompiler.cpp
+++ b/src/declarative/qml/qmlcompiler.cpp
@@ -541,6 +541,8 @@ bool QmlCompiler::compile(QmlEngine *engine,
void QmlCompiler::compileTree(Object *tree)
{
+ compileState.root = tree;
+
QmlInstruction init;
init.type = QmlInstruction::Init;
init.line = 0;
@@ -565,7 +567,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();
@@ -575,7 +577,7 @@ bool QmlCompiler::compileObject(Object *obj, int ctxt)
return true;
}
- ctxt = 0;
+ BindingContext objCtxt(obj);
int createInstrIdx = output->bytecode.count();
// Create the object
@@ -625,7 +627,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);
}
@@ -633,7 +635,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));
}
}
@@ -645,12 +647,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));
}
}
@@ -681,7 +683,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 ||
@@ -717,6 +719,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);
@@ -732,7 +735,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();
@@ -751,6 +754,7 @@ bool QmlCompiler::compileComponentFromRoot(Object *obj, int ctxt)
ComponentCompileState oldComponentCompileState = compileState;
compileState = ComponentCompileState();
+ compileState.root = obj;
if (obj)
COMPILE_CHECK(compileObject(obj, ctxt));
@@ -761,7 +765,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);
@@ -879,7 +883,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");
@@ -1000,6 +1004,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;
@@ -1020,7 +1025,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);
@@ -1032,7 +1037,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;
@@ -1048,7 +1053,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);
@@ -1065,7 +1070,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;
@@ -1082,7 +1087,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));
@@ -1094,7 +1099,9 @@ bool QmlCompiler::compileListProperty(QmlParser::Property *prop,
fetch.line = prop->location.start.line;
fetch.type = QmlInstruction::FetchQmlList;
fetch.fetchQmlList.property = prop->index;
- fetch.fetchQmlList.type = QmlMetaType::qmlListType(t);
+ int listType = QmlMetaType::qmlListType(t);
+ bool listTypeIsInterface = QmlMetaType::isInterface(listType);
+ fetch.fetchQmlList.type = listType;
output->bytecode << fetch;
for (int ii = 0; ii < prop->values.count(); ++ii) {
@@ -1102,12 +1109,23 @@ bool QmlCompiler::compileListProperty(QmlParser::Property *prop,
if (v->object) {
v->type = Value::CreatedObject;
COMPILE_CHECK(compileObject(v->object, ctxt));
- QmlInstruction assign;
- assign.type = QmlInstruction::AssignObjectList;
- assign.line = prop->location.start.line;
- assign.assignObject.property = output->indexForByteArray(prop->name);
- assign.assignObject.castValue = 0;
- output->bytecode << assign;
+
+ if (!listTypeIsInterface) {
+ if (canConvert(listType, v->object)) {
+ QmlInstruction store;
+ store.type = QmlInstruction::StoreObjectQmlList;
+ store.line = prop->location.start.line;
+ output->bytecode << store;
+ } else {
+ COMPILE_EXCEPTION("Cannot assign object to list");
+ }
+
+ } else {
+ QmlInstruction assign;
+ assign.type = QmlInstruction::AssignObjectList;
+ assign.line = prop->location.start.line;
+ output->bytecode << assign;
+ }
} else {
COMPILE_EXCEPTION("Cannot assign primitives to lists");
}
@@ -1121,7 +1139,10 @@ bool QmlCompiler::compileListProperty(QmlParser::Property *prop,
QmlInstruction fetch;
fetch.type = QmlInstruction::FetchQList;
fetch.line = prop->location.start.line;
- fetch.fetch.property = prop->index;
+ fetch.fetchQmlList.property = prop->index;
+ int listType = QmlMetaType::listType(t);
+ bool listTypeIsInterface = QmlMetaType::isInterface(listType);
+ fetch.fetchQmlList.type = listType;
output->bytecode << fetch;
bool assignedBinding = false;
@@ -1130,12 +1151,22 @@ bool QmlCompiler::compileListProperty(QmlParser::Property *prop,
if (v->object) {
v->type = Value::CreatedObject;
COMPILE_CHECK(compileObject(v->object, ctxt));
- QmlInstruction assign;
- assign.type = QmlInstruction::AssignObjectList;
- assign.line = v->location.start.line;
- assign.assignObject.property = output->indexForByteArray(prop->name);
- assign.assignObject.castValue = 0;
- output->bytecode << assign;
+
+ if (!listTypeIsInterface) {
+ if (canConvert(listType, v->object)) {
+ QmlInstruction store;
+ store.type = QmlInstruction::StoreObjectQList;
+ store.line = prop->location.start.line;
+ output->bytecode << store;
+ } else {
+ COMPILE_EXCEPTION("Cannot assign object to list");
+ }
+ } else {
+ QmlInstruction assign;
+ assign.type = QmlInstruction::AssignObjectList;
+ assign.line = v->location.start.line;
+ output->bytecode << assign;
+ }
} else if (v->value.isScript()) {
if (assignedBinding)
COMPILE_EXCEPTION("Can only assign one binding to lists");
@@ -1174,7 +1205,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);
@@ -1195,7 +1226,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);
@@ -1304,7 +1335,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);
@@ -1420,7 +1451,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);
@@ -1502,7 +1533,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;
@@ -1564,7 +1603,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;
@@ -1577,6 +1616,24 @@ void QmlCompiler::finalizeBinding(const BindingReference &binding)
instr.assignBinding.category = QmlMetaProperty::propertyCategory(mp);
}
+/*!
+ Returns true if object can be assigned to a (QObject) property of type
+ convertType.
+*/
+bool QmlCompiler::canConvert(int convertType, QmlParser::Object *object)
+{
+ const QMetaObject *convertTypeMo =
+ QmlMetaType::rawMetaObjectForType(convertType);
+ const QMetaObject *objectMo = object->metaObject();
+
+ while (objectMo) {
+ if (objectMo == convertTypeMo)
+ return true;
+ objectMo = objectMo->superClass();
+ }
+ return false;
+}
+
QmlCompiledData::QmlCompiledData()
{
}
diff --git a/src/declarative/qml/qmlcompiler_p.h b/src/declarative/qml/qmlcompiler_p.h
index 6b6e1e2..3b1a496 100644
--- a/src/declarative/qml/qmlcompiler_p.h
+++ b/src/declarative/qml/qmlcompiler_p.h
@@ -125,50 +125,67 @@ 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;
void finalizeBinding(const BindingReference &);
+ bool canConvert(int, QmlParser::Object *);
+
struct IdReference {
QString id;
QmlParser::Object *object;
int instructionIdx;
+ int idx;
};
struct BindingReference {
@@ -176,17 +193,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/qmlinstruction.cpp b/src/declarative/qml/qmlinstruction.cpp
index 3fe3a8e..a618fe7 100644
--- a/src/declarative/qml/qmlinstruction.cpp
+++ b/src/declarative/qml/qmlinstruction.cpp
@@ -149,7 +149,7 @@ void QmlCompiledComponent::dump(QmlInstruction *instr, int idx)
qWarning() << idx << "\t" << line << "\t" << "COMPLETE\t\t" << instr->complete.castValue;
break;
case QmlInstruction::AssignObjectList:
- qWarning() << idx << "\t" << line << "\t" << "ASSIGN_OBJECT_LIST\t" << instr->assignObject.property << "\t" << instr->assignObject.castValue << "\t\t" << ((instr->assignObject.property == -1)?QByteArray("default"):datas.at(instr->assignObject.property));
+ qWarning() << idx << "\t" << line << "\t" << "ASSIGN_OBJECT_LIST\t";
break;
case QmlInstruction::FetchAttached:
qWarning() << idx << "\t" << line << "\t" << "FETCH_ATTACHED\t\t" << instr->fetchAttached.id;
diff --git a/src/declarative/qml/qmlinstruction_p.h b/src/declarative/qml/qmlinstruction_p.h
index 7cdc1ed..0f1f697 100644
--- a/src/declarative/qml/qmlinstruction_p.h
+++ b/src/declarative/qml/qmlinstruction_p.h
@@ -107,8 +107,6 @@ public:
StoreSignal, /* storeSignal */
- StoreObjectQmlList,
-
// XXX need to handle storing objects in variants
//
@@ -124,7 +122,9 @@ public:
BeginObject, /* begin */
CompleteObject, /* complete */
- AssignObjectList, /* assignObject */
+ StoreObjectQmlList, /* NA */
+ StoreObjectQList, /* NA */
+ AssignObjectList, /* NA */
FetchAttached, /* fetchAttached */
FetchQmlList, /* fetchQmlList */
@@ -172,10 +172,6 @@ public:
} setId;
struct {
int property;
- int castValue;
- } assignObject;
- struct {
- int property;
} assignValueSource;
struct {
int property;
diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp
index af0b3e0..cdc6a66 100644
--- a/src/declarative/qml/qmlvme.cpp
+++ b/src/declarative/qml/qmlvme.cpp
@@ -66,91 +66,6 @@
#include <private/qmlbindablevalue_p.h>
QT_BEGIN_NAMESPACE
-Q_DECLARE_PERFORMANCE_LOG(QFxCompiler) {
- Q_DECLARE_PERFORMANCE_METRIC(InstrCreateObject);
- Q_DECLARE_PERFORMANCE_METRIC(InstrCreateCustomObject);
- Q_DECLARE_PERFORMANCE_METRIC(InstrSetId);
- Q_DECLARE_PERFORMANCE_METRIC(InstrSetDefault);
- Q_DECLARE_PERFORMANCE_METRIC(InstrCreateComponent);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStoreMetaObject);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStoreReal);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStoreInteger);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStoreBool);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStoreString);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStoreUrl);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStoreColor);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStoreDate);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStoreDateTime);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStoreTime);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStorePoint);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStoreSize);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStoreVariant);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStoreObject);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStoreSignal);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStoreObjectQmlList);
- Q_DECLARE_PERFORMANCE_METRIC(InstrAssignSignalObject);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStoreBinding);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStoreCompiledBinding);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStoreValueSource);
- Q_DECLARE_PERFORMANCE_METRIC(InstrBeginObject);
- Q_DECLARE_PERFORMANCE_METRIC(InstrCompleteObject);
- Q_DECLARE_PERFORMANCE_METRIC(InstrAssignObjectList);
- Q_DECLARE_PERFORMANCE_METRIC(InstrFetchAttached);
- Q_DECLARE_PERFORMANCE_METRIC(InstrFetchQmlList);
- Q_DECLARE_PERFORMANCE_METRIC(InstrFetchQList);
- Q_DECLARE_PERFORMANCE_METRIC(InstrFetchObject);
- Q_DECLARE_PERFORMANCE_METRIC(InstrPopFetchedObject);
- Q_DECLARE_PERFORMANCE_METRIC(InstrPopQList);
- Q_DECLARE_PERFORMANCE_METRIC(InstrPushProperty);
- Q_DECLARE_PERFORMANCE_METRIC(InstrStoreStackObject);
- Q_DECLARE_PERFORMANCE_METRIC(Dummy);
-}
-
-Q_DEFINE_PERFORMANCE_LOG(QFxCompiler, "QFxCompiler") {
- Q_DEFINE_PERFORMANCE_METRIC(InstrCreateObject, "CreateObject");
- Q_DEFINE_PERFORMANCE_METRIC(InstrCreateCustomObject, "CreateCustomObject");
- Q_DEFINE_PERFORMANCE_METRIC(InstrSetId, "SetId");
- Q_DEFINE_PERFORMANCE_METRIC(InstrSetDefault, "SetDefault");
- Q_DEFINE_PERFORMANCE_METRIC(InstrCreateComponent, "CreateComponent");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStoreMetaObject, "StoreMetaObject");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStoreReal, "StoreReal");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStoreInteger, "StoreInteger");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStoreBool, "StoreBool");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStoreString, "StoreString");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStoreUrl, "StoreUrl");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStoreColor, "StoreColor");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStoreDate, "StoreDate");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStoreDateTime, "StoreDateTime");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStoreTime, "StoreTime");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStorePoint, "StorePoint(F)");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStoreSize, "StoreSize(F)");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStoreVariant, "StoreVariant");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStoreObject, "StoreObject");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStoreSignal, "StoreSignal");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStoreObjectQmlList, "StoreObjectQmlList");
- Q_DEFINE_PERFORMANCE_METRIC(InstrAssignSignalObject, "AssignSignalObject");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStoreBinding, "StoreBinding");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStoreCompiledBinding, "StoreCompiledBinding");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStoreValueSource, "StoreValueSource");
- Q_DEFINE_PERFORMANCE_METRIC(InstrBeginObject, "BeginObject");
- Q_DEFINE_PERFORMANCE_METRIC(InstrCompleteObject, "CompleteObject");
- Q_DEFINE_PERFORMANCE_METRIC(InstrAssignObjectList, "AssignObjectList");
- Q_DEFINE_PERFORMANCE_METRIC(InstrFetchAttached, "FetchAttached");
- Q_DEFINE_PERFORMANCE_METRIC(InstrFetchQmlList, "FetchQmlList");
- Q_DEFINE_PERFORMANCE_METRIC(InstrFetchQList, "FetchQList");
- Q_DEFINE_PERFORMANCE_METRIC(InstrFetchObject, "FetchObject");
- Q_DEFINE_PERFORMANCE_METRIC(InstrPopFetchedObject, "PopFetchedObject");
- Q_DEFINE_PERFORMANCE_METRIC(InstrPopQList, "PopQList");
- Q_DEFINE_PERFORMANCE_METRIC(InstrPushProperty, "PushProperty");
- Q_DEFINE_PERFORMANCE_METRIC(InstrStoreStackObject, "StoreStackObject");
- Q_DEFINE_PERFORMANCE_METRIC(Dummy, "Dummy");
-}
-
-static inline int qIndexOfProperty(QObject *o, const char *name)
-{
- int idx = o->metaObject()->indexOfProperty(name);
- return idx;
-}
QmlVME::QmlVME()
{
@@ -173,13 +88,18 @@ QmlVME::QmlVME()
struct ListInstance
{
ListInstance() {}
+ /*
ListInstance(const QVariant &l, int t)
: list(l), type(t), qmlListInterface(0) {}
+ */
+ ListInstance(QList<void *> *q, int t)
+ : type(t), qListInterface(q) {}
ListInstance(QmlPrivate::ListInterface *q, int t)
: type(t), qmlListInterface(q) {}
- QVariant list;
+ //QVariant list;
int type;
+ QList<void *> *qListInterface;
QmlPrivate::ListInterface *qmlListInterface;
};
@@ -202,9 +122,6 @@ QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledComponent *comp, int start, in
const QList<float> &floatData = comp->floatData;
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxPerfTimer<QFxPerf::VMEExecution> cr;
-#endif
QmlEnginePrivate::SimpleList<QmlBindableValue> bindValues;
QmlEnginePrivate::SimpleList<QmlParserStatus> parserStatus;
@@ -240,9 +157,6 @@ QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledComponent *comp, int start, in
case QmlInstruction::CreateObject:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrCreateObject> cc;
-#endif
QObject *o = types.at(instr.create.type).createInstance(QmlContext::activeContext());
if (!o) {
if(types.at(instr.create.type).component)
@@ -266,9 +180,6 @@ QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledComponent *comp, int start, in
case QmlInstruction::SetId:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrSetId> cc;
-#endif
QObject *target = stack.top();
QmlContext *ctxt =
QmlContext::activeContext();
@@ -282,9 +193,6 @@ QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledComponent *comp, int start, in
case QmlInstruction::SetDefault:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrSetDefault> cc;
-#endif
QObject *target = stack.top();
QmlContext::activeContext()->addDefaultObject(target);
}
@@ -292,9 +200,6 @@ QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledComponent *comp, int start, in
case QmlInstruction::CreateComponent:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrCreateComponent> cc;
-#endif
QObject *qcomp = new QmlComponent(ctxt->engine(), comp, ii + 1, instr.createComponent.count, stack.isEmpty() ? 0 : stack.top());
stack.push(qcomp);
ii += instr.createComponent.count;
@@ -303,9 +208,6 @@ QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledComponent *comp, int start, in
case QmlInstruction::StoreMetaObject:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStoreMetaObject> cc;
-#endif
QObject *target = stack.top();
new QmlVMEMetaObject(target, synthesizedMetaObjects.at(instr.storeMeta.data), &comp->primitives, instr.storeMeta.slotData, comp);
}
@@ -313,9 +215,6 @@ QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledComponent *comp, int start, in
case QmlInstruction::StoreVariant:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStoreVariant> cc;
-#endif
QObject *target = stack.top();
void *a[1];
// XXX - can be more efficient
@@ -328,9 +227,6 @@ QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledComponent *comp, int start, in
case QmlInstruction::StoreString:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStoreString> cc;
-#endif
QObject *target = stack.top();
void *a[1];
a[0] = (void *)&primitives.at(instr.storeString.value);
@@ -341,9 +237,6 @@ QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledComponent *comp, int start, in
case QmlInstruction::StoreUrl:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStoreUrl> cc;
-#endif
QObject *target = stack.top();
void *a[1];
QUrl u(primitives.at(instr.storeUrl.value));
@@ -355,9 +248,6 @@ QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledComponent *comp, int start, in
case QmlInstruction::StoreFloat:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStoreReal> cc;
-#endif
QObject *target = stack.top();
float f = instr.storeFloat.value;
void *a[1];
@@ -367,11 +257,8 @@ QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledComponent *comp, int start, in
}
break;
-case QmlInstruction::StoreDouble:
+ case QmlInstruction::StoreDouble:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStoreReal> cc;
-#endif
QObject *target = stack.top();
double d = instr.storeDouble.value;
void *a[1];
@@ -383,9 +270,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::StoreBool:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStoreBool> cc;
-#endif
QObject *target = stack.top();
void *a[1];
a[0] = (void *)&instr.storeBool.value;
@@ -396,9 +280,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::StoreInteger:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStoreInteger> cc;
-#endif
QObject *target = stack.top();
void *a[1];
a[0] = (void *)&instr.storeInteger.value;
@@ -409,9 +290,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::StoreColor:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStoreColor> cc;
-#endif
QObject *target = stack.top();
void *a[1];
QColor c = QColor::fromRgba(instr.storeColor.value);
@@ -423,9 +301,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::StoreDate:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStoreDate> cc;
-#endif
QObject *target = stack.top();
void *a[1];
QDate d = QDate::fromJulianDay(instr.storeDate.value);
@@ -437,9 +312,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::StoreTime:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- //QFxCompilerTimer<QFxCompiler::InstrStoreTime> cc;
-#endif
QObject *target = stack.top();
void *a[1];
QTime t;
@@ -455,9 +327,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::StoreDateTime:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- //QFxCompilerTimer<QFxCompiler::InstrStoreDateTime> cc;
-#endif
QObject *target = stack.top();
void *a[1];
QTime t;
@@ -474,9 +343,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::StorePoint:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStorePoint> cc;
-#endif
QObject *target = stack.top();
void *a[1];
QPoint p = QPointF(floatData.at(instr.storeRealPair.valueIndex),
@@ -489,9 +355,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::StorePointF:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStorePoint> cc;
-#endif
QObject *target = stack.top();
void *a[1];
QPointF p(floatData.at(instr.storeRealPair.valueIndex),
@@ -504,9 +367,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::StoreSize:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStoreSize> cc;
-#endif
QObject *target = stack.top();
void *a[1];
QSize p = QSizeF(floatData.at(instr.storeRealPair.valueIndex),
@@ -519,9 +379,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::StoreSizeF:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStoreSize> cc;
-#endif
QObject *target = stack.top();
void *a[1];
QSizeF s(floatData.at(instr.storeRealPair.valueIndex),
@@ -534,9 +391,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::StoreRect:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- //QFxCompilerTimer<QFxCompiler::InstrStoreRect> cc;
-#endif
QObject *target = stack.top();
void *a[1];
QRect r = QRectF(floatData.at(instr.storeRect.valueIndex),
@@ -551,9 +405,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::StoreRectF:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- //QFxCompilerTimer<QFxCompiler::InstrStoreRect> cc;
-#endif
QObject *target = stack.top();
void *a[1];
QRectF r(floatData.at(instr.storeRect.valueIndex),
@@ -568,9 +419,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::StoreObject:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStoreObject> cc;
-#endif
QObject *assignObj = stack.pop();
QObject *target = stack.top();
@@ -606,9 +454,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::AssignSignalObject:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrAssignSignalObject> cc;
-#endif
// XXX optimize
QObject *assign = stack.pop();
@@ -638,9 +483,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::StoreSignal:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStoreSignal> cc;
-#endif
QObject *target = stack.top();
// XXX scope
QMetaMethod signal =
@@ -656,9 +498,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::BeginObject:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrBeginObject> cc;
-#endif
QObject *target = stack.top();
QmlParserStatus *status = reinterpret_cast<QmlParserStatus *>(reinterpret_cast<char *>(target) + instr.begin.castValue);
parserStatus.append(status);
@@ -670,9 +509,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::CompleteObject:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrCompleteObject> cc;
-#endif
QObject *target = stack.top();
QmlParserStatus *status = reinterpret_cast<QmlParserStatus *>(reinterpret_cast<char *>(target) + instr.complete.castValue);
status->classComplete();
@@ -681,9 +517,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::PushProperty:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrPushProperty> cc;
-#endif
QObject *target = stack.top();
QmlMetaProperty mp(target, instr.pushProperty.property,
QmlMetaProperty::Object);
@@ -693,9 +526,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::StoreCompiledBinding:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStoreCompiledBinding> cc;
-#endif
QObject *target = stack.top();
QObject *context =
stack.at(stack.count() - 1 - instr.assignBinding.context);
@@ -711,15 +541,12 @@ 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;
case QmlInstruction::StoreBinding:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStoreBinding> cc;
-#endif
QObject *target = stack.top();
QObject *context =
stack.at(stack.count() - 1 - instr.assignBinding.context);
@@ -735,15 +562,12 @@ 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;
case QmlInstruction::StoreValueSource:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStoreValueSource> cc;
-#endif
QObject *assign = stack.pop();
QmlPropertyValueSource *vs =
static_cast<QmlPropertyValueSource *>(assign);
@@ -753,65 +577,47 @@ case QmlInstruction::StoreDouble:
}
break;
+ case QmlInstruction::StoreObjectQmlList:
+ {
+ QObject *assign = stack.pop();
+ const ListInstance &list = qliststack.top();
+
+ void *d = (void *)&assign;
+ list.qmlListInterface->append(d);
+ }
+ break;
+
+ case QmlInstruction::StoreObjectQList:
+ {
+ QObject *assign = stack.pop();
+
+ const ListInstance &list = qliststack.top();
+ list.qListInterface->append((void *)assign);
+ }
+ break;
+
case QmlInstruction::AssignObjectList:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrAssignObjectList> cc;
-#endif
+ // This is only used for assigning interfaces
QObject *assign = stack.pop();
const ListInstance &list = qliststack.top();
- if (list.qmlListInterface) {
- int type = list.type;
-
- void *d = 0;
- void *ptr = 0;
- bool found = false;
-
- if (QmlMetaType::isInterface(type)) {
- const char *iid = QmlMetaType::interfaceIId(type);
- if (iid)
- ptr = assign->qt_metacast(iid);
- if (ptr) {
- d = &ptr;
- found = true;
- }
- } else {
- const QMetaObject *mo =
- QmlMetaType::rawMetaObjectForType(type);
-
- const QMetaObject *assignMo = assign->metaObject();
- while(!found && assignMo) {
- if (assignMo == mo)
- found = true;
- else
- assignMo = assignMo->superClass();
- }
-
- // NOTE: This assumes a cast to QObject does not alter
- // the object pointer
- d = (void *)&assign;
- }
+ int type = list.type;
- if (!found)
- VME_EXCEPTION("Cannot assign object to list");
+ void *ptr = 0;
+
+ const char *iid = QmlMetaType::interfaceIId(type);
+ if (iid)
+ ptr = assign->qt_metacast(iid);
+ if (!ptr)
+ VME_EXCEPTION("Cannot assign object to list");
- list.qmlListInterface->append(d);
+ if (list.qmlListInterface) {
+ void *d = (void *)&ptr;
+ list.qmlListInterface->append(d);
} else {
- int type = list.type;
-
- if (QmlMetaType::isInterface(type)) {
- void *ptr = 0;
- const char *iid = QmlMetaType::interfaceIId(type);
- if (iid)
- ptr = assign->qt_metacast(iid);
- QVariant v(list.type, &ptr);
- QmlMetaType::append(list.list, v);
- } else {
- QVariant v = QmlMetaType::fromObject(assign, list.type);
- QmlMetaType::append(list.list, v);
- }
+ list.qListInterface->append(ptr);
}
}
break;
@@ -858,9 +664,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::FetchAttached:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrFetchAttached> cc;
-#endif
QObject *target = stack.top();
QObject *qmlObject = qmlAttachedPropertiesObjectById(instr.fetchAttached.id, target);
@@ -874,9 +677,6 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::FetchQmlList:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrFetchQmlList> cc;
-#endif
QObject *target = stack.top();
void *a[1];
@@ -895,22 +695,24 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::FetchQList:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrFetchQList> cc;
-#endif
QObject *target = stack.top();
- QMetaProperty prop =
- target->metaObject()->property(instr.fetch.property);
- QVariant v = prop.read(target);
- qliststack.push(ListInstance(v, QmlMetaType::listType(prop.userType())));
+
+ void *a[1];
+ // We know that QList<T *>* can be converted to
+ // QList<void *>*
+ QList<void *> *list = 0;
+ a[0] = &list;
+ QMetaObject::metacall(target, QMetaObject::ReadProperty,
+ instr.fetchQmlList.property, a);
+ if (!list)
+ VME_EXCEPTION("Cannot assign to null list");
+
+ qliststack.push(ListInstance(list, instr.fetchQmlList.type));
}
break;
case QmlInstruction::FetchObject:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrFetchObject> cc;
-#endif
QObject *target = stack.top();
QObject *obj = 0;
@@ -940,28 +742,18 @@ case QmlInstruction::StoreDouble:
case QmlInstruction::PopQList:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrPopQList> cc;
-#endif
qliststack.pop();
}
break;
case QmlInstruction::PopFetchedObject:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrPopFetchedObject> cc;
-#endif
stack.pop();
}
break;
case QmlInstruction::StoreStackObject:
{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrStoreStackObject> cc;
-#endif
-
const QmlMetaProperty &prop =
pushedProperties.at(instr.assignStackObject.property);
QObject *obj = savedObjects[instr.assignStackObject.object];
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