[new compiler] Add the correct object index to the custom parser

Without the correct index the calls to astForBinding run out of bounds. Fixes
tst_qqmllistmodel crash.

Change-Id: I6fb8b77866cbf247e7373cdbece6833c92be3615
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
This commit is contained in:
Simon Hausmann 2014-03-02 20:35:57 +01:00 committed by The Qt Project
parent 57665bf23a
commit 06479ddfe3
10 changed files with 23 additions and 19 deletions

View File

@ -1849,7 +1849,7 @@ bool QQmlPropertyValidator::validateObject(int objectIndex, const QV4::CompiledD
customParser->compiler = this;
QQmlCompiledData::CustomParserData data;
data.bindings = customParserBindings;
data.compilationArtifact = customParser->compile(qmlUnit, customBindings);
data.compilationArtifact = customParser->compile(qmlUnit, objectIndex, customBindings);
customParser->compiler = 0;
customParserData->insert(objectIndex, data);
const QList<QQmlError> parserErrors = customParser->errors();

View File

@ -140,7 +140,7 @@ public:
Flags flags() const { return m_flags; }
virtual QByteArray compile(const QList<QQmlCustomParserProperty> &)=0;
virtual QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &bindings) = 0;
virtual QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, int objectIndex, const QList<const QV4::CompiledData::Binding *> &bindings) = 0;
virtual void setCustomData(QObject *, const QByteArray &)=0;
QList<QQmlError> errors() const { return exceptions; }

View File

@ -251,8 +251,9 @@ QQmlConnectionsParser::compile(const QList<QQmlCustomParserProperty> &props)
return rv;
}
QByteArray QQmlConnectionsParser::compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &props)
QByteArray QQmlConnectionsParser::compile(const QV4::CompiledData::QmlUnit *qmlUnit, int objectIndex, const QList<const QV4::CompiledData::Binding *> &props)
{
Q_UNUSED(objectIndex)
QByteArray rv;
QDataStream ds(&rv, QIODevice::WriteOnly);

View File

@ -85,7 +85,7 @@ class QQmlConnectionsParser : public QQmlCustomParser
{
public:
virtual QByteArray compile(const QList<QQmlCustomParserProperty> &);
virtual QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &props);
virtual QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, int objectIndex, const QList<const QV4::CompiledData::Binding *> &props);
virtual void setCustomData(QObject *, const QByteArray &);
};

View File

@ -2385,10 +2385,10 @@ bool QQmlListModelParser::compileProperty(const QQmlCustomParserProperty &prop,
return true;
}
bool QQmlListModelParser::compileProperty(const QV4::CompiledData::QmlUnit *qmlUnit, const QV4::CompiledData::Binding *binding, QList<QQmlListModelParser::ListInstruction> &instr, QByteArray &data)
bool QQmlListModelParser::compileProperty(const QV4::CompiledData::QmlUnit *qmlUnit, int objectIndex, const QV4::CompiledData::Binding *binding, QList<QQmlListModelParser::ListInstruction> &instr, QByteArray &data)
{
const quint32 targetObjectIndex = binding->value.objectIndex;
if (binding->type >= QV4::CompiledData::Binding::Type_Object) {
const quint32 targetObjectIndex = binding->value.objectIndex;
const QV4::CompiledData::Object *target = qmlUnit->objectAt(targetObjectIndex);
QString objName = qmlUnit->header.stringAt(target->inheritedTypeNameIndex);
if (objName != listElementTypeName) {
@ -2427,7 +2427,7 @@ bool QQmlListModelParser::compileProperty(const QV4::CompiledData::QmlUnit *qmlU
li.dataIdx = ref;
instr << li;
if (!compileProperty(qmlUnit, binding, instr, data))
if (!compileProperty(qmlUnit, targetObjectIndex, binding, instr, data))
return false;
li.type = ListInstruction::Pop;
@ -2466,7 +2466,7 @@ bool QQmlListModelParser::compileProperty(const QV4::CompiledData::QmlUnit *qmlU
int v = evaluateEnum(script, &ok);
if (!ok) {
using namespace QQmlJS;
AST::Node *node = astForBinding(targetObjectIndex, binding->value.compiledScriptIndex);
AST::Node *node = astForBinding(objectIndex, binding->value.compiledScriptIndex);
if (AST::ExpressionStatement *stmt = AST::cast<AST::ExpressionStatement*>(node))
node = stmt->expression;
AST::StringLiteral *literal = 0;
@ -2552,7 +2552,7 @@ QByteArray QQmlListModelParser::compile(const QList<QQmlCustomParserProperty> &c
return rv;
}
QByteArray QQmlListModelParser::compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &bindings)
QByteArray QQmlListModelParser::compile(const QV4::CompiledData::QmlUnit *qmlUnit, int objectIndex, const QList<const QV4::CompiledData::Binding *> &bindings)
{
QList<ListInstruction> instr;
QByteArray data;
@ -2564,7 +2564,7 @@ QByteArray QQmlListModelParser::compile(const QV4::CompiledData::QmlUnit *qmlUni
error(binding, QQmlListModel::tr("ListModel: undefined property '%1'").arg(propName));
return QByteArray();
}
if (!compileProperty(qmlUnit, binding, instr, data))
if (!compileProperty(qmlUnit, objectIndex, binding, instr, data))
return QByteArray();
}

View File

@ -160,7 +160,7 @@ class QQmlListModelParser : public QQmlCustomParser
public:
QQmlListModelParser() : QQmlCustomParser(QQmlCustomParser::AcceptsSignalHandlers) {}
QByteArray compile(const QList<QQmlCustomParserProperty> &);
QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &bindings);
QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, int objectIndex, const QList<const QV4::CompiledData::Binding *> &bindings);
void setCustomData(QObject *, const QByteArray &);
private:
@ -176,7 +176,7 @@ private:
ListInstruction *instructions() const;
};
bool compileProperty(const QQmlCustomParserProperty &prop, QList<ListInstruction> &instr, QByteArray &data);
bool compileProperty(const QV4::CompiledData::QmlUnit *qmlUnit, const QV4::CompiledData::Binding *binding, QList<ListInstruction> &instr, QByteArray &data);
bool compileProperty(const QV4::CompiledData::QmlUnit *qmlUnit, int objectIndex, const QV4::CompiledData::Binding *binding, QList<ListInstruction> &instr, QByteArray &data);
bool definesEmptyList(const QString &);

View File

@ -331,8 +331,9 @@ QQuickPropertyChangesParser::compile(const QList<QQmlCustomParserProperty> &prop
return rv;
}
QByteArray QQuickPropertyChangesParser::compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &props)
QByteArray QQuickPropertyChangesParser::compile(const QV4::CompiledData::QmlUnit *qmlUnit, int objectIndex, const QList<const QV4::CompiledData::Binding *> &props)
{
Q_UNUSED(objectIndex)
QList<QPair<QString, const QV4::CompiledData::Binding *> > data;
for (int ii = 0; ii < props.count(); ++ii)
compileList(data, QString(), qmlUnit, props.at(ii));

View File

@ -96,7 +96,7 @@ public:
void compileList(QList<QPair<QString, const QV4::CompiledData::Binding *> > &list, const QString &pre, const QV4::CompiledData::QmlUnit *qmlUnit, const QV4::CompiledData::Binding *binding);
virtual QByteArray compile(const QList<QQmlCustomParserProperty> &);
virtual QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &props);
virtual QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, int objectIndex, const QList<const QV4::CompiledData::Binding *> &props);
virtual void setCustomData(QObject *, const QByteArray &);
};

