QmlCompiler: Use lookupResultMetaType() also for calls
This is generally better than doing a string lookup of the type. In turn, drop the lookup preparation for SetLookup. It's not doing anything useful anymore and would fail on the new lookupResultMetaType(). Change-Id: If52a44161f106c72c34d0d4ada2052fc2e287b4d Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
parent
ec124524ec
commit
1d59171d19
|
@ -974,6 +974,8 @@ void qmlRegisterTypeAndRevisions<QQmlTypeNotAvailable, void>(
|
||||||
qmlregister(TypeAndRevisionsRegistration, &type);
|
qmlregister(TypeAndRevisionsRegistration, &type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct LookupNotInitialized {};
|
||||||
|
|
||||||
QObject *AOTCompiledContext::thisObject() const
|
QObject *AOTCompiledContext::thisObject() const
|
||||||
{
|
{
|
||||||
return static_cast<QV4::MetaTypesStackFrame *>(engine->handle()->currentStackFrame)
|
return static_cast<QV4::MetaTypesStackFrame *>(engine->handle()->currentStackFrame)
|
||||||
|
@ -1283,8 +1285,8 @@ static ObjectPropertyResult resetFallbackProperty(
|
||||||
|
|
||||||
static bool isTypeCompatible(QMetaType lookupType, QMetaType propertyType)
|
static bool isTypeCompatible(QMetaType lookupType, QMetaType propertyType)
|
||||||
{
|
{
|
||||||
if (!lookupType.isValid()) {
|
if (lookupType == QMetaType::fromType<LookupNotInitialized>()) {
|
||||||
// If type is invalid, then the calling code depends on the lookup
|
// If lookup is not initialized, then the calling code depends on the lookup
|
||||||
// to be set up in order to query the type, via lookupResultMetaType.
|
// to be set up in order to query the type, via lookupResultMetaType.
|
||||||
// We cannot verify the type in this case.
|
// We cannot verify the type in this case.
|
||||||
} else if ((lookupType.flags() & QMetaType::IsQmlList)
|
} else if ((lookupType.flags() & QMetaType::IsQmlList)
|
||||||
|
@ -1597,8 +1599,10 @@ QMetaType AOTCompiledContext::lookupResultMetaType(uint index) const
|
||||||
= reinterpret_cast<const QMetaObject *>(l->qobjectFallbackLookup.metaObject - 1);
|
= reinterpret_cast<const QMetaObject *>(l->qobjectFallbackLookup.metaObject - 1);
|
||||||
const int coreIndex = l->qobjectFallbackLookup.coreIndex;
|
const int coreIndex = l->qobjectFallbackLookup.coreIndex;
|
||||||
return metaObject->property(coreIndex).metaType();
|
return metaObject->property(coreIndex).metaType();
|
||||||
|
} else if (l->getter == QV4::Lookup::getterQObjectMethod) {
|
||||||
|
return l->qobjectMethodLookup.propertyData->propType();
|
||||||
}
|
}
|
||||||
return QMetaType();
|
return QMetaType::fromType<LookupNotInitialized>();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isUndefined(const void *value, QMetaType type)
|
static bool isUndefined(const void *value, QMetaType type)
|
||||||
|
@ -1625,7 +1629,7 @@ void AOTCompiledContext::storeNameSloppy(uint nameIndex, void *value, QMetaType
|
||||||
l.nameIndex = nameIndex;
|
l.nameIndex = nameIndex;
|
||||||
l.forCall = false;
|
l.forCall = false;
|
||||||
ObjectPropertyResult storeResult = ObjectPropertyResult::NeedsInit;
|
ObjectPropertyResult storeResult = ObjectPropertyResult::NeedsInit;
|
||||||
switch (initObjectLookup(this, &l, qmlScopeObject, QMetaType())) {
|
switch (initObjectLookup(this, &l, qmlScopeObject, QMetaType::fromType<LookupNotInitialized>())) {
|
||||||
case ObjectLookupResult::ObjectAsVariant:
|
case ObjectLookupResult::ObjectAsVariant:
|
||||||
case ObjectLookupResult::Object: {
|
case ObjectLookupResult::Object: {
|
||||||
const QMetaType propType = l.qobjectLookup.propertyData->propType();
|
const QMetaType propType = l.qobjectLookup.propertyData->propType();
|
||||||
|
@ -1780,6 +1784,9 @@ bool AOTCompiledContext::callQmlContextPropertyLookup(
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (types[0] == QMetaType::fromType<LookupNotInitialized>())
|
||||||
|
return false;
|
||||||
|
|
||||||
function->call(qmlScopeObject, args, types, argc);
|
function->call(qmlScopeObject, args, types, argc);
|
||||||
return !scope.hasException();
|
return !scope.hasException();
|
||||||
}
|
}
|
||||||
|
@ -1787,8 +1794,8 @@ bool AOTCompiledContext::callQmlContextPropertyLookup(
|
||||||
void AOTCompiledContext::initCallQmlContextPropertyLookup(uint index) const
|
void AOTCompiledContext::initCallQmlContextPropertyLookup(uint index) const
|
||||||
{
|
{
|
||||||
Q_UNUSED(index);
|
Q_UNUSED(index);
|
||||||
Q_ASSERT(engine->hasError());
|
if (engine->hasError())
|
||||||
amendException(engine->handle());
|
amendException(engine->handle());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AOTCompiledContext::loadContextIdLookup(uint index, void *target) const
|
bool AOTCompiledContext::loadContextIdLookup(uint index, void *target) const
|
||||||
|
@ -1862,6 +1869,9 @@ bool AOTCompiledContext::callObjectPropertyLookup(
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (types[0] == QMetaType::fromType<LookupNotInitialized>())
|
||||||
|
return false;
|
||||||
|
|
||||||
function->call(object, args, types, argc);
|
function->call(object, args, types, argc);
|
||||||
return !scope.hasException();
|
return !scope.hasException();
|
||||||
}
|
}
|
||||||
|
@ -1869,8 +1879,8 @@ bool AOTCompiledContext::callObjectPropertyLookup(
|
||||||
void AOTCompiledContext::initCallObjectPropertyLookup(uint index) const
|
void AOTCompiledContext::initCallObjectPropertyLookup(uint index) const
|
||||||
{
|
{
|
||||||
Q_UNUSED(index);
|
Q_UNUSED(index);
|
||||||
Q_ASSERT(engine->hasError());
|
if (engine->hasError())
|
||||||
amendException(engine->handle());
|
amendException(engine->handle());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AOTCompiledContext::callGlobalLookup(
|
bool AOTCompiledContext::callGlobalLookup(
|
||||||
|
|
|
@ -1551,22 +1551,6 @@ void QQmlJSCodeGenerator::generate_StoreProperty(int nameIndex, int baseReg)
|
||||||
reject(u"StoreProperty"_s);
|
reject(u"StoreProperty"_s);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString QQmlJSCodeGenerator::setLookupPreparation(
|
|
||||||
const QQmlJSRegisterContent &content, const QString &arg, int lookup)
|
|
||||||
{
|
|
||||||
if (m_typeResolver->registerContains(content, content.storedType()))
|
|
||||||
return QString();
|
|
||||||
|
|
||||||
if (registerIsStoredIn(content, m_typeResolver->varType())) {
|
|
||||||
return u"const QMetaType argType = aotContext->lookupResultMetaType("_s
|
|
||||||
+ QString::number(lookup) + u");\n"_s
|
|
||||||
+ u"if (argType.isValid())\n "_s + arg + u".convert(argType)";
|
|
||||||
}
|
|
||||||
// TODO: We could make sure they're compatible, for example QObject pointers.
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void QQmlJSCodeGenerator::generate_SetLookup(int index, int baseReg)
|
void QQmlJSCodeGenerator::generate_SetLookup(int index, int baseReg)
|
||||||
{
|
{
|
||||||
INJECT_TRACE_INFO(generate_SetLookup);
|
INJECT_TRACE_INFO(generate_SetLookup);
|
||||||
|
@ -1605,7 +1589,6 @@ void QQmlJSCodeGenerator::generate_SetLookup(int index, int baseReg)
|
||||||
m_body += u"{\n"_s;
|
m_body += u"{\n"_s;
|
||||||
QString variableIn;
|
QString variableIn;
|
||||||
QString variableInType;
|
QString variableInType;
|
||||||
QString preparation;
|
|
||||||
QString argType;
|
QString argType;
|
||||||
if (!m_typeResolver->registerContains(
|
if (!m_typeResolver->registerContains(
|
||||||
m_state.accumulatorIn(), property.containedType())) {
|
m_state.accumulatorIn(), property.containedType())) {
|
||||||
|
@ -1614,11 +1597,7 @@ void QQmlJSCodeGenerator::generate_SetLookup(int index, int baseReg)
|
||||||
+ u";\n"_s;
|
+ u";\n"_s;
|
||||||
variableIn = contentPointer(property, u"converted"_s);
|
variableIn = contentPointer(property, u"converted"_s);
|
||||||
variableInType = contentType(property, u"converted"_s);
|
variableInType = contentType(property, u"converted"_s);
|
||||||
preparation = setLookupPreparation(property, u"converted"_s, index);
|
argType = contentType(property, u"converted"_s);
|
||||||
if (preparation.isEmpty())
|
|
||||||
argType = contentType(property, u"converted"_s);
|
|
||||||
else
|
|
||||||
argType = u"argType"_s;
|
|
||||||
} else {
|
} else {
|
||||||
variableIn = contentPointer(property, m_state.accumulatorVariableIn);
|
variableIn = contentPointer(property, m_state.accumulatorVariableIn);
|
||||||
variableInType = contentType(property, m_state.accumulatorVariableIn);
|
variableInType = contentType(property, m_state.accumulatorVariableIn);
|
||||||
|
@ -1635,7 +1614,7 @@ void QQmlJSCodeGenerator::generate_SetLookup(int index, int baseReg)
|
||||||
+ u", "_s + basePointer + u", "_s + variableIn + u')';
|
+ u", "_s + basePointer + u", "_s + variableIn + u')';
|
||||||
const QString initialization = u"aotContext->initSetObjectLookup("_s
|
const QString initialization = u"aotContext->initSetObjectLookup("_s
|
||||||
+ indexString + u", "_s + basePointer + u", "_s + argType + u')';
|
+ indexString + u", "_s + basePointer + u", "_s + argType + u')';
|
||||||
generateLookup(lookup, initialization, preparation);
|
generateLookup(lookup, initialization);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case QQmlJSScope::AccessSemantics::Sequence: {
|
case QQmlJSScope::AccessSemantics::Sequence: {
|
||||||
|
@ -1675,7 +1654,7 @@ void QQmlJSCodeGenerator::generate_SetLookup(int index, int baseReg)
|
||||||
+ indexString + u", "_s + metaObject(originalScope)
|
+ indexString + u", "_s + metaObject(originalScope)
|
||||||
+ u", "_s + argType + u')';
|
+ u", "_s + argType + u')';
|
||||||
|
|
||||||
generateLookup(lookup, initialization, preparation);
|
generateLookup(lookup, initialization);
|
||||||
generateWriteBack(baseReg);
|
generateWriteBack(baseReg);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -1715,7 +1694,8 @@ void QQmlJSCodeGenerator::generate_Resume(int)
|
||||||
BYTECODE_UNIMPLEMENTED();
|
BYTECODE_UNIMPLEMENTED();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString QQmlJSCodeGenerator::argumentsList(int argc, int argv, QString *outVar)
|
QQmlJSCodeGenerator::ArgumentsAndTypes QQmlJSCodeGenerator::argumentsList(
|
||||||
|
int argc, int argv, QString *outVar)
|
||||||
{
|
{
|
||||||
QString types;
|
QString types;
|
||||||
QString args;
|
QString args;
|
||||||
|
@ -1729,12 +1709,6 @@ QString QQmlJSCodeGenerator::argumentsList(int argc, int argv, QString *outVar)
|
||||||
*outVar = u"callResult"_s;
|
*outVar = u"callResult"_s;
|
||||||
const QQmlJSScope::ConstPtr outType = m_state.accumulatorOut().storedType();
|
const QQmlJSScope::ConstPtr outType = m_state.accumulatorOut().storedType();
|
||||||
m_body += outType->augmentedInternalName() + u' ' + *outVar;
|
m_body += outType->augmentedInternalName() + u' ' + *outVar;
|
||||||
if (!m_typeResolver->registerContains(m_state.accumulatorOut(), outType)) {
|
|
||||||
if (m_typeResolver->equals(outType, m_typeResolver->varType())
|
|
||||||
|| m_typeResolver->equals(outType, m_typeResolver->jsPrimitiveType())) {
|
|
||||||
m_body += u'(' + metaType(m_state.accumulatorOut().containedType()) + u')';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_body += u";\n";
|
m_body += u";\n";
|
||||||
|
|
||||||
args = contentPointer(m_state.accumulatorOut(), *outVar);
|
args = contentPointer(m_state.accumulatorOut(), *outVar);
|
||||||
|
@ -1748,8 +1722,7 @@ QString QQmlJSCodeGenerator::argumentsList(int argc, int argv, QString *outVar)
|
||||||
types += u", "_s + contentType(content, var);
|
types += u", "_s + contentType(content, var);
|
||||||
}
|
}
|
||||||
|
|
||||||
return u"void *args[] = { "_s + args + u" };\n"_s
|
return {args, types};
|
||||||
+ u"const QMetaType types[] = { "_s + types + u" };\n"_s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QQmlJSCodeGenerator::generateMoveOutVar(const QString &outVar)
|
void QQmlJSCodeGenerator::generateMoveOutVar(const QString &outVar)
|
||||||
|
@ -2264,13 +2237,22 @@ void QQmlJSCodeGenerator::generate_CallPropertyLookup(int index, int base, int a
|
||||||
m_body += u"{\n"_s;
|
m_body += u"{\n"_s;
|
||||||
|
|
||||||
QString outVar;
|
QString outVar;
|
||||||
m_body += argumentsList(argc, argv, &outVar);
|
const ArgumentsAndTypes argsAndTypes = argumentsList(argc, argv, &outVar);
|
||||||
const QString lookup = u"aotContext->callObjectPropertyLookup("_s + indexString
|
|
||||||
+ u", "_s + inputPointer
|
m_body += u"const auto doCall = [&]() {\n"_s
|
||||||
+ u", args, types, "_s + QString::number(argc) + u')';
|
+ u" void *args[] = {" + argsAndTypes.arguments + u"};\n"_s
|
||||||
|
+ u" QMetaType types[] = {" + argsAndTypes.types + u"};\n"_s
|
||||||
|
+ u" return aotContext->callObjectPropertyLookup("_s
|
||||||
|
+ indexString + u", "_s + inputPointer + u", args, types, "
|
||||||
|
+ QString::number(argc) + u");\n"
|
||||||
|
+ u"};\n"_s;
|
||||||
|
|
||||||
|
const QString lookup = u"doCall()"_s;
|
||||||
const QString initialization = u"aotContext->initCallObjectPropertyLookup("_s
|
const QString initialization = u"aotContext->initCallObjectPropertyLookup("_s
|
||||||
+ indexString + u')';
|
+ indexString + u')';
|
||||||
generateLookup(lookup, initialization);
|
const QString preparation = getLookupPreparation(m_state.accumulatorOut(), outVar, index);
|
||||||
|
|
||||||
|
generateLookup(lookup, initialization, preparation);
|
||||||
generateMoveOutVar(outVar);
|
generateMoveOutVar(outVar);
|
||||||
|
|
||||||
m_body += u"}\n"_s;
|
m_body += u"}\n"_s;
|
||||||
|
@ -2320,12 +2302,19 @@ void QQmlJSCodeGenerator::generate_CallQmlContextPropertyLookup(int index, int a
|
||||||
|
|
||||||
m_body += u"{\n"_s;
|
m_body += u"{\n"_s;
|
||||||
QString outVar;
|
QString outVar;
|
||||||
m_body += argumentsList(argc, argv, &outVar);
|
const ArgumentsAndTypes argsAndTypes = argumentsList(argc, argv, &outVar);
|
||||||
const QString lookup = u"aotContext->callQmlContextPropertyLookup("_s + indexString
|
m_body += u"const auto doCall = [&]() {\n"_s
|
||||||
+ u", args, types, "_s + QString::number(argc) + u')';
|
+ u" void *args[] = {" + argsAndTypes.arguments + u"};\n"_s
|
||||||
|
+ u" QMetaType types[] = {" + argsAndTypes.types + u"};\n"_s
|
||||||
|
+ u" return aotContext->callQmlContextPropertyLookup("_s
|
||||||
|
+ indexString + u", args, types, " + QString::number(argc) + u");\n"
|
||||||
|
+ u"};\n"_s;
|
||||||
|
|
||||||
|
const QString lookup = u"doCall()"_s;
|
||||||
const QString initialization = u"aotContext->initCallQmlContextPropertyLookup("_s
|
const QString initialization = u"aotContext->initCallQmlContextPropertyLookup("_s
|
||||||
+ indexString + u')';
|
+ indexString + u')';
|
||||||
generateLookup(lookup, initialization);
|
const QString preparation = getLookupPreparation(m_state.accumulatorOut(), outVar, index);
|
||||||
|
generateLookup(lookup, initialization, preparation);
|
||||||
generateMoveOutVar(outVar);
|
generateMoveOutVar(outVar);
|
||||||
|
|
||||||
m_body += u"}\n"_s;
|
m_body += u"}\n"_s;
|
||||||
|
@ -2920,6 +2909,12 @@ QString QQmlJSCodeGenerator::getLookupPreparation(
|
||||||
return var + u" = QVariant(aotContext->lookupResultMetaType("_s
|
return var + u" = QVariant(aotContext->lookupResultMetaType("_s
|
||||||
+ QString::number(lookup) + u"))"_s;
|
+ QString::number(lookup) + u"))"_s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (registerIsStoredIn(content, m_typeResolver->jsPrimitiveType())) {
|
||||||
|
return var + u" = QJSPrimitiveValue(aotContext->lookupResultMetaType("_s
|
||||||
|
+ QString::number(lookup) + u"))"_s;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: We could make sure they're compatible, for example QObject pointers.
|
// TODO: We could make sure they're compatible, for example QObject pointers.
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -260,8 +260,6 @@ protected:
|
||||||
const QString &resultPreparation = QString());
|
const QString &resultPreparation = QString());
|
||||||
QString getLookupPreparation(
|
QString getLookupPreparation(
|
||||||
const QQmlJSRegisterContent &content, const QString &var, int lookup);
|
const QQmlJSRegisterContent &content, const QString &var, int lookup);
|
||||||
QString setLookupPreparation(
|
|
||||||
const QQmlJSRegisterContent &content, const QString &arg, int lookup);
|
|
||||||
void generateEnumLookup(int index);
|
void generateEnumLookup(int index);
|
||||||
|
|
||||||
QString registerVariable(int index) const;
|
QString registerVariable(int index) const;
|
||||||
|
@ -316,7 +314,14 @@ private:
|
||||||
|
|
||||||
|
|
||||||
QString eqIntExpression(int lhsConst);
|
QString eqIntExpression(int lhsConst);
|
||||||
QString argumentsList(int argc, int argv, QString *outVar);
|
|
||||||
|
struct ArgumentsAndTypes
|
||||||
|
{
|
||||||
|
QString arguments;
|
||||||
|
QString types;
|
||||||
|
};
|
||||||
|
|
||||||
|
ArgumentsAndTypes argumentsList(int argc, int argv, QString *outVar);
|
||||||
QString castTargetName(const QQmlJSScope::ConstPtr &type) const;
|
QString castTargetName(const QQmlJSScope::ConstPtr &type) const;
|
||||||
|
|
||||||
bool inlineStringMethod(const QString &name, int base, int argc, int argv);
|
bool inlineStringMethod(const QString &name, int base, int argc, int argv);
|
||||||
|
|
Loading…
Reference in New Issue