Commit Graph

524 Commits

Author SHA1 Message Date
Ulf Hermann d3b3fef5a8 Qml: Allow const and non-const QObjectWrappers to coexist
We can access the same QObject in const and non-const contexts. Both
should be possible. Store the const objectwrapper in
m_multiplyWrappedObjects. That's somewhat slow, but const QObjects are
rather rare.

Pick-to: 6.4
Fixes: QTBUG-98479
Change-Id: I047afc121f5c29b955cd833e0a2c8299fc52b021
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2022-09-07 16:57:16 +02:00
Fabian Kosmale 84483bff4f Engine: Fix handling of attached objects in function calls
When we use an attached object as an argument to a function call, we
need to properly extract it from the QmlTypeWrapper. Before this change,
we simpley left the argument pointer as null, which lead to subsequent
crashes when it got dereferenced.

Moreover, treat passing namespaces to functions expecting a QObject as a
TypeError, by returning false from CallArgument::fromValue (used to
crash for the same reason as with the attached object case).

Pick-to: 6.2 6.3 6.4
Fixes: QTBUG-106119
Change-Id: Ifa6a32e20a29935aff1f265eb0edd3e35ea1c11b
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2022-09-02 20:43:08 +02:00
Fabian Kosmale 2879c7c341 Integrate property binding evaluation fix from qtbase
This is basically the same as QTBUG-105204, only with the QML engine
being involved.

Fixes: QTBUG-104982
Pick-to: 6.4 6.3 6.2
Change-Id: I5afaadedcd7af41198702a8f2331703b4f6ef2e7
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2022-09-01 22:12:32 +02:00
Ulf Hermann 0b9fa18dfe V4: Mark InternalClass parents when running GC
We need to preserve them as they notify us about protoId related
changes. In order to avoid wasting heap space in case many properties
are added and removed from the same object, we put a mechanism in place
to rebuild the InternalClass hierarchy if many redundant transitions are
detected.

Amends commit 69d76d59ce.

Pick-to: 5.15 6.2 6.3 6.4
Fixes: QTBUG-91687
Task-number: QTBUG-58559
Change-Id: I3238931b5919ed2b98059e0b7f928334284ce7bf
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2022-08-03 08:32:33 +02:00
Ulf Hermann ef057772c4 Fix array-like methods on V4 sequences
We need to properly convert value type lists on assignment and we need
to add the "length" property to the own properties. Furthermore, the V4
sequence methods were confused about integer type ranges. We teach
them about qsizetype, properly range check everything, and drop the
artificial limitation to INT_MAX.

Pick-to: 6.4
Task-number: QTBUG-82443
Change-Id: Ie5af1130c9e78e412c171e6fa26a28a6a7a5d498
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2022-07-19 10:52:31 +02:00
Leticia Valladares c61075d2e0 UrlObject: Add colon after scheme
This change adds a colon after scheme in methods 'setProtocol' and
'setUrl' on its protocol line. Likewise, this includes a test called
'colonAfterProtocol' to check if colons were correctly added by using
different schemes: ftp, http and https, or if colons were removed when
setting the scheme (i.e. from protocol 'ftp:', 'ftp:http:' or 'ftp:::'
to 'ftp').

Fixes: QTBUG-103746
Change-Id: I8f847bedd23e476e0ae7901a2f3f3963da3ca04d
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2022-07-14 23:59:21 +02:00
Fabian Kosmale 8122dcea13 QML engine: Let string match QUrl during overload resolution
If an overload set contains a function with a QUrl parameter, and we
pass in a string, that would have resulted in the worst-possible score
of 10 for that function.

Given that URLs are often provided as strings in QML for convenience
(instead of using e.g. Qt.url), that is arguably a bad idea.
Starting from this commit, they'll get a score of 6: QJsonValue still
wins (to minimize the risk of breaking existing overload sets), but we
no longer claim that there is no match at all for such a parameter.

