Commit Graph

135 Commits

Author SHA1 Message Date
Ulf Hermann 4ab857c37b QmlCompile: Double-check types before generating lookups
In case of incomplete type information, we can get QJSValue as output
type where we expect QObject*. We cannot generate any sensible code for
that.

Change-Id: If817de7dca3b5b0b58aff92dec2dd12a7c10d250
Pick-to: 6.2 6.3
Fixes: QTBUG-102554
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2022-04-25 08:44:43 +02:00
Ulf Hermann ec79af7396 DelegateModel: Use actual bindings for required properties
Tracking the change signals is brittle and error prone. We have bindings
for this case. Let's use them. We can construct a synthetic
QV4::Function that contains its own QQmlJSAotFunction. In order to pass
the property index to the function we generalize the "index" property of
QQmlJSAotFunction to contain any extra data the function may want to
use. If there is no compilation unit, we pass that instead.

Fixes: QTBUG-91649
Change-Id: I0758bcc4964a48c6818d18bfb0972e67dbc16a1f
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2022-04-11 14:12:09 +02:00
Ulf Hermann 8a229c38fb QmlCompiler: Analyze type conversions before reads in basic blocks
The type conversions happen before the value is read. Therefore, we need
to record them in this order. Otherwise, we may lose a type conversion
if the instruction writes the same register as it reads.

Fixes: QTBUG-102281
Change-Id: Id63a69f86af90c8dc987c0301db3958322c006a1
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2022-04-06 17:12:50 +02:00
Ulf Hermann a55299615f QmlCompiler: Fix string-to-bool conversion via QJSPrimitiveValue
We had a typo in there.

Pick-to: 6.2 6.3
Fixes: QTBUG-102309
Change-Id: I11eb9d35fde3b92d2e48e845740379e10c53774a
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2022-04-06 17:12:41 +02:00
Ulf Hermann 0b63f3b66d QmlCompiler: Respect qualified property types
Factor out the name construction routine duplicated all over the place
and apply it to all places where it was missing.

Fixes: QTBUG-102147
Change-Id: I7c93b4878cedf3489b978591da8d8dfbb2b98c9b
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2022-04-06 05:02:34 +02:00
Ulf Hermann d425712e93 QmlCompiler: Allow primitive conversion from any number to bool
Task-number: QTBUG-102281
Change-Id: I0dac4ce9c86c55e52283a6e05b0c3c0cc46551be
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2022-04-05 14:27:12 +02:00
Andreas Buhr 598bfdb139 Repair tst_qmlcppcodegen on Android
tst_qmlcppcodegen tries to start itself again using QProcess.
This does not work on Android. This patch skips this test.

Task-number: QTBUG-101865
Pick-to: 6.2 6.3
Change-Id: Ib8f9a5e028a938949347bc8e83ea483d0228968e
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
2022-04-05 14:12:02 +02:00
Ulf Hermann c12f0f07f5 QmlCompiler: Improve ambiguous type detection
When detecting an ambiguous type, we need to invalidate the entry in the
list of types, rather than delete it. If we delete it and we get yet
another version of the type, we'll add that one just like it was not
ambiguous.

Furthermore, we cannot check the type name when looking for ambiguity.
The QML name can be bent and twisted in various ways, to import
ambiguous-looking types under different names, so that they are actually
not ambiguous.

Pick-to: 6.2 6.3
Fixes: QTBUG-102153
Change-Id: Iee7951229c5f68b168899e55164e8cf91587eec1
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2022-04-01 20:58:49 +02:00
Ulf Hermann 5901fba811 QmlCompiler: Fix a number of warts regarding type lookup
There was a condition missing in qqml.cpp making most type lookups crash
right away. Furthermore, we need to generate code for type lookups we do
need. Finally, the shadow check should skip instructions we don't need
anymore. Shadowing in optimized-out code is not very interesting.

