From 1a1f10806c901bc10483370a932d41af0c9629cd Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 22 Jun 2015 16:33:40 +0200 Subject: Access the id objects through a specialized runtime method This brings us one step closer to getting rid of the QQmlContextWrapper. Change-Id: Ied57f4c174c2ebd95096310a4ad4c0c28787e7a4 Reviewed-by: Simon Hausmann --- src/qml/compiler/qqmlirbuilder.cpp | 5 +---- src/qml/compiler/qqmlirbuilder_p.h | 1 - src/qml/compiler/qqmltypecompiler.cpp | 1 - src/qml/compiler/qv4instr_moth_p.h | 14 ++++++++------ src/qml/compiler/qv4isel_moth.cpp | 13 ++++++------- src/qml/compiler/qv4isel_moth_p.h | 1 - src/qml/compiler/qv4isel_p.cpp | 14 +++++++++----- src/qml/compiler/qv4isel_p.h | 1 - src/qml/compiler/qv4jsir.cpp | 12 ++++++------ src/qml/compiler/qv4jsir_p.h | 20 ++++++++++++-------- src/qml/compiler/qv4ssa.cpp | 4 ++-- 11 files changed, 44 insertions(+), 42 deletions(-) (limited to 'src/qml/compiler') diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index 079ab95f00..4b1e3601dc 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -1458,7 +1458,6 @@ JSCodeGen::JSCodeGen(const QString &fileName, const QString &sourceCode, QV4::IR , _scopeObject(0) , _qmlContextTemp(-1) , _importedScriptsTemp(-1) - , _idArrayTemp(-1) { _module = jsModule; _module->setFileName(fileName); @@ -1765,14 +1764,12 @@ void JSCodeGen::beginFunctionBodyHook() { _qmlContextTemp = _block->newTemp(); _importedScriptsTemp = _block->newTemp(); - _idArrayTemp = _block->newTemp(); #ifndef V4_BOOTSTRAP QV4::IR::Temp *temp = _block->TEMP(_qmlContextTemp); move(temp, _block->NAME(QV4::IR::Name::builtin_qml_context, 0, 0)); move(_block->TEMP(_importedScriptsTemp), _block->NAME(QV4::IR::Name::builtin_qml_imported_scripts_object, 0, 0)); - move(_block->TEMP(_idArrayTemp), _block->NAME(QV4::IR::Name::builtin_qml_id_array, 0, 0)); #endif } @@ -1798,7 +1795,7 @@ QV4::IR::Expr *JSCodeGen::fallbackNameLookup(const QString &name, int line, int foreach (const IdMapping &mapping, _idObjects) if (name == mapping.name) { _function->idObjectDependencies.insert(mapping.idIndex); - QV4::IR::Expr *s = subscript(_block->TEMP(_idArrayTemp), _block->CONST(QV4::IR::SInt32Type, mapping.idIndex)); + QV4::IR::Expr *s = _block->MEMBER(_block->TEMP(_qmlContextTemp), _function->newString(name), 0, QV4::IR::Member::MemberOfIdObjectsArray, mapping.idIndex); QV4::IR::Temp *result = _block->TEMP(_block->newTemp()); _block->MOVE(result, s); result = _block->TEMP(result->index); diff --git a/src/qml/compiler/qqmlirbuilder_p.h b/src/qml/compiler/qqmlirbuilder_p.h index 8d8978d947..5617912081 100644 --- a/src/qml/compiler/qqmlirbuilder_p.h +++ b/src/qml/compiler/qqmlirbuilder_p.h @@ -497,7 +497,6 @@ private: QQmlPropertyCache *_scopeObject; int _qmlContextTemp; int _importedScriptsTemp; - int _idArrayTemp; }; } // namespace QmlIR diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp index cf37806d7c..911be238b9 100644 --- a/src/qml/compiler/qqmltypecompiler.cpp +++ b/src/qml/compiler/qqmltypecompiler.cpp @@ -2624,7 +2624,6 @@ void QQmlJavaScriptBindingExpressionSimplificationPass::visitMove(QV4::IR::Move if (QV4::IR::Name *n = move->source->asName()) { if (n->builtin == QV4::IR::Name::builtin_qml_context - || n->builtin == QV4::IR::Name::builtin_qml_id_array || n->builtin == QV4::IR::Name::builtin_qml_imported_scripts_object) { // these are free of side-effects return; diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h index 886ff99ce7..6839c7f609 100644 --- a/src/qml/compiler/qv4instr_moth_p.h +++ b/src/qml/compiler/qv4instr_moth_p.h @@ -68,6 +68,7 @@ QT_BEGIN_NAMESPACE F(StoreContextObjectProperty, storeContextObjectProperty) \ F(LoadScopeObjectProperty, loadScopeObjectProperty) \ F(LoadContextObjectProperty, loadContextObjectProperty) \ + F(LoadIdObject, loadIdObject) \ F(LoadAttachedQObjectProperty, loadAttachedQObjectProperty) \ F(LoadSingletonQObjectProperty, loadQObjectProperty) \ F(Push, push) \ @@ -132,7 +133,6 @@ QT_BEGIN_NAMESPACE F(BinopContext, binopContext) \ F(LoadThis, loadThis) \ F(LoadQmlContext, loadQmlContext) \ - F(LoadQmlIdArray, loadQmlIdArray) \ F(LoadQmlImportedScripts, loadQmlImportedScripts) \ F(LoadQmlSingleton, loadQmlSingleton) @@ -310,6 +310,12 @@ union Instr Param base; Param result; }; + struct instr_loadIdObject { + MOTH_INSTR_HEADER + int index; + Param base; + Param result; + }; struct instr_loadQObjectProperty { MOTH_INSTR_HEADER int propertyIndex; @@ -733,10 +739,6 @@ union Instr MOTH_INSTR_HEADER Param result; }; - struct instr_loadQmlIdArray { - MOTH_INSTR_HEADER - Param result; - }; struct instr_loadQmlImportedScripts { MOTH_INSTR_HEADER Param result; @@ -768,6 +770,7 @@ union Instr instr_getLookup getLookup; instr_loadScopeObjectProperty loadScopeObjectProperty; instr_loadContextObjectProperty loadContextObjectProperty; + instr_loadIdObject loadIdObject; instr_loadQObjectProperty loadQObjectProperty; instr_loadAttachedQObjectProperty loadAttachedQObjectProperty; instr_storeProperty storeProperty; @@ -837,7 +840,6 @@ union Instr instr_binopContext binopContext; instr_loadThis loadThis; instr_loadQmlContext loadQmlContext; - instr_loadQmlIdArray loadQmlIdArray; instr_loadQmlImportedScripts loadQmlImportedScripts; instr_loadQmlSingleton loadQmlSingleton; diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp index 4830f01152..ede1e6938f 100644 --- a/src/qml/compiler/qv4isel_moth.cpp +++ b/src/qml/compiler/qv4isel_moth.cpp @@ -595,13 +595,6 @@ void InstructionSelection::loadQmlContext(IR::Expr *e) addInstruction(load); } -void InstructionSelection::loadQmlIdArray(IR::Expr *e) -{ - Instruction::LoadQmlIdArray load; - load.result = getResultParam(e); - addInstruction(load); -} - void InstructionSelection::loadQmlImportedScripts(IR::Expr *e) { Instruction::LoadQmlImportedScripts load; @@ -752,6 +745,12 @@ void InstructionSelection::getQmlContextProperty(IR::Expr *source, IR::Member::M load.propertyIndex = index; load.result = getResultParam(target); addInstruction(load); + } else if (kind == IR::Member::MemberOfIdObjectsArray) { + Instruction::LoadIdObject load; + load.base = getParam(source); + load.index = index; + load.result = getResultParam(target); + addInstruction(load); } else { Q_ASSERT(false); } diff --git a/src/qml/compiler/qv4isel_moth_p.h b/src/qml/compiler/qv4isel_moth_p.h index 64e12489ca..ac1eaba740 100644 --- a/src/qml/compiler/qv4isel_moth_p.h +++ b/src/qml/compiler/qv4isel_moth_p.h @@ -104,7 +104,6 @@ protected: virtual void constructValue(IR::Expr *value, IR::ExprList *args, IR::Expr *result); virtual void loadThisObject(IR::Expr *e); virtual void loadQmlContext(IR::Expr *e); - virtual void loadQmlIdArray(IR::Expr *e); virtual void loadQmlImportedScripts(IR::Expr *e); virtual void loadQmlSingleton(const QString &name, IR::Expr *e); virtual void loadConst(IR::Const *sourceConst, IR::Expr *e); diff --git a/src/qml/compiler/qv4isel_p.cpp b/src/qml/compiler/qv4isel_p.cpp index 4ed321b006..9d172b1223 100644 --- a/src/qml/compiler/qv4isel_p.cpp +++ b/src/qml/compiler/qv4isel_p.cpp @@ -93,8 +93,6 @@ void IRDecoder::visitMove(IR::Move *s) loadThisObject(s->target); else if (n->builtin == IR::Name::builtin_qml_context) loadQmlContext(s->target); - else if (n->builtin == IR::Name::builtin_qml_id_array) - loadQmlIdArray(s->target); else if (n->builtin == IR::Name::builtin_qml_imported_scripts_object) loadQmlImportedScripts(s->target); else if (n->qmlSingleton) @@ -138,8 +136,8 @@ void IRDecoder::visitMove(IR::Move *s) #else bool captureRequired = true; - Q_ASSERT(m->kind != IR::Member::MemberOfEnum); - const int attachedPropertiesId = m->attachedPropertiesIdOrEnumValue; + Q_ASSERT(m->kind != IR::Member::MemberOfEnum && m->kind != IR::Member::MemberOfIdObjectsArray); + const int attachedPropertiesId = m->attachedPropertiesId; const bool isSingletonProperty = m->kind == IR::Member::MemberOfSingletonObject; if (_function && attachedPropertiesId == 0 && !m->property->isConstant()) { @@ -158,6 +156,9 @@ void IRDecoder::visitMove(IR::Move *s) getQObjectProperty(m->base, m->property->coreIndex, captureRequired, isSingletonProperty, attachedPropertiesId, s->target); #endif // V4_BOOTSTRAP return; + } else if (m->kind == IR::Member::MemberOfIdObjectsArray) { + getQmlContextProperty(m->base, (IR::Member::MemberKind)m->kind, m->idIndex, s->target); + return; } else if (m->base->asTemp() || m->base->asConst() || m->base->asArgLocal()) { getProperty(m->base, *m->name, s->target); return; @@ -177,6 +178,7 @@ void IRDecoder::visitMove(IR::Move *s) return; } else if (Member *member = c->base->asMember()) { #ifndef V4_BOOTSTRAP + Q_ASSERT(member->kind != IR::Member::MemberOfIdObjectsArray); if (member->kind == IR::Member::MemberOfQmlScopeObject || member->kind == IR::Member::MemberOfQmlContextObject) { callQmlContextProperty(member->base, (IR::Member::MemberKind)member->kind, member->property->coreIndex, c->args, s->target); return; @@ -200,7 +202,8 @@ void IRDecoder::visitMove(IR::Move *s) if (m->base->asTemp() || m->base->asConst() || m->base->asArgLocal()) { if (s->source->asTemp() || s->source->asConst() || s->source->asArgLocal()) { Q_ASSERT(m->kind != IR::Member::MemberOfEnum); - const int attachedPropertiesId = m->attachedPropertiesIdOrEnumValue; + Q_ASSERT(m->kind != IR::Member::MemberOfIdObjectsArray); + const int attachedPropertiesId = m->attachedPropertiesId; if (m->property && attachedPropertiesId == 0) { #ifdef V4_BOOTSTRAP Q_UNIMPLEMENTED(); @@ -251,6 +254,7 @@ void IRDecoder::visitExp(IR::Exp *s) } else if (Member *member = c->base->asMember()) { Q_ASSERT(member->base->asTemp() || member->base->asArgLocal()); #ifndef V4_BOOTSTRAP + Q_ASSERT(member->kind != IR::Member::MemberOfIdObjectsArray); if (member->kind == IR::Member::MemberOfQmlScopeObject || member->kind == IR::Member::MemberOfQmlContextObject) { callQmlContextProperty(member->base, (IR::Member::MemberKind)member->kind, member->property->coreIndex, c->args, 0); return; diff --git a/src/qml/compiler/qv4isel_p.h b/src/qml/compiler/qv4isel_p.h index 80040da185..2b8aa7eb33 100644 --- a/src/qml/compiler/qv4isel_p.h +++ b/src/qml/compiler/qv4isel_p.h @@ -138,7 +138,6 @@ public: // to implement by subclasses: virtual void constructValue(IR::Expr *value, IR::ExprList *args, IR::Expr *result) = 0; virtual void loadThisObject(IR::Expr *target) = 0; virtual void loadQmlContext(IR::Expr *target) = 0; - virtual void loadQmlIdArray(IR::Expr *target) = 0; virtual void loadQmlImportedScripts(IR::Expr *target) = 0; virtual void loadQmlSingleton(const QString &name, IR::Expr *target) = 0; virtual void loadConst(IR::Const *sourceConst, IR::Expr *target) = 0; diff --git a/src/qml/compiler/qv4jsir.cpp b/src/qml/compiler/qv4jsir.cpp index 841a1aefcc..98b53c6b3b 100644 --- a/src/qml/compiler/qv4jsir.cpp +++ b/src/qml/compiler/qv4jsir.cpp @@ -343,8 +343,6 @@ const char *builtin_to_string(Name::Builtin b) return "builtin_convert_this_to_object"; case IR::Name::builtin_qml_context: return "builtin_qml_context"; - case IR::Name::builtin_qml_id_array: - return "builtin_qml_id_array"; case IR::Name::builtin_qml_imported_scripts_object: return "builtin_qml_imported_scripts_object"; } @@ -933,7 +931,7 @@ void CloneExpr::visitSubscript(Subscript *e) void CloneExpr::visitMember(Member *e) { Expr *clonedBase = clone(e->base); - cloned = block->MEMBER(clonedBase, e->name, e->property, e->kind, e->attachedPropertiesIdOrEnumValue); + cloned = block->MEMBER(clonedBase, e->name, e->property, e->kind, e->idIndex); } IRPrinter::IRPrinter(QTextStream *out) @@ -1237,9 +1235,9 @@ void IRPrinter::visitSubscript(Subscript *e) void IRPrinter::visitMember(Member *e) { - if (e->kind != Member::MemberOfEnum - && e->attachedPropertiesIdOrEnumValue != 0 && !e->base->asTemp()) - *out << "[[attached property from " << e->attachedPropertiesIdOrEnumValue << "]]"; + if (e->kind != Member::MemberOfEnum && e->kind != Member::MemberOfIdObjectsArray + && e->attachedPropertiesId != 0 && !e->base->asTemp()) + *out << "[[attached property from " << e->attachedPropertiesId << "]]"; else e->base->accept(this); *out << '.' << *e->name; @@ -1248,6 +1246,8 @@ void IRPrinter::visitMember(Member *e) *out << " (meta-property " << e->property->coreIndex << " <" << QMetaType::typeName(e->property->propType) << ">)"; + else if (e->kind == Member::MemberOfIdObjectsArray) + *out << "(id object " << e->idIndex << ")"; #endif } diff --git a/src/qml/compiler/qv4jsir_p.h b/src/qml/compiler/qv4jsir_p.h index a4fb5246d0..568ded5337 100644 --- a/src/qml/compiler/qv4jsir_p.h +++ b/src/qml/compiler/qv4jsir_p.h @@ -338,7 +338,6 @@ struct Name: Expr { builtin_setup_argument_object, builtin_convert_this_to_object, builtin_qml_context, - builtin_qml_id_array, builtin_qml_imported_scripts_object }; @@ -557,13 +556,18 @@ struct Member: Expr { MemberOfEnum, MemberOfQmlScopeObject, MemberOfQmlContextObject, - MemberOfSingletonObject + MemberOfIdObjectsArray, + MemberOfSingletonObject, }; Expr *base; const QString *name; QQmlPropertyData *property; - int attachedPropertiesIdOrEnumValue; // depending on kind + union { // depending on kind + int attachedPropertiesId; + int enumValue; + int idIndex; + }; uchar freeOfSideEffects : 1; // This is set for example for for QObject properties. All sorts of extra behavior @@ -576,20 +580,20 @@ struct Member: Expr { void setEnumValue(int value) { kind = MemberOfEnum; - attachedPropertiesIdOrEnumValue = value; + enumValue = value; } void setAttachedPropertiesId(int id) { - Q_ASSERT(kind != MemberOfEnum); - attachedPropertiesIdOrEnumValue = id; + Q_ASSERT(kind != MemberOfEnum && kind != MemberOfIdObjectsArray); + attachedPropertiesId = id; } - void init(Expr *base, const QString *name, QQmlPropertyData *property = 0, uchar kind = UnspecifiedMember, int attachedPropertiesIdOrEnumValue = 0) + void init(Expr *base, const QString *name, QQmlPropertyData *property = 0, uchar kind = UnspecifiedMember, int index = 0) { this->base = base; this->name = name; this->property = property; - this->attachedPropertiesIdOrEnumValue = attachedPropertiesIdOrEnumValue; + this->idIndex = index; this->freeOfSideEffects = false; this->inhibitTypeConversionOnWrite = property != 0; this->kind = kind; diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp index e61a602e64..cc60dde4cc 100644 --- a/src/qml/compiler/qv4ssa.cpp +++ b/src/qml/compiler/qv4ssa.cpp @@ -4020,14 +4020,14 @@ void optimizeSSA(StatementWorklist &W, DefUses &defUses, DominatorTree &df) if (Member *member = m->source->asMember()) { if (member->kind == Member::MemberOfEnum) { Const *c = function->New(); - const int enumValue = member->attachedPropertiesIdOrEnumValue; + const int enumValue = member->enumValue; c->init(SInt32Type, enumValue); replaceUses(targetTemp, c, W); defUses.removeDef(*targetTemp); W.remove(s); defUses.removeUse(s, *member->base->asTemp()); continue; - } else if (member->attachedPropertiesIdOrEnumValue != 0 && member->property && member->base->asTemp()) { + } else if (member->kind != IR::Member::MemberOfIdObjectsArray && member->attachedPropertiesId != 0 && member->property && member->base->asTemp()) { // Attached properties have no dependency on their base. Isel doesn't // need it and we can eliminate the temp used to initialize it. defUses.removeUse(s, *member->base->asTemp()); -- cgit v1.2.3