Change-Id: Ic0faa0029c9d5f14aff143cbd7fd4859d9ac2b2a
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2022-07-12 20:17:15 +02:00
Lucie Gérard 0dc4fd240a Use SPDX license identifiers
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>
2022-06-11 08:05:15 +02:00
Sona Kurazyan 2c9c1590e6 Replace uses of deprecated _qs with _s/QStringLiteral
Task-number: QTBUG-101408
Change-Id: Ic925751b73f52d8fa5add5cacc52d6dd6ea2dc27
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2022-04-29 09:47:43 +02:00
Ulf Hermann 762938aa5d Generalize QQmlAbstractBinding::isValueTypeProxy()
Instead of a bool we can just return an enum of the actual kind. This
way all the checks become more readable. Furthermore, we can eliminate a
dynamic_cast without sacrificing readability.

Change-Id: I8a38687f9b796cd47196a6ab0385624c737e4435
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2022-04-25 19:39:48 +02:00
Ulf Hermann 41a5c7b223 V4 Date: Support another nonstandard date format QDateTime has dropped
Amends commit 43eaa77e8e.

Fixes: QTBUG-100377
Pick-to: 6.2 6.3
Change-Id: I01028bd991b8a64bd9dcad31ce90536d83dad0a1
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
2022-02-03 00:52:49 +01:00
Ulf Hermann 712b637b58 Rename "Basic Types" to "Value Types"
Internally they've been called "value types" all along. Now that we are
adding the ability to define your own value types the "basic" name is
not really fitting anymore. Value types can be quite complex.

Change-Id: I5fb4abec1dd2f0bbf7fb7f08b02db0882490e983
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2022-01-21 01:23:59 +01:00
Fabian Kosmale e743b6e5e9 qqmltypecompiler: Be conservative in enum optimization
QQmlEnumTypeResolver constains logic to find enumerations in bindings
and turn those bindings into simple integer bindings. However, that
logic got confused when we had a complex expression (as in, not only an
identifier but any compound expression).
Instead of trying to create a mini-expression parser, we opt to be more
conservative in the analysis and reject anything that does not look like
one or more identifiers separated by dots.
The use case of optimizing simple arithmetic operations involving enums
in bindings is left to qmlsc.

Pick-to: 6.2
Fixes: QTBUG-98311
Change-Id: I6f8c3fa2a2712dabdea035e2447d52c415ebfc3f
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
2021-11-26 15:57:01 +01:00
Fabian Kosmale dde1d86baa QML/JS: Reject yield expression not directly in generator functions
If an inner function contains a yield expression, we need to reject the
program even if that function is inside of a generator function.

Fixes: QTBUG-98356
Pick-to: 6.2 5.15
Change-Id: I2e820a1ca5f0da4080e313fd9809aa8bfdc1b681
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2021-11-18 07:31:36 +01:00
Fabian Kosmale be194d965d Handle function as default arguments in toplevel functions
Top level functions, that is, those directly defined in a QML component
as opposed to those defined inside another function or class, are not
visited directly by the ScanFunction visitor. Instead, they are manually
considered in generateJSCodeForFunctionsAndBindings, and the visitor is
then run on their body.
This worked mostly fine, with one notable exception: In case there is a
function expression used as the default value of a function parameter,
that function would have never been visited. This would lead to
subsequent asserts/crashes in the codegen, as the function was not
properly set up.
We fix this by manually visiting the function's formals in addition to
the body.

Pick-to: 6.2 5.15
Fixes: QTBUG-98032
Change-Id: I5cb4caae39ab45f01a0dfa1555099d7d4b796a19
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2021-11-10 22:02:29 +01:00
Ulf Hermann 9b2ba45c18 Allow ImmediatePropertyNames in addition to DeferredPropertyNames
If given, all properties but the ones mentioned in
ImmediatePropertyNames are deferred. Also add some warnings related to
DeferredPropertyNames being ignored in some cases. Finally, scanObject()
can return false now. Therefore adapt its caller to take that into
account.

Task-number: QTBUG-95117
Change-Id: I1e696228de7ad3b495bf7791fdb014768aff4c96
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Maximilian Goldstein <max.goldstein@qt.io>
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
2021-10-28 17:49:52 +02:00
Ulf Hermann 9021f46cc0 QV4::QObjectWrapper: Improve overload resolution
QQmlV4Function should be used as the last fallback if there are other
options available. Also, take QVariantMap into account.

