| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
| |
The list of names is still suboptimal, but at least it's shared now.
Task-number: QTBUG-69898
Change-Id: I16c9839c4a1f097053b28caea894b67757972826
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We only need to check in one central location and we can allow for more
recursion. 4k recursions seem tolerable. A common default for stack
sizes is 8MB. Each recursion step takes up to 1k stack space in debug
mode. So, exhausting this would burn about half of the available stack
size. We don't report the exact source location in this case as finding
the source location may itself trigger a deep recursion.
Fixes: QTBUG-74087
Change-Id: I43e6e20b322f6035c7136a6f381230ec285c30ae
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Result objects are rather large, 96 bytes here. In a recursive algorithm
such as our parser, we should not keep too many of them on the stack.
Also, the size of Reference can be reduced by employing a bit field
rather than a number of booleans.
Also, try to convince the compiler to inline the accept() functions. The
extra stack frames those create are unnecessary.
Task-number: QTBUG-74087
Change-Id: I5c064491172366bb0abef99ffe9314080401a7d1
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
|
|
|
|
|
| |
This prevents jumping over the resetting of the unwind handler when an
exception occurs.
(cherry-picked from commit 0282b89ec672e25a465a8e51bc74c7fd58a624b1)
Fixes: QTBUG-73985
Change-Id: I4a4da815f54c13980d239e0492f9b013991cfbd5
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
|
|
|
|
|
|
|
|
|
|
|
| |
If there was a rest element in the list, the generated code would jump
over the clean-up (closing of the iterator). However, this would also
jump over any resetting of the unwind handler.
(cherry-picked from commit 3310f173c1c6208cb0f6541578419196bc29831f)
Task-number: QTBUG-73985
Change-Id: I9a1bcb9e69fd98975fe9c89e23a4568b0dafdf83
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
|
|
|
|
|
|
|
|
|
|
|
| |
If fast QML lookups are disabled, we generally want to look up by
string. If the name then happens to be a member of the global JavaScript
object, we still don't want to directly access that, as the name could
have been overridden in a deeper context.
Fixes: QTBUG-73750
Change-Id: Id16110969123d91501064ba46bfad4c2a39e4650
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Consider this JavaScript snippet:
function f() {
for (var i in []) {}
}
This generates the following bytecode sequence:
2 0: 14 00 09 MoveConst r3, C0
3: ec 00 00 DefineArray (function), 0
6: da 00 GetIterator 0
8: 18 08 StoreReg r2
10: c0 0f SetUnwindHandler 27
12: 50 04 Jump 18
14: 16 0a LoadReg r4
16: 18 07 StoreReg r1
3 18: 16 08 LoadReg r2
20: dc 0a 09 IteratorNext r4, r3
23: 54 f5 JumpFalse 14
25: 50 03 Jump 30
27: c0 00 SetUnwindHandler <null>
29: c2 UnwindDispatch
4 30: 0e LoadUndefined
31: 02 Ret
The problem is a normal loop exit: instruction 23 will not jump back,
but fall through, and then instruction 25 will jump over the
instructions resetting the unwind handler (27 + 29). Removing this jump
fixes the issue.
Change-Id: Ic9f03555ebebc27144490bce04e9a4166ed7c97c
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Make sure the unwind handler is always reset when leaving the
try block.
This exposes a couple of failures in the ECMAScript test suite
that were before passing by pure luck.
Task-number: QTBUG-72858
Change-Id: I014b1e37c2beff136ecd53a665a2f10933f7e12c
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
|
|\
| |
| |
| |
| |
| |
| |
| | |
Conflicts:
src/qml/jsruntime/qv4script.cpp
src/qml/parser/qqmljslexer.cpp
Change-Id: I82252a8c504a4b77c45f4f8efe849ff9acb949fd
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Since change 9333ea8649838d7e0400b0e94c8cbd4fa5d216b0, we lookup
properties in the QML context object before the global object to
have proper scoping rules for QML.
Unfortunately this lead to a performance regression when using global
properties such as Math in imported script files, as the lookup would
always go through the qml context first.
This can be fixed, as we know that the global object is frozen in qml
mode, and the standard names of properties in the global object are
illegal to use in QML. So simply check for those names in the code
generator and create lookups into the global object for those.
Change-Id: I4b2089178c9e5f9440abdfd834cf7d92c3c0e2c3
Fixes: QTBUG-71591
Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
|
| |
| |
| |
| |
| |
| |
| |
| |
| | |
This is to prevent extremely deeply nested expressions and statements
make the code-generator run out of (native) stack space.
Task-number: QTBUG-71087
Change-Id: I8e1a20a361bff3e49101e535754546475a63ca18
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
| |
| |
| |
| |
| | |
Change-Id: If9468b93b08ad355f07d1436ca88e8d36be22070
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
The destructor for the Jump object will check if it is linked somewhere.
So when doing an early-exit after generating a jump (and before linking
it) and after an error occurred, make sure to call link anyway. At this
point no code will be generated, so where the jump points to is kinda
pointless.
Change-Id: I09fa03d4224805a838088acd0c5c83d02b328045
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
|
|\|
| |
| |
| | |
Change-Id: I7623438dde316ae1e97802f91991f2e7ccc205a5
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
We won't use the bytecode anyway, and it prevents consistency checks
that come after the error from failing. Specifically: there might be
jumps that have no label defined.
Fixes: QTBUG-71738
Change-Id: I62a7e943b0156d42caccfa40507853de79e3b1ce
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
| |
| |
| |
| |
| |
| |
| | |
If a tagged template gets evaluated multiple times, the
underlying template object is shared.
Change-Id: Ie2f476fbc93d5991322ce1087c42719a8d8333ae
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|/
|
|
|
|
|
|
|
| |
Create the proper template object for a tagged template.
This fixes quite a few use cases (esp. String.raw), but is not
yet 100% spec compliant.
Change-Id: I69eaee22c384c0d1bd2c6c56ad711d29521b0b86
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
|
|
|
|
|
| |
Add new enum value QV4::Compiler::ContextType::ScriptImportedByQML, which
behaves exactly the same as ContextType::Global. A follow-up patch will change
the behavior slightly.
Task-number: QTBUG-69408
Change-Id: I20d27804fd1433f2229704546bcd78a0ac108c01
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
| |
Change-Id: I34d70759732433b6f0ecccc5ae175d33ec8e1577
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
|
|
|
|
| |
For example: 'for (foo() in something) {}' is not valid: a call
expression is not an lvalue.
Task-number: QTBUG-71086
Change-Id: Ia1498cd38526b073afb8e4524ceaea14dca3d65f
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
|
|
|
|
|
|
|
|
| |
There is a {{Q_UNREACHABLE}} right after it.
Change-Id: Id69fb1403a5f99912e6fbcb4a397a78a9d6948d7
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
|
|
|
|
|
| |
The visit() methods need to return false on parse errors, so
that we don't continue iterating into that subtree of the AST,
but rather exit as quickly as possible.
Task-number: QTBUG-71090
Change-Id: I1912d955a0ffc86389a4cbbb3b6ac0209c3c556a
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
|
|
|
|
| |
And not use (a possibly invalid result) blindly, because this will cause
assertion failures down the line.
Task-number: QTBUG-71081
Change-Id: Id10149c55026094a355bd747f66014119c0e24f5
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
|
| |
Task-number: QTBUG-71079
Change-Id: I999130f3994f513bb9d2ca8ddaa94688451937fc
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
|
|
|
| |
This removes the call to Reference::operator= and allows the constructor
and assignment to be inlined.
Change-Id: I173ae47127cc5c939300c1178c4c8637882f1c49
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
| |
Change-Id: I5346fc36c89b7969c2bef3069f256f33bd4d9eb9
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>
|
|
|
|
|
|
|
|
|
|
|
|
| |
Get rid of Primitive and move the corresponding methods
directly into Value. Mark many methods in Value as
constexpr and turn Value into a POD type again.
Keep Primitive as a pure alias to Value for source
compatibility of other modules that might be using it.
Change-Id: Icb47458947dd3482c8852e95782123ea4346f5ec
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
| |
Change-Id: I2d65fe6fb3d9f299f5aeff1542c7dc1d2db8b012
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
| |
Change-Id: I6cbe0610b65c9f9d7381bc1c70ae17e10486d5c3
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
| |
Change-Id: I5b054b59519ed825459a5b0b0a7cd2c6fc8a3797
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
| |
Change-Id: Id1bba1a729124bccb8a90dcf40252fe5c69d27a3
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When an exception happens during destructuring, IteratorClose
needs to be called, unless the exception happened inside the
IteratorNext call (in that case the iterator is assumed to be
invalid and we shouldn't call close on it).
Implement this, by ensuring that we set the done return variable
of IteratorNext to true whenever IteratorNext throws an exception.
IteratorClose will check the done state and not do anything in that
case.
Change-Id: I73a27f855f2c4d3134b8cc8980e64bf797d03886
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
|
|
|
| |
This is not perfect yet, as the two regressions in TestExpectations
show, but it's an improvement over the current situation.
Change-Id: I82c0ef0f69619562037c573bea1026abc53c1ab3
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
| |
Change-Id: I1855eb303225d1784b019f8eebab0ad8bf2cdf5e
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
| |
Change-Id: I4c0cfc3a120fc0b246760886b576e92d3f7623ff
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
|
| |
Task-number: QTBUG-70315
Change-Id: I2408c7a8561a000cb161e0bad066e5754be3b7ef
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
| |
Change-Id: I9d656b631935286c4b550be3318329487693de44
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
|
|
|
|
|
| |
Change-Id: Ia520d43ea2c29c16cfc8ffc86a32187a78848502
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
|
|
|
|
|
| |
Methods behave slightly different than normal functions as they have
a home object and define how super property access is being done. To
implement this correctly, we need to create these methods during object
initialization time.
Change-Id: Ib3f670c8790b882c6472de786938ca4f0b73f66f
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
| |
Change-Id: I648e173a156ffd47564192ecdcb81a03281fdcb4
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
|
|
|
|
|
| |
So far we've not been doing the TDZ check for expressions such as
x.name, a[x] and super[x] correctly. Fix this by adding a second
boolean that states whether a tdz check for the subscript is required
and use the first boolean to check the base of these references.
Change-Id: I658cd5b69f001fbdc714f252914ad9749734f027
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
If we access a lexically scoped variable after the initializer, then we
know it's either initialized or at least undefined, so we don't need to
do the TDZ check anymore.
The ES tests ensure that we don't optimize too much and the newly
revived tst_v4misc test ensures that we do not generate the TDZ check
instruction for certain scenarios.
Change-Id: I6706d1feb22217f323124ee698ebadb70324693b
Reviewed-by: Lars Knoll <lars.knoll@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>
|
|
|
|
|
| |
Change-Id: Ia510efa990b58d19eca635433187d3ffbc6e003a
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
|
|
|
|
|
|
|
|
| |
When registering a default export, make sure that the local name
points either to an entry that we've entered into the environment or
the synthetic entry we create.
Change-Id: I37e160dc1e3231214bb68f72d6bb0746d7aee3b3
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
|
|
|
|
|
|
|
|
|
| |
Now that ImportDeclaration and ExportDeclaration are also statements in
the AST, we can get rid of the ModuleItemList in the AST. We keep it in
the grammar, but map it to a statement list.
Change-Id: I4cab29fe9b075e88454fe3b194126f728000856a
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The evaluation of a module can have side-effects by modifying the global
object or objects in it. Therefore even a seemingly empty import such as
import "./foo.js"
needs to be listed in the module requests. It's also important that they
are evaluated in the order of declaration. Therefore we collect all
module requests separately - even those that don't have import variables
to process. This patch also ensures that the export and import
declarations are visited in the correct order, by unifying both AST
nodes to be hooked into the statement list.
The fact that we connect the module list items into a statement list is
solely an artifact of re-using defineFunction() which takes a
StatementList as body.
Change-Id: I75dc357b2aecfc324d9a9fe66952eff1ec1dfd8a
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
|