aboutsummaryrefslogtreecommitdiffstats
path: root/src/qmlcompiler/qqmljsoptimizations.cpp
Commit message (Collapse)AuthorAgeFilesLines
* QmlCompiler: Don't adjust the same conversion multiple timesUlf Hermann2025-09-231-1/+1
| | | | | | | | | | | | The same conversion can re-surface in multiple places in the byte code by virtue of being stored and loaded unchanged. If we've already adjusted it, we don't need to do it again. Pick-to: 6.10 Fixes: QTBUG-140415 Change-Id: Ic1e7e90af49f0ee9440a9c37abd4ab8ee0fdbe3e Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io> Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
* Add security header for src/qmlcompilerOlivier De Cannière2025-09-171-0/+1
| | | | | | | | | | | | | | | | | | We assume that QML or JS code comes from a trusted source. Therefore, most files are deemed to be significant even if they parse data. This includes the source code itself but also the associated metadata or cache files. However, the QML compiler also generates C++ code. Extra care needs to be taken with the generator as a vulnerability there could propagate and have a disproportionate effect on the program's security. It is marked as critical. QUIP: 23 Fixes: QTBUG-136195 Pick-to: 6.10 6.9 6.8 Change-Id: I70630361ec8e9cb3969f78a3fdf36a41334a33b3 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* QmlCompiler: Ensure QObjects returned to AOT-compiled code are wrappedUlf Hermann2025-09-021-4/+16
| | | | | | | | | | | | If a QObject is returned from a method call, the QML engine takes ownership of it and it needs to be deleted by the garbage collector. Our generated C++ code so far did not actually take ownership of the object and thereby caused it to leak. Pick-to: 6.10 6.9 6.8 Fixes: QTBUG-138919 Change-Id: I7bd57b3612bf4b98937756e8a7a7c03aff1c9b32 Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
* QmlCompiler: Rename sequences' "valueType" to "elementType"Ulf Hermann2025-08-311-3/+4
| | | | | | | | | "valueType" is ambiguous. The prevailing meaning is a type that's passed by value in QML. We mean the type of the list contents (or elements) here. Change-Id: Iaf4c0efe272dc6ec7511d2361e7e5ce475936fba Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
* QmlCompiler: Discern between different kinds of side effectsUlf Hermann2025-06-231-1/+1
| | | | | | | | | | A mere jump does not cause all value types and lists to be invalidated. Only calls to other functions or writes to other properties do that. Pick-to: 6.10 6.9 6.8 6.5 Fixes: QTBUG-137540 Change-Id: I069c6873455c51bbea59cf876d2bc7ecd188f81b Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
* QmlCompiler: Simplify register allocationUlf Hermann2025-06-231-2/+2
| | | | | | | | | | | We already have distinct "types" per value, the QQmlJSRegisterContents. We can reserve one stack slot per QQmlJSRegisterContent to avoid any aliasing and a lot of unnecessary copies. Pick-to: 6.10 6.9 6.8 6.5 Task-number: QTBUG-137540 Change-Id: I55a59fe2adea49bbb2e16bd610e304701d004a8c Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
* Compiler: Fix various clazy warningsOlivier De Cannière2025-03-211-3/+3
| | | | | Change-Id: Ib83c8d3452d5a0521295750f068f429b414da6ff Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QmlCompiler: Pass QQmlJSRegisterContent by valueUlf Hermann2024-12-031-6/+6
| | | | | | | | | It's only a single pointer these days. Task-number: QTBUG-124670 Change-Id: Id51fe268108733b07d77c70531f38914a8adfdae Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
* QmlCompiler: Clean up API of QQmlJSRegisterContentUlf Hermann2024-12-031-1/+1
| | | | | | | | Rename some methods and write some comments. Task-number: QTBUG-124670 Change-Id: I3046d545374c92dd7441d58d2b8fe2abc25078b8 Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
* QmlCompiler: Remove trivial type comparison methodsUlf Hermann2024-11-291-4/+4
| | | | | | | | We can compare types without QQmlJSTypeResovler now. Task-number: QTBUG-124670 Change-Id: Id06c8cd5cc8f03683134ad13e02d54ae4da9fae3 Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
* QmlCompiler: Move type adjustment into QQmlJSRegisterContentUlf Hermann2024-11-281-39/+44
| | | | | | | | | | | | | | | | | | | | | | | | | | This is the central piece of the refactoring. Instead of re-writing the QQmlJSScopes on adjustment we now rewrite the QQmlJSRegisterContents. The main benefit of this is that we can locally link QQmlJSRegisterContents together without invoking QQmlJSTypeResolver. The other benefit is that we gain more control over where the re-written types show up. QQmlJSScope is stored in many places that should really not be re-written. QQmlJSRegisterContent is only used locally when analyzing a binding or function. Finally, we can now chain the type adjustments with other operations on QQmlJSRegisterContents, without restrictions. This makes a few methods of QQmlJSTypeResolver obsolete. Those will be removed in a separate step. In order to get this right, we need to deviate from the notion that every read register is either a rename or a conversion. Rather, we must pass any "as-is" read of a register through that way. We rely on those to be re-written when the original register is. Task-number: QTBUG-124670 Change-Id: I0d968dfe495b82d9d9f67d598447bd2ad5bdcd04 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
* QmlCompiler: Do not adjust object definitions multiple timesUlf Hermann2024-11-231-0/+2
| | | | | | | | | Once we have handled them, we need to remove them from the list of reader locations. Task-number: QTBUG-124670 Change-Id: Ibe08a86a497c42fcca1d246d38e68e73e9a98fe5 Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
* QmlCompiler: Allow conversion of object literals to QJSValueUlf Hermann2024-11-011-1/+2
| | | | | | Task-number: QTBUG-124634 Change-Id: Ifb09c0f5e4a732518e44a8d3b73c5a836ad66508 Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
* QmlCompiler: Store full type information for conversion originsUlf Hermann2024-10-101-8/+18
| | | | | | | | | | With this in place, we don't have to synthesize conversion origins anymore and get to trace values through conversions. Task-number: QTBUG-124670 Change-Id: Ib3646d410526eca7b982f86adef9d5a387ff56ea Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Compiler: Create infrastructure to support multiple warningsOlivier De Cannière2024-08-211-11/+9
| | | | | | | | | | | | | | | | | Currently only one DiagnosticMessage can be stored at a time when using the compiler. However, we want to be able to show more than one to the user. Therefore, use a list that gets passed inside the compiler instead of a pointer to the sole error. This also means that the error is valid by its very existence. There is no need to check validity explicitly anymore. Task-number: QTBUG-127624 Change-Id: I356db917b86703b508dc1ad52de7825d82eafd71 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
* QmlCompiler: Remove left-over newAnnotations in populateReaderLocationsOlivier De Cannière2024-07-031-9/+1
| | | | | | | | | | | | After the break up of populateReaderLocation, the newAnnotations were left over there. They can be removed as they serve no purpose any more. Every instruction in m_annotations is simply copied into it and the whole thing is then moved back to m_annotations. Amends 5a011a0c38036cb58705fcb0da081d2204b85923 Change-Id: I44239a3db78c6d549518ec4d2b8333c2f2e328cb Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Compiler: Weaken god function populateReaderLocationsOlivier De Cannière2024-07-021-67/+75
| | | | | | | | | | | | | | | | The function populateReaderLocations does too much and is very hard to understand. This patch breaks up its functionality into several pieces. populateReaderLocations keeps the code related to what its name suggests it does: determining, for each instruction, what it reads and writes. The dead store elimination part is extracted into a separate function. The TODO for the merging of conversions types using QSet::unite() was also removed. This function was recently optimized in 92acc94fa98d19929d28feb5d543acf8c50c2290 and can be used again. Change-Id: Iad0870e08d09b47acbc51afa96e582f95e61b18f Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* QmlCompiler: Remove unused QQmlJSCompilePass::readTypesUlf Hermann2024-06-161-9/+1
| | | | | | Change-Id: Ib3cb24e750c9bfdbcc21b781f0b3de92ee074c92 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
* QmlCompiler: Remove QQmlJSTypeResolver::containedType()Ulf Hermann2024-06-161-5/+5
| | | | | | | | | We don't need the type resolver anymore to determine the contained type. QQmlJSRegisterContent can do it by itself. Change-Id: I395dc76cff751f6ac1afdfcd4ef7f80f05fcc36f Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QmlCompiler: Create QQmlJSRegisterContent unstoredUlf Hermann2024-06-161-22/+1
| | | | | | | | | | Add a separate pass to populate the stored types and only run that after we're done with all the type propagation and optimization. Task-number: QTBUG-124670 Change-Id: I740063908b22684f5d2c72d6261fad98850d8636 Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QmlCompiler: Reduce the usage of storedType()Ulf Hermann2024-06-161-0/+1
| | | | | | | | | | | | We don't actually need the stored type until we hit the storage generalizer. There are two cases where the stored type is the same as the contained type: methods and import namespaces. Store the contained type separately in those cases. Task-number: QTBUG-124670 Change-Id: I395203ab204162b2754914438f56546e07453272 Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QmlCompiler: fix unity buildsTim Blechmann2024-04-301-10/+3
| | | | | | | | | | `deduplicate` was declared in two translation units, which is breaking unity builds. Moving the definition to QQmlJSUtils fixes the builds and makes the code more robust towards potential ODR violations in case the function is ever changed in one TU, but not in the other. Change-Id: I57627399d50d284ce031af245fd4ad5aa1ab6405 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Compiler: Extract Basic blocks generation into its own compiler passOlivier De Cannière2024-04-191-0/+538
The old basic blocks pass was responsible for two things: the basic blocks generation and dead code analysis/type adjustments based on those blocks and the type propagation performed earlier. Now the basic blocks get generated first, even before the type propagation and the dead code analysis and type adjustments are now grouped in a pass called QQmlJSOptimizations. The rest of the passes remain unchanged. Change-Id: I7b4303eaf67c761a49b82ab194e5d035d24d2615 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>