Change-Id: I9ebf39f4f860cf3bf44c6cbc80efbac7ea30c70b
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2021-10-21 09:47:01 +02:00
Tatiana Borisova 8a70b5f9d3 Fix autotest private API part compilation for INTEGRITY
- process should be used with config check

Change-Id: Ie35df508cacb16078face96ef1834a895614a870
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2021-10-11 22:21:35 +03:00
Fabian Kosmale 5ff83606a1 QQmlObjectCreator: Correctly remove overwritten bindings
For QProperty bindings, we would not explicitly remove bindings that were
added and later overwritten.
For "complex" bindings, that would cause some unnecessary binding
evaluation during object creation.
Worse, in the case of a literal binding overwriting a complex binding,
we would acutally end up with the complex binding still being there,
because the literal binding would result in an immediate write of the
value, whereas the binding was only installed at a later point.
We fix this by removing the binding from the list of to-be-installed
bindings when it gets overwritten.
We also now take the IsPropertyObserver flag into consideration when
checking whether existing bindings should be removed: IsPropertyObserver
is basically the same as IsSignalHandlerExpression, but for QProperty
bindings instead of "old-style" bindings.

Pick-to: 6.2
Fixes: QTBUG-96668
Change-Id: I2ef00d5b62af4f6fcc71960c38e1f0568b3b9c40
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
2021-10-05 21:29:41 +02:00
Ulf Hermann b3fe31a0ff Fix scoping of JavaScript function names
Function declarations add their name to the outer scope, but not the
inner scope. Function expressions add their name to the inner scope,
unless the name is actually picked from the outer scope rather than
given after the function token.

We don't add the name to any scope in the case of functions declared in
QML elements because the QML element will receive the function as
appropriately named, and typed, property. It is always better to use
that one than to use a JavaScript local.

This causes some additional ecmascript tests to pass.

Pick-to: 6.2
Fixes: QTBUG-96625
Change-Id: I0b8ee98917d102a99fb6b9bd918037c71867a4a5
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2021-09-29 13:39:41 +02:00
Mitch Curtis e310dadef7 Consolidate test helpers into private libraries
Previously each test would include and build sources from the shared
folder. Now we make those sources a library, build it once, then have
each test link to it instead.

We also take the opportunity to move some helpers that qtquickcontrols2
had added into the quicktestutils library where it makes sense, and
for the helpers that don't make sense to be there, move them into
quickcontrolstestutils.

We add the libraries to src/ so that they are internal modules built as
part of Qt, rather than tests. That way we can use them in a standalone
test outside of qtdeclarative.

Task-number: QTBUG-95621
Pick-to: 6.2
Change-Id: I0a2ab3976fdbff2e4414df7bdc0808f16453b80a
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2021-09-13 21:17:04 +02:00
Maximilian Goldstein 37b2231f1a tst_qqmlecmascript: Test that deferred names gets overwritten
Change-Id: I32d7ba2230dbd98f918e6e55abbe6b3fd43028d2
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2021-08-31 13:51:06 +02:00
Fabian Kosmale f0e5ff83a1 tst_qqmlecmascript: Check that parent can defer child class properties
It is arguably a bad idea to defer properties which might get defined in
child classes, but checking it in the engine would be expensive: We
cannot simply check that the property exist, as we might want to defer
attached properties.
So for now, we add a test to document and verify the behavior.

Change-Id: I264b136638c4ecddfa52b6687797cb981d9b531e
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2021-08-26 11:17:17 +02:00
Fabian Kosmale c081316a42 tst_qqmlecmascript: Test that it is possible to defer parent properties
This test is meant to narrow down the semantics of the currently
underspecified deferred properties.

Task-number: QTBUG-95117
Change-Id: Iee6b9d4caea1a248cf5c2d6773e12a314c01bae7
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Reviewed-by: Maximilian Goldstein <max.goldstein@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2021-08-25 14:40:51 +02:00
Fabian Kosmale 86039f61b3 QQmlObjectCreator: Add scripts also to context of inline components
The object creator only called setImportedScripts on a context if
subComponentIndex was -1 (indicating the root of a component). However,
since the introduction of inline components, subcomponents can also be
component roots. This patch adjusts the check to also consider inline
components. This fixes the issue that javascript libraries could nod be
referenced inside inline components.