Pick-to: 6.2 6.3 6.3.0
Change-Id: I34e9de7686528b39a35e59c616e4e28b32a6e031
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2022-03-23 12:29:26 +01:00
Ulf Hermann 8a9607acfc QmlCompiler: Support type lookups in prefix-imported modules
We just have to return a plain metaType if it's neither an attached type
nor a singleton.

Pick-to: 6.3
Fixes: QTBUG-101811
Change-Id: I6a78ffe4504606d0cb34f1a6ca9d5511a3447d7f
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2022-03-22 17:47:47 +01:00
Ulf Hermann 922b95ea15 QmlCompiler: Avoid some deprecation warnings
QString::count() is deprecated, and also the "engine" argument to
QQmlListReference. Also, properly convert the results of "length"
retrieval.

Change-Id: Ib7edde1326a0347902174a23147086b9deccfe17
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2022-03-14 20:53:52 +01:00
Ulf Hermann 6eff3465b5 QmlCompiler: Implement generate_DefineArray
Using the type cloning and adaption mechanism we can now determine what
kind of list we have to create in order to avoid a later conversion. We
can even propagate the type adjustment into the element types we read.

Fixes: QTBUG-100157
Change-Id: Ia2f160ebae56f39ee5946f49d2f8c5b4986a6b77
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2022-03-14 20:53:52 +01:00
Ulf Hermann 1e722f5e8e QML: Handle dynamic meta objects in AOT lookups
If we are dealing with dynamic metaobjects, the QML engine may not
create property caches. We cannot see this at compile time. Therefore,
we need to establish a fallback infrastructure that does the same
operations on plain QMetaObject.

Pick-to: 6.2 6.3
Fixes: QTBUG-101349
Change-Id: I8c936fc077b0018df71196620b6987825253cb39
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2022-03-03 18:44:38 +01:00
Andreas Buhr 85b086a97b Fix compilation of tst_qmlcppcodegen on Android
It seems MOC does not like methods named "isnan" on Android.
It generates a call to "__builtin_isnan".
This patch is a workaround. A real fix in MOC would be better.

Pick-to: 6.3
Change-Id: If73a4d7580ac51f6c60f4fb92c9699d077f4452f
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2022-03-02 14:21:08 +01:00
Ulf Hermann 074b66e007 QmlCompiler: On MoveReg, check if we need to move at all
As we don't store void, null and empty lists, moving those is a noop.
Don't generate invalid code for that.

Pick-to: 6.2 6.3
Change-Id: Ica6714acd0ce8a5ddca44d9a397e776eb3df4247
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2022-03-01 08:51:52 +01:00
Ulf Hermann 23ab2e0f55 QmlCompiler: Correctly label arguments and return types of JS functions
Returning void from any JS function doesn't quite cut it.

Pick-to: 6.3
Fixes: QTBUG-101285
Change-Id: I199813627614061ec25139277e8ea23cb844aac5
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Maximilian Goldstein <max.goldstein@qt.io>
2022-02-25 14:08:22 +01:00
Ulf Hermann c8e756e560 QML: Take care of QVariant when converting function arguments
We cannot convert to QVariant using QMetaType::convert(). But we can
just construct a QVariant with the desired type and data. This will
become an issue once we automatically convert argument types to match
the desired type inside the function.

As a side effect, also allow declaring "var" arguments to functions.

Change-Id: Idc14021d8d85d3d09ee7b7f286de91b56ea02bfd
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2022-02-23 12:09:42 +01:00
Ulf Hermann 88147eb3f6 QmlCompiler: Avoid infinite loop in dead store elimination
We have to mark the required variables also in block 0. And we shouldn't
generate empty blocks.

Pick-to: 6.3
Fixes: QTBUG-101011
Change-Id: I0dd19f69f45f507cb83e2ddfba3060de48a940b4
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2022-02-18 16:48:50 +01:00
Ulf Hermann d0f4e0c037 QmlCompiler: Perform QVariant conversion in JavaScript semantics
In JavaScript we have a number of extra conversions not covered by
qvariant_cast. Therefore, add a method to perform a QVariant conversion
in JavaScript semantics to QJSEngine, and use that in the compiler.

