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);
|
||||
}
|
||||
|
||||
struct LookupNotInitialized {};
|
||||
|
||||
QObject *AOTCompiledContext::thisObject() const
|
||||
{
|
||||
return static_cast<QV4::MetaTypesStackFrame *>(engine->handle()->currentStackFrame)
|
||||
|
@ -1283,8 +1285,8 @@ static ObjectPropertyResult resetFallbackProperty(
|
|||
|
||||
static bool isTypeCompatible(QMetaType lookupType, QMetaType propertyType)
|
||||
{
|
||||
if (!lookupType.isValid()) {
|
||||
// If type is invalid, then the calling code depends on the lookup
|
||||
if (lookupType == QMetaType::fromType<LookupNotInitialized>()) {
|
||||
// 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.
|
||||
// We cannot verify the type in this case.
|
||||
} else if ((lookupType.flags() & QMetaType::IsQmlList)
|
||||
|
@ -1597,8 +1599,10 @@ QMetaType AOTCompiledContext::lookupResultMetaType(uint index) const
|
|||
= reinterpret_cast<const QMetaObject *>(l->qobjectFallbackLookup.metaObject - 1);
|
||||
const int coreIndex = l->qobjectFallbackLookup.coreIndex;
|
||||
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)
|
||||
|
@ -1625,7 +1629,7 @@ void AOTCompiledContext::storeNameSloppy(uint nameIndex, void *value, QMetaType
|
|||
l.nameIndex = nameIndex;
|
||||
l.forCall = false;
|
||||
ObjectPropertyResult storeResult = ObjectPropertyResult::NeedsInit;
|
||||
switch (initObjectLookup(this, &l, qmlScopeObject, QMetaType())) {
|
||||
switch (initObjectLookup(this, &l, qmlScopeObject, QMetaType::fromType<LookupNotInitialized>())) {
|
||||
case ObjectLookupResult::ObjectAsVariant:
|
||||
case ObjectLookupResult::Object: {
|
||||
const QMetaType propType = l.qobjectLookup.propertyData->propType();
|
||||
|
@ -1780,6 +1784,9 @@ bool AOTCompiledContext::callQmlContextPropertyLookup(
|
|||
return false;
|
||||
}
|
||||
|
||||
if (types[0] == QMetaType::fromType<LookupNotInitialized>())
|
||||
return false;
|
||||
|
||||
function->call(qmlScopeObject, args, types, argc);
|
||||
return !scope.hasException();
|
||||
}
|
||||
|
@ -1787,7 +1794,7 @@ bool AOTCompiledContext::callQmlContextPropertyLookup(
|
|||
void AOTCompiledContext::initCallQmlContextPropertyLookup(uint index) const
|
||||
{
|
||||
Q_UNUSED(index);
|
||||
Q_ASSERT(engine->hasError());
|
||||
if (engine->hasError())
|
||||
amendException(engine->handle());
|
||||
}
|
||||
|
||||
|
@ -1862,6 +1869,9 @@ bool AOTCompiledContext::callObjectPropertyLookup(
|
|||
return false;
|
||||
}
|
||||
|
||||
if (types[0] == QMetaType::fromType<LookupNotInitialized>())
|
||||
return false;
|
||||
|
||||
function->call(object, args, types, argc);
|
||||
return !scope.hasException();
|
||||
}
|
||||
|
@ -1869,7 +1879,7 @@ bool AOTCompiledContext::callObjectPropertyLookup(
|
|||
void AOTCompiledContext::initCallObjectPropertyLookup(uint index) const
|
||||
{
|
||||
Q_UNUSED(index);
|
||||
Q_ASSERT(engine->hasError());
|
||||
if (engine->hasError())
|
||||
amendException(engine->handle());
|
||||
}
|
||||
|
||||
|
|
|
@ -1551,22 +1551,6 @@ void QQmlJSCodeGenerator::generate_StoreProperty(int nameIndex, int baseReg)
|
|||
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)
|
||||
{
|
||||
INJECT_TRACE_INFO(generate_SetLookup);
|
||||
|
@ -1605,7 +1589,6 @@ void QQmlJSCodeGenerator::generate_SetLookup(int index, int baseReg)
|
|||
m_body += u"{\n"_s;
|
||||
QString variableIn;
|
||||
QString variableInType;
|
||||
QString preparation;
|
||||
QString argType;
|
||||
if (!m_typeResolver->registerContains(
|
||||
m_state.accumulatorIn(), property.containedType())) {
|
||||
|
@ -1614,11 +1597,7 @@ void QQmlJSCodeGenerator::generate_SetLookup(int index, int baseReg)
|
|||
+ u";\n"_s;
|
||||
variableIn = contentPointer(property, u"converted"_s);
|
||||
variableInType = contentType(property, u"converted"_s);
|
||||
preparation = setLookupPreparation(property, u"converted"_s, index);
|
||||
if (preparation.isEmpty())
|
||||
argType = contentType(property, u"converted"_s);
|
||||
else
|
||||
argType = u"argType"_s;
|
||||
} else {
|
||||
variableIn = contentPointer(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')';
|
||||
const QString initialization = u"aotContext->initSetObjectLookup("_s
|
||||
+ indexString + u", "_s + basePointer + u", "_s + argType + u')';
|
||||
generateLookup(lookup, initialization, preparation);
|
||||
generateLookup(lookup, initialization);
|
||||
break;
|
||||
}
|
||||
case QQmlJSScope::AccessSemantics::Sequence: {
|
||||
|
@ -1675,7 +1654,7 @@ void QQmlJSCodeGenerator::generate_SetLookup(int index, int baseReg)
|
|||
+ indexString + u", "_s + metaObject(originalScope)
|
||||
+ u", "_s + argType + u')';
|
||||
|
||||
generateLookup(lookup, initialization, preparation);
|
||||
generateLookup(lookup, initialization);
|
||||
generateWriteBack(baseReg);
|
||||
|
||||
break;
|
||||
|
@ -1715,7 +1694,8 @@ void QQmlJSCodeGenerator::generate_Resume(int)
|
|||
BYTECODE_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
QString QQmlJSCodeGenerator::argumentsList(int argc, int argv, QString *outVar)
|
||||
QQmlJSCodeGenerator::ArgumentsAndTypes QQmlJSCodeGenerator::argumentsList(
|
||||
int argc, int argv, QString *outVar)
|
||||
{
|
||||
QString types;
|
||||
QString args;
|
||||
|
@ -1729,12 +1709,6 @@ QString QQmlJSCodeGenerator::argumentsList(int argc, int argv, QString *outVar)
|
|||
*outVar = u"callResult"_s;
|
||||
const QQmlJSScope::ConstPtr outType = m_state.accumulatorOut().storedType();
|
||||
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";
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
return u"void *args[] = { "_s + args + u" };\n"_s
|
||||
+ u"const QMetaType types[] = { "_s + types + u" };\n"_s;
|
||||
return {args, types};
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
QString outVar;
|
||||
m_body += argumentsList(argc, argv, &outVar);
|
||||
const QString lookup = u"aotContext->callObjectPropertyLookup("_s + indexString
|
||||
+ u", "_s + inputPointer
|
||||
+ u", args, types, "_s + QString::number(argc) + u')';
|
||||
const ArgumentsAndTypes argsAndTypes = argumentsList(argc, argv, &outVar);
|
||||
|
||||
m_body += u"const auto doCall = [&]() {\n"_s
|
||||
+ 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
|
||||
+ indexString + u')';
|
||||
generateLookup(lookup, initialization);
|
||||
const QString preparation = getLookupPreparation(m_state.accumulatorOut(), outVar, index);
|
||||
|
||||
generateLookup(lookup, initialization, preparation);
|
||||
generateMoveOutVar(outVar);
|
||||
|
||||
m_body += u"}\n"_s;
|
||||
|
@ -2320,12 +2302,19 @@ void QQmlJSCodeGenerator::generate_CallQmlContextPropertyLookup(int index, int a
|
|||
|
||||
m_body += u"{\n"_s;
|
||||
QString outVar;
|
||||
m_body += argumentsList(argc, argv, &outVar);
|
||||
const QString lookup = u"aotContext->callQmlContextPropertyLookup("_s + indexString
|
||||
+ u", args, types, "_s + QString::number(argc) + u')';
|
||||
const ArgumentsAndTypes argsAndTypes = argumentsList(argc, argv, &outVar);
|
||||
m_body += u"const auto doCall = [&]() {\n"_s
|
||||
+ 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
|
||||
+ indexString + u')';
|
||||
generateLookup(lookup, initialization);
|
||||
const QString preparation = getLookupPreparation(m_state.accumulatorOut(), outVar, index);
|
||||
generateLookup(lookup, initialization, preparation);
|
||||
generateMoveOutVar(outVar);
|
||||
|
||||
m_body += u"}\n"_s;
|
||||
|
@ -2920,6 +2909,12 @@ QString QQmlJSCodeGenerator::getLookupPreparation(
|
|||
return var + u" = QVariant(aotContext->lookupResultMetaType("_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.
|
||||
return QString();
|
||||
}
|
||||
|
|
|
@ -260,8 +260,6 @@ protected:
|
|||
const QString &resultPreparation = QString());
|
||||
QString getLookupPreparation(
|
||||
const QQmlJSRegisterContent &content, const QString &var, int lookup);
|
||||
QString setLookupPreparation(
|
||||
const QQmlJSRegisterContent &content, const QString &arg, int lookup);
|
||||
void generateEnumLookup(int index);
|
||||
|
||||
QString registerVariable(int index) const;
|
||||
|
@ -316,7 +314,14 @@ private:
|
|||
|
||||
|
||||
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;
|
||||
|
||||
bool inlineStringMethod(const QString &name, int base, int argc, int argv);
|
||||
|
|
Loading…
Reference in New Issue