Fixes: QTBUG-95095
Pick-to: 6.2 6.1
Change-Id: I22d14c6f102edca6d2991d25280bfe3c42df820f
Reviewed-by: Ivan Tkachenko <me@ratijas.tk>
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
2021-08-05 19:20:41 +02:00
Fabian Kosmale d36b480a95 QV4::Heap::GeneratorObject: remove unused member
The member was marked as a Pointer for the gc; however it was never
used, and thus also left uninitialized. This could cause memory
corruption or asserts during the gc's mark phase.

Fixes: QTBUG-95417
Pick-to: 6.2 6.1 5.15
Change-Id: Ide826c0284b6060de8689e6f0dc753011108dba9
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Maximilian Goldstein <max.goldstein@qt.io>
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
2021-08-02 17:58:47 +02:00
Ulf Hermann 8635e5b300 Use QV4::Scope::hasException() where applicable
It is shorter and encapsulates the exception handling a bit.

Change-Id: I8e2dc0eb3b930e222b8cb4852b73d99ca18a0379
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2021-06-30 11:23:08 +02:00
Ulf Hermann 0472a7a432 Evaluate type assertions in QML
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>
2021-05-26 14:46:39 +02:00
Edward Welbourne 0a673d257a Make QDate handling consistent in its use of UTC
Due to the quirk of ECMAScript's Date.parse() spec [0] stipulating the
use of UTC for date-only strings, in contrast to most other ways of
creating a Date using local time, reasonable users get surprised by
the behavior of QDate properties initialized from strings. This can't
be avoided without breaking other uses of Date, so document the
work-around needed to cope with it (use UTC-specific methods to access
the Date object).

[0] https://tc39.es/ecma262/#sec-date.parse

Make conversions back to QDate from Date work round the possibility
that the Date, seen as a QDateTime(,, LocalTime), needs to be handled
as UTC when extracting the date, and catch two more places that
conversion from QDate neglected to use UTC's start of day, for
consistency.

Revised tests to call UTC-specific methods instead of the local-time
ones, where appropriate. Drive-by: some tests were (entirely bogusly)
constructing a fresh Date using the UTC-fields of the Date they had,
in order to then test the non-UTC fields of this fresh Date; instead,
simply test that the UTC fields are as expected.

[ChangeLog][QML][Behavior change] Where a QDate is represented in
QML's JavaScript as a Date, it is now more consistently associated
with the start of the UTC day it describes. Previously cases where it
was represented as the start of local time's day could lead to a Date
turning into a QDate for the preceding day. Inconsistencies in the
specified behavior of Date preclude eliminating such problems
entirely, but they should now be limited to cases where (perversely
for a date property or parameter) the date is specified with a local
time late enough to make it coincide with the start of the next UTC
day (in which case that next day's QDate will be its C++
representation).

Fixes: QTBUG-92466
Change-Id: I2306dd9ecef0d5c2d59b562762392e51bb6d66ca
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2021-05-18 16:24:13 +02:00
Edward Welbourne cdf85cf884 Make tst_qqmlecmascript::dateParse() more thorough
Expand the test to pass a local-time QDateTime in (to check it arrives
in the form expected) and, parallel to the UTC time test, that the
various ways of constructing a local-time Date in JS do actually
produce the expected results.

Change-Id: I5ee8b4d3c0c15a5aa1168c7fb20646f3b55a7488
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2021-05-11 16:20:55 +02:00
Edward Welbourne 0e7dcfb641 Make a UTC time test more thorough and coherent
It was previously mixing in testing of QString -> JS String and JS's
Number() and its string's split(), none of which was relevant,
illuminating or simplifying.  It also had a MyDateClass instance in
the test that wasn't used, and only failed or passed, without giving
any clue to what went wrong.

Add console.log()s to report each error, pass a UTC QDateTime as
parameter instead of a QString, use the known values for the date and
time fields instead of extracting them from a string, and verify that
the passed QDateTime has all expected UTC properties. Test all ways of
constructing a UTC time, rather than only one of them.

