Otherwise it will assume the last statement as the location of the
jump, and that might be a statement that is never hit.
Task-number: QTBUG-59204
Change-Id: I66019a284b061358939b23e649ca0832b5442388
Reviewed-by: hjk <hjk@qt.io>
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
In many cases, the result can be directly assigned to the left-hand
side. So leave it to the place where the binop is used to decide when
to assign it to a temporary.
Change-Id: I9a88a71a77aa73afe88007eca744d3782fca34ac
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
We also tie this up to the existing skeletal "const" support so that they
are also checked for duplicate declarations.
While we do that, change from using a boolean to an enum so we make the scope of
a declaration a little more easily comprehensible.
Change-Id: I6a6e08aed4e16a53690d6f6bafb55632807b6024
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
More in keeping with the spec's terminology, and allows us to introduce
a LexicalEnvironment for ES6.
Change-Id: I1d98387a0ad6372317cf1036f814ac0c6063c1bf
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Spec 13.3.1.1 (Static Semantics: Early Errors) says:
It is a Syntax Error if the BoundNames of BindingList contains any
duplicate entries.
Only let/const are supposed to be treated in this way, so we ensure that
one of them has been marked read-only (since we don't support "let"
yet).
There's still no runtime check on assigning to a constant-declared variable.
[ChangeLog][QtQml] "const" variable declarations now throw a SyntaxError if
multiple attempts to declare the same variable name are found. Note that
"const" is still not fully spec-compliant (i.e. reassignment at runtime is
not disallowed).
Task-number: QTBUG-58493
Change-Id: I31fd5f2bf3e79d48734e8ecb714c4e7f47e31d2a
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This seems to match up with the spec behavior. 13.3.1.1 (Static Semantics:
Early Errors) says:
It is a Syntax Error if Initializer is not present and IsConstantDeclaration
of the LexicalDeclaration containing this production is true.
In addition, we also allow "const" to be used in JS mode too. We don't
yet fully support the semantics, but as it's there, why not let it work.
[ChangeLog][QtQml] "const" variable declarations are now available in JS
as well as QML mode.
[ChangeLog][QtQml] "const" variable declarations now require an
initializer, bringing them closer to the required spec behavior.
Task-number: QTBUG-58493
Change-Id: Ife5d5979b3e7a5d7340bf04f43605f847ee25ee2
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
.. instead of first assigning to a temporary and then assigning the
temporary to the argument/local.
Change-Id: I15a6c2073b78c5cfc829c7edef07c6bf48be7886
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
There is no reason not to do this, plus it only takes up memory (for
assignment to temporaries) and makes SSA transformation more costly.
Change-Id: I09edbabe6ed50ab1a61b29ebd2ab541bccc95fad
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Arguments and locals can be used directly as the base of a subscript,
so they do not need to be assigned to a temporary first. For indices,
arguments, locals, and constants, can be used just fine for subscripts.
This reduces a whole lot of assignments to temporaries when generating
the IR. Although they will be removed in an optimization pass, they do
consume memory for no good reason, and make SSA transformation take more
time.
Change-Id: Ie2af65b66fecee3e140228a9532c9fab08474f5b
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
When exiting a catch block with a return statement, we'll unwind the
exception handling manually and emit finally statements right before
jumping to the exit block. If we throw an exception in the final block,
we'll end up using the exception handler of the catch block that
contains the return statement, which means we'll end up popping the
exception scope one too many times, once through
ScopeAndFinally::CatchScope in unwindException() and then when executing
the exception handler block. The latter we should not be executing,
instead we should jump straight to the exit block. Therefore any
statements emitted as part of the manual exception unwinding (finally
block here) need to be part of a new basic block with no exception
handler.
This bug became visible in debug builds where the Scope destructor
compares the scope mark against the engine stack top to ensure correct
cleanup order (which was wrong). However that in turn was hidden in
debug builds again due to an accidental = instead of == in a Q_ASSERT.
With the Q_ASSERT fixed this use-case is covered by
ch12/12.14/S12.14_A13_T3
Change-Id: Id74a1b2bb3e063871b89cc05353b601dd60df08e
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
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
Specifically: don't de-reference a result and assume that it's not-null.
Task-number: QTBUG-54687
Change-Id: If07d3250a95a7815ab7a3262b88e0227965ef8e7
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
QML objects can be re-parented on the fly, resulting in different
dependencies for expressions like 'parent.width'. So, because of this,
dependencies are cleared and re-calculated after every binding
evaluation.
However, dependencies on properties of the scope and context objects
cannot change, because these objects do not get changed for the
life-time of a binding. So we can permanently register them. This is
only done for bindings, not for functions, because those might be
conditionally executed.
According to valgrind, this is a reduction of ~186 instructions on x86
for every evaluation of:
Item {
height: width
}
Change-Id: Ib095497323d4f08caf712d480007e2627a176369
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Part of 0e053528 was reverted in the merge, about lastTimestamp. It
will be applied later in separate commit.
qmltest::shadersource-dynamic-sourceobject::test_endresult() was
blacklisted on linux.
Conflicts:
.qmake.conf
tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp
tests/auto/qmltest/BLACKLIST
tests/auto/qmltest/qmltest.pro
Task-number: QTBUG-53590
Task-number: QTBUG-53971
Change-Id: I48af90b49a3c7b29de16f4178a04807f8bc05130
We need to evaluate the expression for the "with" statement that is supposed to
define the new scope _before_ opening up the scope, otherwise - when the
evaluation of the expression throws an exception - we'll try to pop the "with"
scope we couldn't open in the first place.
[ChangeLog][QtQml] Fix crash when using the "with" statement with an expression
that throws an exception.
Task-number: QTBUG-53794
Change-Id: I7733f5a4c5d844916302b9a91c789a0f6b421e8a
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
... in string comparisons. It's more efficient.
Change-Id: I3be5a2be9ba5d55546472eac28f5f639a496bf3b
Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
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>
Commit 75c22465cf regressed in allowing
locals and arguments to be passed directly as further arguments to function
calls, but that's incorrect when considering
var i = 2;
testFunction(i, i += 2)
where it is instrumental to place the first argument into a temp (making a
copy) instead of passing it directly.
Change-Id: Iffcf6c6eda92a8fb665982cda1db0b96359cd092
Task-number: QTBUG-45879
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
This is a cleaner separation and further reduces include dependencies
in the definitions of our basic data structured.
Change-Id: I18aa86cdea0c0dfbc16075d4d617af97e638811e
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
The old code would evaluate the expression in the switch
statement once for every case label. This is not only slower
than it should be, but can also lead to unexpected results in
case the expression doesn't always evaluate to the same value
or has side effects.
Task-number: QTBUG-41630
Change-Id: Id93baca7e3aa09ce884967ef6524d4c4f055bcd6
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
Avoid repeated instantiation of end() in loops, use variable instead.
Change-Id: I3bb1c6918cfd16a5dcefbcc03c442e99fe9bf76b
Reviewed-by: Erik Verbruggen <erik.verbruggen@theqtcompany.com>
Qt copyrights are now in The Qt Company, so we could update the source
code headers accordingly. In the same go we should also fix the links to
point to qt.io.
Change-Id: I61120571787870c0ed17066afb31779b1e6e30e9
Reviewed-by: Iikka Eklund <iikka.eklund@theqtcompany.com>
This takes the time taken in qmlErrors for my (admittedly terribly morbid)
testcase from ~104ms to ~1ms.
Change-Id: I288086caa6e6b58f67e9feb6f1761c3310f01ead
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
The methods don't require a context, and thus shouldn't be
implemented there.
Change-Id: If058e0c5067093a4161f2275ac4288aa2bc500f3
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Also centralized the context state saver and added line number saving, so that the
JS jobs for evaluation of breakpoint conditions don't change the state of the current
engine context.
Task-number: QTBUG-37119
Task-number: QTCREATORBUG-11516
Change-Id: Ia21b3d64e239e5b67f3c07e1c006d8e6748f29b6
Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com>
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
We perform loop detection to be able to assign to each block its loop,
an chain them up from inner loop to outer loop. The new algorithm works
on each basic block just once, and looks at a basic block just the
number of connections it has. As it relies on the dominator tree it is
more robust on actually finding al looping constructs and only those
rather than relying on the statements used. It assumes that a basic
block is analyzed before the one that dominate it (to guarantee finding
outer loop headers before inner loop headers), so blocks are ordered to
work on them in a way that guarantees that, using dominator tree depth,
that is trivially available.
Loop detection allows us to then schedule the loop body before the part
after the loop (the header dominates both so just domination cannot
choose between both), and can be used to optimize loops (either
unrolling the first iteration or hoisting constant parts out of it).
It also helps with generated JavaScript code: in order to simulate gotos
or other unconditional branches, nested labeled do-while(false) loops
are often used in combination with break/continue to "jump" between
"loops".
Change-Id: Idfcc74589e057b191f74880ffd309d0a9c301811
Reviewed-by: Fawzi Mohamed <fawzi.mohamed@digia.com>
There are a couple of reasons to split the temporaries off from the
arguments and locals:
Temporaries are invisible, and changes to them cannot be observed.
On the other hand, arguments and locals are visible, and writes to them
can be seen from other places (nested functions), or by using the
arguments array. So, in practice these correspond to memory locations.
(One could argue that if neither nested functions, nor eval(), nor
arguments[] is used, the loads/stores are invisible too. But that's an
optimization, and changing locals/arguments to temporaries can be done
in a separate pass.)
Because of the "volatile" nature of arguments and locals, their usage
cannot be optimized. All optimizations (SSA construction, register
allocation, copy elimination, etc.) work on temporaries. Being able to
easily ignore all non-temporaries has the benefit that optimizations can
be faster.
Previously, Temps were not uniquely numbered: argument 1, local 1, and
temporary 1 all had the same number and were distinguishable by their
type. So, for any mapping from Temp to something else, a QHash was used.
Now that Temps only hold proper temporaries, the indexes do uniquely
identify them. Add to that the fact that after transforming to SSA form
all temporaries are renumbered starting from 0 and without any holes in
the numbering, many of those datastructures can be changed to simple
vectors. That change gives a noticeable performance improvement.
One implication of this change is that a number of functions that took
a Temp as their argument, now need to take Temp-or-ArgLocal, so Expr.
However, it turns out that there are very few places where that applies,
as many of those places also need to take constants or names. However,
explicitly separating memory loads/stores for arguments/locals from
temporaries adds the benefit that it's now easier to do a peep-hole
optimizer for those load/store operations in the future: when a load is
directly preceded by a store, it can be eliminated if the value is
still available in a temporary.
Change-Id: I4114006b076795d9ea9fe3649cdb3b9d7b7508f0
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
This is among other things needed to fix the qml import scanner to detect
dependencies from .js files correctly.
The patch also fixes the use of Q_QML_EXPORT towards Q_QML_PRIVATE_EXPORT
where appropriate and corrects the wrong include path for the double conversion
code to actually be relative to the file it is included from. This worked by
accident because of other include paths present in the build.
Change-Id: I338583dad2f76300819af8ab0dae8e5724c84430
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
BasicBlocks have an index property which points to the index of that
basic block in the container array in Function. This property can be
used to store calculated information about basic blocks in a vector,
where the vector index corresponds to the basic block index. This is
a lot cheaper than storing any information in a
QHash<BasicBlock *, ....>.
However, this numbering requires that no re-ordering or deletion of
blocks happens. This change cleans up all that handling which was
scattered over a number of places.
Change-Id: I337abd39c030b9d30c82b7bbcf2ba89e50a08e63
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
When the iterator calculation contains a condition, newly created
basic-blocks were marked as loop blocks. However, their parent was not
the loop header.
Task-number: QTBUG-38187
Change-Id: I9ee7a3e0bd536c2a005b91f8333931ce929245af
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* Object literals with array indices are now created with one
run-time call, instead of an initial one for non-integral keys
followed by sub-sequent define_builtin_property calls.
* Cleaned up propert name retrieval. Instead of using a visitor,
it's easier to define a virtual method on the PropertyName type. The visitor
doesn't buy us much as it's not possible to recurse within property names, and
this way we can use it also from the function scanner to correctly determine
the number of arguments needed for object literal initalizations.
* Similarly the duplicated/common name member for all property assignments
has been moved into PropertyName, for convenient access without AST casts.
* Removed now unused builtin_define_property/settergetter functions from IR,
run-time and moth.
Change-Id: I90d54c81ea5f3f500f4f4a9c14f7caf5135e7f9f
Reviewed-by: Lars Knoll <lars.knoll@digia.com>