Remove all code that supported converting between JS RegExp's and
QRegExp, as QRegExp is going away in Qt6.
Change-Id: I4863e68dd87a337d7e836d1b26c28ee3bb914e9f
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
This class is not a private detail of QQmlContext. And it is incredibly
hard to see who owns what in there. Let's add some civilization ...
We enforce refcounting for QQmlContextData across the code base, with
two exceptions:
1. QQmlContextPrivate may or may not own its QQmlContextData.
2. We may request a QQmlContextData owned by its parent QQmlContextData.
For these two cases we keep flags in QQmlContextData and when the
respective field (m_parent or m_publicContext) is reset, we release()
once.
Furthermore, QQmlContextData and QQmlGuardedContextData are moved to
their own files, in order to de-spaghettify qqmlcontext_p.h and
qqmlcontext.cpp.
When the QQmlEngine is deleted, any QQmlComponents drop their object
creators now, in order to release any context data held by those.
Before, the context data would be deleted, but the object creators would
retain the dangling pointer.
[ChangeLog][QML][Important Behavior Changes] QQmlContext::baseUrl() does
what the documentation says now: It prefers explicitly set baseUrls over
compilation unit URLs. Only if no baseUrl is set, the CU's URL is
returned. It used to prefer the CU's URL.
Change-Id: Ieeb5dcb07b45d891526191321386d5443b8f5738
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Being careful, we can now save primitive values inline. We use the heap
pointer of QV4::Value as either QString* or QV4::Value* for complex
types. We cannot store persistent managed QV4::Value without the double
indirection as those need to be allocated in a special place.
The generic QVariant case is not supported anymore. The only place where
it was actually needed were the stream operators for QJSValue. Those
were fundamentally broken:
* A managed QJSValue saved and loaded from a stream was converted to a
QVariant-type QJSValue
* QVariant-type QJSValues were not callable, could not be objects or
arrays, or any of the special types.
* Cyclic references were forcibly broken when saving to a data stream.
In general the support for saving and loading of managed types to/from
a data stream was so abysmally bad that we don't lose much by dropping
it.
[ChangeLog][QML][Important Behavior Changes] When saving a QJSValue to a
QDataStream only primitive values or strings will be retained. Support
for objects and arrays was incomplete and unreliable already before. It
cannot work correctly as we don't necessarily have a JavaScript heap
when loading a QJSValue from a stream. Therefore, we don't have a proper
place to keep any managed values. Using QVariant to keep them instead is
a bad idea because QVariant cannot represent everything a QJSValue can
contain.
Fixes: QTBUG-75174
Change-Id: I75697670639bca8d4b1668763d7020c4cf871bda
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This is needed in a few places outside of declarative, so this change
restores the loc member in DiagnosticMessage and moves
QQmlJS::AST::SourceLocation into common's QQmlJS namespace/directory.
QQmlError is unaffected and retains only line/column.
Amends d4d197d062
Change-Id: Ifb9d344228e3c6e9e26fc4fe112686f9336ea2b2
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Instead of applying a heuristic on when to call drain() in unrelated
code, we check the stack limit on each push(). If the soft limit is
reached we try to drain. As drain() itself can push again, we try to
limit the stack size by allowing at most 65 recursions of drain(). If
none of that helps, we crash with a meaningful error message.
This allows us to remove all the hacky drain() calls in other parts of
the code.
Change-Id: Ib979339470da0e85981de8131e7997755b757c71
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
The previous attempt to fix this was lost in a merge resolution.
Change-Id: I0638c434543d231352c44687b06bf429b7be7a04
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
If the provided typeHint is -1, it does not make sense to construct a
QVariant of this type and to check whether it is appendable.
Fixes: QTBUG-81945
Change-Id: I32cbb9e70e210a7eca8d55801c1783338d1173b7
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
We started to convert containers to QJSValues, so that we could use them
as JavaScript arrays. Unfortunately, this would then lead to a type missmatch
when those same values where to be stored in a property of the container
type. This commit fixes this by converting them back to the original
type.
Fixes: QTBUG-80916
Change-Id: I30a3b03e17c34b171d4a6881dfd7801c13e94d80
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
[ChangeLog][QtQml] Added Qt.uiLanguage and QJSEngine::uiLanguage properties
These properties mirror the same value in QML and C++ and can be used
freely. They also provide API symmetry to Qt for MCUs.
QQmlApplicationEngine binds to this property and applies translations
accordingly by constructing a QLocale with the value and using
QTranslator::load(locale).
Change-Id: Id87d6ee64679b07ff3cb47844594e8eeebd8c8b6
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Christian Kamm <mail@ckamm.de>
as type is going to be deprecated.
This change was done automatically with the help of clazy.
In addition, ColumnRoleMetadata was changed to take an int instead
of a QVariant::Type
Change-Id: Ibc02d7b52e7d931a56c19fdebc4788b5e6df2a39
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
MemoryManager::collectFromJSStack did push to the mark stack without
checking if there is actually still space available. To fix this, we now
drain the stack once we hit the limit.
The test case is a slightly modified version compared to the reported
one, removing one loop. This was required as our regular expression does
not throw an exception when there are too many capture groups. However,
to trigger the bug, looping was not actually necessary.
Change-Id: I4d00865f25a989c380f4f5b221f4068c80b71d2b
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
In XMLHttpRequest, we need to get the QNetworkAccessManager from the
engine. However, if the request originates from a WorkerScript, there
exists no qmlEngine. We therefore add a new indirection to access the
QNAM, and set it up accordinly in registerWorkerScript.
Fixes: QTBUG-81055
Change-Id: I8915202b6d6b7139c8386304b3d1d7a22a82045e
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
8704c64094 introduced new conversions
via sequentialIterableToJS. Due to that, QVariant properties which
formerly stored e.g. std::vector<QObject*> now would store a QJSValue.
Those would still claim to support a conversion to QVariantList, but
-contrary to what our documentation says-, we were not able to do a
conversion to QSequentialIterable. The default constructed
QSequentialIterable would then crash when calling begin(), as that
function pointer was null.
This patch fixes this by adding the necessary support to convert a
QJSValue containing an array.
Non-array QJSValues will still return an "empty" QSequentialIterable.
Note that this changes what happens when a QJSValue is converted to a
QVariantList, as QVariantValueHelperInterface<QVariantList> will check
first if there is a converter to QSequentialIterableImpl before
attempting to call any directly installed converter to QVariantList. In
order to not change the existing behavior, the QSequentialIterable
returns the QVariant corresponding to the QJSValue at a given array
position, intead of a QVariant containing the QJSValue.
Fixes: QTBUG-80609
Change-Id: I8101229c0d2043b3f2d618ed035b279844802dd8
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
With QV4_CRASH_ON_STACKOVERFLOW set you can use up all the stack
provided by the operating system to parse and execute JavaScript. Once
the stack space is exhausted the program crashes like it would in case
of a C++ stack overflow.
We cannot reliably determine either the maximum stack size or the amount
of stack space currently in use at runtime. Therefore, the guards we
usually put in place are necessarily conservative.
[ChangeLog][QtQml] There is now an option to disable the (necessarily)
conservative stack size checks when parsing and executing JavaScript. If
the environment variable QV4_CRASH_ON_STACKOVERFLOW is set, JavaScript
stack overflows crash the program the same way C++ stack overflows do.
On the flip side, more stack space is made available that way.
Task-number: QTBUG-74087
Change-Id: I5e9d9ec6c0c9c6258c31d9e2d04a5c1819fbf400
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Added the missing lookup for cached .mjs files in
ExecutionEngine::compileModule. This allows using .mjs files in
WorkerScript {} elements in conjunction with the Qt Quick Compiler and
also fixes the use when using QJSEngine::importModule.
[ChangeLog][QtQml] Fix loading of EcmaScript modules when using the Qt
Quick Compiler.
Fixes: QTBUG-77761
Change-Id: I58130b0468f4920b2f6c49b98a2f51d5ae3a0491
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
QMLEngine by default allocates 4 MB for javascript stack and garbage
collection stack takes 2 MB. It is a lot of memory for platforms without
virtual memory.
Change-Id: I1575dd9584898dca33df66704f716c7b5a7c01c1
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
We only need two classes to describe all possible diagnostics:
* A low-level private POD DiagnosticMessage. This is easily copied and
passed around internally. It doesn't need to adhere to a stable API
and it doesn't carry any extra baggage.
* The high-level public QQmlError with its stable interface. This can
internally also use a DiagnosticMessage as storage.
Change-Id: I52be88d9b5d9855a661b8032b01eedb43a0fb0b3
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
I've never seen it used and I've never seen the companion library
required to operate it.
Change-Id: I5a0e6aed9a416f1bd26dea97def9667a11a4d77d
Reviewed-by: Robin Burchell <robin.burchell@crimson.no>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Michael Brasser <michael.brasser@live.com>
They all had some interesting bugs and duplicated each other:
a, propertiesFrozen() changed each property individually, creating a lot
of unnecessary intermediate classes. frozen() changed them all at once.
b, If a class happened to contain only properties that matched the
characteristics of being "sealed" or "frozen", sealed(), frozen() and
propertiesFrozen() would set the flags in place and return the same
class. This is bad because it violates the assumption that an
InternalClass is immutable and it breaks the recursive freezing
algorithm we rely on for the global object. It would stop freezing child
objects at any such class, even if the children were not frozen.
c, propertiesFrozen() did not set any of the flags even though it
effectively sealed and froze the class. Therefore, when requesting the
same class as frozen() it would iterate through all the properties
again.
d, frozen() implicitly also sealed the object and made it
non-extensible. sealed() also implicitly made it non-extensible. This is
impractical as we want to allow objects to be extensible even though all
their properties are frozen. Therefore we only set the flag that belongs
to each method now. We do know, however, that a frozen object is
implicitly sealed. Therefore we can short-circuit this transition.
Furthermore, we need to remove the assert in InternalClass::init() as
you can indeed use frozen objects as prototypes for others, but that
needs to be recorded in the original InternalClass via the isUsedAsProto
flag. In order to set this flag, we need to perform a transition and
therefore, derive from the old InternalClass.
The JavaScript isFrozen() method asks for an _implicitly_, "duck typed",
frozen state, which is different from what our "isFrozen" flag denotes.
Therefore we add a separate const method that just checks whether all
properties are frozen.
Task-number: QTBUG-76033
Change-Id: I375fef83fb99035d470490fdf2348766b090831e
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
We need a CompilationUnit that only holds the data needed for
compilation and another one that is executable by the runtime.
Change-Id: I704d859ba028576a18460f5e3a59f210f64535d3
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This is a better fit for the method. In turn, remove all the
V4_BOOTSTRAP conditions from qv4engine_p.h and make sure we don't
include or compile it in bootstrap mode.
Change-Id: I5933b0724e561313ca20c420b83e4d70e63bddf5
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
For clang we need to use has_feature to detect the presence of an ASAN
build. Amends commit eb363c3a0b
Task-number: QTBUG-75410
Change-Id: I2adb69deb07f8c6b77be8c2f23751fd0a2bbdb95
Reviewed-by: Erik Verbruggen <erik.verbruggen@me.com>
The tracing JIT won't be finished. Therefore, remove the parts that have
already been integrated.
Change-Id: If72036be904bd7fc17ba9bcba0a317f8ed6cb30d
Reviewed-by: Erik Verbruggen <erik.verbruggen@me.com>
ASAN enabled builds require more stack space and therefore our call
depth limits should be lower.
In my measurements with a recursion through arrow functions with the
interpreter, as per the test case in the bug report, different types of
builds require different amounts of stack space. On x86-64 Linux, I
measured, by printing $rsp and subtracting:
Debug: ~6k
Debug with -Og: ~590 bytes
Release with -O2: ~570 bytes
Release (-O2) with ASAN: ~40k
Fixes: QTBUG-75410
Change-Id: I403b261c677b1adb9f349958339b5a1294ae4d5d
Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
This way you can enable or disable the JIT when configuring Qt. The
conditions for the availability of the JIT have also been cleaned up.
There is no reason anymore to artificially restrict availability on x86
and x86_64. The reason for the existence of those clauses are old
problems on windows that have been fixed by now. However, on arm and
arm64, we need a specialization of the cacheFlush() function for each OS
to be supported. Therefore, restrict to the systems for which such a
specialization exists. iOS and tvOS are technically supported and you
can enable the JIT via the feature flag now. Due to Apple's policy we
disable it by default, though.
Change-Id: I5fe2a2bf6799b2d11b7ae7c7a85962bcbf44f919
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Technically UINT_MAX is actually a valid array index, although that is
an academic problem right now. However, we do have a method
isArrayIndex() and should just use that to determine if a PropertyKey is
an array index.
Fixes: QTBUG-73893
Change-Id: I302e7894331ed2ab4717f7d8d6cc7d8974dabb4e
Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
Those are "scarce" resources which need to be kept as QVariant.
Fixes: QTBUG-74751
Change-Id: I28381e2a754ed4bbf4e409dc275f6288b64416cc
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This makes the use of the feature easier and lowers the dependency
on setup of internal structures.
Also, evaluation of expressions is notoriously expensive and unreliable
on the gdb side, so moving the complexity to the compiled side is
an advantage.
Task-number: QTCREATORBUG-22209
Change-Id: Id43d5c2bf4d852d496ceb59189209d167213afcb
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>