Change-Id: I3f5828fc994e38d567e06edf96071188154de8bc
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2021-05-11 16:20:55 +02:00
Edward Welbourne e8ea7a1262 Clean up tst_qqmlecmascript: don't leak on failure
Lots of tests were following the antipattern of deleting a pointer
after the last QVERIFY() or QCOMPARE(), which leads to the pointer
being leaked on failure. Use QScopedPointer consistently (it was
already in use patchily).

That changed one mis-use of QPointer (that was only checked for
non-null immediately on creation, never referenced later, so being
cleared on deletion wasn't relevant; and thus needed an overt delete,
that QScopedPointer made redundant); but another appears to be
deliberate, so documented that as such (to the best of my
understanding, gc is meant to pick it up).

This mostly arose with component.create() results, most of which were
checked, albeit in inconsistent ways. Always check these before
dereferencing, and use the same form for the check in all cases: use
QScopedPointer's in-built cast-to-bool rather than !isNull(); and
report the component.errorString(), using QVERIFY2(), on failure.

In many cases the return from component.create() is passed through a
qobject_cast<> before use; in principle, this could result in null
even though create() returned a non-null pointer. Convert those to
hold the return from create() in the QScopedPointer<> and cast its
data() to get a plain pointer for subsequent use.

Split assorted lines that got long (or longer) as a result.
Removed a fatuous empty constructor.

Change-Id: I88abba9e7ea72e30c92a11a5af5f17486f07f847
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2021-05-11 16:20:55 +02:00
Fabian Kosmale 9da03da2e3 Apply constant binding removal optimization to QProperty bindings
This applies the logic from 7cb6dce1f3 to
non-QQmlAbstractBinding bindings, too.
The logic to detect whether a binding has no dependencies has consider
the QPropertyBindingPrivate's dependency  observer count.

In addition, change the existing detection logic to remove properties
without a context, too. The  original logic probably wanted to guard
against accessing binding->context()->unresolvedNames when context was
nullptr; however, the check should have tested "context ->
unresolvedNames", not "context and unresolvedNames". And after the
refactoring which introduced hasUnresolvedNames() as a function, the
context check became completely superfluous.

Fixes: QTBUG-92996
Change-Id: Ia3bc39e184f431210b3bb2d38154acf820525e98
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2021-05-10 23:00:40 +02:00
Fabian Kosmale 297a3479c6 QQmlPropertyBinding: Call RESET every time binding evaluates to undefined
To be in line with the behavior of the old bindings, we have to call
reset, even when the binding was undefined before.
Add a test which checks this behavior for both new and old types of
properties. Amends d64e7c9c6c.

Task-number: QTBUG-91001
Pick-to: 6.1
Change-Id: I1067a2fd56d5b7587281a9262e9bd389c825e587
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2021-04-22 08:44:32 +02:00
Fabian Kosmale 7fa4c31d53 Adjust to QProperty using eager evaluation
Besides API changes, we need to
- adjust QQmlBind to unlink the binding properly (that probably was
  broken already before, but did not cause issues so far, as the old
  binding would not have been evaluated without a read access) and
- skip tests in tst_qmlcompiler_manual, as the bindings are executed
  before the engine is correctly set.