Pick-to: 6.3
Fixes: QTBUG-100883
Change-Id: I8b0bfa0974bc6b339d2601fb373859bc710788c8
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Reviewed-by: Jarkko Koivikko <jarkko.koivikko@code-q.fi>
2022-02-18 12:13:47 +01:00
Ulf Hermann 69fefd94e8 QmlCompiler: Do not crash on attempts to lookup a function in the scope
Rather, reject the code and let the engine handle it.

Pick-to: 6.2 6.3
Fixes: QTBUG-100980
Change-Id: Ibcd1249ba3550b40121622752b4ca22d1df3ed2a
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Jarkko Koivikko <jarkko.koivikko@code-q.fi>
2022-02-18 12:13:47 +01:00
Ulf Hermann 795d7dafe5 QmlCompiler: Do not generate block comments into C++ code
The code we're commenting could again contain block comments. You cannot
nest them.

Pick-to: 6.2 6.3
Fixes: QTBUG-100978
Change-Id: I78685bf29dd30f05e5a3b17abc43ba0b4cb6849e
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
2022-02-18 12:13:47 +01:00
Ulf Hermann 4c716dd19c QmlCompiler: Correctly encode inf/nan/-0 into C++
Pick-to: 6.2 6.3
Fixes: QTBUG-100947
Change-Id: If0b05adac91f687daf697f3510e4cf48e7de4537
Reviewed-by: Maximilian Goldstein <max.goldstein@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2022-02-18 12:13:47 +01:00
Ulf Hermann db6459665c QmlCompiler: Place code for CmpNeInt in parentheses
Otherwise it will apply the '!' to the first argument.

Fixes: QTBUG-100480
Pick-to: 6.2 6.3
Change-Id: Iaefa25d062ad8bbd9d4278ffeaa52fc53ed417e2
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2022-02-04 15:55:00 +01:00
Ulf Hermann 3747c02fe6 QmlCompiler: Handle ID lookups of incomplete types correctly
Incomplete types are generally stored in some wrapper type. We cannot
just assign to the accumulator. Also, we already know whether we have an
ID lookup there. No need to determine it again.

Pick-to: 6.2 6.3
Change-Id: I1f9fd9f147c44975df33fe862523987d8e711905
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2022-01-22 09:59:09 +01:00
Ulf Hermann e19d48d073 QmlCompiler: Respect revisions
The only place where revisions matter is at the boundary between
composite and non-composite types. The revision of the first composite
type inherited from determines which members of all composite ancestors
are available. Therefore, store the revision together with the base type
and pass it through the imports to have it available. Then use it to
check availability of methods and properties.

The test exposes two further problems, which are fixed, too:

1. If no method is found to call, we need to generate an error in the
   type propagator. We don't know what the call will result in, after
   all, and the code generator should reject it.
2. We need to check the right scopes for hasOwnMethod(). Otherwise we
   might not find methods that are available.

Pick-to: 6.2 6.3
Fixes: QTBUG-99128
Change-Id: I4c320b8dfb490b140d7b8c16e6b638b32f156faa
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2022-01-21 01:23:58 +01:00
Ulf Hermann 6a54c6013d QmlCompiler: Handle context push/pop in dead code
Otherwise we end up with unmatched curly braces in the generated code.

Pick-to: 6.2 6.3
Change-Id: I4c24d4062a8ed54cd6a9ecb43dfd2b5d0a26c9e1
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Maximilian Goldstein <max.goldstein@qt.io>
2022-01-18 12:51:38 +01:00
Ulf Hermann bd0f4459ce Re-allow retrieval of list properties in QQmlJSCodeGenerator
It's not particularly slow. It probably was when we were using
QQmlListReference or JavaScript arrays.

