aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2013-10-28 17:02:54 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-10-31 18:55:14 +0100
commitf0ad3a5943804e9eb8e03434a4584eaafa5c5aea (patch)
tree8d2cb4402d63ced4e89c6c610fc839e0260d8e92
parentb0afac3daf1cbb9daacbeac0183ef6254de6cc95 (diff)
Implement loading of resolved imported scripts
We can resolve the use of names that refer to imported scripts at compile time and load them at run-time by index through context->importedScripts. Change-Id: I681b19e7d68dbf3b9a68af00b4cea2a9254c2d78 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
-rw-r--r--src/qml/compiler/qqmlcodegenerator.cpp16
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h7
-rw-r--r--src/qml/compiler/qv4isel_masm.cpp7
-rw-r--r--src/qml/compiler/qv4isel_masm_p.h3
-rw-r--r--src/qml/compiler/qv4isel_moth.cpp10
-rw-r--r--src/qml/compiler/qv4isel_moth_p.h3
-rw-r--r--src/qml/compiler/qv4isel_p.cpp14
-rw-r--r--src/qml/compiler/qv4isel_p.h3
-rw-r--r--src/qml/compiler/qv4jsir.cpp20
-rw-r--r--src/qml/compiler/qv4jsir_p.h15
-rw-r--r--src/qml/compiler/qv4regalloc.cpp8
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp6
-rw-r--r--src/qml/jsruntime/qv4runtime_p.h1
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp4
14 files changed, 88 insertions, 29 deletions
diff --git a/src/qml/compiler/qqmlcodegenerator.cpp b/src/qml/compiler/qqmlcodegenerator.cpp
index 5fefa61a7a..40e64205ae 100644
--- a/src/qml/compiler/qqmlcodegenerator.cpp
+++ b/src/qml/compiler/qqmlcodegenerator.cpp
@@ -1324,11 +1324,11 @@ V4IR::Expr *JSCodeGen::member(V4IR::Expr *base, const QString *name)
// Check if it's suitable for caching
if (propertySuitable)
cache = engine->propertyCacheForType(baseAsMember->property->propType);
- } else if (baseAsMember->type == V4IR::Member::MemberByObjectId) {
+ } else if (baseAsMember->type == V4IR::Member::MemberOfQmlContext) {
// Similarly, properties of an id referenced object also don't need to be final, because
// we intend to find the version of a property available at compile time, not at run-time.
foreach (const IdMapping &mapping, _idObjects) {
- if (baseAsMember->objectId == mapping.idIndex) {
+ if (baseAsMember->memberIndex == mapping.idIndex) {
cache = mapping.type;
break;
}
@@ -1363,15 +1363,21 @@ V4IR::Expr *JSCodeGen::fallbackNameLookup(const QString &name, int line, int col
// Look for IDs first.
foreach (const IdMapping &mapping, _idObjects)
if (name == mapping.name) {
- result = _block->QML_CONTEXT_ID_MEMBER(_block->NAME(V4IR::Name::builtin_qml_id_scope, line, col),
+ result = _block->QML_CONTEXT_MEMBER(_block->NAME(V4IR::Name::builtin_qml_id_scope, line, col),
_function->newString(mapping.name), mapping.idIndex);
break;
}
if (!result) {
QQmlTypeNameCache::Result r = imports->query(name);
- if (r.isValid())
- return 0; // TODO: We can't do fast lookup for these yet.
+ if (r.isValid()) {
+ if (r.scriptIndex != -1) {
+ result = _block->QML_CONTEXT_MEMBER(_block->NAME(V4IR::Name::builtin_qml_imported_scripts_scope, line, col),
+ _function->newString(name), r.scriptIndex);
+ } else {
+ return 0; // TODO: We can't do fast lookup for these yet.
+ }
+ }
}
if (!result && _scopeObject) {
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h
index 99aed0db97..d99e0fee0d 100644
--- a/src/qml/compiler/qv4instr_moth_p.h
+++ b/src/qml/compiler/qv4instr_moth_p.h
@@ -125,6 +125,7 @@ QT_BEGIN_NAMESPACE
F(SubNumberParams, subNumberParams) \
F(LoadThis, loadThis) \
F(LoadQmlIdObject, loadQmlIdObject) \
+ F(LoadQmlImportedScript, loadQmlImportedScript) \
F(LoadQmlContextObject, loadQmlContextObject) \
F(LoadQmlScopeObject, loadQmlScopeObject)
@@ -644,6 +645,11 @@ union Instr
Param result;
int id;
};
+ struct instr_loadQmlImportedScript {
+ MOTH_INSTR_HEADER
+ Param result;
+ int index;
+ };
struct instr_loadQmlContextObject {
MOTH_INSTR_HEADER
Param result;
@@ -729,6 +735,7 @@ union Instr
instr_subNumberParams subNumberParams;
instr_loadThis loadThis;
instr_loadQmlIdObject loadQmlIdObject;
+ instr_loadQmlImportedScript loadQmlImportedScript;
instr_loadQmlContextObject loadQmlContextObject;
instr_loadQmlScopeObject loadQmlScopeObject;
diff --git a/src/qml/compiler/qv4isel_masm.cpp b/src/qml/compiler/qv4isel_masm.cpp
index ecfe7dd0a0..7162fe905e 100644
--- a/src/qml/compiler/qv4isel_masm.cpp
+++ b/src/qml/compiler/qv4isel_masm.cpp
@@ -948,11 +948,16 @@ void InstructionSelection::loadThisObject(V4IR::Temp *temp)
#endif
}
-void InstructionSelection::loadIdObject(int id, V4IR::Temp *temp)
+void InstructionSelection::loadQmlIdObject(int id, V4IR::Temp *temp)
{
generateFunctionCall(temp, __qmljs_get_id_object, Assembler::ContextRegister, Assembler::TrustedImm32(id));
}
+void InstructionSelection::loadQmlImportedScript(int index, V4IR::Temp *temp)
+{
+ generateFunctionCall(temp, __qmljs_get_imported_script, Assembler::ContextRegister, Assembler::TrustedImm32(index));
+}
+
void InstructionSelection::loadQmlContextObject(V4IR::Temp *temp)
{
generateFunctionCall(temp, __qmljs_get_context_object, Assembler::ContextRegister);
diff --git a/src/qml/compiler/qv4isel_masm_p.h b/src/qml/compiler/qv4isel_masm_p.h
index b5f95f0062..1db7c5f59e 100644
--- a/src/qml/compiler/qv4isel_masm_p.h
+++ b/src/qml/compiler/qv4isel_masm_p.h
@@ -1469,7 +1469,8 @@ 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 loadIdObject(int id, V4IR::Temp *temp);
+ virtual void loadQmlIdObject(int id, V4IR::Temp *temp);
+ virtual void loadQmlImportedScript(int index, V4IR::Temp *temp);
virtual void loadQmlContextObject(V4IR::Temp *temp);
virtual void loadQmlScopeObject(V4IR::Temp *temp);
virtual void loadConst(V4IR::Const *sourceConst, V4IR::Temp *targetTemp);
diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp
index 954c4f532e..a8d8d7454f 100644
--- a/src/qml/compiler/qv4isel_moth.cpp
+++ b/src/qml/compiler/qv4isel_moth.cpp
@@ -454,7 +454,7 @@ void InstructionSelection::loadThisObject(V4IR::Temp *temp)
addInstruction(load);
}
-void InstructionSelection::loadIdObject(int id, V4IR::Temp *temp)
+void InstructionSelection::loadQmlIdObject(int id, V4IR::Temp *temp)
{
Instruction::LoadQmlIdObject load;
load.result = getResultParam(temp);
@@ -462,6 +462,14 @@ void InstructionSelection::loadIdObject(int id, V4IR::Temp *temp)
addInstruction(load);
}
+void InstructionSelection::loadQmlImportedScript(int index, V4IR::Temp *temp)
+{
+ Instruction::LoadQmlImportedScript load;
+ load.result = getResultParam(temp);
+ load.index = index;
+ addInstruction(load);
+}
+
void InstructionSelection::loadQmlContextObject(V4IR::Temp *temp)
{
Instruction::LoadQmlContextObject load;
diff --git a/src/qml/compiler/qv4isel_moth_p.h b/src/qml/compiler/qv4isel_moth_p.h
index 61fc092c57..8c00954bd3 100644
--- a/src/qml/compiler/qv4isel_moth_p.h
+++ b/src/qml/compiler/qv4isel_moth_p.h
@@ -114,7 +114,8 @@ 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 loadIdObject(int id, V4IR::Temp *temp);
+ virtual void loadQmlIdObject(int id, V4IR::Temp *temp);
+ virtual void loadQmlImportedScript(int index, V4IR::Temp *temp);
virtual void loadQmlContextObject(V4IR::Temp *temp);
virtual void loadQmlScopeObject(V4IR::Temp *temp);
virtual void loadConst(V4IR::Const *sourceConst, V4IR::Temp *targetTemp);
diff --git a/src/qml/compiler/qv4isel_p.cpp b/src/qml/compiler/qv4isel_p.cpp
index d6f0b4b804..3b7509d7bf 100644
--- a/src/qml/compiler/qv4isel_p.cpp
+++ b/src/qml/compiler/qv4isel_p.cpp
@@ -140,9 +140,17 @@ void IRDecoder::visitMove(V4IR::Move *s)
return;
}
} else if (V4IR::Member *m = s->source->asMember()) {
- if (m->type == V4IR::Member::MemberByObjectId) {
- loadIdObject(m->objectId, t);
- return;
+ 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 (base->builtin == V4IR::Name::builtin_qml_imported_scripts_scope) {
+ loadQmlImportedScript(m->memberIndex, t);
+ return;
+ }
} else if (m->type == V4IR::Member::MemberOfQObject) {
getQObjectProperty(m->base, m->property->coreIndex, t);
return;
diff --git a/src/qml/compiler/qv4isel_p.h b/src/qml/compiler/qv4isel_p.h
index bdb998fc0b..177bbeb0d4 100644
--- a/src/qml/compiler/qv4isel_p.h
+++ b/src/qml/compiler/qv4isel_p.h
@@ -140,7 +140,8 @@ 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 loadIdObject(int id, V4IR::Temp *temp) = 0;
+ virtual void loadQmlIdObject(int id, V4IR::Temp *temp) = 0;
+ virtual void loadQmlImportedScript(int index, V4IR::Temp *temp) = 0;
virtual void loadQmlContextObject(V4IR::Temp *temp) = 0;
virtual void loadQmlScopeObject(V4IR::Temp *temp) = 0;
virtual void loadConst(V4IR::Const *sourceConst, V4IR::Temp *targetTemp) = 0;
diff --git a/src/qml/compiler/qv4jsir.cpp b/src/qml/compiler/qv4jsir.cpp
index a3654a1bea..2e80fc1f31 100644
--- a/src/qml/compiler/qv4jsir.cpp
+++ b/src/qml/compiler/qv4jsir.cpp
@@ -424,6 +424,8 @@ static const char *builtin_to_string(Name::Builtin b)
return "builtin_setup_argument_object";
case V4IR::Name::builtin_qml_id_scope:
return "builtin_qml_id_scope";
+ case V4IR::Name::builtin_qml_imported_scripts_scope:
+ return "builtin_qml_imported_scripts_scope";
case V4IR::Name::builtin_qml_scope_object:
return "builtin_qml_scope_object";
case V4IR::Name::builtin_qml_context_object:
@@ -826,11 +828,10 @@ Expr *BasicBlock::MEMBER(Expr *base, const QString *name)
return e;
}
-Expr *BasicBlock::QML_CONTEXT_ID_MEMBER(Expr *base, const QString *id, int objectId)
+Expr *BasicBlock::QML_CONTEXT_MEMBER(Expr *base, const QString *id, int memberIndex)
{
Member*e = function->New<Member>();
- Q_ASSERT(base->asName() && base->asName()->builtin == Name::builtin_qml_id_scope);
- e->initQmlIdObject(base, id, objectId);
+ e->initQmlContextMember(base, id, memberIndex);
return e;
}
@@ -1029,8 +1030,8 @@ void CloneExpr::visitMember(Member *e)
{
if (e->type == Member::MemberByName)
cloned = block->MEMBER(clone(e->base), e->name);
- else if (e->type == Member::MemberByObjectId)
- cloned = block->QML_CONTEXT_ID_MEMBER(clone(e->base), e->name, e->objectId);
+ else if (e->type == Member::MemberOfQmlContext)
+ cloned = block->QML_CONTEXT_MEMBER(clone(e->base), e->name, e->memberIndex);
else if (e->type == Member::MemberOfQObject)
cloned = block->QML_QOBJECT_PROPERTY(clone(e->base), e->name, e->property);
else
@@ -1039,9 +1040,12 @@ void CloneExpr::visitMember(Member *e)
void QmlDependenciesCollector::visitMember(Member *e) {
e->base->accept(this);
- if (e->type == Member::MemberByObjectId)
- _usedIdObjects.insert(e->objectId);
- else if (e->type == Member::MemberOfQObject
+ if (e->type == Member::MemberOfQmlContext) {
+ V4IR::Name *base = e->base->asName();
+ Q_ASSERT(base);
+ if (base->builtin == V4IR::Name::builtin_qml_id_scope)
+ _usedIdObjects.insert(e->memberIndex);
+ } else if (e->type == Member::MemberOfQObject
&& !e->property->isFunction()) { // only non-functions have notifyIndex
if (Name *base = e->base->asName()) {
diff --git a/src/qml/compiler/qv4jsir_p.h b/src/qml/compiler/qv4jsir_p.h
index 7e7a972c54..3cd8bfccb5 100644
--- a/src/qml/compiler/qv4jsir_p.h
+++ b/src/qml/compiler/qv4jsir_p.h
@@ -325,6 +325,7 @@ struct Name: Expr {
builtin_define_object_literal,
builtin_setup_argument_object,
builtin_qml_id_scope,
+ builtin_qml_imported_scripts_scope,
builtin_qml_context_object,
builtin_qml_scope_object
};
@@ -519,14 +520,14 @@ struct Member: Expr {
enum MemberType {
MemberByName,
// QML extensions
- MemberByObjectId, // lookup in context's id values
+ MemberOfQmlContext, // lookup in context's id values
MemberOfQObject
};
MemberType type;
Expr *base;
const QString *name;
- int objectId;
+ int memberIndex; // used if type == MemberOfQmlContext
QQmlPropertyData *property;
void init(Expr *base, const QString *name)
@@ -534,16 +535,16 @@ struct Member: Expr {
this->type = MemberByName;
this->base = base;
this->name = name;
- this->objectId = -1;
+ this->memberIndex = -1;
this->property = 0;
}
- void initQmlIdObject(Expr *base, const QString *name, int objectId)
+ void initQmlContextMember(Expr *base, const QString *name, int memberIndex)
{
- this->type = MemberByObjectId;
+ this->type = MemberOfQmlContext;
this->base = base;
this->name = name;
- this->objectId = objectId;
+ this->memberIndex = memberIndex;
this->property = 0;
}
@@ -846,7 +847,7 @@ struct BasicBlock {
Expr *NEW(Expr *base, ExprList *args = 0);
Expr *SUBSCRIPT(Expr *base, Expr *index);
Expr *MEMBER(Expr *base, const QString *name);
- Expr *QML_CONTEXT_ID_MEMBER(Expr *base, const QString *id, int idIndex);
+ Expr *QML_CONTEXT_MEMBER(Expr *base, const QString *id, int memberIndex);
Expr *QML_QOBJECT_PROPERTY(Expr *base, const QString *id, QQmlPropertyData *property);
Stmt *EXP(Expr *expr);
diff --git a/src/qml/compiler/qv4regalloc.cpp b/src/qml/compiler/qv4regalloc.cpp
index 501f5b7edb..15b0d42169 100644
--- a/src/qml/compiler/qv4regalloc.cpp
+++ b/src/qml/compiler/qv4regalloc.cpp
@@ -334,7 +334,13 @@ protected: // IRDecoder
addDef(temp);
}
- virtual void loadIdObject(int id, V4IR::Temp *temp)
+ virtual void loadQmlIdObject(int id, V4IR::Temp *temp)
+ {
+ addDef(temp);
+ addCall();
+ }
+
+ virtual void loadQmlImportedScript(int index, V4IR::Temp *temp)
{
addDef(temp);
addCall();
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index 856dedc9ec..e227178042 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -1218,6 +1218,12 @@ void __qmljs_set_qobject_property(ExecutionContext *ctx, const ValueRef object,
wrapper->setProperty(ctx, propertyIndex, value);
}
+ReturnedValue __qmljs_get_imported_script(ExecutionContext *ctx, int index)
+{
+ QQmlContextData *context = QmlContextWrapper::callingContext(ctx->engine);
+ return context->importedScripts.at(index).value();
+}
+
} // namespace QV4
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4runtime_p.h b/src/qml/jsruntime/qv4runtime_p.h
index 85d8041a58..7315258b5e 100644
--- a/src/qml/jsruntime/qv4runtime_p.h
+++ b/src/qml/jsruntime/qv4runtime_p.h
@@ -165,6 +165,7 @@ QV4::ReturnedValue __qmljs_get_element(QV4::ExecutionContext *ctx, const QV4::Va
void __qmljs_set_element(QV4::ExecutionContext *ctx, const QV4::ValueRef object, const QV4::ValueRef index, const QV4::ValueRef value);
QV4::ReturnedValue __qmljs_get_id_object(ExecutionContext *ctx, int id);
+QV4::ReturnedValue __qmljs_get_imported_script(ExecutionContext *ctx, int index);
QV4::ReturnedValue __qmljs_get_context_object(ExecutionContext *ctx);
QV4::ReturnedValue __qmljs_get_scope_object(ExecutionContext *ctx);
QV4::ReturnedValue __qmljs_get_qobject_property(ExecutionContext *ctx, const ValueRef object, int propertyIndex);
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index ecbc78cd26..6d08e09a30 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -641,6 +641,10 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
VALUE(instr.result) = __qmljs_get_id_object(context, instr.id);
MOTH_END_INSTR(LoadQmlIdObject)
+ MOTH_BEGIN_INSTR(LoadQmlImportedScript)
+ VALUE(instr.result) = __qmljs_get_imported_script(context, instr.index);
+ MOTH_END_INSTR(LoadQmlImportedScript)
+
MOTH_BEGIN_INSTR(LoadQmlContextObject)
VALUE(instr.result) = __qmljs_get_context_object(context);
MOTH_END_INSTR(LoadContextObject)