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>
This commit is contained in:
parent
b0afac3daf
commit
f0ad3a5943
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue