Details
-
User Story
-
Resolution: Unresolved
-
P2: Important
-
6.x
Description
qmltc would significantly benefit from the information exposed by qmlsc. Mostly, we could drastically optimize JavaScript interaction model by being able to provide generated C++ function signatures to qmltc during its compilation phase.
Consider the following scenarios:
- Complex JavaScript code: QML document contains a non-trivial JS. That code is then bound to a particular property (either as a general binding or as a signal/property-change handler). We can avoid QQmlEngine indirection here by exposing a function for each ahead-of-time compiled piece of JavaScript.
- Simple JavaScript property bindings: often enough, things that do not look like JavaScript bindings tend to be them: bindings to enum values, constant math expressions, etc. These things can in theory be optimized even further by exposing the whole expression to qmltc, so that it could just dump it into the C++ file, avoiding a QQmlEngine call and C++ function call altogether.
(Complex) JavaScript code is a general pattern. At present, it seems that qmltc needs the following information:
- header file path with all generated functions (their declarations)
- name / signature of a function for each JavaScript block in the program
- a way to map a JavaScript block to a function ahead-of-time
This model, in fact, does not have to assume that every JavaScript expression is compiled to C++. qmltc could just fall back to QQmlEngine call when the function is infeasible for qmlsc to compile.
Simple (dependency-free, constant) JavaScript code is a special case. QQmlObjectCreator does the following:
- installs every binding
- evaluates them once
- sees whether bindings could be removed
qmlsc, on the other hand, should be able to see this ahead-of-time and basically generate constant expressions. If this is the case, qmltc might benefit from exposing such directly and it needs:
- the expression (with a guarantee that it evaluates to the type convertible to the corresponding property type)
- a way to map a JavaScript binding to an expression ahead-of-time
As in the case of the general pattern, no assumptions on whether everything has to be compiled to C++ are made. Exposing expressions (essentially generated function definitions) allows to convert a binding setup into a property assignment, which is usually a much simpler construct.
More generally, qmlsc, given some additional user-driven context, should be able to compile even non-trivial JavaScript into C++ constant expression. Consider:
Text {
id: myText
text: "Some lengthy text"
}
Rectangle {
width: myText.text.length
}
If a user can guarantee that myText.text is unmodified within the whole QML application, myText.text and myText.text.length essentially become constant values that we can propagate around the document. This means that Rectangle's width also becomes constant and so on. The problem in general is that the user could modify myText.text from C++ and our tooling would definitely miss that. One solution is to introduce an expression annotation (e.g. "immutable"/"constexpr"/"consteval") to mark every non-modifiable expression as constant, thus allowing qmlsc to understand what it could optimize and fail at run time if properties ( ? ) with constant expressions get modified.
This, however, truly requires QTBUG-96548.
Attachments
Issue Links
- is required for
-
QTBUG-120004 QML Type Compliler in Qt 6.8(?)
- Open
- relates to
-
QTBUG-105538 qmltc evolution collection task
- Open