| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This relies heavily on the documented fact that we only support trusted
QML/JS content, meaning most files are only significant, not critical.
This also extends to the handling of qmlc files (as in
compilationunitmapper), as we store them in a user owned, non-shared
cache directory – so any vulnerability there would already mean that an
attacker has write-priviledges on user data.
An exception is ArrayBuffer, which can be used with arbitrary user data,
and should create a valid QBA.
Fixes: QTBUG-136970
Pick-to: 6.10 6.9 6.8
QUIP: 23
Change-Id: I22033fe6ab4acf8362a8183e25b92331d45cb32c
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
The interpreter already has the necessary setup, but the JIT did simply
write the value without marking so far.
We fix this by adding a new runtime function call, which simply uses
QV4::WriteBarrier::markCustom to mark the given value.
Both the StoreLocal and StoreScopedLocal bytecode instructions are
handled by adding the code to BaselineAssembler::storeLocal.
Pick-to: 6.8
Change-Id: I4b9226848bff029a076c0cfa6daf899ca9b84622
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
|
| |
Task-number: QTBUG-117983
Change-Id: I5790f01d614cd70c7fcc9bd817ec6ace3f3e3730
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Instead of dragging another stack value around to mark if the iterator
was done, rather pass it an offset it should jump to if so. It can then
jump over any IteratorClose instruction while the ExceptionHandler can
still point to the IteratorClose instruction.
For this to work, we also have to refrain from checking for exceptions
as part of IteratorNext or IteratorClose. If IteratorNext generates an
exception, it also jumps to the "done" label, after which we dispatch
the exception. We don't want to jump to the exception handler for other
instructions in between as that would close the iterator. The iterator
should _not_ be closed if it has just thrown an exception, though. The
same holds for IteratorClose: If it throws an exception, we don't want
to jump back to the beginning of the loop's exception handler, since
that would produce an infinite loop. We also don't want to reset the
exception handler before IteratorClose because it needs to also be reset
if the iterator does not need to be closed.
This saves quite a few instructions and stack variables on actual
iteration.
For destructuring, we have to change the execution flow a bit. We need
to first perform the iteration for non-rest parameters, saving the
results in separate stack slots. This way we can apply our new "jump if
done" behavior if the iterator runs out or produces an exception itself.
We then save the "done" state in a separate stack slot, as before.
During the assignment of the iteration results to the actual variables,
we install an exception handler, so that we can still close the iterator
if one of the initializers throws an exception. This produces a few more
instructions than before:
1. We need to set and read the "needsClose" variable explicitly rather
than having IteratorNext and IteratorDone do it implicitly.
2. We need an additional CheckException after the iteration.
3. We need an additional conditional Jump over the IteratorDone.
Everything considered, the savings we get for regular iteration and the
more consistent semantics of the instructions involved are well worth
the few extra instructions on destructuring, especially since everything
those extra instructions do was done implicitly by the iterator
instructions before.
For consistency, the IteratorNextForYieldStar instruction is refactored
to work the same way as IteratorNext: In case of either an exception or
"done" it jumps to an offset, and we refrain from individually
exception-checking each IteratorNextForYieldStart instruction.
Task-number: QTBUG-116725
Change-Id: I9e2ad4319495aecabafdbbd3dd0cbf3c6191f942
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
|
| |
|
|
|
|
|
|
|
|
| |
We need to do the subscript lookup before generating the arguments since
the arguments may change the array.
Fixes: QTBUG-106708
Change-Id: Ia3a0dd34c6ed8d39e86ad20911a632d691826322
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Replace the current license disclaimer in files by
a SPDX-License-Identifier.
Files that have to be modified by hand are modified.
License files are organized under LICENSES directory.
Pick-to: 6.4
Task-number: QTBUG-67283
Change-Id: I63563bbeb6f60f89d2c99660400dca7fab78a294
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Type assertions actually check whether the expression matches the type,
and return null if it doesn't.
[ChangeLog][QtQml] You can use TypeScript-like type assertions using
"as" now. In contrast to TypeScript, QML's type assertions are enforced
at runtime. If the type doesn't match, null is returned for object
types. Also, type assertions can only cast to object types. There is no
way to create a value type or primitive type reference. As value types
and primitives cannot be polymorphic, this doesn't matter, though.
There are other ways of converting those.
Task-number: QTBUG-93662
Change-Id: I00fce3d4ea7a8c6b4631c580eaf6c113ac485813
Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
Reviewed-by: Paul Wicking <paul.wicking@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When called via the metaobject system, parameters and return values are
passed as void*, with accompanying type information in the form of
QMetaType. The same format is expected when calling an AOT
compiled function.
Previously, we would first convert all the parameters to QV4::Value,
just to convert them back the moment we notice that there is an AOT
compiled function. This is wasteful.
This change provides a second call infrastructure that accepts void* and
QMetaType as parameter and return value format, and passes them as-is
all the way to any AOT compiled functions. If there is no AOT compiled
function, the conversion is done when detecting this, rather than when
initiating the call. This also passes the information "ignore return
value" all the way down to the actual function call. If the caller is
not interested in the return value, we don't have to marshal it back at
all.
For now, we only add the extra "callWithMetaTypes" vtable entry to
ArrowFunction. However, other callables could also receive variants
optimized for calling with void*/int rather than V4 values.
This required changing the way how function arguments are stored in the
property cache. We squeeze the return type into
QQmlPropertyCacheMethodArguments now, and we use QMetaType instead of
integers. In turn, we remove some unused bits.
Change-Id: I946e603e623d9d985c54d3a15f6f4b7c7b7d8c60
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
| |
The method names are only used for debugging purposes. We don't need to
pass them through production code. Centralize the names of all the
runtime methods in a symbol table and only look them up when actually
printing them.
Change-Id: I0d9d7db04b961841242acdbaaa7a2ba29b1f4ff2
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
| |
|
|
|
|
|
|
| |
Provide different export macros and different top level headers for
each, don't include runtime headers from compiler sources.
Change-Id: I7dc3f8c95839a00a871ba045ec65af87123154be
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
| |
|
|
|
|
|
|
| |
The tracing JIT won't be finished. Therefore, remove the parts that have
already been integrated.
Change-Id: If72036be904bd7fc17ba9bcba0a317f8ed6cb30d
Reviewed-by: Erik Verbruggen <erik.verbruggen@me.com>
|
| |\
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Conflicts:
src/qml/compiler/qv4compileddata_p.h
src/qml/jit/qv4baselinejit.cpp
src/qml/jit/qv4jithelpers.cpp
src/qml/jsruntime/qv4lookup.cpp
src/qml/jsruntime/qv4runtime.cpp
src/qml/jsruntime/qv4runtimeapi_p.h
src/qml/jsruntime/qv4vme_moth.cpp
src/qml/qml/qqmltypemodule_p.h
Change-Id: If28793e9e08418457a11fc2c5832f03cab2fcc76
|
| | |\
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Conflicts:
src/qml/compiler/qqmltypecompiler.cpp
src/qml/compiler/qv4bytecodehandler.cpp
src/qml/compiler/qv4codegen.cpp
src/qml/compiler/qv4compileddata_p.h
src/qml/compiler/qv4compiler.cpp
src/qml/compiler/qv4instr_moth.cpp
src/qml/compiler/qv4instr_moth_p.h
src/qml/jit/qv4baselinejit.cpp
src/qml/jit/qv4baselinejit_p.h
src/qml/jsruntime/qv4function.cpp
src/qml/jsruntime/qv4vme_moth.cpp
Change-Id: I8fb4d6f19677bcec0a4593b250f2eda5ae85e3d2
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
After enabling lookups in QML files, we can remove all the code that
tries to deal with (type) compile time detection of access to id objects
and properties of the scope/context object. This also allows removing
quite a bit of run-time code paths and even byte code instructions.
Task-number: QTBUG-69898
Change-Id: I7b26d7983393594a3ef56466d3e633f1822b76f4
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
When resolving names in the context of QML bindings, we now direct
runtime access to QQmlContextWrapper::resolveQmlPropertyLookupGetter. At the
moment this does basically the same as Runtime::method_loadName, which
we called earlier. However this now provides the opportunity to optimize
lookups in the QML context in a central place.
When performing a call on a scope or context object property, we also
did not use a CallName() instruction - which would have gotten the
thisObject wrong - but instead we use a dedicated
CallScopeObjectProperty and CallContextObjectProperty instruction. These
rely on identifying these properties at compile time, which goes away
with lookups (and also doesn't work when using ahead-of-time
compilation). Therefore the qml context property lookup is using a
getPropertyAndBase style signature and
Runtime::method_callQmlContextPropertyLookup uses that.
For the tests to pass, some error expectations need adjusting. In
particular the compile-time detection of write attempts to id objects is
now delayed to the run-time.
The old code path is still there and will be removed separately in the
next commit (as it is massive).
Task-number: QTBUG-69898
Change-Id: Iad1ff93d3758c4db984a7c2d003beee21ed2275c
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
This is the in a series of patches for a JIT that can use traced
information to generate better code. In this patch, traced information
is not used/stored yet. It allows testing the basic infrastructure
without trying to do any optimizations, therefore making it easier to
debug, test, and review.
Change-Id: I589bdadf731c36542331abe64e1b39e305b6723e
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Mark method that:
- change the context (e.g. PushCallContext)
- are pure (don't throw, have no visible side-effects, e.g. ToBoolean)
- use the last argument as an output parameter (e.g. IteratorNext)
These are used in subsequent patches to give the JIT more information
about the call. For example, a pure function can be placed anywhere
before its first use, as long as its parameter values are known.
Change-Id: I31355d2016b6676f339a9838c25b941d0e7860f0
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |/ /
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
The declarations and usage of runtime functions have seen a number of
changes:
- we don't use the array of method pointers anymore because we don't use
cross-platform AOT JITting
- the check if a method can throw a JS exception was invalid, and was
not used anymore
- value-pointer vs. const-value-ref was inconsistent
This patch cleans that up. By fixing the exception checking, we can now
use it in the baseline JIT to automatically insert those checks. To make
that work correctly, all runtime methods are in a struct, which gets
annotated to indicate if that method throws. (The old way of checking
which type of engine was used is fragile: some non-throwing methods
do not take an engine parameter at all, and those got flagged as
throwing). By using a struct, we can also get rid of a bunch of
interesting macros.
The flags in the struct (as mentioned above) can later be extended to
capture more information, e.g. if a method will change the context.
Change-Id: I1e0b9ba62a0bf538eb728b4378e2678136e29a64
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
|
| |/
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Collect type information about values used in a function. These include
all parameters, and the results of many bytecode instructions. For array
loads/stores, it also tracks if the access is in-bounds of a
SimpleArrayData.
Collection is only enabled when the qml-tracing feature is turned on
while configuring.
In subsequent patches this is used to generated optimized JITted code.
Change-Id: I63985c334c3fdc55fca7fb4addfe3e535989aac5
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
|
|
| |
This runtime function was the only one taking argc before arguments.
Change-Id: If0b049697f7fcc2746e8d287193a5b1230a6ea56
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
|
| |
|
|
|
| |
Change-Id: If1629109722496b3fd10b36b2376548440f2fee9
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
| |
|
|
|
|
|
| |
Doing the tail call in the runtime will come in a follow-up patch
Change-Id: I8224aac0edbdc765ee9b97703948edd52fd33f3e
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
| |
|
|
|
| |
Change-Id: I5b054b59519ed825459a5b0b0a7cd2c6fc8a3797
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
| |
|
|
|
| |
Change-Id: Ia520d43ea2c29c16cfc8ffc86a32187a78848502
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
| |
|
|
|
|
|
|
|
| |
As per spec, this should be uninitialized in derived
constructors, and the base constructor needs to get
called exactly once.
Change-Id: If31804e58d7ba62efde8fbf6cd852674f8da4495
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
With const and let it is possible to access the declared member before
initialization. This is expected to throw a type reference error at
run-time.
We initialize such variables with the empty value when entering their
scope and check upon access for that. For locals we place the lexically
scoped variables at the end. For register allocated lexical variables we
group them into one batch and remember the index/size.
Change-Id: Icb493ee0de0525bb682e1bc58981a4dfd33f750e
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
|
| |
|
|
|
|
|
|
| |
Those are mostly working now, but when calling super properties
the this object is not setup correctly.
Change-Id: Ib42129ae6e729eeca00275f707f480371b7e42a5
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
| |
|
|
|
|
|
| |
This is required to be able to support the super() call.
Change-Id: I9998680341d701727ac1697187ad33481bdde422
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
| |
|
|
|
|
|
|
| |
We can do the isStrict() check and throwTypeError() call in the runtime
function instead of doing it twice on the two call sites.
Change-Id: I5689babe4873c0bc3e7c85ca2d15a33f8ccb8794
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
|
| |
|
|
|
|
|
|
| |
We can do the isStrict() check and throwTypeError() call in the runtime
function instead of doing it twice on the two call sites.
Change-Id: I70df3d7fe4333921a85c11b1573e234f7da2f47d
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Most of the class creation is done inside the runtime
in the CreateClass method. Added a corresponding
instruction to the interpreter and jit.
The compiled data now contains an array of classes
containing the compile time generated layout of the class.
Currently, classes without an explicit constructor and
classes with inheritance are not supported.
Done-with: Yulong Bai <yulong.bai@qt.io>
Change-Id: I0185dcc1e3b0b8f44deff74e44a8262fc646aa9e
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
| |
Function calls with thread are modelled by pushing
an empty value in front of every argument that
requires spreading. The runtime methods callWithSpread
and constructWithSpread then take care of spreading
out the arguments.
Change-Id: Ie877c59d3d9d08fc5f20d7befb7153c7b716bf30
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
| |
|
|
|
|
|
|
| |
The delete operator is rarely used, so it's simpler to
unify these into one DeleteProperty instruction.
Change-Id: I8c0d4455b35efb03db2ab0010df70030d774a6ae
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Our method to create object literals wasn't compliant with the
ES7 spec, as we would in some cases re-order the properties.
This violated the spec which required properties to be created
in order, so that for-of would also iterate over them in creation
order.
As a nice side effect, this simplifies the code and gets a couple
of test cases using computed property names to pass.
Task-number: QTBUG-62512
Change-Id: I6dfe004357c5d46a0890027f4fd9e2d1e1a2a17a
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
| |
|
|
|
|
|
|
| |
Instead of duplicating the accumulator-to-object conversion in moth as
well as the JIT, let's do that in one place in the runtime.
Change-Id: I6870567d3c4fe663e54fece024f1e5e9bde97c35
Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
|
| |
|
|
|
|
|
|
| |
Array destructuring assignments require a call to iterator.return if
the iterator hasn't been exhausted during destructuring.
Change-Id: I39fe4bc01bef6fb2ad3bda92caf6779fbbddc8e2
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
| |
|
|
|
|
|
|
|
|
| |
The instruction now writes the value into a stack slot,
and returns the done state in the accumulator. This should
make it easier to implement the IteratorClose functionality
required by the spec.
Change-Id: I8cc497c54b0d044bd3c68a5a1b774eea8b2740ef
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
| |
|
|
|
|
|
| |
"var [x, ...y] = array" now works as intended.
Change-Id: I45238f27f468d0b0e14dc0e931c55c4f40043690
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
| |
|
|
|
|
|
|
| |
Array destructuring should use iterator objects, not integer
indexes.
Change-Id: I769bb1d63246da6bc45233f7a6e9a8e5ddc53a4d
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
| |
Added an IteratorNext instruction to fetch the next
iteration value (empty if the iterator is done).
This will also help to implement array destructuring without
requiring huge amounts of byte code.
Change-Id: If96c1e81471e5e2b0b7b2af122238d87741aa371
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
| |
|
|
|
|
|
|
| |
Regular for loops also have a per iteration context for lexically
declared variables as well.
Change-Id: I35cb58bfb198c7dc32d70f41ea0ced7ddefcc37e
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This requires a bit more work than simply pushing a
new BlockContext for the lexically declared variables,
as eval() and the Function constructor operate on the
global scope (including the lexically declared names).
To fix this introduce Push/PopScriptContext instructions,
that create a BlockContext for the lexically declared
vars and pushes that one as a global script context that
eval and friends use.
Change-Id: I0fd0b0f682f82e250545e874fe93978449fe5e46
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
The support is basically at the same level as for for-in
at the moment.
Currently unimplemented:
* Destructuring
* Proper lexical scoping
* calling iterator.throw()/return() when required
Change-Id: If193ce0b054c4315fc16b7e174334a31b2730dcf
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
| |
|
|
|
|
|
|
|
| |
Added SymbolObject, the equivalent to StringObject which was
still missing so far. Added the predefined standard symbols,
and fixed most test failures related to symbols.
Change-Id: I1e28b439e7c4f5141b4a09bd8fb666c60691f192
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Remove the need for a specialized catch context, instead
use a regular block context, that also captures the
catched variable.
This also removes the need to do lookups by name inside
a catch expression.
Change-Id: I8b037add7f423922e2a76b4c0da646ca7e25813a
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
This is still to some extend work in progress as
lexically scoped for loops won't yet do the right
thing.
let and const variables are still accessible before
they are declared, and the global scope doesn't yet
have a proper context for lexically declared variables.
Change-Id: Ie39f74a8fccdaead437fbf07f9fc228a444c26ed
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
| |
|
|
|
|
|
| |
function foo(a, b, ...c) {...} now works correctly.
Change-Id: Ie442a0e7cc5e9dc4156e56b348bba305cced8531
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Given the following expression
var x = MySingleton.MyEnumValue
where MySingleton is a QML (composite) singleton and MyEnumValue comes
from a QML declared enum, we had code in place up to (and including)
5.10 to attempt to optimize that expression to a enum constant at
compile time. In 5.10 that optimization does not exist anymore. In <=
5.10 we would also skip the optimization under certain circumstances
(too many statementes, etc.). The fallback that is in place for handling
this at run-time tried to be smart by avoiding the
QQmlContextWrapper::get lookup and return straight a reference to the
singleton as QObject. That works for regular property lookups, but it
fails when trying to look up something like an enum, that isn't a
meta-object property.
Change-Id: I1819b9d8ae06a3f595e067bf5b018c4065be76bb
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
When a function is called that is in a QML scope or a QML context, set
the 'this' object to the QML scope. This is done by introducing two new
interpreter instructions, which get the context passed in.
Note: this patch is 5.11 specific. 5.9 had a similair issue, but the
implementation is quite different, so that was fixed separately.
Task-number: QTBUG-66432
Change-Id: Ie43150cdd26360025895df28d31264985abf1c15
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
| |
|
|
|
|
|
| |
The VME shouldn't have to care about this part
Change-Id: I9e49353dce29912f5a222b7ed1b42ace2aa8cebd
Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
|