Use the QmlContext to access properties of the scope object

Add some runtime methods to access properties of the scope
object directly (using the QmlContext), and generate proper
code to call those.

Change-Id: I0b29357c9a3b9ad53ba568ec6cb763e8ecb10f21
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
This commit is contained in:
Lars Knoll 2015-06-19 14:18:13 +02:00 committed by Simon Hausmann
parent 18557c2676
commit b288956817
19 changed files with 210 additions and 59 deletions

View File

@ -1458,7 +1458,6 @@ JSCodeGen::JSCodeGen(const QString &fileName, const QString &sourceCode, QV4::IR
, _scopeObject(0)
, _qmlContextTemp(-1)
, _contextObjectTemp(-1)
, _scopeObjectTemp(-1)
, _importedScriptsTemp(-1)
, _idArrayTemp(-1)
{
@ -1767,7 +1766,6 @@ void JSCodeGen::beginFunctionBodyHook()
{
_qmlContextTemp = _block->newTemp();
_contextObjectTemp = _block->newTemp();
_scopeObjectTemp = _block->newTemp();
_importedScriptsTemp = _block->newTemp();
_idArrayTemp = _block->newTemp();
@ -1780,11 +1778,6 @@ void JSCodeGen::beginFunctionBodyHook()
initMetaObjectResolver(temp->memberResolver, _contextObject);
move(temp, _block->NAME(QV4::IR::Name::builtin_qml_context_object, 0, 0));
temp = _block->TEMP(_scopeObjectTemp);
temp->memberResolver = _function->New<QV4::IR::MemberExpressionResolver>();
initMetaObjectResolver(temp->memberResolver, _scopeObject);
move(temp, _block->NAME(QV4::IR::Name::builtin_qml_scope_object, 0, 0));
move(_block->TEMP(_importedScriptsTemp), _block->NAME(QV4::IR::Name::builtin_qml_imported_scripts_object, 0, 0));
move(_block->TEMP(_idArrayTemp), _block->NAME(QV4::IR::Name::builtin_qml_id_array, 0, 0));
#endif
@ -1862,7 +1855,7 @@ QV4::IR::Expr *JSCodeGen::fallbackNameLookup(const QString &name, int line, int
if (propertyExistsButForceNameLookup)
return 0;
if (pd) {
QV4::IR::Temp *base = _block->TEMP(_scopeObjectTemp);
QV4::IR::Temp *base = _block->TEMP(_qmlContextTemp);
base->memberResolver = _function->New<QV4::IR::MemberExpressionResolver>();
initMetaObjectResolver(base->memberResolver, _scopeObject);
return _block->MEMBER(base, _function->newString(name), pd, QV4::IR::Member::MemberOfQmlScopeObject);

View File

@ -497,7 +497,6 @@ private:
QQmlPropertyCache *_scopeObject;
int _qmlContextTemp;
int _contextObjectTemp;
int _scopeObjectTemp;
int _importedScriptsTemp;
int _idArrayTemp;
};

View File

@ -2626,8 +2626,7 @@ void QQmlJavaScriptBindingExpressionSimplificationPass::visitMove(QV4::IR::Move
if (n->builtin == QV4::IR::Name::builtin_qml_context
|| n->builtin == QV4::IR::Name::builtin_qml_id_array
|| n->builtin == QV4::IR::Name::builtin_qml_imported_scripts_object
|| n->builtin == QV4::IR::Name::builtin_qml_context_object
|| n->builtin == QV4::IR::Name::builtin_qml_scope_object) {
|| n->builtin == QV4::IR::Name::builtin_qml_context_object) {
// these are free of side-effects
return;
}

View File

@ -64,12 +64,15 @@ QT_BEGIN_NAMESPACE
F(SetLookup, setLookup) \
F(StoreQObjectProperty, storeQObjectProperty) \
F(LoadQObjectProperty, loadQObjectProperty) \
F(StoreScopeObjectProperty, storeScopeObjectProperty) \
F(LoadScopeObjectProperty, loadScopeObjectProperty) \
F(LoadAttachedQObjectProperty, loadAttachedQObjectProperty) \
F(LoadSingletonQObjectProperty, loadQObjectProperty) \
F(Push, push) \
F(CallValue, callValue) \
F(CallProperty, callProperty) \
F(CallPropertyLookup, callPropertyLookup) \
F(CallScopeObjectProperty, callScopeObjectProperty) \
F(CallElement, callElement) \
F(CallActivationProperty, callActivationProperty) \
F(CallGlobalLookup, callGlobalLookup) \
@ -129,7 +132,6 @@ QT_BEGIN_NAMESPACE
F(LoadQmlIdArray, loadQmlIdArray) \
F(LoadQmlImportedScripts, loadQmlImportedScripts) \
F(LoadQmlContextObject, loadQmlContextObject) \
F(LoadQmlScopeObject, loadQmlScopeObject) \
F(LoadQmlSingleton, loadQmlSingleton)
#if defined(Q_CC_GNU) && (!defined(Q_CC_INTEL) || __INTEL_COMPILER >= 1200)
@ -294,6 +296,12 @@ union Instr
Param base;
Param result;
};
struct instr_loadScopeObjectProperty {
MOTH_INSTR_HEADER
int propertyIndex;
Param base;
Param result;
};
struct instr_loadQObjectProperty {
MOTH_INSTR_HEADER
int propertyIndex;
@ -319,6 +327,12 @@ union Instr
Param base;
Param source;
};
struct instr_storeScopeObjectProperty {
MOTH_INSTR_HEADER
Param base;
int propertyIndex;
Param source;
};
struct instr_storeQObjectProperty {
MOTH_INSTR_HEADER
Param base;
@ -378,6 +392,14 @@ union Instr
Param base;
Param result;
};
struct instr_callScopeObjectProperty {
MOTH_INSTR_HEADER
int index;
quint32 argc;
quint32 callData;
Param base;
Param result;
};
struct instr_callElement {
MOTH_INSTR_HEADER
Param base;
@ -701,10 +723,6 @@ union Instr
MOTH_INSTR_HEADER
Param result;
};
struct instr_loadQmlScopeObject {
MOTH_INSTR_HEADER
Param result;
};
struct instr_loadQmlSingleton {
MOTH_INSTR_HEADER
Param result;
@ -730,15 +748,18 @@ union Instr
instr_storeElementLookup storeElementLookup;
instr_loadProperty loadProperty;
instr_getLookup getLookup;
instr_loadScopeObjectProperty loadScopeObjectProperty;
instr_loadQObjectProperty loadQObjectProperty;
instr_loadAttachedQObjectProperty loadAttachedQObjectProperty;
instr_storeProperty storeProperty;
instr_setLookup setLookup;
instr_storeScopeObjectProperty storeScopeObjectProperty;
instr_storeQObjectProperty storeQObjectProperty;
instr_push push;
instr_callValue callValue;
instr_callProperty callProperty;
instr_callPropertyLookup callPropertyLookup;
instr_callScopeObjectProperty callScopeObjectProperty;
instr_callElement callElement;
instr_callActivationProperty callActivationProperty;
instr_callGlobalLookup callGlobalLookup;
@ -798,7 +819,6 @@ union Instr
instr_loadQmlIdArray loadQmlIdArray;
instr_loadQmlImportedScripts loadQmlImportedScripts;
instr_loadQmlContextObject loadQmlContextObject;
instr_loadQmlScopeObject loadQmlScopeObject;
instr_loadQmlSingleton loadQmlSingleton;
static int size(Type type);

View File

@ -461,6 +461,21 @@ void InstructionSelection::callValue(IR::Expr *value, IR::ExprList *args, IR::Ex
addInstruction(call);
}
void InstructionSelection::callQmlContextProperty(IR::Expr *base, IR::Member::MemberKind kind, int propertyIndex, IR::ExprList *args, IR::Expr *result)
{
if (kind == IR::Member::MemberOfQmlScopeObject) {
Instruction::CallScopeObjectProperty call;
call.base = getParam(base);
call.index = propertyIndex;
prepareCallArgs(args, call.argc);
call.callData = callDataStart();
call.result = getResultParam(result);
addInstruction(call);
} else {
Q_ASSERT(false);
}
}
void InstructionSelection::callProperty(IR::Expr *base, const QString &name, IR::ExprList *args,
IR::Expr *result)
{
@ -593,13 +608,6 @@ void InstructionSelection::loadQmlContextObject(IR::Expr *e)
addInstruction(load);
}
void InstructionSelection::loadQmlScopeObject(IR::Expr *e)
{
Instruction::LoadQmlScopeObject load;
load.result = getResultParam(e);
addInstruction(load);
}
void InstructionSelection::loadQmlSingleton(const QString &name, IR::Expr *e)
{
Instruction::LoadQmlSingleton load;
@ -701,6 +709,19 @@ void InstructionSelection::setProperty(IR::Expr *source, IR::Expr *targetBase,
addInstruction(store);
}
void InstructionSelection::setQmlContextProperty(IR::Expr *source, IR::Expr *targetBase, IR::Member::MemberKind kind, int propertyIndex)
{
if (kind == IR::Member::MemberOfQmlScopeObject) {
Instruction::StoreScopeObjectProperty store;
store.base = getParam(targetBase);
store.propertyIndex = propertyIndex;
store.source = getParam(source);
addInstruction(store);
} else {
Q_ASSERT(false);
}
}
void InstructionSelection::setQObjectProperty(IR::Expr *source, IR::Expr *targetBase, int propertyIndex)
{
Instruction::StoreQObjectProperty store;
@ -710,6 +731,19 @@ void InstructionSelection::setQObjectProperty(IR::Expr *source, IR::Expr *target
addInstruction(store);
}
void InstructionSelection::getQmlContextProperty(IR::Expr *source, IR::Member::MemberKind kind, int index, IR::Expr *target)
{
if (kind == IR::Member::MemberOfQmlScopeObject) {
Instruction::LoadScopeObjectProperty load;
load.base = getParam(source);
load.propertyIndex = index;
load.result = getResultParam(target);
addInstruction(load);
} else {
Q_ASSERT(false);
}
}
void InstructionSelection::getQObjectProperty(IR::Expr *base, int propertyIndex, bool captureRequired, bool isSingletonProperty, int attachedPropertiesId, IR::Expr *target)
{
if (attachedPropertiesId != 0) {

View File

@ -95,6 +95,7 @@ protected:
virtual void callBuiltinSetupArgumentObject(IR::Expr *result);
virtual void callBuiltinConvertThisToObject();
virtual void callValue(IR::Expr *value, IR::ExprList *args, IR::Expr *result);
virtual void callQmlContextProperty(IR::Expr *base, IR::Member::MemberKind kind, int propertyIndex, IR::ExprList *args, IR::Expr *result);
virtual void callProperty(IR::Expr *base, const QString &name, IR::ExprList *args, IR::Expr *result);
virtual void callSubscript(IR::Expr *base, IR::Expr *index, IR::ExprList *args, IR::Expr *result);
virtual void convertType(IR::Expr *source, IR::Expr *target);
@ -106,7 +107,6 @@ protected:
virtual void loadQmlIdArray(IR::Expr *e);
virtual void loadQmlImportedScripts(IR::Expr *e);
virtual void loadQmlContextObject(IR::Expr *e);
virtual void loadQmlScopeObject(IR::Expr *e);
virtual void loadQmlSingleton(const QString &name, IR::Expr *e);
virtual void loadConst(IR::Const *sourceConst, IR::Expr *e);
virtual void loadString(const QString &str, IR::Expr *target);
@ -116,7 +116,9 @@ protected:
virtual void initClosure(IR::Closure *closure, IR::Expr *target);
virtual void getProperty(IR::Expr *base, const QString &name, IR::Expr *target);
virtual void setProperty(IR::Expr *source, IR::Expr *targetBase, const QString &targetName);
virtual void setQmlContextProperty(IR::Expr *source, IR::Expr *targetBase, IR::Member::MemberKind kind, int propertyIndex);
virtual void setQObjectProperty(IR::Expr *source, IR::Expr *targetBase, int propertyIndex);
virtual void getQmlContextProperty(IR::Expr *source, IR::Member::MemberKind kind, int index, IR::Expr *target);
virtual void getQObjectProperty(IR::Expr *base, int propertyIndex, bool captureRequired, bool isSingleton, int attachedPropertiesId, IR::Expr *target);
virtual void getElement(IR::Expr *base, IR::Expr *index, IR::Expr *target);
virtual void setElement(IR::Expr *source, IR::Expr *targetBase, IR::Expr *targetIndex);

View File

@ -97,8 +97,6 @@ void IRDecoder::visitMove(IR::Move *s)
loadQmlIdArray(s->target);
else if (n->builtin == IR::Name::builtin_qml_context_object)
loadQmlContextObject(s->target);
else if (n->builtin == IR::Name::builtin_qml_scope_object)
loadQmlScopeObject(s->target);
else if (n->builtin == IR::Name::builtin_qml_imported_scripts_object)
loadQmlImportedScripts(s->target);
else if (n->qmlSingleton)
@ -155,6 +153,10 @@ void IRDecoder::visitMove(IR::Move *s)
captureRequired = false;
}
}
if (m->kind == IR::Member::MemberOfQmlScopeObject) {
getQmlContextProperty(m->base, (IR::Member::MemberKind)m->kind, m->property->coreIndex, s->target);
return;
}
getQObjectProperty(m->base, m->property->coreIndex, captureRequired, isSingletonProperty, attachedPropertiesId, s->target);
#endif // V4_BOOTSTRAP
return;
@ -176,6 +178,12 @@ void IRDecoder::visitMove(IR::Move *s)
callBuiltin(c, s->target);
return;
} else if (Member *member = c->base->asMember()) {
#ifndef V4_BOOTSTRAP
if (member->kind == IR::Member::MemberOfQmlScopeObject) {
callQmlContextProperty(member->base, (IR::Member::MemberKind)member->kind, member->property->coreIndex, c->args, s->target);
return;
}
#endif
callProperty(member->base, *member->name, c->args, s->target);
return;
} else if (Subscript *ss = c->base->asSubscript()) {
@ -199,6 +207,10 @@ void IRDecoder::visitMove(IR::Move *s)
#ifdef V4_BOOTSTRAP
Q_UNIMPLEMENTED();
#else
if (m->kind == IR::Member::MemberOfQmlScopeObject) {
setQmlContextProperty(s->source, m->base, (IR::Member::MemberKind)m->kind, m->property->coreIndex);
return;
}
setQObjectProperty(s->source, m->base, m->property->coreIndex);
#endif
return;
@ -240,6 +252,12 @@ void IRDecoder::visitExp(IR::Exp *s)
callValue(c->base, c->args, 0);
} else if (Member *member = c->base->asMember()) {
Q_ASSERT(member->base->asTemp() || member->base->asArgLocal());
#ifndef V4_BOOTSTRAP
if (member->kind == IR::Member::MemberOfQmlScopeObject) {
callQmlContextProperty(member->base, (IR::Member::MemberKind)member->kind, member->property->coreIndex, c->args, 0);
return;
}
#endif
callProperty(member->base, *member->name, c->args, 0);
} else if (Subscript *s = c->base->asSubscript()) {
callSubscript(s->base, s->index, c->args, 0);

View File

@ -129,6 +129,7 @@ public: // to implement by subclasses:
virtual void callBuiltinSetupArgumentObject(IR::Expr *result) = 0;
virtual void callBuiltinConvertThisToObject() = 0;
virtual void callValue(IR::Expr *value, IR::ExprList *args, IR::Expr *result) = 0;
virtual void callQmlContextProperty(IR::Expr *base, IR::Member::MemberKind kind, int propertyIndex, IR::ExprList *args, IR::Expr *result) = 0;
virtual void callProperty(IR::Expr *base, const QString &name, IR::ExprList *args, IR::Expr *result) = 0;
virtual void callSubscript(IR::Expr *base, IR::Expr *index, IR::ExprList *args, IR::Expr *result) = 0;
virtual void convertType(IR::Expr *source, IR::Expr *target) = 0;
@ -140,7 +141,6 @@ public: // to implement by subclasses:
virtual void loadQmlIdArray(IR::Expr *target) = 0;
virtual void loadQmlImportedScripts(IR::Expr *target) = 0;
virtual void loadQmlContextObject(IR::Expr *target) = 0;
virtual void loadQmlScopeObject(IR::Expr *target) = 0;
virtual void loadQmlSingleton(const QString &name, IR::Expr *target) = 0;
virtual void loadConst(IR::Const *sourceConst, IR::Expr *target) = 0;
virtual void loadString(const QString &str, IR::Expr *target) = 0;
@ -150,7 +150,9 @@ public: // to implement by subclasses:
virtual void initClosure(IR::Closure *closure, IR::Expr *target) = 0;
virtual void getProperty(IR::Expr *base, const QString &name, IR::Expr *target) = 0;
virtual void getQObjectProperty(IR::Expr *base, int propertyIndex, bool captureRequired, bool isSingletonProperty, int attachedPropertiesId, IR::Expr *target) = 0;
virtual void getQmlContextProperty(IR::Expr *source, IR::Member::MemberKind kind, int index, IR::Expr *target) = 0;
virtual void setProperty(IR::Expr *source, IR::Expr *targetBase, const QString &targetName) = 0;
virtual void setQmlContextProperty(IR::Expr *source, IR::Expr *targetBase, IR::Member::MemberKind kind, int propertyIndex) = 0;
virtual void setQObjectProperty(IR::Expr *source, IR::Expr *targetBase, int propertyIndex) = 0;
virtual void getElement(IR::Expr *base, IR::Expr *index, IR::Expr *target) = 0;
virtual void setElement(IR::Expr *source, IR::Expr *targetBase, IR::Expr *targetIndex) = 0;

View File

@ -347,8 +347,6 @@ const char *builtin_to_string(Name::Builtin b)
return "builtin_qml_id_array";
case IR::Name::builtin_qml_imported_scripts_object:
return "builtin_qml_imported_scripts_object";
case IR::Name::builtin_qml_scope_object:
return "builtin_qml_scope_object";
case IR::Name::builtin_qml_context_object:
return "builtin_qml_context_object";
}

View File

@ -340,8 +340,7 @@ struct Name: Expr {
builtin_qml_context,
builtin_qml_id_array,
builtin_qml_imported_scripts_object,
builtin_qml_context_object,
builtin_qml_scope_object
builtin_qml_context_object
};
const QString *id;

View File

@ -594,11 +594,6 @@ void InstructionSelection::loadQmlContextObject(IR::Expr *temp)
generateFunctionCall(temp, Runtime::getQmlContextObject, Assembler::EngineRegister);
}
void InstructionSelection::loadQmlScopeObject(IR::Expr *temp)
{
generateFunctionCall(temp, Runtime::getQmlScopeObject, Assembler::EngineRegister);
}
void InstructionSelection::loadQmlSingleton(const QString &name, IR::Expr *temp)
{
generateFunctionCall(temp, Runtime::getQmlSingleton, Assembler::EngineRegister, Assembler::StringToIndex(name));
@ -685,6 +680,14 @@ void InstructionSelection::getProperty(IR::Expr *base, const QString &name, IR::
}
}
void InstructionSelection::getQmlContextProperty(IR::Expr *base, IR::Member::MemberKind kind, int index, IR::Expr *target)
{
if (kind == IR::Member::MemberOfQmlScopeObject)
generateFunctionCall(target, Runtime::getQmlScopeObjectProperty, Assembler::EngineRegister, Assembler::PointerToValue(base), Assembler::TrustedImm32(index));
else
Q_ASSERT(false);
}
void InstructionSelection::getQObjectProperty(IR::Expr *base, int propertyIndex, bool captureRequired, bool isSingleton, int attachedPropertiesId, IR::Expr *target)
{
if (attachedPropertiesId != 0)
@ -713,6 +716,15 @@ void InstructionSelection::setProperty(IR::Expr *source, IR::Expr *targetBase,
}
}
void InstructionSelection::setQmlContextProperty(IR::Expr *source, IR::Expr *targetBase, IR::Member::MemberKind kind, int propertyIndex)
{
if (kind == IR::Member::MemberOfQmlScopeObject)
generateFunctionCall(Assembler::Void, Runtime::setQmlScopeObjectProperty, Assembler::EngineRegister, Assembler::PointerToValue(targetBase),
Assembler::TrustedImm32(propertyIndex), Assembler::PointerToValue(source));
else
Q_ASSERT(false);
}
void InstructionSelection::setQObjectProperty(IR::Expr *source, IR::Expr *targetBase, int propertyIndex)
{
generateFunctionCall(Assembler::Void, Runtime::setQmlQObjectProperty, Assembler::EngineRegister, Assembler::PointerToValue(targetBase),
@ -906,6 +918,19 @@ void InstructionSelection::binop(IR::AluOp oper, IR::Expr *leftSource, IR::Expr
binop.generate(leftSource, rightSource, target);
}
void InstructionSelection::callQmlContextProperty(IR::Expr *base, IR::Member::MemberKind kind, int propertyIndex, IR::ExprList *args, IR::Expr *result)
{
prepareCallData(args, base);
if (kind == IR::Member::MemberOfQmlScopeObject)
generateFunctionCall(result, Runtime::callQmlScopeObjectProperty,
Assembler::EngineRegister,
Assembler::TrustedImm32(propertyIndex),
baseAddressForCallData());
else
Q_ASSERT(false);
}
void InstructionSelection::callProperty(IR::Expr *base, const QString &name, IR::ExprList *args,
IR::Expr *result)
{

View File

@ -91,6 +91,7 @@ protected:
virtual void callBuiltinSetupArgumentObject(IR::Expr *result);
virtual void callBuiltinConvertThisToObject();
virtual void callValue(IR::Expr *value, IR::ExprList *args, IR::Expr *result);
virtual void callQmlContextProperty(IR::Expr *base, IR::Member::MemberKind kind, int propertyIndex, IR::ExprList *args, IR::Expr *result);
virtual void callProperty(IR::Expr *base, const QString &name, IR::ExprList *args, IR::Expr *result);
virtual void callSubscript(IR::Expr *base, IR::Expr *index, IR::ExprList *args, IR::Expr *result);
virtual void convertType(IR::Expr *source, IR::Expr *target);
@ -99,7 +100,6 @@ protected:
virtual void loadQmlIdArray(IR::Expr *target);
virtual void loadQmlImportedScripts(IR::Expr *target);
virtual void loadQmlContextObject(IR::Expr *target);
virtual void loadQmlScopeObject(IR::Expr *target);
virtual void loadQmlSingleton(const QString &name, IR::Expr *target);
virtual void loadConst(IR::Const *sourceConst, IR::Expr *target);
virtual void loadString(const QString &str, IR::Expr *target);
@ -108,8 +108,10 @@ protected:
virtual void setActivationProperty(IR::Expr *source, const QString &targetName);
virtual void initClosure(IR::Closure *closure, IR::Expr *target);
virtual void getProperty(IR::Expr *base, const QString &name, IR::Expr *target);
virtual void getQmlContextProperty(IR::Expr *source, IR::Member::MemberKind kind, int index, IR::Expr *target);
virtual void getQObjectProperty(IR::Expr *base, int propertyIndex, bool captureRequired, bool isSingleton, int attachedPropertiesId, IR::Expr *target);
virtual void setProperty(IR::Expr *source, IR::Expr *targetBase, const QString &targetName);
virtual void setQmlContextProperty(IR::Expr *source, IR::Expr *targetBase, IR::Member::MemberKind kind, int propertyIndex);
virtual void setQObjectProperty(IR::Expr *source, IR::Expr *targetBase, int propertyIndex);
virtual void getElement(IR::Expr *base, IR::Expr *index, IR::Expr *target);
virtual void setElement(IR::Expr *source, IR::Expr *targetBase, IR::Expr *targetIndex);

View File

@ -299,6 +299,16 @@ protected: // IRDecoder
addCall();
}
virtual void callQmlContextProperty(IR::Expr *base, IR::Member::MemberKind /*kind*/, int propertyIndex, IR::ExprList *args, IR::Expr *result)
{
Q_UNUSED(propertyIndex)
addDef(result);
addUses(base->asTemp(), Use::CouldHaveRegister);
addUses(args, Use::CouldHaveRegister);
addCall();
}
virtual void callProperty(IR::Expr *base, const QString &name, IR::ExprList *args,
IR::Expr *result)
{
@ -445,14 +455,6 @@ protected: // IRDecoder
addCall();
}
virtual void loadQmlScopeObject(Expr *temp)
{
Q_UNUSED(temp);
addDef(temp);
addCall();
}
virtual void loadQmlSingleton(const QString &/*name*/, Expr *temp)
{
Q_UNUSED(temp);
@ -517,6 +519,13 @@ protected: // IRDecoder
addCall();
}
virtual void setQmlContextProperty(IR::Expr *source, IR::Expr *targetBase, IR::Member::MemberKind /*kind*/, int /*propertyIndex*/)
{
addUses(source->asTemp(), Use::CouldHaveRegister);
addUses(targetBase->asTemp(), Use::CouldHaveRegister);
addCall();
}
virtual void setQObjectProperty(IR::Expr *source, IR::Expr *targetBase, int /*propertyIndex*/)
{
addUses(source->asTemp(), Use::CouldHaveRegister);
@ -524,6 +533,13 @@ protected: // IRDecoder
addCall();
}
virtual void getQmlContextProperty(IR::Expr *base, IR::Member::MemberKind /*kind*/, int /*index*/, IR::Expr *target)
{
addDef(target);
addUses(base->asTemp(), Use::CouldHaveRegister);
addCall();
}
virtual void getQObjectProperty(IR::Expr *base, int /*propertyIndex*/, bool /*captureRequired*/, bool /*isSingleton*/, int /*attachedPropertiesId*/, IR::Expr *target)
{
addDef(target);

View File

@ -743,6 +743,8 @@ Heap::QmlContext *ExecutionEngine::qmlContext() const
Heap::QmlContextWrapper *ExecutionEngine::qmlContextObject() const
{
Heap::QmlContext *ctx = qmlContext();
if (!ctx)
return 0;
Q_ASSERT(ctx->qml);
return ctx->qml;
}

View File

@ -657,9 +657,14 @@ ReturnedValue QObjectWrapper::getProperty(ExecutionEngine *engine, QObject *obje
void QObjectWrapper::setProperty(ExecutionEngine *engine, int propertyIndex, const Value &value)
{
if (QQmlData::wasDeleted(d()->object))
setProperty(engine, d()->object, propertyIndex, value);
}
void QObjectWrapper::setProperty(ExecutionEngine *engine, QObject *object, int propertyIndex, const Value &value)
{
if (QQmlData::wasDeleted(object))
return;
QQmlData *ddata = QQmlData::get(d()->object, /*create*/false);
QQmlData *ddata = QQmlData::get(object, /*create*/false);
if (!ddata)
return;
@ -667,7 +672,7 @@ void QObjectWrapper::setProperty(ExecutionEngine *engine, int propertyIndex, con
Q_ASSERT(cache);
QQmlPropertyData *property = cache->property(propertyIndex);
Q_ASSERT(property); // We resolved this property earlier, so it better exist!
return setProperty(engine, d()->object, property, value);
return setProperty(engine, object, property, value);
}
bool QObjectWrapper::isEqualTo(Managed *a, Managed *b)

View File

@ -115,6 +115,7 @@ struct Q_QML_EXPORT QObjectWrapper : public Object
using Object::get;
static ReturnedValue getProperty(ExecutionEngine *engine, QObject *object, int propertyIndex, bool captureRequired);
static void setProperty(ExecutionEngine *engine, QObject *object, int propertyIndex, const Value &value);
void setProperty(ExecutionEngine *engine, int propertyIndex, const Value &value);
protected:

View File

@ -948,6 +948,18 @@ ReturnedValue Runtime::callActivationProperty(ExecutionEngine *engine, int nameI
return o->call(callData);
}
ReturnedValue Runtime::callQmlScopeObjectProperty(ExecutionEngine *engine, int propertyIndex, CallData *callData)
{
Scope scope(engine);
ScopedFunctionObject o(scope, getQmlScopeObjectProperty(engine, callData->thisObject, propertyIndex));
if (!o) {
QString error = QStringLiteral("Property '%1' of object %2 is not a function").arg(propertyIndex).arg(callData->thisObject.toQStringNoThrow());
return engine->throwTypeError(error);
}
return o->call(callData);
}
ReturnedValue Runtime::callProperty(ExecutionEngine *engine, int nameIndex, CallData *callData)
{
Scope scope(engine);
@ -1351,11 +1363,6 @@ ReturnedValue Runtime::getQmlContextObject(NoThrowEngine *engine)
return QObjectWrapper::wrap(engine, context->contextObject);
}
ReturnedValue Runtime::getQmlScopeObject(NoThrowEngine *engine)
{
return QObjectWrapper::wrap(engine, engine->qmlScopeObject());
}
ReturnedValue Runtime::getQmlQObjectProperty(ExecutionEngine *engine, const Value &object, int propertyIndex, bool captureRequired)
{
Scope scope(engine);
@ -1377,6 +1384,12 @@ QV4::ReturnedValue Runtime::getQmlAttachedProperty(ExecutionEngine *engine, int
return QV4::QObjectWrapper::getProperty(engine, attachedObject, propertyIndex, /*captureRequired*/true);
}
ReturnedValue Runtime::getQmlScopeObjectProperty(ExecutionEngine *engine, const Value &context, int propertyIndex)
{
const QmlContext &c = static_cast<const QmlContext &>(context);
return QV4::QObjectWrapper::getProperty(engine, c.d()->qml->scopeObject, propertyIndex, false);
}
ReturnedValue Runtime::getQmlSingletonQObjectProperty(ExecutionEngine *engine, const Value &object, int propertyIndex, bool captureRequired)
{
Scope scope(engine);
@ -1388,6 +1401,12 @@ ReturnedValue Runtime::getQmlSingletonQObjectProperty(ExecutionEngine *engine, c
return QV4::QObjectWrapper::getProperty(scope.engine, wrapper->singletonObject(), propertyIndex, captureRequired);
}
void Runtime::setQmlScopeObjectProperty(ExecutionEngine *engine, const Value &context, int propertyIndex, const Value &value)
{
const QmlContext &c = static_cast<const QmlContext &>(context);
return QV4::QObjectWrapper::setProperty(engine, c.d()->qml->scopeObject, propertyIndex, value);
}
void Runtime::setQmlQObjectProperty(ExecutionEngine *engine, const Value &object, int propertyIndex, const Value &value)
{
Scope scope(engine);

View File

@ -91,6 +91,7 @@ struct Q_QML_PRIVATE_EXPORT Runtime {
// call
static ReturnedValue callGlobalLookup(ExecutionEngine *engine, uint index, CallData *callData);
static ReturnedValue callActivationProperty(ExecutionEngine *engine, int nameIndex, CallData *callData);
static ReturnedValue callQmlScopeObjectProperty(ExecutionEngine *engine, int propertyIndex, CallData *callData);
static ReturnedValue callProperty(ExecutionEngine *engine, int nameIndex, CallData *callData);
static ReturnedValue callPropertyLookup(ExecutionEngine *engine, uint index, CallData *callData);
static ReturnedValue callElement(ExecutionEngine *engine, const Value &index, CallData *callData);
@ -211,11 +212,12 @@ struct Q_QML_PRIVATE_EXPORT Runtime {
static ReturnedValue getQmlIdArray(NoThrowEngine *engine);
static ReturnedValue getQmlImportedScripts(NoThrowEngine *engine);
static ReturnedValue getQmlContextObject(NoThrowEngine *engine);
static ReturnedValue getQmlScopeObject(NoThrowEngine *engine);
static ReturnedValue getQmlSingleton(NoThrowEngine *engine, int nameIndex);
static ReturnedValue getQmlAttachedProperty(ExecutionEngine *engine, int attachedPropertiesId, int propertyIndex);
static ReturnedValue getQmlScopeObjectProperty(ExecutionEngine *engine, const Value &context, int propertyIndex);
static ReturnedValue getQmlQObjectProperty(ExecutionEngine *engine, const Value &object, int propertyIndex, bool captureRequired);
static ReturnedValue getQmlSingletonQObjectProperty(ExecutionEngine *engine, const Value &object, int propertyIndex, bool captureRequired);
static void setQmlScopeObjectProperty(ExecutionEngine *engine, const Value &context, int propertyIndex, const Value &value);
static void setQmlQObjectProperty(ExecutionEngine *engine, const Value &object, int propertyIndex, const Value &value);
};

View File

@ -513,6 +513,15 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
STOREVALUE(instr.result, Runtime::getQmlQObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, instr.captureRequired));
MOTH_END_INSTR(LoadQObjectProperty)
MOTH_BEGIN_INSTR(StoreScopeObjectProperty)
Runtime::setQmlScopeObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, VALUE(instr.source));
CHECK_EXCEPTION;
MOTH_END_INSTR(StoreScopeObjectProperty)
MOTH_BEGIN_INSTR(LoadScopeObjectProperty)
STOREVALUE(instr.result, Runtime::getQmlScopeObjectProperty(engine, VALUE(instr.base), instr.propertyIndex));
MOTH_END_INSTR(LoadScopeObjectProperty)
MOTH_BEGIN_INSTR(LoadAttachedQObjectProperty)
STOREVALUE(instr.result, Runtime::getQmlAttachedProperty(engine, instr.attachedPropertiesId, instr.propertyIndex));
MOTH_END_INSTR(LoadAttachedQObjectProperty)
@ -566,6 +575,16 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
STOREVALUE(instr.result, Runtime::callPropertyLookup(engine, instr.lookupIndex, callData));
MOTH_END_INSTR(CallPropertyLookup)
MOTH_BEGIN_INSTR(CallScopeObjectProperty)
TRACE(property name, "%s, args=%u, argc=%u, this=%s", qPrintable(runtimeStrings[instr.name]->toQString()), instr.callData, instr.argc, (VALUE(instr.base)).toString(context)->toQString().toUtf8().constData());
Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
callData->tag = QV4::Value::Integer_Type;
callData->argc = instr.argc;
callData->thisObject = VALUE(instr.base);
STOREVALUE(instr.result, Runtime::callQmlScopeObjectProperty(engine, instr.index, callData));
MOTH_END_INSTR(CallScopeObjectProperty)
MOTH_BEGIN_INSTR(CallElement)
Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
@ -881,10 +900,6 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
VALUE(instr.result) = Runtime::getQmlContextObject(static_cast<QV4::NoThrowEngine*>(engine));
MOTH_END_INSTR(LoadContextObject)
MOTH_BEGIN_INSTR(LoadQmlScopeObject)
VALUE(instr.result) = Runtime::getQmlScopeObject(static_cast<QV4::NoThrowEngine*>(engine));
MOTH_END_INSTR(LoadScopeObject)
MOTH_BEGIN_INSTR(LoadQmlSingleton)
VALUE(instr.result) = Runtime::getQmlSingleton(static_cast<QV4::NoThrowEngine*>(engine), instr.name);
MOTH_END_INSTR(LoadQmlSingleton)