| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We were only collecting the 'QML' functions that would be passed to the
AOT compiler. Other function types were ignored.
Also collect those and pass them to the compiler but only use them when
linting. Defer invistigating whether it is a good idea to try to
compile JS functions as well to a later point.
Logic in a few places was adapted with this changing assumption.
[ChangeLog][QML][qmllint] qmllint will now lint inner functions,
defined in javascript, in addition to top-level functions and bindings.
Fixes: QTBUG-138845
Pick-to: 6.10 6.8 6.5
Change-Id: If6f62aeace8739442b6a1f355fad95ce19c0643c
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
|
|
|
| |
Overriding the function only to then call the base implementation and
nothing else is not very productive.
Change-Id: Ib3cba0d38de652c94689b0bac5e878f629e35bd3
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Previously, the error message for an invalid import qualifier did not show the qualifier name or explain what was wrong.
This change adds the qualifier name to the message and says it must start with an uppercase letter.
Pick-to: 6.10
Fixes: QTBUG-133313
Change-Id: I0bd4bb143f7b4cdc3b26cae73ab42a4fb05977b1
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
| |
Expression is confusing.
Pick-to: 6.9 6.8 6.5
Change-Id: I365ce06a266e24a506b14734fef8b977d6794a72
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
| |
This reverts commit 18c421fe6159dc921643c72ae335cf189eb1cc3a.
Removing the dependency hashing is not safe because there are various
other bits covered by it, not only the alias target IDs.
Task-number: QTBUG-136806
Change-Id: I4a8a57d810203a47945ce67916ee5b54ee7a603d
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
| |
Since we don't store any property indices in the compilation units
anymore, we don't need to hash the dependencies anymore.
Task-number: QTBUG-135286
Change-Id: I2ea05c920475749f2a2d6cf309d0956a74d6c688
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The compiler is very polite and does not tell the user about its useless
code. Codegen::statementList(StatementList *ast) silently discards
unreachable statements during byte code generation.
Warn the user that their code is unreachable. Don't warn about
function definitions because these ones are "hoisted" up,
which means that their definition is supposed to be pushed up, so that
they can be used even if they are behind a "return" or "throw"
statement.
Don't use the qqmljsbasicblock analysis for that, it reports too many
"false positives" where the compiler generates dead code that can't be
fixed by the user.
Task-number: QTBUG-129307
Change-Id: Ia26e8af1adf4e63b26dcaa7fb10be73b7eb084d7
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Warn about functions used before their declaration. Its not technically
an error like the "var used before declaration" because functions are
"hoisted up" and therefore available even before their declaration, so
create a new warning category for it instead of reusing the "var used
before declaration" category. Disable the warning by default: Qt Creator
used to have it as default, while other tools like eslint don't.
For the same reason, don't warn about functions used before declaration
during codegen, and add a method to warn about it in
CodeGenWarningInterface. The code for "var used before declaration"
can be reused by function declarations by adding a sourcelocation for
function declarations in the "addLocalVar"-call, so make sure to
differentiate between functions and vars by adding an extra member to
Context::ResolvedName.
Task-number: QTBUG-129307
Change-Id: I83a4f8cd00c120db23a0cec3365a00ed44de2836
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This fixes a qmllint warning about unqualified access in the wrong place
in the following unconventional but valid case:
Warning: .../Main.qml:5:9: Unqualified access [unqualified]
console.log(a = 1)
^^^^^^^
Warning: .../Main.qml:5:21: Unqualified access [unqualified]
console.log(a = 1)
^
Pick-to: 6.9 6.8 6.5
Change-Id: I8eaa43f520c394b094917fe37dc6115ec2f7af74
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
| |
Change-Id: I766dc99b8daaeaa64da9075dcfde5dff507c27f2
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Signal handler in QML can be bound to a Javascript expression.
For example:
```
onHello: console.log(10)
```
Where "onHello" is a Signal Handler.
When this is the case a certain amount of code will be generated
for the Signal Handler, performing some setup routines and executing the
provided expression, generally in a way that is somewhat equivalent to
the same expression being executed as the body of a function call.
It is possible to bind a Signal Handler to a anonymous function, say:
```
onHello: function () { ... }
```
Or:
```
onHello: () => { ... }
```
When this is the case, if the usual process was followed, executing the
Signal Handler would simply produce an anonymous function, but would
never actually call it.
Instead, when such a literal function expression is bound to a Signal
Handler, it is treated specially.
In particular, while the code generation will generally behave similarly,
on execution of the Signal Handler, the expression will be directly
called while the "wrapping" function that was generated around the
expression is ignored.
While this works correctly in many cases, it can misbehave on certain
occasions.
For example, an arrow function doesn't generally set up its own
context for a call, instead borrowing from the outer context at the time
of creation.
When making such a call to an arrow function, in a QML context, it is
then possible to execute code in an environment that wasn't properly set
up for it.
In particular, if the body of the arrow function introduces a
`LoadLocal` instruction, which assumes, when interpreted, an available
`CallContext`, it is possible to try and access memory that was never
correctly set up.
It is, for example, possible to do so by usage of `arguments`, a special
reference that allows access to a pack of arguments in all non-arrow
functions, which will produce a `LoadLocal` instruction when accessed,
for example:
```
onHello: () => { console.log(arguments) }
```
Internally, when generating code for a JavaScript program or expression,
an analysis is performed to understand whether the special "arguments"
reference is being used. When that is the case and the context in which
the reference is used is under a context where the reference can exist, a
local variable for "arguments" is injected and a "LoadLocal" instruction
is later generated to access it.
The analysis considers a binding scope as being able to provide the
"arguments" reference, something that is generally true due to the
"wrapping" that is performed when generating an expression for the
binding, and which needs to be guaranteed in certain cases.
While this breaks down in the face of directly calling the "inner"
function in a Signal Handler binding, such that the analysis might
itself not be thorough enough in those cases, at the time the analysis
is performed we cannot currently know whether the binding we are dealing
with is that of a Signal Handler.
Furthermore, we don't always bypass the "wrapping" function in a Signal
Handler, as there are other cases where this can create issues, for
example the usage of "this" in an arrow function.
When this is the case, instead of directly calling the "inner" function,
the normal "wrapping" function is called to perform setup routines and
obtain the function itself by executing the bound expression,
subsequently calling the function obtained in this way.
To avoid the issue with the usage of "arguments", we re-use the same
methodology, ensuring that when the special "arguments" object is
referenced we never bypass the setup provided by the binding expression.
This ensures that the arrow function will be created in a context where
`arguments` is present and where the necessary setup for the call is
performed.
The special object will be always be empty in that context, which aligns
the behavior to that of non-signal bindings.
To do so, an additional case was added to the code in `writeFunction`
that sets up a binding expression to later skip to its inner function.
A few test cases were added to inspect usages of the "arguments" special
reference under binding contexts.
Fixes: QTBUG-134215
Change-Id: Ib7fdfee91709358f2ee465b1926809ca4617d6f6
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The data structure version is supposed to encode any incompatible
changes to our compilation unit format. Checking the compile hash and Qt
version in addition is redundant and excessively restrictive.
[ChangeLog][QtQml] You can now use QML code compiled with Qt Quick
Compiler across Qt versions as long as the compilation unit format
hasn't changed between those versions. You cannot rely on the
compilation unit format to stay unchanged under any specific
circumstances. However, we won't change it unnecessarily.
Change-Id: I8c407b505ac7fa952f53fa25bb6d4e7caf0fba0c
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
| |
This works the same as the FINAL attribute to Q_PROPERTY.
Task-number: QTBUG-98320
Change-Id: Icc2cf1afb5354fd711770f7147ded853b74cd1da
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
The bit is taken from nameIndex. It should have more than enough
capacity with 31 bits. The reserved bit will be used as a flag in
subsequent commits.
A more typed and centrally enforced aproach to the indexes will be
necessary in the future.
Change-Id: Ia7c686affba6d5320e674dd3f32b7c59b6321e22
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
|
| |
Change-Id: Ie956854fd0e89fd7fde0509fb46ac861c9571d0f
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
|
| |
|
|
|
|
|
| |
Nothing overrides it (anymore?).
Change-Id: I8704c0f2a853c9ff3b102e11b7dab20e7e35cc94
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
| |
We need to assign them right away when creating the module. If we do it
later on, there are a lot of different code paths to cover and in fact
we were missing some.
Pick-to: 6.9 6.8
Task-number: QTBUG-133053
Change-Id: I57e381c787f504eb9bcd8c2041e41b4f1d1f8b53
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
| |
The destructor seems to be declared to check another object's state (?),
but the class itself does not seem to have any invariants, and has been
used as such for a while, so just redeclare the copy/move operations.
Change-Id: I78a6cf6bfde38c2d53ac31f398e123e4fcf6e247
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
QT_TR_NOOP and QT_TRANSLATE_NOOP bindings can have a disambiguation
string. Adjust the parser to handle this properly, and amend
tst_qqmllistmodel to handle this case.
Moreover, adjust the test case to still trigger the expected error in
"QT_TR_NOOP extra param": The second parameter would now be (correctly)
parsed as disambiguation string, thus add a third one.
[ChangeLog][QtQml][ListElement] ListElement now supports disambiguation
strings when QT_TR_NOOP is used.
Pick-to: 6.9 6.8 6.5
Fixes: QTBUG-132684
Change-Id: Ia133d3c1eece036f982cad8578cfdee89d9216b4
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
|
|
|
|
| |
Instead of passing them around everywhere, use the ones we statically
know and only validate them when creating a new engine.
Task-number: QTBUG-131721
Change-Id: I7fb93d15eb6e4194c46249727bcf7a48f5dce730
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
| |
These are the actual global names as present in the global object. We
should use the same ones everywhere.
Change-Id: I4fb42f609b656019db5169fd4ea2b243feab18d6
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
| |
When adding to them, we want to be able to see what we're doing.
Change-Id: I563999d8371ff7bd60ca5ad8e7663fd3fe2f4fca
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
QQmlTypeLoader::injectedScript() was unsafe and impossible to fix
because it had to query the engine from the type loader thread in order
to find out whether to load a script from an actual file.
By removing the whole special-casing of native modules, we can make the
script loading thread safe. A native module is now also a compilation
unit, with a regular QV4::Module as value. This means we can remove a
lot of code that deals with the native modules in the engine.
The downside is that native modules are now a lot larger than before.
However, given that they don't appear in any examples and hardly any
bugs have been filed about native modules since their introduction, we
can assume that they are not a very popular feature. The reduction in
complexity and the removal of the native modules map in the engine is
expected to outweigh the extra memory overhead for native modules.
Task-number: QTBUG-131721
Pick-to: 6.8
Change-Id: Ia7388d7ba8d71637559a791d874257fba4646330
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
| |
We're not guaranteed to get string IDs for those.
Pick-to: 6.8
Change-Id: I5800a1e90589f3a6ae55ce8624fa56968f0f3ec3
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
(cherry picked from commit b8c3cf7192fe5793fdaf56a1203cb2cf76d8c3a2)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
|
| |
|
|
|
|
|
|
| |
This enables us to encode instructions efficiently in between 1 and 18
bytes.
Change-Id: I2e6437ffb31c34069241cfe716f6c61e20388892
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
The code that handles the GetException instruction uses GetException in
the BEGIN macro and HasException in the END macro. Use GetException for
both so that they match.
Also remove two defines from the instruction generation macros which
aren't used anywhere.
Change-Id: If5c88e94de831cd3d60d6316026fbf7335fb89e0
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
| |
Either make them static or declare them in a header. We want them to be
static wherever possible, in order to reduce the number of visible
symbols. If they can't be static, however, they should at least be
declared in only one place.
Task-number: QTBUG-67692
Change-Id: I91fa641b46510ea8902b478d31dfd60d34b5f580
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
By using an "as" cast you want to check the type of the value, not
coerce it. Previously, however, if you did this with a value type, it
would create the value type instead of just checking for it.
Add an attribute "Assertable" to the ValueTypeBehavior pragma that
prevents this and enables the correct behavior. Also print a warning
when coercing as part of an as-cast.
[ChangeLog][QtQml] A new attribute "Assertable" has been added to the
"ValueTypeBehavior" pragma. You should always use it if you want to
type-check value types using "as". If you don't use it, an instance of
the type is created as result of the "as" if the type doesn't match.
Task-number: QTBUG-124662
Change-Id: I1d5a6ca0a6f97d7d48440330bed1f9f6472198aa
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This location is then used later, for example, to improve the accuracy
of warnings.
OLD
Warning: Main.qml:22:30: function without return type annotation returns
double of double [compiler]
function type() { return 1 + 1 }
^^^^^^
NEW
Warning: Main.qml:22:30: function without return type annotation returns
double of double [compiler]
function type() { return 1 + 1 }
^^^^^
The location stored is the combined locations of the left operand, the
operator, and the right operator. We should investigate if this is the
right approach. Created QTBUG-124548.
Task-number: QTBUG-124548
Task-number: QTBUG-124220
Pick-to: 6.7
Change-Id: Icac335d53349c05d0e9ee6e436bc6ab08ad970d2
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
|
| |
Task-number: QTBUG-117983
Change-Id: I5790f01d614cd70c7fcc9bd817ec6ace3f3e3730
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
We want to re-use the base compilation unit across engines. For that to
work it cannot be a slice of the engine-specific
ExecutableCompilationUnit.
Since CompiledData::CompilationUnit is refcounted on its own now, make
it unmovable.
Change-Id: I8418c9754d7a07e5210c1e7a7fc69355e1d57807
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
| |
Task-number: QTBUG-117983
Change-Id: I717bf43032e72ec743f238ac48935a3019f1879d
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
|
|
|
|
| |
Amends: 86c48761dc7ba5bcac7dc6740e94efbfb8678403
Fixes: QTBUG-120504
Pick-to: 6.7
Change-Id: Id77236a07d7c1a16e2f60238909eff245c5c354a
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
|
|
|
|
| |
Despite its name, it's really large.
Coverity-Id: 434159
Change-Id: I7ccdfbdf0582edd13011d89dbb50a17ea1455637
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
|
| |
|
|
|
|
|
|
|
|
| |
Amends commit 86c48761dc7ba5bcac7dc6740e94efbfb8678403.
Pick-to: 6.7
Fixes: QTBUG-120168
Change-Id: I5848d8394498bafb1e897eca865d405224eaf997
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This patch changes the way optional chains are dealt with in the
bytecode. Instead of dealing with the 'bad' case (where the base of the
lookup is null or undefined) of each instruction separately, all
optional operations point to the same piece of code at the end of the
optional chain to deal with bad accesses.
In practice, for the lookup `root?.foo.bar?.baz` the following
bytecode instructions are generated.
LoadQmlContextPropertyLookup // root
GetOptionalLookup --v // ?.foo
GetLookup | // .bar
GetOptionalLookup --v // ?.baz
Jump done ------------v
undefined: <----< |
LoadUndefined |
done: <------<
In this way, the 'bad' case is handled in one place at the undefined
label. If, on the other hand, the chain evaluation reaches the bottom,
one jump takes the resulting value to the rest of the program. In this
way, the 'bad' case has a constant size relative to the length of the
chain. If no optional operation is performed at all. The 'bad' case
handler is not generated at all.
For this to work, GetOptionalLookup now jumps to the undefined label
when its base is null of undefined. Other operations such as function
calls `f?.()`, array access `a?.[0]` and delete expressions
`delete foo?.bar` have also been adapted to point to the undefined
label.
Change-Id: I07158efc8767d84a7588299cae9fb763b0f6e253
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Translator pragma can be used to set the translation context
instead of having the file name used
[ChangeLog][qml][translation][Important Behavior Changes] The context
for the translation can now be controled in a given file
using pragma Translator.
Task-number: QTBUG-114528
Change-Id: I6d9d7fb81ea969a90d8637d7277bdbe96c102088
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
An empty context is to be passed as-is. We shall not replace it with the
file context context. Since the TranslationData struct has a field for
the context, we need to invent a "no context" value we use for the
methods that don't allow you to set a context (e.g. qsTr, qsTrId). We
cannot use 0 because that is the empty string which is a valid context
now.
Amends commit 9cfc19faf5d1ce2b9626914ab4528998b072385d.
Pick-to: 6.6 6.5
Fixes: QTBUG-118469
Change-Id: I160c512f42aba4a8ae2fc8860cdf4e50c53d9d3e
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
| |
The source and destination arguments of the bytecode are always given as
source first and destination second. The bytecode dumper flips this
convention. Let's fix that.
Change-Id: I0489a80f9b0494e303a5ad981ca16b68a1ad358e
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Sami Shalayel <sami.shalayel@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 want to control the warnings about variables used before declaration
and injected signal parameters separately, and they are not necessarily
part of the compiler warnings.
Fixes: QTBUG-116764
Change-Id: If3f28f99b539a069cbdb7854d701c027debc77be
Reviewed-by: Andreas Aardal Hanssen <andrhans@cisco.com>
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
For try-catch-finally sequences with a catch block, the generator would
start by setting the unwind handler to code from the finally block and
immediately after that set the handler to code from the catch block,
overwriting the last instruction.
In cases with catch blocks, do not emit the first instruction setting
the unwind handler.
Change-Id: I588433c1ad2521b1750f77f2084315a707577a8a
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
For binary expressions with the ?? operator, two cases must be handled
in two code paths. When the lhs is defined, it is used as the result of
the expression. When the lhs is undefined, the rhs expression is used as
a fallback instead. Distinguishing between these two branches can be
done with a test such as CmpEqNull and a conditional jump based on it..
Previously, on top of a conditional JumpTrue to jump to the correct
location based on the test, a second JumpFalse was emitted to perform
the same operation a second time. This is redundant.
The second jump was removed and the logic was slightly reorganized.
Change-Id: I65479752d9fac8c18ef2475b062dd2b5262c372e
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
|
|
|
| |
We only need the unwind handler for for..of loops in order to close the
iterator.
Change-Id: Ieae67cf852fd858e0c1956889d4cf5b40a660b7e
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Remove custom implementations found in qqmljs* and use the
static helper methods from qqmlsignalnames_p.h instead. This sometimes
requires to move some code around to avoid bugs with property that do
not have letters in their name.
Add a warning in the JS implementation of the SignalSpy.qml that the
used heuristic might fail on certain signal names.
Add tests in in tst_qqmllanguage to see if the property change handlers
work correctly for weird names.
Change-Id: I4dc73c34df7f77f529511fa04ab5fcc5385b59fc
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Here are the sorts of things that were found:
- Uninitialized variables containing garbage.
- Calling member function through nullptr (where this is not actually
used inside the function because that would trigger a segfault).
- static_cast'ing double to int where the double is either +/-infinity
or is outside the range of min and max values for int.
Additionally, the uses of QJSNumberCoercion::isInteger() in the code
generator have been replaced by QJSNumberCoercion::isArrayIndex() and
the former was deprecated as it is no longer being used.
Pick-to: 6.5 6.6
Change-Id: I9318671ccbda37e5519f4fcb84a1537585c2103f
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
If the QV4_DUMP_BASIC_BLOCKS environment variable is set, the compiler
will output the details of the basic blocks of the compiled functions to
the console.
It will also generate a control flow graph containing the byte code in
DOT format for easier visualization and debugging of the program
execution and of the structure of the generated code. The value of
QV4_DUMP_BASIC_BLOCKS will be used as the path to the folder in which to
output the DOT files. If the path is any of ["-", "1", "true"] or if
files can't be opened, it will be dumped to stdout instead.
The logic in dumpByteCode has been adapted to use a QTextStream. This
way it can continue to be used to dump the byte code of the whole
program as before and also to construct the CFG.
Change-Id: If398d795e4fc0950b5fa8ee1349e80b1ae262deb
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
With this change, qmlcachegen can populate structured value types from
object literals.
Also fix the construction of value types via Q_INVOKABLE ctors. We don't
need to wrap the ctor argument in QVariant if we can store the original
type, and we should always look at the base type for the creatable flag,
not the extension.
Task-number: QTBUG-107469
Task-number: QTBUG-112485
Change-Id: I9f3db13f00466dc9d87237bdf0b380d6eeb58a10
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
| |
[ChangeLog][QtQml][Important Behavior Changes] Type annotations on function signatures are now enforced, no matter if the code in question is interpreted, JIT-compiled, or AOT-compiled. Previously, only AOT-compiled code enforced the signatures. Therefore you could produce divergent behavior by passing or returning values that violated the type annotations.
Fixes: QTBUG-113527
Fixes: QTBUG-109221
Change-Id: Ie573b31f35813db37b75189e747c764d1b9bbe78
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This gives us a unified interface to all kinds of QML types at run time
and reduces the effort of finding corresponding type attributes.
QQmlType is much larger than CompositeMetaTypeIds. Most composite types,
however, are initially referenced by URL, and we call typeForUrl anyway.
typeForUrl already creates a mostly functional QQmlType; we only need to
add the dynamic metatypes. The same type can be retrieved later and
associated with the actual CU using the compositeTypes hash. That way,
we don't need any extra type. We do, however, incur the cost of creating
the QMetaTypePrivate instances when first referencing a type. This could
be optimized, like many things in this area, by using thread safe lazy
initialization.
Now some QQmlTypes implicitly depend on the CUs they were created for.
This creates problems if the CUs are removed but the types still
persist. Such a situation can arise if you create and delete engines. In
order to avoid it, we:
1. Make the compositeTypes hold a strong reference to the CUs
2. When unlinking, avoid dropping the property caches (as those are used
to hold the metaobjects)
Now, however we got a cyclic reference between the CU and its
QQmlType(s). To resolve this, we clear the QQmlTypes on unlinking.
Finally, to avoid deletion recursion when clearing the last CUs on
destruction of the QQmlMetaTypeData, we move the compilation units out
of the way first.
All of this still doesn't work if multiple CUs hold the same QQmlType,
since compositeTypes can only hold one CU per type and that may be the
one that gets removed first. Therefore, we cannot allow such a situation
to happen and have to create a new QQmlType if it arises. It can only
arise if you have multiple engines loading the same QML components,
which should be fairly rare.
For inline components, we apply a similar trick: You can either find an
inline component by Url, and receive any type that matches, no matter
what CU it belongs to. Or you can request an inline component type that
belongs to a specific CU. It turns out we don't have to store the
containing type of an IC at all. Also, we slightly change the naming of
internal components' "class names" since we want to use the inline
components' element names for them.
Change-Id: I0ef89bd4b0a02cc927aed2525e72f6bff56df626
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
|