aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4jscall_p.h
Commit message (Collapse)AuthorAgeFilesLines
* QtQml: Properly enforce signatures of AOT-compiled functionsUlf Hermann2024-04-261-7/+7
| | | | | | | | | | | | | 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>
* QtQml: Fix some type conversion edge casesUlf Hermann2024-04-231-9/+19
| | | | | | | | | | | | 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>
* QtQml: Consider value types when looking for metaobjectsUlf Hermann2024-02-151-1/+1
| | | | | | | | | | | We have quite a few types with only extension metaobjects now. Move the functionality to retrieve the metaobject into QQmlType where it belongs. Pick-to: 6.7 6.6 Fixes: QTBUG-119829 Change-Id: I2b99b1a305d8726547ae0512d3c832799a4e4b04 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
* Remove the use of Q_QML_PRIVATE_EXPORTAlexey Edelev2024-01-111-1/+1
| | | | | | Task-number: QTBUG-117983 Change-Id: I5790f01d614cd70c7fcc9bd817ec6ace3f3e3730 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* QML: Don't crash when calling coerceAndCall() with null thisObjectUlf Hermann2023-12-081-2/+5
| | | | | | | | Pick-to: 6.6 6.5 Fixes: QTBUG-119395 Change-Id: I5877beef9a53d358a6f58f9ce5029688bd9dcedb Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QML: Fix further return type constructionsUlf Hermann2023-10-201-5/+4
| | | | | | | | | | | | | There, too, the return type is already initialized and needs to be copied or moved rather than placement new'd. Amends commit 1d8859ce3a3d161ffa2ccd74f195b276795a5af5. Change-Id: I5008659171962a3bd476a6e890e7576579646ae3 Reviewed-by: Semih Yavuz <semih.yavuz@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Sami Shalayel <sami.shalayel@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* QtQml: Fix return type constructions when calling methodsUlf Hermann2023-10-071-9/+17
| | | | | | | | | | | | | | | We now expect the return type to be initialized in all cases. This is in line with what the various metacall() methods expect. Unifying this behavior makes it much easier to reason about and avoids complicated bugs and memory leaks. The code generated by QmlCompiler always passes initialized values for the return type anyway. Amends commit 4f1b9156a48e44cf1f127a4563d0ac69ab436f12 Amends commit 02c4c817fe1cfa4766c56759be99fb081382a586 Change-Id: I26c016676dd82c91d6ef81762b5c4b599f6f7f72 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* QtQml: Construct return type before metaCallUlf Hermann2023-09-291-0/+2
| | | | | | | | | The metacall expects initialized memory. Let's give it what it wants. Fixes: QTBUG-117672 Change-Id: If139029ac4771ac919c5f09728633546e7bb9d1e Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QML: Implement QObjectMethod::virtualCallWithMetaTypesUlf Hermann2023-09-281-2/+157
| | | | | | | | | | | | We can use the same mechanism we have in place when calling typed JavaScript functions. The type coercion is generalized and moved to qv4jscall_p.h. We also use the correct JavaScript coercion in the rare fallback case where the types are actually different. Fixes: QTBUG-113258 Change-Id: I30404ee0122433b47227b2fc0dc4b0e3862a99c7 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QtQml: Optimize string/URL check in coerce()Ulf Hermann2023-07-101-3/+3
| | | | | | | | | | We only need to check isString() once. This will also help static analyzers recognize that we cannot in fact dereference a nullptr there. Coverity-Id: 415866 Change-Id: I2f8462defbd9ffa7f4e0a8f184b920941a524eea Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
* QML: Un-specialcase QStringList and QVariantList conversionUlf Hermann2023-06-301-4/+13
| | | | | | | | | | | | | | | | | | Those are just regular sequences these days. They can be written back. Drop some now-dead code and deduplicate the value type conversion code in the process. We should try the (more common) value type conversion before the sequence conversion, but after all the "simple" conversions. [ChangeLog][QtQml][Important Behavior Changes] Converting a QVariantList to a QJSValue via, for example QJSEngine::toScriptValue() does not produce a JavaScript array anymore, but rather a better suited sequence object that behaves almost like a JavaScript array. The only difference is that its QJSValue::isArray() will return false now. Fixes: QTBUG-113690 Change-Id: Ib176c34d59c45a6b5cff68d029c4b1b87d7aa192 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QML: Improve the JS-to-JS type check when enforcing signaturesUlf Hermann2023-06-261-30/+199
| | | | | | | | | We do not have to coerce via the C++ type. Rather, we match the JavaScript representations of the types and coerce as needed. Task-number: QTBUG-113527 Change-Id: Id5c30cd46293f2d7aedd699f141a9fe19511b622 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Undeprecate AOTCompiledFunctionUlf Hermann2023-05-231-2/+2
| | | | | | | We're going to call the JavaScript-typed functions a different name. Change-Id: If92c3fb1b16b1b0bd7d009e7dd712ae6405e1232 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Move ScopedStackFrame into qv4stackframe_p.hUlf Hermann2023-05-171-31/+4
| | | | | | | | | | | 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 <fabian.kosmale@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* Add option to enforce function signaturesUlf Hermann2022-10-141-0/+39
| | | | | | | | | | | | | | | | | | | | | By default, the QML engine does not enforce signatures given as type annotations to functions. By passing different types than the function declares, you can get different behavior between the interpreter/JIT and the AOT-compiled code. In addition, in interpreted or JIT'ed mode, we pass all non-primitive value types as references. This means, if you modify them within the called function, the modifications are propagated back to the place where the value was loaded from. Enforcing the signature prevents all of this, at a run time cost. Since we have to coerce all arguments to the desired types, the function call overhead grows. This change introduces a pragma "FunctionSignatureBehavior" which you can set to "Ignored" or "Enforced" to choose one way or the other as universal way of handling type annotations. Fixes: QTBUG-106819 Change-Id: I50e9b2bd6702907da44974cd9e05b48a96bb609e Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* V4: Use an enum to categorize functions and rename aotFunctionUlf Hermann2022-09-291-1/+1
| | | | | | | | We want to use the aotFunction member also for typed JavaScript functions. Change-Id: Iad6d12ebed3ad3069832484137ed8e4d9e7a7cf4 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* V4: Make ExecutionEngine::toVariant() staticUlf Hermann2022-09-201-1/+1
| | | | | | | | | 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 <fabian.kosmale@qt.io>
* Do not call metaTypeFromJS on an objectUlf Hermann2022-09-131-2/+2
| | | | | | | | | This is misleading since the method is static. Change-Id: I921906a06575f263a7619cef01698923d1d5e61f Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Sami Shalayel <sami.shalayel@qt.io> Reviewed-by: Semih Yavuz <semih.yavuz@qt.io>
* Qml: When cloning a stack frame, also clone its instruction pointerUlf Hermann2022-07-221-2/+6
| | | | | | | | | | | | Otherwise we get an out of range access when looking for the line number. To be extra safe, we also add another guard against this to the lineNumber() function. Pick-to: 6.2 6.3 6.4 Fixes: QTBUG-90466 Change-Id: I4d9cb52ecba2631696537f02a3c1b75c3658ceb8 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* 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 <shawn.rutledge@qt.io>
* Eliminate JS call frame from metatypes callsUlf Hermann2021-06-101-21/+32
| | | | | | | | 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 <fabian.kosmale@qt.io>
* Do QMetaType-style call in QQmlPropertyBinding::evaluateUlf Hermann2021-06-021-7/+5
| | | | | | | | | | | | | | | | We already have a void* and metatype available. There is no need to convert, unless we have bound arguments. The call() itself will convert as necessary anyway. However, we do need to figure out whether the returned value was undefined. Pass this information up from the actual call. This reverts commit 8ac705247430ff6fbbc25a9db20c0e7dc572abe7. The original commit 3a4e013f0058952c94ed3414aafbf96216efff8d was correct. We were just missing the value type conversions in metaTypeFromJS(). Change-Id: Ic4b2ebf1eb3fb2e5a50a045be774dd02d0fed7c6 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Revert "Do QMetaType-style call in QQmlPropertyBinding::evaluate"Ivan Solovev2021-05-251-5/+7
| | | | | | | | | | This reverts commit 3a4e013f0058952c94ed3414aafbf96216efff8d. The patch seems to break the tests in QtPositioning (see QTBUG-93983 for some more details) Task-number: QTBUG-93983 Change-Id: Ie2caa8418f06add1c24d9f3d3d137e51e94908c2 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Do QMetaType-style call in QQmlPropertyBinding::evaluateUlf Hermann2021-05-201-7/+5
| | | | | | | | | | | | | | We already have a void* and metatype available. There is no need to convert, unless we have bound arguments. The call() itself will convert as necessary anyway. However, we do need to figure out whether the returned value was undefined. Pass this information up from the actual call. Change-Id: Icfa69e946adf80d18110a158f5bab906674b7381 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* Avoid needless construction and destruction of return valuesUlf Hermann2021-03-291-6/+6
| | | | | | | | | | In most cases the AOT compiled function will successfully placement-new the return value. Therefore, we can provide uninitialized space. Only do the construct/destruct dance in the cases when it's already slow. Change-Id: Ia339774fde03e459f290f167ddadd1c47a644b8e Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
* 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 <ulf.hermann@qt.io> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
* Use QMetaType for ExecutionEngine::metaTypeFromJS()Ulf Hermann2021-03-241-2/+2
| | | | | | | | We should avoid looking up metatypes by ID. That's expensive. Change-Id: I00ce0a7f95ec82b0db6e7eb976e39e50522a7fe4 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
* Optimize stack frame setup for AOT compiled functionsUlf Hermann2021-03-231-3/+89
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When called via the metaobject system, parameters and return values are passed as void*, with accompanying type information in the form of QMetaType. The same format is expected when calling an AOT compiled function. Previously, we would first convert all the parameters to QV4::Value, just to convert them back the moment we notice that there is an AOT compiled function. This is wasteful. This change provides a second call infrastructure that accepts void* and QMetaType as parameter and return value format, and passes them as-is all the way to any AOT compiled functions. If there is no AOT compiled function, the conversion is done when detecting this, rather than when initiating the call. This also passes the information "ignore return value" all the way down to the actual function call. If the caller is not interested in the return value, we don't have to marshal it back at all. For now, we only add the extra "callWithMetaTypes" vtable entry to ArrowFunction. However, other callables could also receive variants optimized for calling with void*/int rather than V4 values. This required changing the way how function arguments are stored in the property cache. We squeeze the return type into QQmlPropertyCacheMethodArguments now, and we use QMetaType instead of integers. In turn, we remove some unused bits. Change-Id: I946e603e623d9d985c54d3a15f6f4b7c7b7d8c60 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Clean up JSCallData setupUlf Hermann2021-03-171-25/+47
| | | | | | | | | | | | | | | | | 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>
* Don't store the scope in JSCallDataUlf Hermann2021-03-171-13/+9
| | | | | | | | | | | We only need it when generating CallData, or when filling in any thisObject or arguments that weren't provided. Provide a constructor that expects thisObject and arguments to be pre-allocated and one that allocates them in a scope passed as argument. Change-Id: Iddfba63f4dbc5b09e2b33fb22a94eea88f515902 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
* Engine: Cleanup method argument passingFabian Kosmale2021-03-041-2/+2
| | | | | | | | | | | | Instead of arguments around as a pointer to [argc, metaTypeId1, metaTypeId12, ...] pass argc and a pointer to [QMetaType1, QMetaType2] around. Moreover, make use of the fact that we now carry the metatype instead of only the id in a few places, to avoid id -> metatype lookups. Task-number: QTBUG-82931 Change-Id: Ib00e4d793727f85f3358a8162d1aac972daab3d3 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* QV4::populateJSCallArguments: Use v4->metaTypeToJSFabian Kosmale2021-02-191-1/+1
| | | | | | | | | | It appears that nowadays v4->metaTypeToJS handles QVariant and QObject derived classes just fine, and in exactly the same way as the custom code in populateJSCallArguments did. Task-number: QTBUG-82931 Change-Id: Ic5f97dfc3296a409fdd6a1fcb78d3b9bdba5f3a1 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Transform JSCallData args setting into a functionAndrei Golubev2021-02-121-0/+2
| | | | | | Change-Id: I4154a0b5c7115375292794e0564d2f3657e6b4dd Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Fix crash when running with aggressive gcSimon Hausmann2018-08-281-0/+1
| | | | | | | | | | The CallData is allocated on the JS stack explicitly uninitialized. So it's important to initialize all fields (including the new newTarget) to avoid dangling pointers. Task-number: QTBUG-70205 Change-Id: Id3511fa5e32a75b3cb16f39cc0805dc2ebf42f71 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* Implement IsConstructor for Function objectsLars Knoll2018-08-231-4/+2
| | | | | | | | Use the jsConstruct member in the function object for this and set it to a nullptr for methods that are not a constructor. Change-Id: I63d2971b23b2596a8e3b6d2781f0d9ed3208693b Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* Move the C++ and JS stack frame definitions into it's own fileLars Knoll2018-07-031-0/+1
| | | | | Change-Id: I86e89e07197aec6071809c2d32bd5c98cb7ac6f6 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* Implement support for new.targetLars Knoll2018-07-031-1/+1
| | | | | | | | | Support the new.target meta property in the codegen, and add support for passing the newtarget into the constructor vtable methods and the execution context. Change-Id: I62ea58e5e92d894035a76e35776203e9837c383b Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* Move the Vtable for Managed objects into it's own fileLars Knoll2018-07-031-0/+2
| | | | | | | | Move both the code from qv4object and qv4managed into a new qv4vtable_p.h file. Change-Id: Ib1d58120b6c3b9b779b2692526c7e40a5265c4db Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* Cleanup JS stack allocationsLars Knoll2018-05-261-3/+2
| | | | | | | | Avoid double writes to the stack, and use scope.alloc() for most allocations on the stack. Change-Id: I8b89273c1b6796d955fc8eeb72c67cff208ef786 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* use nullptr consistently (clang-tidy)Shawn Rutledge2018-02-261-2/+2
| | | | | | | | | | | | | From now on we prefer nullptr instead of 0 to clarify cases where we are assigning or testing a pointer rather than a numeric zero. Also, replaced cases where 0 was passed as Qt::KeyboardModifiers with Qt::NoModifier (clang-tidy replaced them with nullptr, which waas wrong, so it was just as well to make the tests more readable rather than to revert those lines). Change-Id: I4735d35e4d9f42db5216862ce091429eadc6e65d Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* Further cleanup JSCallDataLars Knoll2017-11-071-15/+26
| | | | | | | Avoid allocations on the JS stack if possible Change-Id: I344cd6dceb6264314f9d22c94db22b22d1d24d14 Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
* Simplify JSCallData constructionLars Knoll2017-11-071-27/+3
| | | | | Change-Id: Ic53532edae9a209aa7125af6f00a9d993d74f1a3 Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
* Get rid of the implicit cast operator to a CallDataLars Knoll2017-11-071-1/+3
| | | | | Change-Id: I1c35fbf8f7355bc2393ae931f99e591b800f2f45 Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
* Get rid of JSCallData::call()Lars Knoll2017-11-071-11/+0
| | | | | Change-Id: I6b99e9a7102b3dcb6a7699f54b6456eba6248699 Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
* Get rid of JSCallData::callAsConstructor()Lars Knoll2017-11-071-4/+0
| | | | | Change-Id: I7c7a69791e98ba0ce82b4d23785fc12a510c449e Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
* Add a FunctionObject::call(AsConstructor) overloadLars Knoll2017-11-071-3/+16
| | | | | | | add an overload taking a JSCallData for convenience. Change-Id: I8ebc190354943e6ceed676c3c0e1803586426769 Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
* Rename JSCall to JSCallDataLars Knoll2017-11-071-7/+7
| | | | | | | | As, this is going to change in a simple stack based structure to keep pointers to the data to pass to calls. Change-Id: Ia9aa3f81ee3eeba36affd16aac7b2fe97d59aea9 Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
* Change signature of call/constructLars Knoll2017-11-071-3/+3
| | | | | Change-Id: I139a7a31651d9a2ea46ced88978ac4633294bc60 Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
* Move the construction of the JSCall frame into the runtimeLars Knoll2017-11-071-0/+12
| | | | | | | The VME shouldn't have to care about this part Change-Id: I9e49353dce29912f5a222b7ed1b42ace2aa8cebd Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
* Refactor Call/Construct instructionsLars Knoll2017-11-071-3/+15
| | | | | | | | | | | | | | | | Give them a pointer to argc and argv instead of a pointer to a full callData. Like this we can construct the callData at the end of the JS stack and avoid the need to create an additional copy in VME::exec(). This also opens up the option of completely avoiding all copies for calls into runtime methods. Also make sure that the calldata we pass into other functions is always at the top of the JS stack. Change-Id: I3d0eb49f7bfd7adb9ddabb213422087c66e5a520 Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>