Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-98789

Simplify binding order in QmlIR

    XMLWordPrintable

Details

    Description

      QmlIR orders bindings in a very special way:

      • generally, as the AST is traversed, bindings are prepended to an array of bindings (making several binding types to be stored in reverse order)
      • bindings on list properties are special (since they require proper ordering). when UiArrayBinding is encountered in the AST, it is traversed in the reverse order and the within-array bindings (which are prepended) happen to get appended instead. Commit [1] introduced this
      • bindings on default properties are also special (they, in fact, also require proper ordering e.g. QQuickItem's data is default list property). These bindings seem to be inserted into the array (instead of being prepended), with the insertion position being defined by the source location (this makes sure that their mutual order is correct, which is what is needed). Commit [2] introduced this in the current form

      Overall, turns out that changing this order is exceptionally painful. We have quite a bunch of tests that basically test the evaluation order of bindings (which must be unspecified).
      More problematic than these are the tests that fail due to internal code dependencies.
      Debugging the failures in https://codereview.qt-project.org/c/qt/qtdeclarative/+/382978 reveals the following:

      • QQmlObjectCreator codes around the binding order, by using special (QFiniteStack) data structures to store certain kinds of bindings. For instance,
        + Working with QQmlObjectCreatorSharedState::allCreatedBindings assumes the order of the bindings is reversed and so it re-reverses it
        + QQmlObjectCreatorSharedState::allParserStatusCallbacks and QQmlObjectCreatorSharedState::allCreatedObjects are similar to allCreatedBindings (in that they are also stacks, instead of queues). But these are trickier and it is unclear whether they should be changed at all
      • Deferred properties are affected by the binding order (as they are populated by QV4::CompiledData::Binding entries). And then they leak into user code (e.g. see quickBeginDeferred() and quickCompleteDeferred() for examples in qqc2) which may potentially (even if unintentionally) exploit the order in which the bindings appear
      • QmlIR passes (QQmlCompilePass subclasses) in QQmlTypeCompiler:
        + there's a dedicated QmlIR pass that fixes up undetected default property bindings (part of commit [1])
        + from the gist of binding order, other passes might add extra IR information in a specific order, which then could easily backfire in the user code (deferred properties, custom parsers, etc.)
      • Custom parsers might also abuse the order theoretically (but so far no issues were found)

      In theory, there are extra places that could blow up if the order is changed.
      Not changing the order means that any (old and new) tooling that interacts with the QmlIR has to be aware of the weird order.

      [1]: ea5a1e84cf68b9e9504109b4f86f08c6b09a28ed
      [2]: 55627060d5560aadcee22842eaf3833d4c623976

      Attachments

        Issue Links

          No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

              qtqmlteam Qt Qml Team User
              agolubev Andrei Golubev
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated:

                Gerrit Reviews

                  There are no open Gerrit changes