diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2013-11-02 18:48:18 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-11-25 22:04:42 +0100 |
commit | a41764cafbc85c271edde8d09eae46798ccdcb8d (patch) | |
tree | cb027ea57c6f764bdc277bf899caa3f8a866647b /src/qml/compiler | |
parent | 62c906059516bb829f05073096fd3e12f5103fba (diff) |
IR Cleanup, resolve ID objects through array subscripts
...instead of a special MEMBER type. This allows removing the
type member from V4IR::Member altogether (and thus unshadow from
V4IR::Expr::type). By not requiring the base of a id lookup
member expression to be a NAME, we can also speed up repeated
id lookups by fetching the id object array wrapper only once
per function.
Change-Id: I3e9b8f498d32ace4a0cc2254f49e02ecc124f79c
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/qml/compiler')
-rw-r--r-- | src/qml/compiler/qqmlcodegenerator.cpp | 12 | ||||
-rw-r--r-- | src/qml/compiler/qqmlcodegenerator_p.h | 2 | ||||
-rw-r--r-- | src/qml/compiler/qv4instr_moth_p.h | 7 | ||||
-rw-r--r-- | src/qml/compiler/qv4isel_masm.cpp | 4 | ||||
-rw-r--r-- | src/qml/compiler/qv4isel_masm_p.h | 2 | ||||
-rw-r--r-- | src/qml/compiler/qv4isel_moth.cpp | 5 | ||||
-rw-r--r-- | src/qml/compiler/qv4isel_moth_p.h | 2 | ||||
-rw-r--r-- | src/qml/compiler/qv4isel_p.cpp | 12 | ||||
-rw-r--r-- | src/qml/compiler/qv4isel_p.h | 2 | ||||
-rw-r--r-- | src/qml/compiler/qv4jsir.cpp | 18 | ||||
-rw-r--r-- | src/qml/compiler/qv4jsir_p.h | 30 | ||||
-rw-r--r-- | src/qml/compiler/qv4regalloc.cpp | 3 |
12 files changed, 34 insertions, 65 deletions
diff --git a/src/qml/compiler/qqmlcodegenerator.cpp b/src/qml/compiler/qqmlcodegenerator.cpp index 4e1d2ef9c8..b38e2670e6 100644 --- a/src/qml/compiler/qqmlcodegenerator.cpp +++ b/src/qml/compiler/qqmlcodegenerator.cpp @@ -1213,6 +1213,7 @@ JSCodeGen::JSCodeGen(QQmlEnginePrivate *enginePrivate, const QString &fileName, , _contextObjectTemp(-1) , _scopeObjectTemp(-1) , _importedScriptsTemp(-1) + , _idArrayTemp(-1) { _module = jsModule; _module->setFileName(fileName); @@ -1372,6 +1373,7 @@ void JSCodeGen::beginFunctionBodyHook() _contextObjectTemp = _block->newTemp(); _scopeObjectTemp = _block->newTemp(); _importedScriptsTemp = _block->newTemp(); + _idArrayTemp = _block->newTemp(); V4IR::Temp *temp = _block->TEMP(_contextObjectTemp); initMetaObjectResolver(&temp->memberResolver, _contextObject); @@ -1382,6 +1384,7 @@ void JSCodeGen::beginFunctionBodyHook() move(temp, _block->NAME(V4IR::Name::builtin_qml_scope_object, 0, 0)); move(_block->TEMP(_importedScriptsTemp), _block->NAME(V4IR::Name::builtin_qml_imported_scripts_object, 0, 0)); + move(_block->TEMP(_idArrayTemp), _block->NAME(V4IR::Name::builtin_qml_id_array, 0, 0)); } V4IR::Expr *JSCodeGen::fallbackNameLookup(const QString &name, int line, int col) @@ -1403,8 +1406,13 @@ V4IR::Expr *JSCodeGen::fallbackNameLookup(const QString &name, int line, int col foreach (const IdMapping &mapping, _idObjects) if (name == mapping.name) { _function->idObjectDependencies.insert(mapping.idIndex); - return _block->QML_CONTEXT_MEMBER(_block->NAME(V4IR::Name::builtin_qml_id_scope, line, col), - _function->newString(mapping.name), mapping.idIndex); + V4IR::Expr *s = subscript(_block->TEMP(_idArrayTemp), _block->CONST(V4IR::SInt32Type, mapping.idIndex)); + V4IR::Temp *result = _block->TEMP(_block->newTemp()); + initMetaObjectResolver(&result->memberResolver, mapping.type); + _block->MOVE(result, s); + result = _block->TEMP(result->index); + result->isReadOnly = true; // don't allow use as lvalue + return result; } { diff --git a/src/qml/compiler/qqmlcodegenerator_p.h b/src/qml/compiler/qqmlcodegenerator_p.h index 4f80a7f148..636f2827bb 100644 --- a/src/qml/compiler/qqmlcodegenerator_p.h +++ b/src/qml/compiler/qqmlcodegenerator_p.h @@ -381,7 +381,7 @@ private: int _contextObjectTemp; int _scopeObjectTemp; int _importedScriptsTemp; - int _idScopeTemp; + int _idArrayTemp; }; } // namespace QtQml diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h index a2b8c870a5..5c92439f0c 100644 --- a/src/qml/compiler/qv4instr_moth_p.h +++ b/src/qml/compiler/qv4instr_moth_p.h @@ -126,7 +126,7 @@ QT_BEGIN_NAMESPACE F(MulNumberParams, mulNumberParams) \ F(SubNumberParams, subNumberParams) \ F(LoadThis, loadThis) \ - F(LoadQmlIdObject, loadQmlIdObject) \ + F(LoadQmlIdArray, loadQmlIdArray) \ F(LoadQmlImportedScripts, loadQmlImportedScripts) \ F(LoadQmlContextObject, loadQmlContextObject) \ F(LoadQmlScopeObject, loadQmlScopeObject) @@ -654,10 +654,9 @@ union Instr MOTH_INSTR_HEADER Param result; }; - struct instr_loadQmlIdObject { + struct instr_loadQmlIdArray { MOTH_INSTR_HEADER Param result; - int id; }; struct instr_loadQmlImportedScripts { MOTH_INSTR_HEADER @@ -749,7 +748,7 @@ union Instr instr_mulNumberParams mulNumberParams; instr_subNumberParams subNumberParams; instr_loadThis loadThis; - instr_loadQmlIdObject loadQmlIdObject; + instr_loadQmlIdArray loadQmlIdArray; instr_loadQmlImportedScripts loadQmlImportedScripts; instr_loadQmlContextObject loadQmlContextObject; instr_loadQmlScopeObject loadQmlScopeObject; diff --git a/src/qml/compiler/qv4isel_masm.cpp b/src/qml/compiler/qv4isel_masm.cpp index 6f8bf13bd7..0854dd55ab 100644 --- a/src/qml/compiler/qv4isel_masm.cpp +++ b/src/qml/compiler/qv4isel_masm.cpp @@ -880,9 +880,9 @@ void InstructionSelection::loadThisObject(V4IR::Temp *temp) #endif } -void InstructionSelection::loadQmlIdObject(int id, V4IR::Temp *temp) +void InstructionSelection::loadQmlIdArray(V4IR::Temp *temp) { - generateFunctionCall(temp, __qmljs_get_id_object, Assembler::ContextRegister, Assembler::TrustedImm32(id)); + generateFunctionCall(temp, __qmljs_get_id_array, Assembler::ContextRegister); } void InstructionSelection::loadQmlImportedScripts(V4IR::Temp *temp) diff --git a/src/qml/compiler/qv4isel_masm_p.h b/src/qml/compiler/qv4isel_masm_p.h index 0c2c994e32..5a02b62a73 100644 --- a/src/qml/compiler/qv4isel_masm_p.h +++ b/src/qml/compiler/qv4isel_masm_p.h @@ -1457,7 +1457,7 @@ protected: virtual void callSubscript(V4IR::Expr *base, V4IR::Expr *index, V4IR::ExprList *args, V4IR::Temp *result); virtual void convertType(V4IR::Temp *source, V4IR::Temp *target); virtual void loadThisObject(V4IR::Temp *temp); - virtual void loadQmlIdObject(int id, V4IR::Temp *temp); + virtual void loadQmlIdArray(V4IR::Temp *temp); virtual void loadQmlImportedScripts(V4IR::Temp *temp); virtual void loadQmlContextObject(V4IR::Temp *temp); virtual void loadQmlScopeObject(V4IR::Temp *temp); diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp index 1b973b2359..c76c236de4 100644 --- a/src/qml/compiler/qv4isel_moth.cpp +++ b/src/qml/compiler/qv4isel_moth.cpp @@ -388,11 +388,10 @@ void InstructionSelection::loadThisObject(V4IR::Temp *temp) addInstruction(load); } -void InstructionSelection::loadQmlIdObject(int id, V4IR::Temp *temp) +void InstructionSelection::loadQmlIdArray(V4IR::Temp *temp) { - Instruction::LoadQmlIdObject load; + Instruction::LoadQmlIdArray load; load.result = getResultParam(temp); - load.id = id; addInstruction(load); } diff --git a/src/qml/compiler/qv4isel_moth_p.h b/src/qml/compiler/qv4isel_moth_p.h index ef26ba875d..bde7997c33 100644 --- a/src/qml/compiler/qv4isel_moth_p.h +++ b/src/qml/compiler/qv4isel_moth_p.h @@ -112,7 +112,7 @@ protected: virtual void constructProperty(V4IR::Temp *base, const QString &name, V4IR::ExprList *args, V4IR::Temp *result); virtual void constructValue(V4IR::Temp *value, V4IR::ExprList *args, V4IR::Temp *result); virtual void loadThisObject(V4IR::Temp *temp); - virtual void loadQmlIdObject(int id, V4IR::Temp *temp); + virtual void loadQmlIdArray(V4IR::Temp *temp); virtual void loadQmlImportedScripts(V4IR::Temp *temp); virtual void loadQmlContextObject(V4IR::Temp *temp); virtual void loadQmlScopeObject(V4IR::Temp *temp); diff --git a/src/qml/compiler/qv4isel_p.cpp b/src/qml/compiler/qv4isel_p.cpp index b3407867b4..a14a11c43e 100644 --- a/src/qml/compiler/qv4isel_p.cpp +++ b/src/qml/compiler/qv4isel_p.cpp @@ -103,6 +103,8 @@ void IRDecoder::visitMove(V4IR::Move *s) if (V4IR::Name *n = s->source->asName()) { if (n->id && *n->id == QStringLiteral("this")) // TODO: `this' should be a builtin. loadThisObject(t); + else if (n->builtin == V4IR::Name::builtin_qml_id_array) + loadQmlIdArray(t); else if (n->builtin == V4IR::Name::builtin_qml_context_object) loadQmlContextObject(t); else if (n->builtin == V4IR::Name::builtin_qml_scope_object) @@ -142,15 +144,7 @@ void IRDecoder::visitMove(V4IR::Move *s) return; } } else if (V4IR::Member *m = s->source->asMember()) { - if (m->type == V4IR::Member::MemberOfQmlContext) { - V4IR::Name *base = m->base->asName(); - Q_ASSERT(base); - - if (base->builtin == V4IR::Name::builtin_qml_id_scope) { - loadQmlIdObject(m->memberIndex, t); - return; - } - } else if (m->property) { + if (m->property) { bool captureRequired = true; if (_function) { captureRequired = !_function->contextObjectDependencies.contains(m->property) diff --git a/src/qml/compiler/qv4isel_p.h b/src/qml/compiler/qv4isel_p.h index 647d85996d..6671ac1426 100644 --- a/src/qml/compiler/qv4isel_p.h +++ b/src/qml/compiler/qv4isel_p.h @@ -144,7 +144,7 @@ public: // to implement by subclasses: virtual void constructProperty(V4IR::Temp *base, const QString &name, V4IR::ExprList *args, V4IR::Temp *result) = 0; virtual void constructValue(V4IR::Temp *value, V4IR::ExprList *args, V4IR::Temp *result) = 0; virtual void loadThisObject(V4IR::Temp *temp) = 0; - virtual void loadQmlIdObject(int id, V4IR::Temp *temp) = 0; + virtual void loadQmlIdArray(V4IR::Temp *temp) = 0; virtual void loadQmlImportedScripts(V4IR::Temp *temp) = 0; virtual void loadQmlContextObject(V4IR::Temp *temp) = 0; virtual void loadQmlScopeObject(V4IR::Temp *temp) = 0; diff --git a/src/qml/compiler/qv4jsir.cpp b/src/qml/compiler/qv4jsir.cpp index 949a73432d..79b963f400 100644 --- a/src/qml/compiler/qv4jsir.cpp +++ b/src/qml/compiler/qv4jsir.cpp @@ -433,8 +433,8 @@ static const char *builtin_to_string(Name::Builtin b) return "builtin_setup_argument_object"; case V4IR::Name::builtin_convert_this_to_object: return "builtin_convert_this_to_object"; - case V4IR::Name::builtin_qml_id_scope: - return "builtin_qml_id_scope"; + case V4IR::Name::builtin_qml_id_array: + return "builtin_qml_id_array"; case V4IR::Name::builtin_qml_imported_scripts_object: return "builtin_qml_imported_scripts_object"; case V4IR::Name::builtin_qml_scope_object: @@ -841,13 +841,6 @@ Expr *BasicBlock::MEMBER(Expr *base, const QString *name, QQmlPropertyData *prop return e; } -Expr *BasicBlock::QML_CONTEXT_MEMBER(Expr *base, const QString *id, int memberIndex) -{ - Member*e = function->New<Member>(); - e->initQmlContextMember(base, id, memberIndex); - return e; -} - Stmt *BasicBlock::EXP(Expr *expr) { if (isTerminated()) @@ -1034,12 +1027,7 @@ void CloneExpr::visitSubscript(Subscript *e) void CloneExpr::visitMember(Member *e) { - if (e->type == Member::MemberByName) - cloned = block->MEMBER(clone(e->base), e->name, e->property); - else if (e->type == Member::MemberOfQmlContext) - cloned = block->QML_CONTEXT_MEMBER(clone(e->base), e->name, e->memberIndex); - else - Q_ASSERT(!"Unimplemented!"); + cloned = block->MEMBER(clone(e->base), e->name, e->property); } } // end of namespace IR diff --git a/src/qml/compiler/qv4jsir_p.h b/src/qml/compiler/qv4jsir_p.h index 5fd58acba4..fd54460b5c 100644 --- a/src/qml/compiler/qv4jsir_p.h +++ b/src/qml/compiler/qv4jsir_p.h @@ -343,7 +343,7 @@ struct Name: Expr { builtin_define_object_literal, builtin_setup_argument_object, builtin_convert_this_to_object, - builtin_qml_id_scope, + builtin_qml_id_array, builtin_qml_imported_scripts_object, builtin_qml_context_object, builtin_qml_scope_object @@ -378,9 +378,10 @@ struct Temp: Expr { }; unsigned index; - unsigned scope : 28; // how many scopes outside the current one? + unsigned scope : 27; // how many scopes outside the current one? unsigned kind : 3; unsigned isArgumentsOrEval : 1; + unsigned isReadOnly : 1; // Used when temp is used as base in member expression MemberExpressionResolver memberResolver; @@ -394,10 +395,11 @@ struct Temp: Expr { this->index = index; this->scope = scope; this->isArgumentsOrEval = false; + this->isReadOnly = false; } virtual void accept(ExprVisitor *v) { v->visitTemp(this); } - virtual bool isLValue() { return true; } + virtual bool isLValue() { return !isReadOnly; } virtual Temp *asTemp() { return this; } virtual void dump(QTextStream &out) const; @@ -538,38 +540,19 @@ struct Subscript: Expr { }; struct Member: Expr { - enum MemberType { - MemberByName, - // QML extensions - MemberOfQmlContext // lookup in context's id values - }; - - MemberType type; Expr *base; const QString *name; - int memberIndex; // used if type == MemberOfQmlContext QQmlPropertyData *property; void init(Expr *base, const QString *name, QQmlPropertyData *property = 0) { - this->type = MemberByName; this->base = base; this->name = name; - this->memberIndex = -1; this->property = property; } - void initQmlContextMember(Expr *base, const QString *name, int memberIndex) - { - this->type = MemberOfQmlContext; - this->base = base; - this->name = name; - this->memberIndex = memberIndex; - this->property = 0; - } - virtual void accept(ExprVisitor *v) { v->visitMember(this); } - virtual bool isLValue() { return type != MemberOfQmlContext; } + virtual bool isLValue() { return true; } virtual Member *asMember() { return this; } virtual void dump(QTextStream &out) const; @@ -872,7 +855,6 @@ struct BasicBlock { Expr *NEW(Expr *base, ExprList *args = 0); Expr *SUBSCRIPT(Expr *base, Expr *index); Expr *MEMBER(Expr *base, const QString *name, QQmlPropertyData *property = 0); - Expr *QML_CONTEXT_MEMBER(Expr *base, const QString *id, int memberIndex); Stmt *EXP(Expr *expr); diff --git a/src/qml/compiler/qv4regalloc.cpp b/src/qml/compiler/qv4regalloc.cpp index a0245c6808..a1594da82e 100644 --- a/src/qml/compiler/qv4regalloc.cpp +++ b/src/qml/compiler/qv4regalloc.cpp @@ -338,9 +338,8 @@ protected: // IRDecoder addDef(temp); } - virtual void loadQmlIdObject(int id, V4IR::Temp *temp) + virtual void loadQmlIdArray(V4IR::Temp *temp) { - Q_UNUSED(id); addDef(temp); addCall(); } |