aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4engine_p.h
Commit message (Collapse)AuthorAgeFilesLines
* QJSEngine: Trim compilation units after evaluating a programOlivier De Cannière2025-03-121-1/+2
| | | | | | | | | | | | | | | Not doing so might lead them to accumulate until the js engine is destroyed. We only trim compilation units with the final url that was passed in to evaluate. This way, we prevent accumulation while also preserving compilation units from actual files. Fixes: QTBUG-132931 Pick-to: 6.9 6.8 Change-Id: Ie4f09287e293075de4940ced6146a862c4da3b5b Reviewed-by: Ulf Hermann <[email protected]> Reviewed-by: Fabian Kosmale <[email protected]>
* QtQml: Cache configuration parameters in type loaderUlf Hermann2024-12-191-1/+1
| | | | | | | | | | | | | | | | | | | | | The type loader should not access the engine from its thread. The configuration values about debugging and cache modes are mostly constant, except for the case where a debug client attaches later, when the engine is already running. Attaching a debugger or preview service without blocking the engine is generally a bad idea because part of the application will already have been loaded when the service is attached. That means some files will not be replaced by the preview service and some files will run without debug instructions, making it impossible to set break points. To allow for the maximum flexibility, we read the configuration values right before starting the thread. Since the thread is started on demand, this is actually the last moment when we can safely do so. Task-number: QTBUG-131721 Change-Id: Ida9039a5726a81c610bc96e5f473bd0875b74cd1 Reviewed-by: Fabian Kosmale <[email protected]>
* QtQml: Generalize the global/illegal namesUlf Hermann2024-12-171-4/+0
| | | | | | | | | Instead of passing them around everywhere, use the ones we statically know and only validate them when creating a new engine. Task-number: QTBUG-131721 Change-Id: I7fb93d15eb6e4194c46249727bcf7a48f5dce730 Reviewed-by: Fabian Kosmale <[email protected]>
* QtQml: Initialize ExecutionEngine members inline where possibleUlf Hermann2024-12-121-18/+18
| | | | | Change-Id: Ie343db2be7d3bdd15e5967f14f810bea03831923 Reviewed-by: Sami Shalayel <[email protected]>
* QtQml: Add some consistency to QV4::RegExpUlf Hermann2024-12-121-11/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | The RegExp JIT should behave the same as the V4 JIT. In particular, it should honor the same JIT call threshold and not second guess any manually set thresholds. To do this we need to store the match count in 32 bits. In turn we can store the 5 flags we may have in 8 bits. To make this safe, pass typed flags to the initialization functions. Also, consider the flags when calculating hash values. Finally, in the init() function, we don't need to initialize members to zero, since that is already guaranteed by the memory manager. And we can delete the flagsAsString() method since it's unused. This requires shuffling some #includes into the places where they actually belong. [ChangeLog][QtQml] The JavaScript regular expression engine now honors QV4_JIT_CALL_THRESHOLD for its own JIT. If QV4_JIT_CALL_THRESHOLD is not set, it uses the JIT after 3 interpreted matches for any regular expression, rather than the previous 5. Matching a regular expression on a string longer than 1024 bytes counts as 3 matches. This is to retain the default behavior of JIT'ing regular expressions right away when encountering long strings. Task-number: QTBUG-131957 Change-Id: I269ccea55d34b191ef18d7cd5fccd4cad8aec7cd Reviewed-by: Sami Shalayel <[email protected]> Reviewed-by: Fabian Kosmale <[email protected]>
* QtQml: Model native modules as compilation unitsUlf Hermann2024-12-061-21/+2
| | | | | | | | | | | | | | | | | | | | | | | QQmlTypeLoader::injectedScript() was unsafe and impossible to fix because it had to query the engine from the type loader thread in order to find out whether to load a script from an actual file. By removing the whole special-casing of native modules, we can make the script loading thread safe. A native module is now also a compilation unit, with a regular QV4::Module as value. This means we can remove a lot of code that deals with the native modules in the engine. The downside is that native modules are now a lot larger than before. However, given that they don't appear in any examples and hardly any bugs have been filed about native modules since their introduction, we can assume that they are not a very popular feature. The reduction in complexity and the removal of the native modules map in the engine is expected to outweigh the extra memory overhead for native modules. Task-number: QTBUG-131721 Pick-to: 6.8 Change-Id: Ia7388d7ba8d71637559a791d874257fba4646330 Reviewed-by: Fabian Kosmale <[email protected]>
* Implement read/write-backs for QVariantMap and QVariantHashLuca Di Sera2024-12-011-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When QML receives something from the C++ side, it, sometimes, tries to set up a read/"write-back" mechanism to allow changes on the QML side to be reflected on the C++ side and changes to the original element being synchronized with the QML side. This can happen, for example, when accessing a property of a C++ object that was registered to QML directly from QML. Similarly, it can do so when nesting some of its internal representation of an object with C++ provenance. For example, a `QVariantList` that is passed to the QML side and converted to a `Sequence` type might require some of its stored element to perform a write-back when accessed and modified to ensure that mutations are permanent. For `QVariantMap` and `QVariantHash` this was currently not implemented, with `QVariantMap` being generally converted to a Javascript object and support for `QVariantHash` not necessarily entirely implemented. This can produce surprising results. For example, a `QVariantMap` that is stored in a `QVariantList`, where the list is passed over to the QML side from the C++ side, might incur into its mutations being lost when accessed as a member of the converted `QVariantList`. To ensure that this does not happen, `QVariantMap` and `QVariantHash` will now be converted to a representation that is a `ReferenceObject`, that is, it uses the general read/write-back mechanism in QML. Introduce a new QV4 Object, `VariantAssociationObject`, that can store either a `QVariantMap` or a `QVariantHash` and has read/write-back behavior. The prototype for the object is now registered by the engine and can be accessed through the `variantAssociationPrototype` method. A `QVariantMap`/`QVariantHash` that is being converted to a JS representation will now be converted to the newly introduced object instead of being mapped to a generic JS object. `variantMapToJS` and `variantToJs` in "qv4egnine.cpp", that were used during the conversion of `QVariantMap` to a Javascript object were removed as they are now unused. Some additional cases were added to support conversion from/to `QVariantHash` and conversion from the newly added object. The newly added object supports a small subset of an object functionality and is not intended, at least currently, to support the whole breadth of interactions that a Javascript object would. In particular it aims to support setting properties, retrieving properties, deleting properties, basic iteration and `Object.hasOwnProperty`. It further implements basic read/write-back behavior for those interactions and allows for recursive read/write-backs through the general `virtualMetacall` interface. Additionally, the code `QQmlVMEMetaObject::writeVarProperty` was modified to ensure that the new reference object is detached when assigned to a `var` property, so as to be consistent with the general behavior of the other reference objects. As a drive-by, a comment in the above code that stated that some of the code should be adjusted if a new case was added to it was modified to state that the code should be adjusted with no additional clause, as a new element was added but the adjustment will not be performed as part of this patch. Some general test cases were introduced in `tst_qqmllanguage` for the new object. In particular to test the most basic interactions of the above subset of an object interaction, some of the read/write-back behavior and the behavior of detached when being assigned to a var property. Fixes: QTBUG-129972 Change-Id: Ib655ba6001aef07a74ccf235d2e3223b74d7be59 Reviewed-by: Fabian Kosmale <[email protected]>
* QtQml: Move amendException into ExecutionEngineUlf Hermann2024-10-091-0/+2
| | | | | | | | We'll need it in more places. Change-Id: I8dc23a4b8ee873c0b8e84b3aed9872d48959a021 Reviewed-by: Olivier De Cannière <[email protected]> Reviewed-by: Fabian Kosmale <[email protected]>
* QtQml: Disable AOT compiled code when QML-previewingUlf Hermann2024-09-271-0/+2
| | | | | | | | | | | 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 <[email protected]>
* QtQml: Decouple JavaScript library CUs from enginesUlf Hermann2024-09-201-0/+8
| | | | | | | | | | | | | | | | | | | | | | | | 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 <[email protected]>
* QtQml: Never clear all executable CUs from the QQmlEngineUlf Hermann2024-09-101-1/+0
| | | | | | | | | | | | | | | | | 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 <[email protected]>
* QtQml: Let QQmlTypeWrapper act as a constructor for its typeUlf Hermann2024-05-231-0/+2
| | | | | | | | | | | | | | 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 <[email protected]>
* QtQml: Add a wrapper builtin for QQmlV4Function*Ulf Hermann2024-04-121-1/+1
| | | | | | | | | This way qmltyperegistrar can recognize it and refrain from warning about it. Task-number: QTBUG-101143 Change-Id: I598140e7e90dbd3e27a78c26eff3d46f0fd3e989 Reviewed-by: Fabian Kosmale <[email protected]>
* Prepare for white allocation during gc (0/9): EngineFabian Kosmale2024-03-051-5/+1
| | | | | | | | | | | | When inserting compilation units into the engine, we don't have any write barrier, as those are treaded as roots. However, we still have to be careful when an executable compilation unit is created while the gc is already ongoing. Thus, when we insert a CU into the engine, we mark it. Change-Id: I5e7c7e9518190dd6943cf57b0a82229d6be8d3b9 Reviewed-by: Ulf Hermann <[email protected]> Reviewed-by: Olivier De Cannière <[email protected]>
* QtQml: Use a multihash to store executable CUsUlf Hermann2024-01-251-2/+11
| | | | | | | | | | | | | | | You can produce multiple CUs for the same URL with createQmlObject() and friends. They need to be marked during garbage collection and therefore the engine needs to keep track of them. With the multihash there can be a lot of CUs of the same URL. Searching through them can take a lot of time. However, there is no point in searching for an existing executable CU if we've just freshly compiled the base CU. So, in those cases, insert directly instead. Fixes: QTBUG-121436 Change-Id: I804dbc74d2ade118f6680a7fbde3f234699ccbc3 Reviewed-by: Fabian Kosmale <[email protected]>
* QtQml: Use CompiledData::CompilationUnit in more placesUlf Hermann2024-01-201-9/+8
| | | | | | | | | | We rarely actually need the executable CU, and where we need it, we can dynamically create or retrieve it from the engine. To that end, store all the CUs in the same container in the engine. Change-Id: I0b786048c578ac4f41ae4aee601da850fa400f2e Reviewed-by: Qt CI Bot <[email protected]> Reviewed-by: Fabian Kosmale <[email protected]>
* QtQml: Move creation of ExecutableCompilationUnit into engineUlf Hermann2024-01-111-1/+9
| | | | | | | This is in preparation for letting the engine cache the executable CUs. Change-Id: Ideac10d8dda0784b41304b58f9b9fbd106173ea6 Reviewed-by: Fabian Kosmale <[email protected]>
* QtQml: Remove QQmlTypeLoader from QQmlImportUlf Hermann2024-01-111-0/+9
| | | | | | | | | The type loader belongs to the engine and we must not store it in engine-independent data structures. We do want the import cache to be stored in the type registry, though (in a separate change). Change-Id: I2828f5098b27bf1fc96852fc2bd160db44b109e7 Reviewed-by: Fabian Kosmale <[email protected]>
* QtQml: Get rid of the module mutexUlf Hermann2024-01-101-1/+0
| | | | | | | | | | | | | It only exists so that the type loader can query pre-compiled and native modules from the loader thread. However, the type loader already has a mutex of its own. We can use that to inject a "native" blob into its script cache for the same effect. We need to get rid of the mutex so that we can use the module map for other compilation units, too. Change-Id: I5a9c266ea36b50f5ea69214110def644f7501674 Reviewed-by: Fabian Kosmale <[email protected]>
* QJSValue: convert more aggressively to QVariantFabian Kosmale2023-12-191-0/+1
| | | | | | | | | | | | | | | | | | | | | | | Normally, we don't want to convert aggressively between JS objects and QVariant, as that is prone to losing information. However, QJSValue::toVariant is documented to attempt lossy conversions. Restore the behavior of Qt < 6.5.3 for it. This is done by replacing the boolean indicating we should wrap JS objects into QJSValue with an enum instead. That enum introduces a third state ("Aggressive"), which is only used for QJSValue::toVariant. All other users of QJSEngine::toVariant behave as before (post 6.5.3). Function objects are still not converted, as we know that this would be a futile attempt, and more importantly, to keep the behavior that existed before Qt 6.5.3. Amends 43077556550c6b17226a7d393ec844b605c9c678 which introduced the regression and afe96c4d633146df477012975824b8ab65034239 which fixed the issue only partially. Pick-to: 6.5 6.6 6.7 Fixes: QTBUG-119963 Change-Id: I07d9901437812579ac5b873a4dff4de60c8f617e Reviewed-by: Ulf Hermann <[email protected]> Reviewed-by: Qt CI Bot <[email protected]>
* QtQml: Optimize reading properties into V4 valuesUlf Hermann2023-11-151-0/+1
| | | | | | | | | | | | | | | We need to be more careful here since the builtins will become proper value types with metaobjects, but we don't want to encode them into QQmlValueTypeWrapper, but rather their specialized representations. Besides, avoiding the code path via QVariant and engine->fromVariant() is also a performance boost. Task-number: QTBUG-101143 Change-Id: I1c570ebcb6c4e129e9bdeef069b8a49e2a1e29d6 Reviewed-by: Qt CI Bot <[email protected]> Reviewed-by: Olivier De Cannière <[email protected]> Reviewed-by: Semih Yavuz <[email protected]> Reviewed-by: Fabian Kosmale <[email protected]>
* QML: Allow conversion of symbols to QVariantUlf Hermann2023-06-201-1/+1
| | | | | | | | | | | We produce their descriptiveString or simply a QVariant containing a QJSValue, depending on whether we're supposed to convert objects without equivalent C++ type or not. Pick-to: 6.6 6.5 6.2 Fixes: QTBUG-113854 Change-Id: I22b6038c936d860fdd8aa227f9dfe704e3265a77 Reviewed-by: Fabian Kosmale <[email protected]>
* Move ScopedStackFrame into qv4stackframe_p.hUlf Hermann2023-05-171-12/+18
| | | | | | | | | | | This is where it belongs. We need to apply some tricks to avoid cyclic includes, but that's better than what we have so far. Also, sort and clean up the includes in the affected files. Change-Id: Ia7a957d06c0ca284045d831417740c3f9920bc92 Reviewed-by: Fabian Kosmale <[email protected]> Reviewed-by: Qt CI Bot <[email protected]>
* QML: Fix write back of Date valuesUlf Hermann2023-01-171-3/+5
| | | | | | | | | | A JavaScript Date object can be backed by QDate, QTime or QDateTime. Allow those to be written back. Pick-to: 6.5 Fixes: QTBUG-28981 Change-Id: Ic46b5c4daf75453f03e99470933cf179820e63ef Reviewed-by: Sami Shalayel <[email protected]>
* QtQml: Allow more fine grained control of the disk cacheUlf Hermann2023-01-021-1/+17
| | | | | | | | | You can now enable and disable the AOT-compiled code and the loading and saving of .qmlc files separately. Fixes: QTBUG-101358 Change-Id: I1305c4f2f75d8cff544a127e956589d1ed1aeb52 Reviewed-by: Fabian Kosmale <[email protected]>
* QmlCompiler: Fix wrapping of numbers in QJSPrimitiveValueUlf Hermann2022-12-151-0/+19
| | | | | | | | | | | | | | | | | | We need to explicitly cast to double if we are wrapping a number type that's not natively accepted by the ctors. As a side effect, correctly run conversions from generic QVariant to QJSPrimitiveValue through the engine now. For that we need another clause in metaTypeFromJS(). Since we are calling methods that return list types in the test, we need to add another clause that converts JS arrays to list types. Otherwise we cannot run that test in interpreted mode. Pick-to: 6.5 6.2 6.4 6.4.2 Task-number: QTBUG-109111 Change-Id: I87f7aafd24371d2c1ffe85569e1f2cd3a1979742 Reviewed-by: Fabian Kosmale <[email protected]>
* QML: Add an accurate stack bounds checkerUlf Hermann2022-12-091-5/+59
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This re-introduces a stack bounds checker. The previous stack bounds checker was removed in commit 74f75a3a120b07bbfe6904512b338db8850874e4 because the cost of determining the stack base was deemed too high. Indeed, determining the stack base on linux using the pthread functions costs about 200.000 instructions and the cost grows with the number of concurrently running threads. However, by reading /proc/self/maps directly we can trim this to about 125k instructions. Furthermore, with the new implementation we only need to do this once per engine. Calling JavaScript functions of the same engine from different threads is not supported. So we don't have to consider the case of checking the bounds of a different thread than the one the engine was created in. Furthermore, we get a more accurate number now, which means we don't have to re-check when we get near the boundary. Also, change QV4::markChildQObjectsRecursively() to use an actual QQueue instead of being recursive. This avoids the stack from overflowing when the stack is already almost full, and was leading to crashes in the stackOverflow tests. Make the stack smaller for the the tst_qquickloader::stackOverflow{,2} tests to run faster in the CI (and avoid the timeout). Task-number: QTBUG-106875 Fixes: QTBUG-108182 Change-Id: Ia5d13caa7d072526ff2a3e1713ec7781afc154a9 Reviewed-by: Fabian Kosmale <[email protected]>
* QJSEngine: Provide a method to coerce values in JS fashionUlf Hermann2022-11-151-3/+4
| | | | | | | | | | | JavaScript has its own type coercion rules. We already have a methods that coerce QVariants, QJSValues and QJSManagedValues to specific types. The new method is a generalization of all of those and can coerce everything to everything (as far as JavaScript can). Change-Id: I9b6877fb40f67b6f2354781bbd4cf18cf996c7b0 Reviewed-by: Sami Shalayel <[email protected]> Reviewed-by: Fabian Kosmale <[email protected]>
* QML: Check for stack overflows when creating objectsUlf Hermann2022-11-111-2/+8
| | | | | | | | Pick-to: 5.15 6.2 6.4 Fixes: QTBUG-106875 Change-Id: I3b0abda6948b79a9e3cf263f27885037fff1804c Reviewed-by: Fabian Kosmale <[email protected]> Reviewed-by: Sami Shalayel <[email protected]>
* Recursively write back value types and sequencesUlf Hermann2022-10-191-1/+5
| | | | | | | | | | | | | | | | | Both types have functionality to write themselves back to the properties they were loaded from on change, but so far we could not nest those writes. [ChangeLog][QtQml] You can now assign to properties of nested value types and to elements of containers from QML functions. You cannot, however, take references of such values and elements. This is in contrast to non-nested value types and the containers themselves. However, passing references of value types and containers around generally leads to very confusing effects. Don't do this. Fixes: QTBUG-99766 Change-Id: I74cb89e5c3d733b0b61e42969d617b2ecc1562f4 Reviewed-by: Fabian Kosmale <[email protected]>
* QV4: Avoid memory corruption in Reflect.applyFabian Kosmale2022-10-131-0/+1
| | | | | | | | | | This extracts the check from Function.prototype.apply into a shared function, and uses it in Reflect.apply, which has the same issue. Pick-to: 6.4 6.2 5.15 Task-number: QTBUG-107619 Change-Id: I899464c86554f9bbb5270a95bbe3fe27531e9a27 Reviewed-by: Ulf Hermann <[email protected]>
* Port from container::count() and length() to size()Marc Mutz2022-10-071-1/+1
| | | | | | | | | | | | | | | | | | | | This is a semantic patch using ClangTidyTransformator as in qtbase/df9d882d41b741fef7c5beeddb0abe9d904443d8: auto QtContainerClass = anyOf( expr(hasType(cxxRecordDecl(isSameOrDerivedFrom(hasAnyName(classes))))).bind(o), expr(hasType(namedDecl(hasAnyName(<classes>)))).bind(o)); makeRule(cxxMemberCallExpr(on(QtContainerClass), callee(cxxMethodDecl(hasAnyName({"count", "length"), parameterCountIs(0))))), changeTo(cat(access(o, cat("size"), "()"))), cat("use 'size()' instead of 'count()/length()'")) a.k.a qt-port-to-std-compatible-api with config Scope: 'Container', with the extended set of container classes recognized. Change-Id: Idb1f75dfe2323bd1d9e8b4d58d54f1b4b80c7ed7 Reviewed-by: Fabian Kosmale <[email protected]>
* V4: Drop extra QVariant parameter from fromData()Ulf Hermann2022-10-071-3/+4
| | | | | | | | The data needs to be copied anyway if we are going to store it in ScarceResourceObject. We can just as well copy it from the void pointer. Change-Id: Ic106221138b1236a6ddea20cfdb468c6fbe3e1c3 Reviewed-by: Fabian Kosmale <[email protected]>
* V4: Use an enum to categorize functions and rename aotFunctionUlf Hermann2022-09-291-1/+2
| | | | | | | | We want to use the aotFunction member also for typed JavaScript functions. Change-Id: Iad6d12ebed3ad3069832484137ed8e4d9e7a7cf4 Reviewed-by: Fabian Kosmale <[email protected]>
* V4: Make ExecutionEngine::toVariant() staticUlf Hermann2022-09-201-2/+3
| | | | | | | | | Wherever we need an engine in there, we also have a managed value to get it from. This relieves us from the requirement to drag an engine around wherever we want to call toVariant(). Change-Id: Ib95d02b5fbf5eaa494214e337c9b700e97e5e0df Reviewed-by: Fabian Kosmale <[email protected]>
* QtQml: Remove unused includes in qml, first partSemih Yavuz2022-09-141-1/+0
| | | | | | | | | | | | | | | Drop unnecessary includes detected by clangd-iwyu. Add new includes due to the transitive includes. Also, some of the includes were detected as unused even if they were actually in use. In those cases, use angular brackets instead of "" which deceives the tool not to complain. Affected subfolders: Debugger, Compiler, JsApi, JsRuntime, Memory, Parser Task-number: QTBUG-106473 Change-Id: I01d996a2a2ba31cbbc5f60f5454c8f850298f528 Reviewed-by: Fabian Kosmale <[email protected]>
* Allow limited extensions to globalsUlf Hermann2022-09-071-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We can allow a, overriding data members of globals, such as Error.name b, adding members that don't clash with any internals c, any manipulation of toString(), toLocaleString(), valueOf(), and constructor To that effect, add a "Locked" flag to our internal classes. If that is set, disallow changing prototypes and when defining a property, check if it shadows any non-configurable property. Furthermore, make all non-primitive properties that are not meant to be overridden non-configurable and non-writable. constructor, toString(), toLocaleString() and valueOf() are exempt because they are explicitly meant to be overridden by users. Therefore, we let that happen and refrain from optimizing them or triggering their implicit invocation in optimized code. [ChangeLog][QtQml][Important Behavior Changes] The JavaScript global objects are not frozen anymore in a QML engine. Instead, they are selectively locked. You can extend the objects with new members as long as you don't shadow any existing methods, and you can change or override data members. This also means that most methods of Object.prototype, which was previously exempt from the freezing, cannot be changed anymore. You can, however, change or override constructor, toString(), toLocaleString() and valueOf() on any prototype. Those are clearly meant to be overridden by user code. Fixes: QTBUG-101298 Task-number: QTBUG-84341 Change-Id: Id77db971f76c8f48b18e7a93607da5f947ecfc3e Reviewed-by: Fabian Kosmale <[email protected]>
* QML: Make modules imported with registerModule() available in QMLUlf Hermann2022-09-021-11/+19
| | | | | | | | | So far, you could only use them from pure JavaScript programs. Also, fix re-exporting parts of native modules. Fixes: QTBUG-105901 Change-Id: I170017083284e6457b1aa0c6e606fd26227edae3 Reviewed-by: Fabian Kosmale <[email protected]>
* Use SPDX license identifiersLucie Gérard2022-06-111-38/+2
| | | | | | | | | | | | 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 <[email protected]>
* Make QQmlEngine resolve closures when executing runtime functionsAndrei Golubev2022-04-271-1/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | QML can create a function which holds a closure in the cases like: onSignal: function() { ... } If the left-hand side is a signal handler (or similar), we want to execute the *inner* function when a signal is called, not the outer one. However, under certain conditions (e.g. we use `this`), the outer function must also be called beforehand to correctly setup the calling scope for the inner function Thus, make the QQmlEnginePrivate::executeRuntimeFunction() do that: always call an outer function first and then the inner one if present. This creates an overhead when dealing with certain signal handlers but we could optimize it later if needed Note that the case `property var prop: function() { return 42; }` where a property contains a callable function is no longer supported by the executeRuntimeFunction() routine (we always call the inner code now). This is fine since qmltc (the main beneficiary of the routine) does not rely on this functionality when dealing with property bindings Given the change, qmltc can be simplified to only work with absolute function indices, ignoring the nesting problem altogether Change-Id: I61f61587b6fe700cb695b3b7a213d9cfab0eb746 Reviewed-by: Ulf Hermann <[email protected]>
* ExecutionEngine: Move initialization of statics into separate methodUlf Hermann2022-03-051-8/+8
| | | | | | | | | | ... and do it only for the first engine (ie engineId == 1). The engineId is determined using atomic operations, so this is safe now. Pick-to: 6.3 Task-number: QTBUG-73271 Change-Id: Ife38213fe04e26f35425a29230a2e3b586572dd2 Reviewed-by: Fabian Kosmale <[email protected]>
* QtQml: Do not depend on transitive includesFabian Kosmale2022-03-041-0/+1
| | | | | Change-Id: I287a6e63397c2c6140c3bc3e7d83f3212709531e Reviewed-by: Maximilian Goldstein <[email protected]>
* Remove the qml_sequence_object feature flagUlf Hermann2022-01-151-4/+0
| | | | | | | | | | | | | | | | | | | QML sequences are required for named lists of value types. The original reason for the introduction of this feature was the template code explosion caused by the way the sequence types were registered in Qt5. As we register them differently now, the code size overhead should be smaller. It makes very little sense to switch sequence types off these days. [ChangeLog][QtQml][Important Behavior Changes] The qml_sequence_object feature flag has been removed. Omitting sequences from the QML language does not make much sense now that we use them for lists of value types. The original reason to allow it was that the sequence support took up a lot of space in the binary. This is not the case anymore since 6.0. Change-Id: I2f1d43cdd29ba63853316b06113cb49ed30aa410 Reviewed-by: Joerg Bornemann <[email protected]> Reviewed-by: Fabian Kosmale <[email protected]>
* Eliminate JS call frame from metatypes callsUlf Hermann2021-06-101-4/+1
| | | | | | | | If we call an AOT-compiled function we never need the JavaScript call frame. We can just skip its setup and save some overhead. Change-Id: I39dc2ca6eea5b5a66f3b87b642a310534cecf6cd Reviewed-by: Fabian Kosmale <[email protected]>
* Pass QMetaType by value rather than by ID in more placesUlf Hermann2021-06-091-2/+1
| | | | | | | | | | This saves us some ping-pong between the IDs and the QMetaTypes, and avoids possible ambiguities if multiple metatypes are registered for the same C++ type. Change-Id: I81cec94a9cd05d69927dc884f65574f0ab2ddc22 Reviewed-by: Maximilian Goldstein <[email protected]> Reviewed-by: Fabian Kosmale <[email protected]>
* QQmlEngine::executeRuntimeFunction: pass return value as input argumentAndrei Golubev2021-05-111-2/+2
| | | | | | | | | Use the newer version of QV4::Function::call() that does not require manual JSCallData setup and is more optimal for AOT function calls Change-Id: I5a5e2d0477c0603b05b7213f1b2adcc34d156bf5 Reviewed-by: Fabian Kosmale <[email protected]> Reviewed-by: Ulf Hermann <[email protected]>
* Add QJSEngine::registerModuleAlex Shaw2021-05-011-0/+8
| | | | | | | | | | | | | | | | | | | | | | | | Some applications that use JavaScript as a scripting language may want to extend JS through C++ code. The current way to do that is with global objects. ES6 provides a better way of encapsulating code: modules. registerModule() allows an application to provide a QJSValue as a named module. Developers familiar with Node.js will find this very easy to use. Example: ```c++ QJSValue num(666); myEngine.registerModule("themarkofthebeast", num); ``` ```js import badnews from "themarkofthebeast"; ``` [ChangeLog][QtQml][QJSEngine] Adds the ability to register QJSValues in C++ as modules for importing in MJS files. Change-Id: I0c98dcb746aa2aa15aa2ab3082129d106413a23b Reviewed-by: Ulf Hermann <[email protected]>
* Support native transformation between UrlObject and QVariant/QUrlUlf Hermann2021-04-221-0/+1
| | | | | | | | | | | | | | URL has become a builtin type. We should support it on the same level as QString/String and QDateTime/Date. In order to continue support for comparing URL properties with the JavaScript equality operators, we still pass URLs as variants when using them in JavaScript. However, we now create proper URL objects for QJSValue and QJSManagedValue, and we allow transforming the URL-carrying variant objects back into QUrls. Change-Id: I78cb2d7d51ac720877217d2d4b4d0ab17cdd2a4b Reviewed-by: Fabian Kosmale <[email protected]>
* QV4::Engine::toVariant: Use metatype instead of metatype idFabian Kosmale2021-03-251-1/+1
| | | | | | | | | | 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 <[email protected]> Reviewed-by: Andrei Golubev <[email protected]>
* Inline retrieval of QML contextsUlf Hermann2021-03-251-0/+19
| | | | | | | | In the good case this is just reading a few members of the relevant classes. No need to call functions for this. Change-Id: I9908cd6437cf9a1ca840f9aa0e524d3976272d67 Reviewed-by: Fabian Kosmale <[email protected]>