aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2013-11-02 18:48:18 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-11-25 22:04:42 +0100
commita41764cafbc85c271edde8d09eae46798ccdcb8d (patch)
treecb027ea57c6f764bdc277bf899caa3f8a866647b /src/qml/compiler
parent62c906059516bb829f05073096fd3e12f5103fba (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.cpp12
-rw-r--r--src/qml/compiler/qqmlcodegenerator_p.h2
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h7
-rw-r--r--src/qml/compiler/qv4isel_masm.cpp4
-rw-r--r--src/qml/compiler/qv4isel_masm_p.h2
-rw-r--r--src/qml/compiler/qv4isel_moth.cpp5
-rw-r--r--src/qml/compiler/qv4isel_moth_p.h2
-rw-r--r--src/qml/compiler/qv4isel_p.cpp12
-rw-r--r--src/qml/compiler/qv4isel_p.h2
-rw-r--r--src/qml/compiler/qv4jsir.cpp18
-rw-r--r--src/qml/compiler/qv4jsir_p.h30
-rw-r--r--src/qml/compiler/qv4regalloc.cpp3
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();
}