View File

@ -127,8 +127,9 @@ QByteArray CustomBindingParser::compile(const QList<QQmlCustomParserProperty> &p
return result;
}
QByteArray CustomBindingParser::compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &bindings)
QByteArray CustomBindingParser::compile(const QV4::CompiledData::QmlUnit *qmlUnit, int objectIndex, const QList<const QV4::CompiledData::Binding *> &bindings)
{
Q_UNUSED(objectIndex)
QByteArray result;
QDataStream ds(&result, QIODevice::WriteOnly);
@ -222,9 +223,10 @@ QByteArray EnumSupportingCustomParser::compile(const QList<QQmlCustomParserPrope
return QByteArray();
}
QByteArray EnumSupportingCustomParser::compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &bindings)
QByteArray EnumSupportingCustomParser::compile(const QV4::CompiledData::QmlUnit *qmlUnit, int objectIndex, const QList<const QV4::CompiledData::Binding *> &bindings)
{
Q_UNUSED(qmlUnit)
Q_UNUSED(objectIndex)
if (bindings.count() != 1) {
error(bindings.first(), QStringLiteral("Custom parser invoked incorrectly for unit test"));

View File

@ -723,7 +723,7 @@ class MyCustomParserTypeParser : public QQmlCustomParser
{
public:
QByteArray compile(const QList<QQmlCustomParserProperty> &) { return QByteArray(); }
QByteArray compile(const QV4::CompiledData::QmlUnit *, const QList<const QV4::CompiledData::Binding *> &) { return QByteArray(); }
QByteArray compile(const QV4::CompiledData::QmlUnit *, int, const QList<const QV4::CompiledData::Binding *> &) { return QByteArray(); }
void setCustomData(QObject *, const QByteArray &) {}
};
@ -731,7 +731,7 @@ class EnumSupportingCustomParser : public QQmlCustomParser
{
public:
QByteArray compile(const QList<QQmlCustomParserProperty> &props);
QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &bindings);
QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, int objectIndex, const QList<const QV4::CompiledData::Binding *> &bindings);
void setCustomData(QObject *, const QByteArray &) {}
};
@ -1103,7 +1103,7 @@ public:
class CustomBindingParser : public QQmlCustomParser
{
virtual QByteArray compile(const QList<QQmlCustomParserProperty> &properties);
virtual QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &bindings);
virtual QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, int objectIndex, const QList<const QV4::CompiledData::Binding *> &bindings);
virtual void setCustomData(QObject *object, const QByteArray &data);
};