aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4value_p.h
Commit message (Collapse)AuthorAgeFilesLines
...
* | | Change function signatures for call/construct backLars Knoll2017-08-041-0/+3
| | | | | | | | | | | | | | | | | | | | | | | | Change those back again to return a value. This will be required to avoid creation of Scope objects between JS function calls. Change-Id: I05cb5cf8fd0c13dcefa60d213ccd5983fab57ea3 Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
* | | Tune asArrayIndexErik Verbruggen2017-08-021-2/+2
| | | | | | | | | | | | | | | Change-Id: Icc8a05b9a04d98e6e7c29f1d5b2cea32ce75ad24 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* | | Encode numeric literals as int when possibleErik Verbruggen2017-06-221-0/+8
|/ / | | | | | | | | Change-Id: I5ecc406f06a193b470eb9ac376da6b9f752d01cb Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* | Merge remote-tracking branch 'origin/5.9' into devSimon Hausmann2017-04-071-23/+35
|\| | | | | | | | | | | | | | | | | | | Conflicts: src/qml/jit/qv4assembler.cpp src/qml/jit/qv4assembler_p.h src/qml/jit/qv4isel_masm.cpp src/qml/jsruntime/qv4vme_moth.cpp Change-Id: I865d794e550a263387a39ca8d051ebf48b70cbc0
| * Fix value type encoding constant usage when cross-compilingSimon Hausmann2017-03-301-23/+35
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Our two value encodings use different masks for the upper 4 bytes. Depending on the target architecture we must use different values when generating code that uses these masks. This patch replaces the #ifdef'ed ValueTypeInternal_* enum values with two C++11 scoped enums that allows for the co-existence of both throughout the code base as well as selective use in the code generators. Change-Id: I380c8c28b84df2874cca521b78bfe7f9388ed228 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* | Separate the stack used for GC from the regular JS stackLars Knoll2017-04-071-1/+1
| | | | | | | | | | | | | | | | This is required to be able to implement concurrent or incremental garbage collection. Change-Id: Ib3c5eee3779ca2ee08a57cd3961dbcb0537bbb54 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Merge remote-tracking branch 'origin/5.9' into HEADSimon Hausmann2017-03-231-2/+0
|\| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Conflicts: src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp src/qml/jit/qv4assembler.cpp src/qml/jit/qv4assembler_p.h src/qml/jit/qv4isel_masm.cpp src/qml/jsruntime/qv4context.cpp src/qml/jsruntime/qv4context_p.h src/qml/jsruntime/qv4engine.cpp src/qml/jsruntime/qv4vme_moth.cpp src/qml/memory/qv4mmdefs_p.h Change-Id: I9966750b7cd9106b78e4c4779f12b95a481cca40
| * Complete transition to standard layout classes for JIT accessSimon Hausmann2017-03-211-2/+0
| | | | | | | | | | | | | | | | | | | | | | | | Move the Runtime function pointer array into EngineBase so that we can eliminate the last use of qOffsetOf. For improved cache locality the memory manager point is now also located in the EngineBase. Change-Id: I0b3cf44c726aa4fb8db1206cc414a56c2f522a84 Task-number: QTBUG-58666 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* | Add an actual write barrier and centralize it in one placeLars Knoll2017-03-091-46/+0
| | | | | | | | | | | | | | | | All stores into the Heap from C++ and Moth should now go through the write barrier. Change-Id: Iae9347754b90d68c10fade9f345842e86ec460cd Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | move locals over to be write barrier safeLars Knoll2017-03-091-22/+1
| | | | | | | | | | Change-Id: I56b1dab62ff432273ee8549b0496bd0f3fc655ea Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Go through proper set() functions when writing to MemberDataLars Knoll2017-03-091-0/+38
| | | | | | | | | | | | | | | | This is required, so we only have to add the write barrier in one place. Change-Id: I4e8bde823b30ad18f043312ac3f1ed46597b91a7 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Change getValueOrSetter to be write barrier friendlyLars Knoll2017-03-091-0/+5
| | | | | | | | | | | | | | | | Don't return a naked pointer into the heap, as this makes it impossible to track where and when we're writing into it. Change-Id: I2b9b81779ef8e9fb7a643ddda82aa6af8af459a7 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Add a set() method to HeapValue as wellLars Knoll2017-03-091-1/+4
| | | | | | | | | | | | | | | | And use it instead of simply assigning to it, so we can add a write barrier later on. Change-Id: I31c0d0b20ed5d37fee046aa02af17875679b22bf Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Make every member of a Heap object aware of its offset inside the objectLars Knoll2017-03-091-0/+5
| | | | | | | | | | | | | | | | This will allow adding a write barrier to those fields with manageable effort. Change-Id: I7d06d7ffccbcefe66e2524c64c962353c91c2766 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Refactor how we define Heap objectsLars Knoll2017-03-091-0/+1
| | | | | | | | | | | | | | | | | | | | Declare the type of Heap object in the Member() macro, instead of deducing it from templates. This allows us to encode the offset of the member in the second template argument to Pointer<> in a second step. Change-Id: I2cfb73785749d3fb991689b4e0554a72b3e5e13f Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Unify mark handling for MemberData and ArrayDataLars Knoll2017-03-091-0/+14
|/ | | | | | | | Introduce a ValueArray class, that defines an array of Values at the end of a Heap Object. Change-Id: I00efbf6f5839a6687dd5bc5fc037ec8f06e0936e Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* Make QV4::Value constants of both encodings always availableSimon Hausmann2017-01-301-16/+29
| | | | | | | | | In order to be able to generate native code for either encoding then we need to have all constants available. Change-Id: I851fed70023d3dab11b1e70e1689ea88a98c8564 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* UINT_MAX is not a valid array index in JSLars Knoll2017-01-251-1/+1
| | | | | | | | Fix a regression, where we'd accept UINT_MAX as a valid array index. Change-Id: I5ae8874d590f5e99da2e12d367b6f3c65b2bad0b Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
* Some smaller optimizations for indexed property accessLars Knoll2016-12-101-0/+15
| | | | | | | Saves around 1% of instructions on crypto.js Change-Id: Iccef08b204e6e752d827242baf156efd9a4d58a7 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* Avoid one additional check when retrieving the Heap object from a ValueLars Knoll2016-12-101-7/+7
| | | | | Change-Id: Ief43d899e47cbfd865458a38aab8c466f6c2c76f Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* Clean up duplicated checks whether a Value is a ManagedLars Knoll2016-11-291-6/+6
| | | | | Change-Id: Ib044be254dbb41bd9fb4a6e0baa3bd3c007e6a2a Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* V4: Help the C++ compiler to do more DSE by inlining more codeErik Verbruggen2016-11-291-23/+23
| | | | | | | | | | The JS stack allocation initializes the contents, but in most cases the caller will immediately store a value in that stack slot. When the allocation code is inlined, the compiler can use dead store elimination to remove the unnecessary initialization code. Change-Id: I0495417adc7c1c8764f845032611bd506a8b7df9 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* Merge remote-tracking branch 'origin/5.7' into 5.8v5.8.0-beta1Liang Qi2016-10-271-4/+1
|\ | | | | | | | | | | | | Conflicts: tests/auto/quick/qquicktextedit/BLACKLIST Change-Id: I0b9e5bea5da5d2666887c202e62d889b4aa56900
| * Merge remote-tracking branch 'origin/5.6' into 5.7Liang Qi2016-10-271-4/+20
| |\ | | | | | | | | | | | | | | | | | | | | | | | | Conflicts: src/quick/items/qquickwindow.cpp tests/auto/quick/qquicktext/BLACKLIST tests/auto/quick/qquicktextedit/BLACKLIST Change-Id: I8bd68b0b5e853b7908791d2cbddd18dd527c76ae
| | * Fix QML Compiler crashSimon Hausmann2016-10-251-4/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | After commit 2afb54fb51091765f79548b0b057795bc3c6eb38, Primitive::undefinedValue() uses setM() to clear out all bits. Previously that code was #ifndef'ed out for the bootstrap build, but now that we can do the correct boxing in host builds (as we know the pointer size), we can re-enable setM() in bootstrap builds and fix this crash that was a Q_UNREACHABLE() assertion. Change-Id: I49036792c06c9a17272aba65261ab8f32beb2ad8 Task-number: QTBUG-56658 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* | | Merge remote-tracking branch 'origin/5.6' into 5.8Simon Hausmann2016-10-131-0/+19
|\ \ \ | | |/ | |/| | | | Change-Id: I175b27337b534c0b8f46a4a792d2c43cde73ffc4
| * | V4: Fix usage of QV4::Value tags/typesErik Verbruggen2016-10-131-0/+19
| | | | | | | | | | | | | | | | | | | | | | | | These two were mixed, but have completely different values. Task-number: QTBUG-56471 Change-Id: Ifbf6da3032335ea89bfbc3acde17f64a571b9dc0 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
| * | Fix V4 on big-endianAllan Sandfeld Jensen2016-10-101-8/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We can't both invert offset position and inter-value positions of tag and value. This patch changes 32-bit big-endian to use the same order inside the tag/value but just at different offsets. This also make it compatible with how we use it with doubles. This fixes value/tag reads on 32-bit big-endian and offsets on 64-bit. Task-number: QTBUG-56271 Change-Id: I95cf792c29ac3f42a4018ce1f115193c143a0df0 (cherry picked from commit 2a658344397729450f869138bf77e063a0a6166b) Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* | | Merge remote-tracking branch 'origin/5.7' into 5.8Liang Qi2016-10-101-105/+141
|\ \ \ | | |/ | |/| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Conflicts: examples/quick/quickwidgets/quickwidget/main.cpp src/qml/jsruntime/qv4jsonobject.cpp src/qml/jsruntime/qv4qobjectwrapper.cpp src/qml/jsruntime/qv4qobjectwrapper_p.h src/qml/qml/qqmlengine.cpp src/qml/qml/qqmlpropertycache.cpp src/qml/qml/qqmlpropertycache_p.h src/quick/items/qquickanimatedsprite.cpp src/quick/items/qquickitem.cpp src/quick/items/qquickitem.h src/quick/items/qquickitem_p.h src/quick/items/qquickview_p.h src/quick/scenegraph/qsgcontext.cpp src/quick/scenegraph/qsgdefaultrendercontext.cpp Change-Id: I172c6fbff97208f21ed4c8b6db3d1747a889f22b
| * | Merge remote-tracking branch 'origin/5.6' into 5.7Liang Qi2016-09-301-105/+141
| |\| | | | | | | | | | | | | | | | | | | Conflicts: tests/auto/quick/qquicktext/tst_qquicktext.cpp Change-Id: I241cd418bb7e7b95e0a0a2ee4c465d48be2a5582
| | * V4: Free up 2 address bits in 64bit modeErik Verbruggen2016-09-281-105/+141
| | | | | | | | | | | | | | | | | | | | | | | | | | | This allows for the OS to use 49 address bits. It also maps JS Undefined to the C++ nullptr on 64bit. Task-number: QTBUG-54822 Change-Id: I7cc90620f499be1506a61aac77d72d067308838c Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* | | QML: Make Heap::Object and all subclasses trivialErik Verbruggen2016-10-061-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | GCC6 might dead-store-eliminate out our secret write to Base::mmdata, because it expects all memory content to be "undefined" before constructor calls. Clang might take the same approach if the constructor of Heap::Object is removed. By making these structs trivial, it also makes them memcpy-able. Change-Id: I055b2ad28311b997fbe059849ebda4d5894eaa9b Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | | QML: Make all context objects trivialErik Verbruggen2016-09-301-4/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This change also adds a check to the d() calls for Managed, verifies that the object has been initialized. This is only done for debug builds. To prevent other code from tripping the check, a number of other classes are either marked as trivial, or do initialization in the constructors. Because of template function changes in them memory manager (those now call init() instead of in-place new), String has an extra parameter to force it to temporarily use an old/unmodified template function. Change-Id: I8c35161ce7680835d830638b6d21498c5129b02b Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | | Merge remote-tracking branch 'origin/5.7' into 5.8Liang Qi2016-09-211-8/+5
|\| | | | | | | | | | | | | | | | | | | | Conflicts: src/qml/qml/qqmltypeloader.cpp Change-Id: I07647700fc86764c95a5ef95c568e700a70fe45f
| * | Fix V4 on big-endianAllan Sandfeld Jensen2016-09-121-8/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We can't both invert offset position and inter-value positions of tag and value. This patch changes 32-bit big-endian to use the same order inside the tag/value but just at different offsets. This also make it compatible with how we use it with doubles. This fixes value/tag reads on 32-bit big-endian and offsets on 64-bit. Change-Id: I95cf792c29ac3f42a4018ce1f115193c143a0df0 Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
* | | Merge remote-tracking branch 'origin/5.7' into devEdward Welbourne2016-08-021-2/+2
|\| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Conflicts: src/quick/items/qquickshadereffect.cpp 5.7 had a bug-fix in code dev has replaced wholesale. src/quick/items/qquickwindow.cpp src/quick/items/qquickwindow_p.h One side changed a method's signature; the other side renamed a method declared adjacent to it and changed some code using it, moving some from the public class to its private partner. tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp One side added a blank line before a comment the other re-wrote. Kept the re-write, killed the stray blank. .qmake.conf Ignore 5.7's change to MODULE_VERSION. src/qml/compiler/qqmltypecompiler.cpp src/qml/compiler/qqmlpropertyvalidator.cpp 5.7 changed code in the former that dev moved to the latter. Reflect 5.7's changes there, adapted to dev's form. src/qml/qml/qqmlobjectcreator.cpp One side added new QVariant types; the other changed how it handled each type of QVariant (without git seeing any conflict); adapted the new stanzas to work the same as the transformed ones. tests/manual/v4/test262 dev had a broken sha1 for it; so used 5.7's 9741ac4655808ac46c127e3d1d8ba3d27ada618e Change-Id: I1fbe2255b97d6ef405cdd1d0cea7fab8dc351d6f
| * | Merge remote-tracking branch 'origin/5.6' into 5.7Liang Qi2016-08-011-2/+2
| |\| | | | | | | | | | | | | | | | | | | | | | Conflicts: tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp tests/auto/quick/qquickitem/tst_qquickitem.cpp Change-Id: If261f8eea84dfa5944bb55de999d1f70aba528fd
| | * Fix QQmlEngine crash on big endian 64 bit architectures (s390x)Maximiliano Curia2016-07-201-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This change disables the BIG_ENDIAN 32 bits words mangling in 64 bits machines (where the words are 64 bits long); this would otherwise result in a segfault. Task-number: QTBUG-54717 Change-Id: I6b5ab6f213880b030795185c05e609d290168901 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io> Reviewed-by: Timo Jyrinki <timo.jyrinki@iki.fi> Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
* | | Merge remote-tracking branch 'origin/5.7' into devLiang Qi2016-06-211-42/+52
|\| | | | | | | | | | | | | | | | | | | | | | | | | | Conflicts: src/quick/items/qquickflickable_p_p.h src/quick/items/qquickpathview_p_p.h tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp Change-Id: I77664a095d8a203e07a021c9d5953e02b8b99a1e
| * | Merge remote-tracking branch 'origin/5.6' into 5.7Liang Qi2016-06-201-42/+52
| |\| | | | | | | | | | | | | | | | | | | | | | Conflicts: src/qml/jit/qv4targetplatform_p.h src/quick/accessible/qaccessiblequickitem_p.h Change-Id: Ic95075a5fad81ec997a61561bd65979dfa3b9d4d
| | * V4: Always set the tag when boxing a pointer in QV4::Value.Erik Verbruggen2016-06-161-42/+52
| | | | | | | | | | | | | | | | | | | | | | | | | | | All setters now store tags, so no-one can play loosy-goosy with the boxed values (and accidentally forget to "tag" a value, resulting in random garbage). Change-Id: Ia0b78aa038d3ff46d5292b14bd593de310da16a0 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | | V4: tighten up various casts to check also check type.Erik Verbruggen2016-06-081-2/+11
|/ / | | | | | | | | | | | | | | | | | | All those type conversions assumed that the content of a Value was either the requested type, or 0 (zero, a null pointer). Now, attempting to convert e.g. undefined to a string will fail, instead of returning a weird address. Change-Id: I0f567cdcc9cc9728d019f17693f4a6007394a9c6 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* | Merge remote-tracking branch 'origin/5.6' into 5.7Liang Qi2016-05-191-5/+1
|\| | | | | | | | | | | | | | | | | Conflicts: src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp src/qml/jsruntime/qv4engine.cpp src/qml/jsruntime/qv4engine_p.h Change-Id: I89ffccd699bee675732758d039e22224b275d60d
| * Remove workaround for the pointer size in bootstrapped tool buildsThiago Macieira2016-05-111-5/+1
| | | | | | | | | | | | | | | | | | The pointer size is now correctly set in qprocessordetection.h even for bootstrapped builds. Change-Id: I7e6338336dd6468ead24ffff1410d4ba8b1cbdad Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com> Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
* | Merge remote-tracking branch 'origin/5.6' into 5.7Liang Qi2016-03-071-2/+5
|\| | | | | | | Change-Id: Icfa1d61fcc286c3418d4a625de11d2191336fa60
| * V4: fix bootstrapped builds on Ubuntu 32bit.Erik Verbruggen2016-03-031-2/+5
| | | | | | | | | | | | | | | | We use 64bit value encoding there, so gcc complained that memcpy would write 8 bytes to a 4 byte pointer value. Change-Id: Ib44372fb0e4bbacf0279930f7f5fcf4bbb5d48bf Reviewed-by: Nikolai Kosjar <nikolai.kosjar@theqtcompany.com>
* | Updated license headersJani Heikkinen2016-01-191-14/+20
|/ | | | | | | | | | | From Qt 5.7 -> LGPL v2.1 isn't an option anymore, see http://blog.qt.io/blog/2016/01/13/new-agreement-with-the-kde-free-qt-foundation/ Updated license headers to use new LGPL header instead of LGPL21 one (in those files which will be under LGPL v3) Change-Id: Ic36f1a0a1436fe6ac6eeca8c2375a79857e9cb12 Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
* Remove prohibited uses of underscore + capital letterThiago Macieira2016-01-081-23/+23
| | | | | | | | | | | | | | All identifiers starting with an underscore and a capital letter are reserved to the compiler and must never be used by the user code. Try to find a better name or, in the worst case, move the underscore to the last position in these identifiers. See commit cf63c63d558227fdbef09699c261560e7474f5ea in qtbase for a case of such an identifier causing a build breakage when the compiler began treating it specially (it was _Nullable). Change-Id: I1d0f78915b5942aab07cffff140f9f39c29f0fdf Reviewed-by: Erik Verbruggen <erik.verbruggen@theqtcompany.com>
* Add missing "We mean it" comments to private headers.Friedemann Kleint2015-10-061-0/+11
| | | | | | Task-number: QTBUG-48594 Change-Id: Ifc207938de7f0c8995fc712df92665f222612647 Reviewed-by: Alan Alpert <aalpert@blackberry.com>
* Fix read of uninitialized value (undefined behavior)Thiago Macieira2015-09-241-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Commit 92836d052efb6d8073136e8507083f93fb60bb80 fixed the type punning but introduced undefined behavior on 32-bit systems. Detected by GCC 5.2 qv4value_p.h:96:55: error: ‘v.Qti386::QV4::Value::_val’ may be used uninitialized in this function [-Werror=maybe-uninitialized] qv4scopedvalue_p.h:199:15: note: ‘v.Qti386::QV4::Value::_val’ was declared here Trace: starting at qv4scopedvalue_p.h:199 Value v; v = o; => Value &operator=(Heap::Base *o) { setM(o); => Q_ALWAYS_INLINE void setM(Heap::Base *b) { quint32 v; memcpy(&v, &b, 4); setValue(v); } => Q_ALWAYS_INLINE void setValue(quint32 v) { setTagValue(tag(), v); } => Q_ALWAYS_INLINE quint32 tag() const { return _val >> 32; } The call to tag() reads from _val before it is initialized. Up until C++11, uninitialized variables simply had an indeterminate value. Starting with C++14 (see N3914, resolution of DR1787), reading that variable not as an unsigned char has undefined behavior. See 8.5 [dcl.init] p12: ... When storage for an object with automatic or dynamic storage duration is obtained, the object has an indeterminate value, and if no initialization is performed for the object, that object retains an indeterminate value until that value is replaced (5.18). [...] If an indeterminate value is produced by an evaluation, the behavior is undefined except in the following cases: [list of cases that use unsigned char] Change-Id: I42e7ef1a481840699a8dffff1406852f2badabca Reviewed-by: Ulf Hermann <ulf.hermann@theqtcompany.com>