Change-Id: I97b0ac32b428c1a033664fe8593effadb69cd348
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2021-04-19 13:04:15 +02:00
Maximilian Goldstein 5f7ecce233 Implement optional chaining
This change implements optional chaining (https://github.com/tc39/proposal-optional-chaining) by adding a new type of optional lookup with an offset to the end of a chain.
If `undefined` or `null` is encountered during an access marked as optional, we jump to that end offset.

Features:
- Full support for all kinds of optional chain
- With some codegen overhead but zero overhead during normal non-optional FieldMemberExpression resolution
- Properly retains this contexts and does not need to resolve anything twice (this has been an issue previously)
- No extra AST structures, just flags for existing ones

[ChangeLog][QtQml] Added support for optional chaining (https://github.com/tc39/proposal-optional-chaining)

Fixes: QTBUG-77926
Change-Id: I9a41cdc4ca272066c79c72b9b22206498a546843
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2021-04-13 19:19:56 +02:00
Fabian Kosmale a6cde06936 Adjust to QObjectCompatProperty API changes
Change-Id: I600415cc7e472fb753e83fafbc89f074d13676d7
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2021-04-08 11:12:12 +02:00
Fabian Kosmale e7e4eba687 QV4QObjectWrapper: Store the whole signal
90be89d771 changed the connection logic to
actually pass the receiver to connect in order to fix disconnect
cleanup. However, we omitted to change QObjectSlotDispatcher::impl
accordingly. The previous logic was:
- store the index of the signal in signalIndex
- In impl, in the call case, we would get passed the emitting object
  (sic!) as the receiver parameter. Then we would use the object and the
  signal index to obtain the QMetaMethod.
- From the QMetaMethod, we could get the signal's number of parameters.

After the aforementioned change, that does not work anymore: The
receiver is now the actual receiver of the signal, thus we get the wrong
method, and potentially the wrong number of parameters.
To fix this, we now store the complete QMetaMethod of the signal.

Pick-to: 6.1
Change-Id: I868c51edf24a61d14eaf958ed7942da27f54a5c3
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2021-04-01 10:14:16 +02:00
Fabian Kosmale d009c0088b QV4::Engine::toVariant: Use metatype instead of metatype id
This way, we can avoid the costly id to metatype lookup in case where we
actually need the full metatype.

Task-number: QTBUG-88766
Change-Id: Ibe29b323007f00d2f8d1807fb9b64f9a8f87e807
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
2021-03-25 21:25:28 +01:00
Ulf Hermann 9caea013ce Clean up JSCallData setup
We either have pre-populated arguments and thisObject, then we can just
use them and keep them const. Or, we want to allocate and populate the
arguments and the thisObject. Then, do allocate them in a separate
object, and transform that into JSCallData afterwards if necessary.

Furthermore, avoid alloc(0) as that just returns the current stack top.
Writing to it will clobber other data. Rather, just use nullptr and
crash if it's written to.

Also, remove the useless operator-> from JSCallData. That one just
confuses the reader.

Change-Id: I8310911fcfe005b05a07b78fcb3791d991a0c2ce
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2021-03-17 13:10:22 +01:00
Fabian Kosmale d64e7c9c6c QQmlPropertyBinding: handle reset
Bindings are allowed to toggle between a defined state, and undefined
which calls the property's reset function. Calls to the reset function
must not remove the binding, even when they write to the property.

To support this, we put the binding in a special undefined state, in
which it is still active (and installed on the property), but does not
actually provide its evaluated value to the property. Then, when the
binding later becomes defined again, the binding leaves its undefined
state and works normally again.

Notes:
- Calling the reset function during binding evaluation could have all
  kinds of unwelcome side-effects. We therefore have to suspend binding
  evaluation before the reset call (and restore that state afterwards).
- QObjectCompatProperty expects that we write the current value into the
  propertyDataPtr. If we do not do this, it will overwrite the current
  value with the default constructed value of its property. Arguably, we
  should change the API so that we communicate that nothing has changed;
  but for now, we have to live with that limitation and read the
  current value and write it back again.
- We currently do not handle the case correctly where a non-resettable
  property implemented via QObjectCompatProperty gets assigned undefined
  in a binding. Such a binding is likely unintentional (as the undefined
  assignment only creates a warning), and thus less of a priority.
  Nevertheless, a test marked with QEXPECT_FAIL is added for it.

Fixes: QTBUG-91001
Change-Id: I7ecaa6c8dc1a1f1b33e67b1af65f552c4ca6ffb1
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2021-03-15 11:42:15 +01:00
Maximilian Goldstein 7ea690c61d qv4generatorobject: Fix crash when creating new properties
Previously HeapObject::GeneratorObject utilized a ValueArray member to store stack information.
As we rely on all HeapObject members to have a constant size in order for QV4Table::inlinePropertyOffset
to remain accurate, this lead to a memory conflict when a user defined his own property on the Generator.

Please do not use ValueArray for any types that are user accessible or that you intend to add properties to.

Now the stack information is stored into ArrayObjects instead which circumvents the issue.

Fixes: QTBUG-91491
Pick-to: 5.15 6.0 6.1
Change-Id: Id6f638bf36a3ae3c9320ac99e67214c48dc81226
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
2021-03-08 15:53:45 +01:00
Fabian Kosmale 8e904d9c8b QML engine: Handle const QObject pointer correctly
[ChangeLog][QML][Important Behavior Changes] If a QObject pointer is
passed to the QML engine and subsequently frozen with Object.freeze,
modifying its QObject properties now fails and throws a TypeError. The
TypeError is thrown even in non-strict mode.

[ChangeLog][QML] It is now possible to pass const QObject derived
pointers to QML in properties, and to call Q_INVOKABLE functions which
take such pointers as arguments. If the QML engine receives such a
pointer, it is treated as if the object was frozen.

Fixes: QTBUG-82354
Change-Id: Ib0dbcdfb2370654505936c3cf391d87dd2c9677b
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
2021-03-01 14:56:39 +01:00
Andreas Buhr 7e029878c0 Fix some "can be marked override" warnings
Change-Id: I13da0d085901314950c4fa0afb5853e183652e67
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
2021-02-23 16:50:07 +01:00
Fabian Kosmale 2707910edb QV4QObjectWrapper: handle bindable properties
A function created by Qt.binding should lead to the binding being set
(and replacing any previously existing binding). This was not the case
for bindable properties so far. For those, we would have kept any
existing C++ or QQmlPropertyBinding binding, and instead created a brand
new QML binding which would have been set in addition.
This patch also introduces a new class,
QQmlPropertyBindingJSForBoundFunction, which is used to handle the case
where the binding function is not a simple function, but has its
parameters bound instead.

Change-Id: Ia1417162b9822efb3f17ca4a6ecc02f959392927
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2021-02-19 18:10:23 +01:00
Fabian Kosmale f5877880c5 tst_qqmlecmascript: Adjust to QObjectCompatProperty change in qtbase
Fixes: QTBUG-90786
Change-Id: Id05afbeb18b7c30246a29b95673a1319649f389f
Reviewed-by: Andreas Buhr <andreas.buhr@qt.io>
Reviewed-by: Maximilian Goldstein <max.goldstein@qt.io>
2021-02-01 12:59:59 +01:00
Ulf Hermann b7bbdf7e7d V4: Store instruction pointer before CmpIn
The "in" operator may throw an exception.

Change-Id: I7d0b6e2212ac6ec237fbf14719349f8e23810028
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2021-01-27 10:54:18 +01:00
Fabian Kosmale 9eda73354c QQmlPropertyBinding: improve error reporting
This change ensures that bindings created in QML between new-style
properties contain information about which property caused the loop. To
do this, we store additional information about the property involved to
retrieve its name and position at a later point. We print the warning in
case we detect a binding loop in evaluate, and also set the error
reporting callback correctly, so that the condition can be reported when
the loop is detected in another part of the binding evaluation.

In addition, we do not only set the QPropertyBinding's error member when
JS evaluation results in an error, but also print the warning with
qmlWarning.

Fixes: QTBUG-87733
Change-Id: Idb25237d1f57355ca31189e6bf2a918430b3a810
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2021-01-25 11:21:42 +01:00
Andrei Golubev 90be89d771 Use new QObjectPrivate connection mechanism in dynamic connections
Old API assumes sender == receiver, which results in wrong handling of
connections when receiver is deleted: connection is not removed or
notified elsehow as it's not really tied to a valid receiver

Task-number: QTBUG-86368
Pick-to: 5.15 6.0
Change-Id: I0f3115f1b0f26cf353752ba2b8fd88e0f3bdd388
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2021-01-21 08:38:50 +01:00
Fabian Kosmale 65b88e61a5 QML engine: Fix writing function to property through alias
We special case writing functions to properties, only allowing assigning
them to var properties and QJSValue properties.
This would however break when aliases are involved. This commit fixes
the issue by resolving the alias, and then checking and writing to the
resolved property.

Fixes: QTBUG-90373
Pick-to: 5.15 6.0
Change-Id: Ia09ebe92feeaf8359c99ff9aeadc676b9fcfaa07
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2021-01-18 13:20:12 +01:00