Pick-to: 6.3
Change-Id: I1a4575a5b84cdfb732a6c3615d00bbe2abaffc94
Reviewed-by: Fawzi Mohamed <fawzi.mohamed@qt.io>
2022-01-15 14:22:42 +01:00
Ulf Hermann 0ea14fa126 QmlCompiler: Don't try to get attached objects for non-QObject*
We might end up in this situation if we don't know enough about the
base of the attached lookup. This would generate invalid C++ code.

Pick-to: 6.2 6.3
Change-Id: I210077388d0d1d0d4e9454bd3ba3792af9b42049
Reviewed-by: Maximilian Goldstein <max.goldstein@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2021-12-17 12:43:14 +01:00
Ulf Hermann dd0b82abdc QQmlJSImportsVisitor: Break inheritance cycles
If we keep them around, later passes on the same data may run into
infinite loops. We cannot fully prevent any further processing of the
data because the import can happen from deep within a hierarchy of
components and modules.

Also, separate the deprecation check from the inheritance check.

Pick-to: 6.2
Change-Id: I62ce7cd15be83f60cd72b63ab858632fbc7dea66
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2021-12-12 12:05:28 +01:00
Ulf Hermann 2aa118c118 QQmlJSAotContext: flushPendingBinding() before capturing a property
This avoids duplicate evaluation and binding loops.

Pick-to: 6.2
Change-Id: I5eba42d9dca0782dd964bd64c088c2e158faa9b3
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2021-12-10 10:06:28 +01:00
Ulf Hermann af356e3bc8 qmlcachegen: Don't generate bad code if we cannot resolve a return type
If we cannot resolve a return type, we need to refrain from calling the
method.

Pick-to: 6.2
Task-number: QTBUG-99042
Change-Id: Ie5ba0367c83c178f7e5c112072ca97d3c1c1fb1f
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2021-12-10 02:42:47 +01:00
Ulf Hermann 25333a6af2 QmlCompiler: Split type name by last "::" rather than first
The outer type name can include namespaces, the inner one cannot.

Task-number: QTBUG-99042
Change-Id: Idaa3abbfa7b4ff0c908edd7fdee5c4e2ba0337dc
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2021-12-10 02:42:47 +01:00
Ulf Hermann 1003626e6a QmlCompiler: Fix return type calculation
We can return void from a function, explicitly or implicitly, and we
need to be able to wrap that into a QVariant. In order to explicitly
return void, we need the void type to be exposed and understood.

Pick-to: 6.2
Change-Id: I513cabb25469b89a85b5d212a6825a037400729d
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2021-12-06 19:35:50 +01:00
Ulf Hermann b7b5127747 Test that we can retrieve attached types from "recursive" names
This is what the various SelectionRectangle.qml types in qqc2 do. Amends
commit e6c44662cdc8acfbdbf1c7ed071e1253ff0c1321.

Change-Id: Icb98f262d669ed165a3b3ab1be79b150b6cedc44
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2021-12-04 17:11:27 +01:00
Ulf Hermann 58ff7aa4fe Compile QML files ahead of time with qmlcachegen
qmlcachegen compiles bindings and functions to C++ as far as
QQmlJSAotCompiler can. It does respect "pragma Strict" and rejects the
file if it's violated. Furthermore, it sets up the logger to follow the
qt.qml.compiler.aot logging category. By default it's completely silent.

Compiling the examples with qmlcachegen exposes a bug in the type
resolver where it returns an invalid generic type. It should never do
that. Fix it by returning JSValue.

[ChangeLog][QtQml][Important Behavior Changes] QML bindings and
functions are now compiled to C++ by qmlcachegen, if possible. Use the
qt.qml.compiler.aot logging category to receive diagnostics about the
compilation.

Task-number: QTBUG-98305
Change-Id: I6953812c3fd20b68339617a5714fcbe16a384360
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2021-12-03 12:09:26 +01:00