diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2013-10-28 17:02:54 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-10-31 18:55:14 +0100 |
commit | f0ad3a5943804e9eb8e03434a4584eaafa5c5aea (patch) | |
tree | 8d2cb4402d63ced4e89c6c610fc839e0260d8e92 | |
parent | b0afac3daf1cbb9daacbeac0183ef6254de6cc95 (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.cpp | 16 | ||||
-rw-r--r-- | src/qml/compiler/qv4instr_moth_p.h | 7 | ||||
-rw-r--r-- | src/qml/compiler/qv4isel_masm.cpp | 7 | ||||
-rw-r--r-- | src/qml/compiler/qv4isel_masm_p.h | 3 | ||||
-rw-r--r-- | src/qml/compiler/qv4isel_moth.cpp | 10 | ||||
-rw-r--r-- | src/qml/compiler/qv4isel_moth_p.h | 3 | ||||
-rw-r--r-- | src/qml/compiler/qv4isel_p.cpp | 14 | ||||
-rw-r--r-- | src/qml/compiler/qv4isel_p.h | 3 | ||||
-rw-r--r-- | src/qml/compiler/qv4jsir.cpp | 20 | ||||
-rw-r--r-- | src/qml/compiler/qv4jsir_p.h | 15 | ||||
-rw-r--r-- | src/qml/compiler/qv4regalloc.cpp | 8 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtime.cpp | 6 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtime_p.h | 1 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4vme_moth.cpp | 4 |
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) |