| Commit message (Collapse) | Author | Age | Files | Lines |
| ... | |
| |
|
|
|
|
|
|
|
|
|
| |
We cannot replace AOT-compiled compilation units while an object is
still holding on to them and we cannot delete all objects holding on to
a CU because they might not belong to the preview to begin with.
Pick-to: 6.8 6.5
Fixes: QTBUG-129329
Change-Id: Icbcb7822be770a440f3216955c0ae51151390e17
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In order to re-use the compilation units for JavaScript libraries, we
need to eliminate the "m_value" member they are carrying, indirectly.
The values are tied to specific engines and invalid in others.
Luckily, we already have two suitable places to store such values:
1. In case of a "native" module without a compilation unit we have the
nativeModules hash in ExecutionEngine.
2. In case of a module or library backed by a CU we have the "module"
member of ExecutableCompilationUnit. This can currently only hold
modules but there is no reason why it wouldn't hold JavaScript
libraries equally well.
By using the "empty" V4 value we can also get rid of the m_loaded bool.
As a drive by, correct the QQmlScriptBlob::isNative() misnomer. We don't
want to know whether the script is native (for any value of that), but
rather whether it has a value.
Pick-to: 6.8
Fixes: QTBUG-129052
Change-Id: I284823f4aa26e46dec8328f88f65877f59e40f79
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Since the executable CUs are used as entry points for marking by the GC,
dropping them from QQmlEngine means their strings, lookups, regexes etc
won't get marked anymore. If, however, the CUs are still referenced
elsewhere, their inner objects will still get used, despite having
potentially been swept by the GC.
Also fix the documentation of clearComponentCache() to clarify that it
does in fact not clear all components.
Pick-to: 6.8
Fixes: QTBUG-128638
Fixes: QTBUG-128782
Change-Id: I96480914733c399c18778202ae8dca7e332c3a85
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
| |
We usually have to do some handling in this case, but here we return
anyway.
Coverity-Id: 468063
Change-Id: Ie2ced36322a28d0c68c6c8618eb4f7890ae0f7ab
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
Reviewed-by: Luca Di Sera <luca.disera@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Warning C4146 is issued when the unary minus operator is used on an
unsigned type.
Silence the warning by substituting `-1u` with the equivalent and
clearer `numeric_limits<uint>::max`.
Pick-to: 6.8
Change-Id: Ie73c48467abf4af3059639d8bbd436e6cdc717e0
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
| |
Use `q20::erase` instad of the one-argument overload of erase and the
erase-remove idiom.
Change-Id: I880cdbdf38df1873fb87522975bcd9e9aaf9c9d4
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The backing storage implementation for Maps/Sets, `ESTable`, currently
uses a pair of arrays for its storage of keys and values, respectively.
Additional elements that should be added are appended to the arrays.
When an element is removed, all elements past it are shifted to the
left, to avoid having empty spaces.
The arrays naturally preserve insertion order, which is required to be
the iteration order for `forEach` based on the spec.
`Map/Set.prototype.forEach` implementations make use of this fact by
iterating per-index so that the iteration follows the required order.
As per the spec, during the execution of a `Map/Set.prototype.forEach`
call, a call to `callbackFn` might modify the iterated upon collection
itself.
Depending on the specific changes that are performed, this might break
the iteration cycle in the index-based iteration that the `forEach`
implementation performs.
For example, given:
```
let set = new Set([1,2,3]);
set.forEach((v) => {
console.log(v)
set.delete(v)
})
```
The index based implementation would perform the following iterations:
- Set = [1, 2, 3]; index = 0;
- visit 1
- 1 is deleted from the Set
- ...
- Set = [2, 3]; index = 1;
- visit 3
...
Skipping the required visit of 2 due to the index not being re-adjusted
between iterations.
To avoid the issue, the way that `forEach` implementations iterate over
an `ESTable` was slightly modified.
`ESTable` now exposes a simple structure that can be used to observe
changes in position in relation to a an indexed entry.
An instance of the structure can be registered with the table to observe
the internal changes that the table performs, allowing the re-adjustment
of an index during an index-based iteration.
A small test was added to ensure that the case reported in attached bug
report is solved.
`tst_ecmascripttests` was modified to enable some `forEach` related
tests that were previously failing and will now work due to the
iteration changes.
Fixes: QTBUG-123377
Pick-to: 6.8
Change-Id: I8fc72b747eb295f009c2e2c2933f05b26f1ce717
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Generally, the engine checks for stack overflows each time a function is
called.
In the common case, the entry point for the execution of a function is
`QV4::Moth::VME::exec`, which will perform the check as part of its
execution.
`exec` will then dispatch to the execution of the function, either by
using the JIT when enabled and available or by calling
`QV4::Moth::VME::interpret` when this is not the case.
Generators work slightly differently than a normal call, both when a
Generator Function or Method is executed and when a generator is
resumed.
In particular, the execution of a Generator Function or Method and the
execution of a resumed generator do not pass by `exec`, instead directly
calling `interpret`on the relevant code.
As `interpret` does not perform any check for stack overflows, a call to
a Generator Function or Method or the processing of a resume operation
on a Generator will not identify those overflows, such that it will fail
to throw a `RangeError`, as it would be normal for a normal call,
instead ending up segfaulting down the call chain.
To avoid the issue, ensure that a check for stack overflows is performed
before a call to `interpret` in both `GeneratorFunction::virtualCall`
and `GeneratorObject::resume`, to ensure that an exception is thrown
when required.
The ordering of operations for `resume` was modified to allow for the
abrupt return due to the, now possible, stack overflow exception.
Both `return` and `throw` can produce a resume of the generator and both
of them throw an exception in doing so.
`return` throws an exception as an implementation detail.
An `emptyValue` is thrown, which will later be recognized by the
execution of a `Resume` instruction and cleaned away.
Failure to do the cleaning will produce an issue as an `emptyValue`
should not propagate through the system.
`throw` throws as part of its implementation as expected by the spec.
As both throws are performed before resume is called, the thrown value
would hide the `RangeError` exception that can be thrown due to a stack
overflow.
To allow for the stack overflow to be correctly recognized and its
thrown error not to be hidden, `resume` was modified to accept a third
optional parameter, representing a value to be thrown just before
calling `interpret` and after checking for a stack overflow.
Its call site in `method_next`, `method_return` and `method_throw` were
modified accordingly.
Some test-cases were added to `tst_qjsengine` to ensure that the
correct kind of exception is thrown when a stack overflow happens on the
execution of a Generator Function or Method or when resuming a Generator.
Pick-to: 6.7 6.8
Fixes: QTBUG-127049
Change-Id: I3656957097df3ccd5c6d70f86335bc40e229bb20
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
| |
Fixes: QTBUG-127704
Pick-to: 6.7 6.8
Change-Id: Ifb6aad0feb26fadee2838b74a3a7c29949be05a6
Reviewed-by: Fabian Kosmale <fabian.kosmale@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>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Prefer exact matches where they exist, try all ctors for derived types
then, and only if that doesn't help, try conversion.
In order to properly compare the types, always retrieve variants from V4
values as their "natural" type rather than pre-coercing them.
Pick-to: 6.8
Task-number: QTBUG-125341
Change-Id: Ib3bc45edd6983ca662c556ca8d8c6ed5d2bbaf46
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When a generator function or method is called, the engine needs to
perform some setup for the call to be performed.
For example, it needs to setup an actual generator object, provide it
with a frame for re-entering, actually execution the body of the
generator callable and then return the generator object as the result.
This necessary processing is generally handled by
`GeneratorFunction::virtualCall`.
The engine implements Proper tail calls as introduced by the ES6
specification.
For example in:
```
function foo() { return 0; }
function bar() { return foo(); }
```
The call to `foo()` in `bar()` in in a tail position and can be
optimized accordingly.
In the engine, tail calls will be optimized and implemented as jumps,
eliding the actual call indirection.
While this is generally fine, it produces incorrect results when the
elided call is to a generator function/method, as the required
setup for the generator call is never executed.
For example in:
```
function* foo() { yield 0; }
function bar() { return foo(); }
```
`foo` is a generator function that is called in tail position in `bar`.
When `bar` is called, the call to `foo` will be optimized out and its
body will be executed.
This will correctly execute the body but produce an incorrect result.
The YIELD instruction will mark the incorrect frame as a yielding frame
and no generator object will be constructed or returned, instead
producing an undefined result.
To avoid the issue, disable TCE for
`GeneratorFunction`/`GeneratorMethod` to ensure that tail calls to a
generator function or method will not elide the call to
`GeneratorFunction::virtualCall`, so that they can perform the required
setup for the execution to succeed.
Some test cases were added to `tst_QJSEngine` to test that tails calls
to a generator function or method do not produce an undefined value.
Fixes: QTBUG-109880
Pick-to: 6.5 6.7 6.8
Change-Id: I712ab5c8fdcfde2591b83c4e951dd4723b8bfc1d
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
We universally allow this pretty much everywhere else. We should also
allow it when evaluating bindings. To facilitate this, generalize the
SequencePrototype::toVariant() method so that it works with any
array-like and faithfully coerces the elements by the type coercion
rules.
Pick-to: 6.8
Fixes: QTBUG-126398
Change-Id: I520cd40e5f74bee5ac4b418aa86dc043774efcbe
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
| |
scopde -> scoped
Change-Id: I34d68aa09a9d3fb84cc558055ed0388725f41fbb
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When evaluating a script with `QJSEngine` an empty string literal will
be treated as a null string.
For example evaluating `""` will produce a string-holding `QJSValue`
that produces a null `QString` when the string value is extracted.
This is in contrast with the general behavior of `QJSValue`, where
directly constructing a `QJSValue` from a null or empty `QString` will
produce a `QString` value that is empty but not null.
When the engine reads the literal from the string table, it specifically
returns a null `QString` for zero-sized strings.
This null `QString` will then propagate its null-ness when used to
allocate a string, which will in turn propagate all the way up to the
returned `QJSValue` that holds the produced string.
To align the behavior of a string-holding `QJSValue` produced from the
engine to the behavior of a `QJSValue` directly built from a `QString`,
the specialized code that produced the original null `QString` was
removed, so that an empty string is constructed instead.
This partially amends
ff0857541d5d391c7c03cce5893b41dd9b35e7fa, which
introduced the specialized construction of the null string in relation
to another issue.
The change was already partially amended in
86379e265e19a078545306d93c59b0d92c04920a, where some
of the additional behavior introduced by the original patch was rendered
unnecessary by changes in Qt itself.
The null string behavior for empty literals that was added as part of
the original patch was partly tied to the code removed in the first
amendment and is not expected to break the original case anymore due to
the changes in the context around it.
A test case was added to `tst_QJSEngine` to test the behavior.
The test case that was originally added in
ff0857541d5d391c7c03cce5893b41dd9b35e7fa, which
tested that empty string literals were treated as nulls was modified to
align to the new behavior of non-null, empty strings.
A slight change was made to the implementation for the String prototype
`startsWith` method to adapt it to the changes which exposed a previously
existing bug.
When `startsWith` was given a position as part of its second argument,
this would have been retrieved as a double and then directly passed to
`QStringView::mid`, producing an implicit conversion to `qsizetype`.
For values that `qsizetype` cannot hold, the result can be different
between platforms.
In particular, this showed on a ecmascript compliancy test that would
now fail on ARM mac platforms.
The test would pass infinity as the second argument and an empty literal
string as the first in a call to `startsWith`, which, by the spec
description should return true.
In general, on an ARM mac platform, the conversion would saturate to the
nearest integer, a positive value. On such a parameter the call to `mid`
would return a null string.
Due to the way the `startsWith` implementation for `QStringView` works, this would
require the searched for string to be null for the search to return
true.
Previously, due to literal empty strings being read as null, this would
silently pass.
On the contrary, on a platform such as x86_64, the implicit cast would
generally produce the indefinite integer value, which appears as a
negative integer, producing the whole original string on a call to mid,
which then would have the correct behavior on a call to
`QStringView::startsWith` with regards to the test in question, so that
it would generally pass.
To avoid the platform specific behavior, the position in double form
is now clamped between zero and the length of the string that should be
searched, which should generally avoid the unexpected behavior and be
relatively consistent between platforms.
[ChangeLog][QtQml] Assigning an empty JavaScript string to a property of
type QString now produces only an empty QString, not a null QString.
Fixes: QTBUG-125611
Pick-to: 6.8
Change-Id: Id6850fd98082f33db93d2a7d0bc4f7b5fdcad45b
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
The interpreter already has the necessary setup, but the JIT did simply
write the value without marking so far.
We fix this by adding a new runtime function call, which simply uses
QV4::WriteBarrier::markCustom to mark the given value.
Both the StoreLocal and StoreScopedLocal bytecode instructions are
handled by adding the code to BaselineAssembler::storeLocal.
Pick-to: 6.8
Change-Id: I4b9226848bff029a076c0cfa6daf899ca9b84622
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
If an object is proxied, we can't use the optimized getters for the
lookup, as those would bypass the custom proxy logic.
Fix this by always using the fallback code path when encountering a
Proxy object.
Pick-to: 6.8 6.7 6.5
Fixes: QTBUG-112320
Change-Id: Idd8d4f2cd0134ada010448d470cfc68e765ef125
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
|
|
|
|
| |
In contrast to a WeakMap/WeakSet, Map and Set also accept primitive
keys, from which we obviously won't be able to obtain a heapObject.
Pick-to: 6.8
Change-Id: I2ceeb54339ff3a3a14424c22b2f49d098cd635cd
Reviewed-by: Ulf Hermann <ulf.hermann@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>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When QML reads a property with a C++ provenance it sometimes apply
certain transformations to work with the property in a JS environment.
For example, certain containers, such as `QJsonArray` or
`QVariantList`, are converted to a `Sequence`, an array-like object that
knows how to modify the container and takes care of reflecting mutations
back to the property.
`Sequence` provides a specialized implementation for the built-in sort
method.
Generally, the default sort implementation for an array in JS converts
the elements to a string and compares the stringified representation.
In the case of `Sequence`, the sort implementation will treats the
elements as `QVariant`s and use `QVariant::toString` to perform this
part of the sorting algorithm.
Due to the way `QVariant::toString` works, this can fail for certain
elements.
For example, `QVariant::toString` is unaware of how to produce a string
from a `QJsonValue`, the type of the elements that compose a
`QJsonArray`, thus failing to correctly sort a container with such
elements.
Other than the `Sequence` implementation, the JS runtime provides, as
per specification, a sort method for the Array prototype.
Contrary to other methods that are implemented for the prototype, the
`sort` method is implemented so that it can only work on values that
have a populated `ArrayData`, an optimized storage for certain array and
array-like objects.
As `Sequences` do not use an `ArrayData` storage for their elements, the
method is unable to work on a `Sequence`.
To broaden the ability of the sort method implementation for `Sequence`
to work more generically, the default sort implementation for the Array
prototype sort method was modified to work more generically on objects
that do not present an `ArrayData` storage, with an implementation based
on the latest draft of the JS specification.
The specialized `Sequence` implementation was removed, in favor of
`Sequence` delegating to the Array prototype implementation which would
now support working with `Sequence`s.
While this should be generally slower than the specialized
implementation, foregoing some performance, it should allow a more
generic foundation for the sort method for `Sequences` or other elements
that act like an array but do not use the specialized `ArrayData`
representation.
Some specialization could later be reapplied to `Sequence` to improve
the performances of the implementation.
Previously, the Array prototype implementation would directly delegate
to `ArrayData::sort`, the sort implementation for the specialized
`ArrayData` storage.
This was modified to dispatch to an implementation based on generic
methods when no `ArrayData` is populated on the object of the sort.
The code related to the specialized `Sequence` implementation for sort
was removed and the sequence prototype was modified to not present a
specialized `sort` property, so as to fallback on the Array prototype
one.
The `ArrayData::sort` implementation was slightly modified.
`ArrayData::sort` would perform a check on the presence of a defined
callback for the sorting and throw a type error if the non-undefined
element is not callable, as per specification.
This check was moved to the Array prototype implementation, to be shared
between the specialized `ArrayData::sort` implementation and the
generic implementation.
As per the spec, the check should be performed as soon as the method is
entered and before the receiver of the method is converted to an object.
With the check moved to the start of the Array prototype sort
implementation this ordering of operations is now fulfilled.
The compliance test that checks for this behavior,
`comparefn-nonfunction-call-throws`, that was previously failing, will
now pass and was thus removed from the list of expected failures for the
`ecmascript` tests.
A `QEXPECT_FAIL` related to testing the default sort of a `QJsonArray`
property was removed from `tst_qqmllanguage`, as the sort is now
expected to work correctly.
Fixes: QTBUG-125400
Change-Id: I158a9a160b8bdde2b8a06bb349a76469fc25c5a1
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Map and Set must hold on to their keys (and values in case of Map),
which did not happen if we inserted values into an already marked Map or
Set.
A similar issue holds for weak maps and sets, except that for those we
only want to mark them once we are past the FreeWeak(Maps|Sets) phase.
Pick-to: 6.8
Change-Id: Ibc05be4a85172a9b726beebf0d008acde4479edf
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The QtQml library should hold the builtins and provide no plugin. Move
the types currently exposed in QtQml.Base to QtQml where it makes sense.
Anonymous object types as well as sequence types and value types can
well be exposed as builtins. This makes everybody's life easier since
you now can universally depend on their availability.
The Qt object, despite being a named object type, also becomes a builtin
because you always have the "Qt" member of the JavaScript global object
which holds the same thing. So, formally exposing "Qt" as builtin
doesn't really add anything new.
QQmlLoggingCategory is split up into two classes, not only because we
need the base class when printing to the console from QtQml, but also
because this paves the way for compile time identification of logging
categories as first argument to the console methods.
For QQmlLocale we have to refer to a different trick. The value type and
the QQmlLocale "namespace" have to be builtins, but the "Locale" name,
due to being uppercase and versioned, has to be part of QtQml. We
transform QQmlLocale into a struct so that we can inherit the enums from
QLocale and extend a namespace with it in QtQml.
Pick-to: 6.8
Fixes: QTBUG-119473
Fixes: QTBUG-125765
Change-Id: Ica59390e54c473e33b4315f4384b724c870c1062
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
| |
In particular, don't include qqmllocale_p.h, qqmlbind_p.h and
qv4sequenceobject_p.h where we don't need them. Also, don't qualify
private includes by their module name so that we can move them to other
modules more easily.
Change-Id: Ic13592cef574424498ce9e7708d6fbaa681b81f3
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
|
| |
|
|
|
|
|
|
| |
Most of the time we have a native shift() operation.
Fixes: QTBUG-123882
Change-Id: I1bc50f98f29918a56b5fc70d1644eb99542a3073
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
The value needs to be a default-constructed instance. Otherwise a number
of branches in this method produce unwanted effects, such as appending
to an already existing array rather than creating a new one.
Amends commit 1b89c1edcae68351632c2755e5408410c2ff98e3.
Pick-to: 6.7 6.5
Fixes: QTBUG-125429
Change-Id: If175a02b3a794573abc03df206fbddd41f2855b4
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
| |
This used to (mistakenly) return null, which is much better than
constructing the value type.
Amends commit 71e259837967f1eee50c057229094c2a971a1a61.
Change-Id: I3da9d0a765d118dc8d85d7c5dde91936855bbf67
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
| |
... as required by ECMAScript.
Pick-to: 6.7 6.5
Change-Id: I31bc7e6a87e404a8e6d314c99f163f82208e13a1
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 calls any invokable ctors and only invokable ctors. Any
type that doesn't have an invokable ctor won't even expose a
function, since functions are determined by the presence of call
methods.
QMetaObjectWrapper gains the same functionality since the code is
shared. It can now not only create object types but also value types.
Task-number: QTBUG-124662
Change-Id: Ib30098666f67aef7a1f464f52d9b0bbd70d896d1
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When a property coming from C++ is used in a QML file, the engine might
perform some internal conversion to handle the type.
When a `QJsonArray` property is loaded, currently, it will be converted
to an internal `JsonObject` representation containing an engine-owned
array.
When the conversion is done, the data from the `QJsonArray` is copied as
a part of this process.
The performed copy is expected to act like a Javascript array.
Nonetheless, due to the way the conversion is implemented, using the
property will perform the requested work on the copy without writing
back to the original property.
This in turn prevents certain operation from working as expected, in
particular the mutable methods on the array prototype.
For example, if `jsonArray` is a `QJsonArray` property with a C++
provenance, the following will not register the push on the original
property, so that it will be lost the following time the property is
accessed:
```
...
jsonArray.push(4)
...
```
As a `QJsonArray` property should behave as a Javascript array when used
from QML, a `QJsonArray` property will now be converted to a `Sequence`,
an internal representation that behaves like a Javascript array but acts as a
reference object with property write-backs, to allow in-place mutations
to be correctly reflected on the original property.
Currently, a `QJsonArray` `Sequence` call to the sort method will not
correctly work due to the way the sort method is implemented.
This is currently left as non-working and will be fixed separately.
A non-exhaustive test-case was added to check that a C++ loaded
`QJsonProperty` acts as a Javascript array with regards to the Array
prototype methods, taking into consideration the inability of the sort
method to currently work.
Task-number: QTBUG-111015
Change-Id: Iec48fe4cba9adb9b794e5a568985b86b8da4556c
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
|
|
|
|
| |
The name of a bound function cannot be null.
Amends commit 8b6a9403bf2e04d34b9b07d2780186029fab99d0
Change-Id: I8a32d4c2cc8170f1b5d722cd8c5b823aa2211975
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
These are really rather generic type traits that shouldn't be stored in
individual objects. Moving them away slims down FunctionObject even
more.
FunctionObject doesn't add any extra overhead on top of Object anymore.
You also cannot easily cast an object that doesn't implement any call
methods to FunctionObject anymore. Therefore, we can derive from
FunctionObject even if we only need to implement call methods in a
further derived class.
The fact that ProxyObject is not a FunctionObject but its derivatives
are is already tested as part of the ecmascript test suite.
Task-number: QTBUG-124662
Change-Id: I5632de8c54ac1d6a4b15c4926c655b87b475db49
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Most FunctionObjects do not actually need their custom jsCall members.
They will only call the functions from the vtable anyway. FunctionObject
can therefore be split into a static and a dynamic variant. Only the
dyanmic variant needs to carry (and invoke) the extra pointer. The
jsCallWithMetaTypes pointer is completely pointless because none of the
dynamic functions actually implement it.
Furthermore, the QV4::Function and QV4::ExecutionContext pointers in
FunctionObject are only needed by actual JavaScript functions. The
builtins that like to be dynamic functions never need them. Therefore,
split out another class for this.
In the generic FunctionObject, we need the capability to decide at run
time whether the function shall be a constructor or not. Add a flag to
replace the check for jsCallAsConstructor.
Also, where we can, avoid the pessimization of checking whether a
function is a constructor before trying to call it as constructor.
Rather have the default implementation throw the exception.
As a side effect, for most functions we don't need an ExecutionContext
anymore. The engine is enough.
Task-number: QTBUG-124662
Change-Id: Iac657fa71288dd6ec230a33de2986ba3bcf4628c
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
| |
We want to use it from QQmlTypeWrapper and avoid circular includes.
Task-number: QTBUG-124662
Change-Id: I4c78a17eb262a303b7239bbdd853ec02d609c330
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Pass the metatypes of the contained types rather than the stored types.
[ChangeLog][QtQml][Important Behavior Changes] The AOT compiled code for
type-annotated JavaScript functions does not let you pass or return
values of the wrong type anymore.
Fixes: QTBUG-119885
Change-Id: I685d398c0745d32a999a3abd76c622a2c0d6651f
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
WeakValue::set shold normally not mark objects, given that a weak value
is not supposed to keep an object alive.
However, if we are past GCState::HandleQObjectWrappers, nothing will
reset weak values referencing unmarked values, even if sweep collects
the referenced value.
That leads to stale pointers, and then most likely to crashes.
To avoid this, we mark the objects under this special condition.
The test is written in a way that would also allow for resetting the new
weak values instead, but the current implementation treats memory usage
for throughput and doesn't revisit weak values to reset them.
Change-Id: I789f63c1d8609957711c2253d2e76b4bd3f9810a
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
This is in preparation for using exact types and actually enforcing
them. We shouldn't wrap the return value into a QVariant in order to
then painstakingly unwrap it again. The generated code can already do
the right thing.
Task-number: QTBUG-119885
Change-Id: I13e517967ee982be717024a9abb74d5e02a185d6
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
If the type conversion code fails to convert an argument, we still need
to make sure the argument has a definite value. Otherwise we may trigger
undefined behavior somewhere down the line. Furthermore, we want to look
at the precise type when converting list properties. Otherwise we get a
list property without any methods back when converting.
Pick-to: 6.7 6.5 6.2
Change-Id: I012c0360ef1578c768362d5a4648252d3e6803d8
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
| |
Use QHash/QMap's constFind() instead of non-const find() where
applicable to avoid unnecessary detaches.
Change-Id: I6b31af1d163d11deb229681ff7e2f6c9f8335d8c
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
|
| |
Change-Id: Ieb108a84f5c1fefe813ac0af6c2ca9332fdbefe8
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Commit b9bfdea0e2c6721d2306af0ecc44f88da9988957 removed specialized
code for QVariantList conversions by relying on sequences instead.
Some checks for sequences and other array-like containers were missed.
Add those and perform all calls to QJsonObject::toJsonArray through a
common QV4::Object interface.
Amends b9bfdea0e2c6721d2306af0ecc44f88da9988957
Pick-to: 6.7
Fixes: QTBUG-123993
Change-Id: Ia671d556af4f2b4d44f652fa93182977d88621f2
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
|
|
|
|
|
| |
There might be potential extra QList detach due to the use of non-const
QList iterators in UrlSearchParamsPrototype::method_delete(). To avoid
this, we can use QList::removeIf() which doesn't detach if there is
nothing to remove and also makes the code a bit clearer.
Change-Id: Ia4d2d2d0ac2d1dc4b08ed0b34b701bab7bca6250
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
|
|
|
|
| |
This way qmltyperegistrar can recognize it and refrain from warning
about it.
Task-number: QTBUG-101143
Change-Id: I598140e7e90dbd3e27a78c26eff3d46f0fd3e989
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
| |
The root node of a sparse array can be null.
Pick-to: 6.7 6.5 6.2 5.15
Fixes: QTBUG-123596
Change-Id: I5ea7fd73aeec460082d0cf19c7fc8a01993ed1f9
Reviewed-by: Semih Yavuz <semih.yavuz@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
| |
Fixes a heap-buffer-overflow issue in ESTable::remove due to an off by
one error in the count provided to memmove calls.
Task-number: QTBUG-123999
Pick-to: 6.7 6.5 6.2 5.15
Change-Id: I4ee0fbc16ba8936ea921e5f1d1bb267dae0b1d5f
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When setting values on a newly allocated Array- or MemberData,
d7aa952e143accc18d54707d956d019272197078 made the assumption that it is
safe to skip the write-barrier, as the new values would be marked when
the "values" member would be written to (pushing the new data on the
mark stack, and then later marking all objects stored in values when it
gets popped and markObjects runs).
Now that we no longer do black allocations, this actually holds true.
Add a unit test to verify it.
Task-number: QTBUG-119274
Task-number: QTBUG-121910
Change-Id: Ia1ceeaffeaf30dc1fb2b9e1992dd0b599050294c
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Semih Yavuz <semih.yavuz@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
With the current setup, we would have risked running out of native heap
space if the incremental garbage collection takes too long.
Remedy this by forcing the current gc run to complete immediately once
we overshoot the limit by a factor of 3/2.
We still need to respect that the gc must not run in a critical section:
Handle this by rechecking the condition when leaving the critical
section, and only forcing a gc run at that point if necessary.
Note that we currently update the gc limits before the gc cycle
finishes, so that the effective limit might actually not be 3/2 in that
case. This will be remedied in an upcoming patch.
Change-Id: I19c367bd1ff6ffc129293fc79e39b101f0728135
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
ExecutableCompilationUnits are meant to be part of the roots as far as
the gc is concerned. However, they can be created at any point in time,
notably also while the GC is running. This was safe so far because all
allocations are black, and the compilation unit will only reference
freshly allocated heap items. As we want to move away from that pattern,
we have to change this:
We could use the typical combination of QV4::Scope and usage of the
WriteBarrier, however that would add overhead for a very uncommon case
(except when using QV4_MM_AGGRESSIVE_GC). Instead, we temporarily block
the garbage collection, reset the state of an ongoing garbage collection
and at the end of the setup of the ExecutableCompilationUnit, we mark
the ExecutableCompilationUnit if the GC was already running.
Introduce a new blocked state (CriticalSection) to distinguish between
the normal blocked state (gc is running) and the new state where we must
not even run an incremental gc to completion until the section has
finished.
Task-number: QTBUG-121910
Change-Id: I1dba3cc8a4f8d2b741a1a5e84fdfe7736b08e166
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Prevent QObjectWrapper from being gced - if we use white alloctations,
and the weak values have already been marked, then nothing will mark the
newly created QObjectWrapper. Use a helper function which takes care of
the marking, and call it in the appropriate places. Also mark the normal
wrap and wrapConst functions as [[nodiscard]] to avoid this issue from
resurfacing in the future, and adjust a few call-sites to also call
ensureWrapper.
Change-Id: I8d4c73ae62b61d21b1456a3b096fc6a42f302160
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We temporarily forbid the GC from running before global object is setup,
as our root set marking would otherwise run into issues in incremental
mode (we don't revisit roots, and roots don't generally employ write
barriers, so we might miss internal classes referenced by the global
object). The GC would normally never run while the engine's constructor
has not completed, however this does not hold true when
QV4_MM_AGGRESSIVE_GC is enabled.
Task-number: QTBUG-121910
Change-Id: I08360005f66bb6e6a36da2e16704093398f0d154
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|