And get rid of another temp in the IR.
Change-Id: I039393e020e5141f1986aee276246c30fd8057f3
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
, _contextObject(0)
, _scopeObject(0)
, _qmlContextTemp(-1)
- , _contextObjectTemp(-1)
, _importedScriptsTemp(-1)
, _idArrayTemp(-1)
{
void JSCodeGen::beginFunctionBodyHook()
{
_qmlContextTemp = _block->newTemp();
- _contextObjectTemp = _block->newTemp();
_importedScriptsTemp = _block->newTemp();
_idArrayTemp = _block->newTemp();
QV4::IR::Temp *temp = _block->TEMP(_qmlContextTemp);
move(temp, _block->NAME(QV4::IR::Name::builtin_qml_context, 0, 0));
- temp = _block->TEMP(_contextObjectTemp);
- temp->memberResolver = _function->New<QV4::IR::MemberExpressionResolver>();
- initMetaObjectResolver(temp->memberResolver, _contextObject);
- move(temp, _block->NAME(QV4::IR::Name::builtin_qml_context_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
if (propertyExistsButForceNameLookup)
return 0;
if (pd) {
- QV4::IR::Temp *base = _block->TEMP(_contextObjectTemp);
+ QV4::IR::Temp *base = _block->TEMP(_qmlContextTemp);
base->memberResolver = _function->New<QV4::IR::MemberExpressionResolver>();
initMetaObjectResolver(base->memberResolver, _contextObject);
return _block->MEMBER(base, _function->newString(name), pd, QV4::IR::Member::MemberOfQmlContextObject);
QQmlPropertyCache *_contextObject;
QQmlPropertyCache *_scopeObject;
int _qmlContextTemp;
- int _contextObjectTemp;
int _importedScriptsTemp;
int _idArrayTemp;
};
if (QV4::IR::Name *n = move->source->asName()) {
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_imported_scripts_object) {
// these are free of side-effects
return;
}
F(StoreQObjectProperty, storeQObjectProperty) \
F(LoadQObjectProperty, loadQObjectProperty) \
F(StoreScopeObjectProperty, storeScopeObjectProperty) \
+ F(StoreContextObjectProperty, storeContextObjectProperty) \
F(LoadScopeObjectProperty, loadScopeObjectProperty) \
+ F(LoadContextObjectProperty, loadContextObjectProperty) \
F(LoadAttachedQObjectProperty, loadAttachedQObjectProperty) \
F(LoadSingletonQObjectProperty, loadQObjectProperty) \
F(Push, push) \
F(CallProperty, callProperty) \
F(CallPropertyLookup, callPropertyLookup) \
F(CallScopeObjectProperty, callScopeObjectProperty) \
+ F(CallContextObjectProperty, callContextObjectProperty) \
F(CallElement, callElement) \
F(CallActivationProperty, callActivationProperty) \
F(CallGlobalLookup, callGlobalLookup) \
F(LoadQmlContext, loadQmlContext) \
F(LoadQmlIdArray, loadQmlIdArray) \
F(LoadQmlImportedScripts, loadQmlImportedScripts) \
- F(LoadQmlContextObject, loadQmlContextObject) \
F(LoadQmlSingleton, loadQmlSingleton)
#if defined(Q_CC_GNU) && (!defined(Q_CC_INTEL) || __INTEL_COMPILER >= 1200)
Param base;
Param result;
};
+ struct instr_loadContextObjectProperty {
+ MOTH_INSTR_HEADER
+ int propertyIndex;
+ Param base;
+ Param result;
+ };
struct instr_loadQObjectProperty {
MOTH_INSTR_HEADER
int propertyIndex;
int propertyIndex;
Param source;
};
+ struct instr_storeContextObjectProperty {
+ MOTH_INSTR_HEADER
+ Param base;
+ int propertyIndex;
+ Param source;
+ };
struct instr_storeQObjectProperty {
MOTH_INSTR_HEADER
Param base;
Param base;
Param result;
};
+ struct instr_callContextObjectProperty {
+ MOTH_INSTR_HEADER
+ int index;
+ quint32 argc;
+ quint32 callData;
+ Param base;
+ Param result;
+ };
struct instr_callElement {
MOTH_INSTR_HEADER
Param base;
MOTH_INSTR_HEADER
Param result;
};
- struct instr_loadQmlContextObject {
- MOTH_INSTR_HEADER
- Param result;
- };
struct instr_loadQmlSingleton {
MOTH_INSTR_HEADER
Param result;
instr_loadProperty loadProperty;
instr_getLookup getLookup;
instr_loadScopeObjectProperty loadScopeObjectProperty;
+ instr_loadContextObjectProperty loadContextObjectProperty;
instr_loadQObjectProperty loadQObjectProperty;
instr_loadAttachedQObjectProperty loadAttachedQObjectProperty;
instr_storeProperty storeProperty;
instr_setLookup setLookup;
instr_storeScopeObjectProperty storeScopeObjectProperty;
+ instr_storeContextObjectProperty storeContextObjectProperty;
instr_storeQObjectProperty storeQObjectProperty;
instr_push push;
instr_callValue callValue;
instr_callProperty callProperty;
instr_callPropertyLookup callPropertyLookup;
instr_callScopeObjectProperty callScopeObjectProperty;
+ instr_callContextObjectProperty callContextObjectProperty;
instr_callElement callElement;
instr_callActivationProperty callActivationProperty;
instr_callGlobalLookup callGlobalLookup;
instr_loadQmlContext loadQmlContext;
instr_loadQmlIdArray loadQmlIdArray;
instr_loadQmlImportedScripts loadQmlImportedScripts;
- instr_loadQmlContextObject loadQmlContextObject;
instr_loadQmlSingleton loadQmlSingleton;
static int size(Type type);
call.callData = callDataStart();
call.result = getResultParam(result);
addInstruction(call);
+ } else if (kind == IR::Member::MemberOfQmlContextObject) {
+ Instruction::CallContextObjectProperty 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);
}
addInstruction(load);
}
-void InstructionSelection::loadQmlContextObject(IR::Expr *e)
-{
- Instruction::LoadQmlContextObject load;
- load.result = getResultParam(e);
- addInstruction(load);
-}
-
void InstructionSelection::loadQmlSingleton(const QString &name, IR::Expr *e)
{
Instruction::LoadQmlSingleton load;
store.propertyIndex = propertyIndex;
store.source = getParam(source);
addInstruction(store);
+ } else if (kind == IR::Member::MemberOfQmlContextObject) {
+ Instruction::StoreContextObjectProperty store;
+ store.base = getParam(targetBase);
+ store.propertyIndex = propertyIndex;
+ store.source = getParam(source);
+ addInstruction(store);
} else {
Q_ASSERT(false);
}
load.propertyIndex = index;
load.result = getResultParam(target);
addInstruction(load);
+ } else if (kind == IR::Member::MemberOfQmlContextObject) {
+ Instruction::LoadContextObjectProperty load;
+ load.base = getParam(source);
+ load.propertyIndex = index;
+ load.result = getResultParam(target);
+ addInstruction(load);
} else {
Q_ASSERT(false);
}
virtual void loadQmlContext(IR::Expr *e);
virtual void loadQmlIdArray(IR::Expr *e);
virtual void loadQmlImportedScripts(IR::Expr *e);
- virtual void loadQmlContextObject(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);
loadQmlContext(s->target);
else if (n->builtin == IR::Name::builtin_qml_id_array)
loadQmlIdArray(s->target);
- else if (n->builtin == IR::Name::builtin_qml_context_object)
- loadQmlContextObject(s->target);
else if (n->builtin == IR::Name::builtin_qml_imported_scripts_object)
loadQmlImportedScripts(s->target);
else if (n->qmlSingleton)
captureRequired = false;
}
}
- if (m->kind == IR::Member::MemberOfQmlScopeObject) {
+ if (m->kind == IR::Member::MemberOfQmlScopeObject || m->kind == IR::Member::MemberOfQmlContextObject) {
getQmlContextProperty(m->base, (IR::Member::MemberKind)m->kind, m->property->coreIndex, s->target);
return;
}
return;
} else if (Member *member = c->base->asMember()) {
#ifndef V4_BOOTSTRAP
- if (member->kind == IR::Member::MemberOfQmlScopeObject) {
+ if (member->kind == IR::Member::MemberOfQmlScopeObject || member->kind == IR::Member::MemberOfQmlContextObject) {
callQmlContextProperty(member->base, (IR::Member::MemberKind)member->kind, member->property->coreIndex, c->args, s->target);
return;
}
#ifdef V4_BOOTSTRAP
Q_UNIMPLEMENTED();
#else
- if (m->kind == IR::Member::MemberOfQmlScopeObject) {
+ if (m->kind == IR::Member::MemberOfQmlScopeObject || m->kind == IR::Member::MemberOfQmlContextObject) {
setQmlContextProperty(s->source, m->base, (IR::Member::MemberKind)m->kind, m->property->coreIndex);
return;
}
} else if (Member *member = c->base->asMember()) {
Q_ASSERT(member->base->asTemp() || member->base->asArgLocal());
#ifndef V4_BOOTSTRAP
- if (member->kind == IR::Member::MemberOfQmlScopeObject) {
+ if (member->kind == IR::Member::MemberOfQmlScopeObject || member->kind == IR::Member::MemberOfQmlContextObject) {
callQmlContextProperty(member->base, (IR::Member::MemberKind)member->kind, member->property->coreIndex, c->args, 0);
return;
}
virtual void loadQmlContext(IR::Expr *target) = 0;
virtual void loadQmlIdArray(IR::Expr *target) = 0;
virtual void loadQmlImportedScripts(IR::Expr *target) = 0;
- virtual void loadQmlContextObject(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;
return "builtin_qml_id_array";
case IR::Name::builtin_qml_imported_scripts_object:
return "builtin_qml_imported_scripts_object";
- case IR::Name::builtin_qml_context_object:
- return "builtin_qml_context_object";
}
return "builtin_(###FIXME)";
};
builtin_convert_this_to_object,
builtin_qml_context,
builtin_qml_id_array,
- builtin_qml_imported_scripts_object,
- builtin_qml_context_object
+ builtin_qml_imported_scripts_object
};
const QString *id;
generateFunctionCall(temp, Runtime::getQmlImportedScripts, Assembler::EngineRegister);
}
-void InstructionSelection::loadQmlContextObject(IR::Expr *temp)
-{
- generateFunctionCall(temp, Runtime::getQmlContextObject, Assembler::EngineRegister);
-}
-
void InstructionSelection::loadQmlSingleton(const QString &name, IR::Expr *temp)
{
generateFunctionCall(temp, Runtime::getQmlSingleton, Assembler::EngineRegister, Assembler::StringToIndex(name));
{
if (kind == IR::Member::MemberOfQmlScopeObject)
generateFunctionCall(target, Runtime::getQmlScopeObjectProperty, Assembler::EngineRegister, Assembler::PointerToValue(base), Assembler::TrustedImm32(index));
+ else if (kind == IR::Member::MemberOfQmlContextObject)
+ generateFunctionCall(target, Runtime::getQmlContextObjectProperty, Assembler::EngineRegister, Assembler::PointerToValue(base), Assembler::TrustedImm32(index));
else
Q_ASSERT(false);
}
if (kind == IR::Member::MemberOfQmlScopeObject)
generateFunctionCall(Assembler::Void, Runtime::setQmlScopeObjectProperty, Assembler::EngineRegister, Assembler::PointerToValue(targetBase),
Assembler::TrustedImm32(propertyIndex), Assembler::PointerToValue(source));
+ else if (kind == IR::Member::MemberOfQmlContextObject)
+ generateFunctionCall(Assembler::Void, Runtime::setQmlContextObjectProperty, Assembler::EngineRegister, Assembler::PointerToValue(targetBase),
+ Assembler::TrustedImm32(propertyIndex), Assembler::PointerToValue(source));
else
Q_ASSERT(false);
}
Assembler::EngineRegister,
Assembler::TrustedImm32(propertyIndex),
baseAddressForCallData());
+ else if (kind == IR::Member::MemberOfQmlContextObject)
+ generateFunctionCall(result, Runtime::callQmlContextObjectProperty,
+ Assembler::EngineRegister,
+ Assembler::TrustedImm32(propertyIndex),
+ baseAddressForCallData());
else
Q_ASSERT(false);
}
virtual void loadQmlContext(IR::Expr *target);
virtual void loadQmlIdArray(IR::Expr *target);
virtual void loadQmlImportedScripts(IR::Expr *target);
- virtual void loadQmlContextObject(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);
addCall();
}
- virtual void loadQmlContextObject(Expr *temp)
- {
- addDef(temp);
- addCall();
- }
-
virtual void loadQmlSingleton(const QString &/*name*/, Expr *temp)
{
Q_UNUSED(temp);
return o->call(callData);
}
+ReturnedValue Runtime::callQmlContextObjectProperty(ExecutionEngine *engine, int propertyIndex, CallData *callData)
+{
+ Scope scope(engine);
+ ScopedFunctionObject o(scope, getQmlContextObjectProperty(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);
return engine->qmlContextObject()->asReturnedValue();
}
-ReturnedValue Runtime::getQmlContextObject(NoThrowEngine *engine)
-{
- QQmlContextData *context = engine->callingQmlContext();
- if (!context)
- return Encode::undefined();
- return QObjectWrapper::wrap(engine, context->contextObject);
-}
-
ReturnedValue Runtime::getQmlQObjectProperty(ExecutionEngine *engine, const Value &object, int propertyIndex, bool captureRequired)
{
Scope scope(engine);
return QV4::QObjectWrapper::getProperty(engine, c.d()->qml->scopeObject, propertyIndex, false);
}
+ReturnedValue Runtime::getQmlContextObjectProperty(ExecutionEngine *engine, const Value &context, int propertyIndex)
+{
+ const QmlContext &c = static_cast<const QmlContext &>(context);
+ return QV4::QObjectWrapper::getProperty(engine, c.d()->qml->context->contextObject, propertyIndex, false);
+}
+
ReturnedValue Runtime::getQmlSingletonQObjectProperty(ExecutionEngine *engine, const Value &object, int propertyIndex, bool captureRequired)
{
Scope scope(engine);
return QV4::QObjectWrapper::setProperty(engine, c.d()->qml->scopeObject, propertyIndex, value);
}
+void Runtime::setQmlContextObjectProperty(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->context->contextObject, propertyIndex, value);
+}
+
void Runtime::setQmlQObjectProperty(ExecutionEngine *engine, const Value &object, int propertyIndex, const Value &value)
{
Scope scope(engine);
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 callQmlContextObjectProperty(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);
static ReturnedValue getQmlContext(NoThrowEngine *engine);
static ReturnedValue getQmlIdArray(NoThrowEngine *engine);
static ReturnedValue getQmlImportedScripts(NoThrowEngine *engine);
- static ReturnedValue getQmlContextObject(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 getQmlContextObjectProperty(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 setQmlContextObjectProperty(ExecutionEngine *engine, const Value &context, int propertyIndex, const Value &value);
static void setQmlQObjectProperty(ExecutionEngine *engine, const Value &object, int propertyIndex, const Value &value);
};
STOREVALUE(instr.result, Runtime::getQmlScopeObjectProperty(engine, VALUE(instr.base), instr.propertyIndex));
MOTH_END_INSTR(LoadScopeObjectProperty)
+ MOTH_BEGIN_INSTR(StoreContextObjectProperty)
+ Runtime::setQmlContextObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, VALUE(instr.source));
+ CHECK_EXCEPTION;
+ MOTH_END_INSTR(StoreContextObjectProperty)
+
+ MOTH_BEGIN_INSTR(LoadContextObjectProperty)
+ STOREVALUE(instr.result, Runtime::getQmlContextObjectProperty(engine, VALUE(instr.base), instr.propertyIndex));
+ MOTH_END_INSTR(LoadContextObjectProperty)
+
MOTH_BEGIN_INSTR(LoadAttachedQObjectProperty)
STOREVALUE(instr.result, Runtime::getQmlAttachedProperty(engine, instr.attachedPropertiesId, instr.propertyIndex));
MOTH_END_INSTR(LoadAttachedQObjectProperty)
STOREVALUE(instr.result, Runtime::callQmlScopeObjectProperty(engine, instr.index, callData));
MOTH_END_INSTR(CallScopeObjectProperty)
+ MOTH_BEGIN_INSTR(CallContextObjectProperty)
+ 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::callQmlContextObjectProperty(engine, instr.index, callData));
+ MOTH_END_INSTR(CallContextObjectProperty)
+
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);
VALUE(instr.result) = Runtime::getQmlImportedScripts(static_cast<QV4::NoThrowEngine*>(engine));
MOTH_END_INSTR(LoadQmlImportedScripts)
- MOTH_BEGIN_INSTR(LoadQmlContextObject)
- VALUE(instr.result) = Runtime::getQmlContextObject(static_cast<QV4::NoThrowEngine*>(engine));
- MOTH_END_INSTR(LoadContextObject)
-
MOTH_BEGIN_INSTR(LoadQmlSingleton)
VALUE(instr.result) = Runtime::getQmlSingleton(static_cast<QV4::NoThrowEngine*>(engine), instr.name);
MOTH_END_INSTR(LoadQmlSingleton)