aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler
Commit message (Collapse)AuthorAgeFilesLines
* Remove dead compile time QML context/scope property and id object codeSimon Hausmann2019-03-2011-749/+13
| | | | | | | | | | | After enabling lookups in QML files, we can remove all the code that tries to deal with (type) compile time detection of access to id objects and properties of the scope/context object. This also allows removing quite a bit of run-time code paths and even byte code instructions. Task-number: QTBUG-69898 Change-Id: I7b26d7983393594a3ef56466d3e633f1822b76f4 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Implement dummy QML lookups for "global" variablesSimon Hausmann2019-03-2012-22/+70
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | When resolving names in the context of QML bindings, we now direct runtime access to QQmlContextWrapper::resolveQmlPropertyLookupGetter. At the moment this does basically the same as Runtime::method_loadName, which we called earlier. However this now provides the opportunity to optimize lookups in the QML context in a central place. When performing a call on a scope or context object property, we also did not use a CallName() instruction - which would have gotten the thisObject wrong - but instead we use a dedicated CallScopeObjectProperty and CallContextObjectProperty instruction. These rely on identifying these properties at compile time, which goes away with lookups (and also doesn't work when using ahead-of-time compilation). Therefore the qml context property lookup is using a getPropertyAndBase style signature and Runtime::method_callQmlContextPropertyLookup uses that. For the tests to pass, some error expectations need adjusting. In particular the compile-time detection of write attempts to id objects is now delayed to the run-time. The old code path is still there and will be removed separately in the next commit (as it is massive). Task-number: QTBUG-69898 Change-Id: Iad1ff93d3758c4db984a7c2d003beee21ed2275c Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Enable lookups in QMLSimon Hausmann2019-03-192-1/+15
| | | | | | | | | | | | | | | | | | | | | | | | | | | The main feature that needs to be implemented in order to enable lookups in QML files is to respect that the QObject wrapper has its own storage layer (meta-object properties). Lookups need to be able to index those when the base is a QObject. This is done by caching the property data and guarding the validity by comparing property cache pointers. The same lookup logic is also implemented for value type wrappers. OVerall there's more that can be done with lookups in meta-objects, for constant properties for example. For "global" lookups we have a safeguard in place that generates a LoadName instruction for property access that should end up in the qml context wrapper. So no changes are needed here at first, but the lookup in the QML context can be optimized in the future. The way of storing the property cache in the lookup itself trades ugliness on destruction against the creation of less internal classes. Another option would be to store the property cache in the internal class and let QObjectWrapper always transition via the property cache. Task-number: QTBUG-69898 Change-Id: I9c378c071acc6d7d4a34a2a76616f9594119d515 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Fix up global name determination when compiling ahead of timeSimon Hausmann2019-03-152-2/+3
| | | | | | | | The list of names is still suboptimal, but at least it's shared now. Task-number: QTBUG-69898 Change-Id: I16c9839c4a1f097053b28caea894b67757972826 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Unify the JavaScript parsing recursion checksUlf Hermann2019-03-155-61/+49
| | | | | | | | | | | | | We only need to check in one central location and we can allow for more recursion. 4k recursions seem tolerable. A common default for stack sizes is 8MB. Each recursion step takes up to 1k stack space in debug mode. So, exhausting this would burn about half of the available stack size. We don't report the exact source location in this case as finding the source location may itself trigger a deep recursion. Fixes: QTBUG-74087 Change-Id: I43e6e20b322f6035c7136a6f381230ec285c30ae Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* Save some stack space during code generationUlf Hermann2019-03-143-135/+176
| | | | | | | | | | | | | | Result objects are rather large, 96 bytes here. In a recursive algorithm such as our parser, we should not keep too many of them on the stack. Also, the size of Reference can be reduced by employing a bit field rather than a number of booleans. Also, try to convince the compiler to inline the accept() functions. The extra stack frames those create are unnecessary. Task-number: QTBUG-74087 Change-Id: I5c064491172366bb0abef99ffe9314080401a7d1 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* V4: Rotate loop in ArrayPattern and eliminate "done" labelErik Verbruggen2019-02-251-11/+5
| | | | | | | | | | This prevents jumping over the resetting of the unwind handler when an exception occurs. (cherry-picked from commit 0282b89ec672e25a465a8e51bc74c7fd58a624b1) Fixes: QTBUG-73985 Change-Id: I4a4da815f54c13980d239e0492f9b013991cfbd5 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* V4: Fix unwind handling when destructuring listsErik Verbruggen2019-02-251-14/+1
| | | | | | | | | | | If there was a rest element in the list, the generated code would jump over the clean-up (closing of the iterator). However, this would also jump over any resetting of the unwind handler. (cherry-picked from commit 3310f173c1c6208cb0f6541578419196bc29831f) Task-number: QTBUG-73985 Change-Id: I9a1bcb9e69fd98975fe9c89e23a4568b0dafdf83 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* QML: Pass type minor version when creating property dataUlf Hermann2019-02-213-5/+7
| | | | | | | | | Depending on the type minor version recursive properties should be available or not. Check for that when resolving grouped properties. Fixes: QTBUG-33179 Change-Id: Id8f62befdc4a29d879710499e19d3d289bd18775 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* Avoid unnecessary re-generation qml cache files in some circumstancesUlf Hermann2019-02-186-31/+41
| | | | | | | | | | | | The map of name IDs to resolved types so far is copied several times during compilation and different compile passes see different copies of it. Compile passes may add things to the map, and if they do that on copies that are inaccessible to other code, we get nondeterministic results. Furthermore all the copies and pointers are confusing and inefficient. Fixes: QTBUG-69340 Change-Id: I43ad3cbeeec34f90e05570eddc901fe8aa64c709 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* Don't optimize global lookups if fast QML lookups are disabledUlf Hermann2019-02-133-2/+5
| | | | | | | | | | | If fast QML lookups are disabled, we generally want to look up by string. If the name then happens to be a member of the global JavaScript object, we still don't want to directly access that, as the name could have been overridden in a deeper context. Fixes: QTBUG-73750 Change-Id: Id16110969123d91501064ba46bfad4c2a39e4650 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* QMLJS: Have ScanFunctions iterate over ArrayPattern nodesErik Verbruggen2019-02-052-0/+9
| | | | | | | | | | | | Like Codegen, have ScanFunctions iterate over the elements in an ArrayPattern, instead of recursing over the tail of the element list. This prevents running out of (native) stack, or hitting the recursion check limiter. Change-Id: I8203af3119ad50f19000a215af42649d9bcb3784 Fixes: QTBUG-73425 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* Improve error messageRainer Keller2019-02-041-1/+5
| | | | | | | Show more datails about what actually went wrong. Change-Id: I418a4d1f433bd4d440fc34e9a4932a9ea010b174 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* V4: Fix unwind handler reset after for-in loopErik Verbruggen2019-01-311-5/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Consider this JavaScript snippet: function f() { for (var i in []) {} } This generates the following bytecode sequence: 2 0: 14 00 09 MoveConst r3, C0 3: ec 00 00 DefineArray (function), 0 6: da 00 GetIterator 0 8: 18 08 StoreReg r2 10: c0 0f SetUnwindHandler 27 12: 50 04 Jump 18 14: 16 0a LoadReg r4 16: 18 07 StoreReg r1 3 18: 16 08 LoadReg r2 20: dc 0a 09 IteratorNext r4, r3 23: 54 f5 JumpFalse 14 25: 50 03 Jump 30 27: c0 00 SetUnwindHandler <null> 29: c2 UnwindDispatch 4 30: 0e LoadUndefined 31: 02 Ret The problem is a normal loop exit: instruction 23 will not jump back, but fall through, and then instruction 25 will jump over the instructions resetting the unwind handler (27 + 29). Removing this jump fixes the issue. Change-Id: Ic9f03555ebebc27144490bce04e9a4166ed7c97c Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Correctly scope unwind handlers for try blocksLars Knoll2019-01-301-3/+0
| | | | | | | | | | | | | Make sure the unwind handler is always reset when leaving the try block. This exposes a couple of failures in the ECMAScript test suite that were before passing by pure luck. Task-number: QTBUG-72858 Change-Id: I014b1e37c2beff136ecd53a665a2f10933f7e12c Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
* Fix byte code register dump outputSimon Hausmann2019-01-291-1/+1
| | | | | | | | The first register allocated in bindings is typically the return address register, which was erroneously shown as argument 0 instead of register 0. Change-Id: I00add0b5b1cd08a4c9b1d42ffe79d2ea7e5a73cf Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* Fix build error when building with -no-feature-translationUlf Hermann2019-01-111-1/+1
| | | | | | Change-Id: Ie97ae901283cf431fc38d238ddbc88a18bd630c8 Fixes: QTBUG-72352 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* Fix ICC warning about old-style scoping rulesThiago Macieira2018-12-121-2/+2
| | | | | | | | | | It's only been 20 years that the new style is the rule... qv4compileddata.cpp(206): error #823: reference is to variable "i" (declared at line 198) -- under old for-init scoping rules it would have been variable "i" (declared at line 204) Change-Id: I4ac1156702324f0fb814fffd156f80ecb6849ee8 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* Merge remote-tracking branch 'origin/5.12.0' into 5.12Qt Forward Merge Bot2018-12-074-8/+79
|\ | | | | | | | | | | | | | | Conflicts: src/qml/jsruntime/qv4script.cpp src/qml/parser/qqmljslexer.cpp Change-Id: I82252a8c504a4b77c45f4f8efe849ff9acb949fd
| * Generate lookups into the global object more aggressivelyLars Knoll2018-11-164-8/+79
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Since change 9333ea8649838d7e0400b0e94c8cbd4fa5d216b0, we lookup properties in the QML context object before the global object to have proper scoping rules for QML. Unfortunately this lead to a performance regression when using global properties such as Math in imported script files, as the lookup would always go through the qml context first. This can be fixed, as we know that the global object is frozen in qml mode, and the standard names of properties in the global object are illegal to use in QML. So simply check for those names in the code generator and create lookups into the global object for those. Change-Id: I4b2089178c9e5f9440abdfd834cf7d92c3c0e2c3 Fixes: QTBUG-71591 Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
* | JS: Limit expression and statement nesting levelErik Verbruggen2018-11-294-2/+55
| | | | | | | | | | | | | | | | | | This is to prevent extremely deeply nested expressions and statements make the code-generator run out of (native) stack space. Task-number: QTBUG-71087 Change-Id: I8e1a20a361bff3e49101e535754546475a63ca18 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | JS: Check pattern target to be an lvalueErik Verbruggen2018-11-191-0/+4
| | | | | | | | | | Change-Id: If9468b93b08ad355f07d1436ca88e8d36be22070 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* | JS: Handle check for dangling jump gracefullyErik Verbruggen2018-11-191-1/+3
| | | | | | | | | | | | | | | | | | | | | | The destructor for the Jump object will check if it is linked somewhere. So when doing an early-exit after generating a jump (and before linking it) and after an error occurred, make sure to call link anyway. At this point no code will be generated, so where the jump points to is kinda pointless. Change-Id: I09fa03d4224805a838088acd0c5c83d02b328045 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* | Properly mark variables as unresolved when accessed from evalLars Knoll2018-11-161-1/+1
| | | | | | | | | | | | | | | | | | If we can't resolve the variable and are executing eval code, we need to look it up by name, and not generate a lookup in the global object. Change-Id: I693b3b714651911f72620160bfc463d6dbb00820 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Merge remote-tracking branch 'origin/5.12.0' into 5.12Qt Forward Merge Bot2018-11-164-51/+49
|\| | | | | | | Change-Id: I7623438dde316ae1e97802f91991f2e7ccc205a5
| * Stop codegen after errorErik Verbruggen2018-11-131-25/+27
| | | | | | | | | | | | | | | | | | | | We won't use the bytecode anyway, and it prevents consistency checks that come after the error from failing. Specifically: there might be jumps that have no label defined. Fixes: QTBUG-71738 Change-Id: I62a7e943b0156d42caccfa40507853de79e3b1ce Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
| * Fix translation bindings when qtquickcompiler is usedFrederik Gladhorn2018-11-061-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | It turns out that the context information is lost when using the compiler. The unit->unitData()->sourceFileIndex is wrong (always 0), which should probably be fixed. This change only works around that by using unit->fileName(); instead. Make sure that the test actually verifies translations happen and have a context. Done-with: Jan Arve Sæther Fixes: QTBUG-71553 Change-Id: Ib5926bd4b9a6267644f5c9328a84c23d61ca5466 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
| * Expose let/const variables from imported JS scriptsJüri Valdmann2018-11-023-25/+21
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch allows QML to access let/const variables defined in JS files. Detailed changes: - The recently added ContextType::ScriptImportedByQML is changed to avoid creating Push/PopScriptContext instructions, similar to ContextType::ESModule. - QV4::Module is changed to also work with CompilationUnits which are not ESModules. In this case QV4::Module will behave as if all lexically scoped variables were exported. - CompilationUnit is changed to support instantiating and evaluating QV4::Modules for non-ESModules as well. - QQmlTypeLoader is changed to always create QV4::Modules for evaluating scripts. For the non-ESModule case, the QV4::Module is evaluated inside a QV4::QmlContext, as before. - A pointer to the QV4::Module is added to QV4::QQmlContextWrapper, and used in virtualGet to access the let/const variables in the CallContext. Access is read-only. Fixes: QTBUG-69408 Change-Id: I6f299363fdf5e1c5a4a0f1d9e655b4dc5112dd00 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Create proper template objects for tagged templatesLars Knoll2018-11-0510-69/+160
| | | | | | | | | | | | | | | | If a tagged template gets evaluated multiple times, the underlying template object is shared. Change-Id: Ie2f476fbc93d5991322ce1087c42719a8d8333ae Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Create proper template objectsLars Knoll2018-11-021-14/+40
|/ | | | | | | | | Create the proper template object for a tagged template. This fixes quite a few use cases (esp. String.raw), but is not yet 100% spec compliant. Change-Id: I69eaee22c384c0d1bd2c6c56ad711d29521b0b86 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* Clone ContextType::Global as ContextType::ScriptImportedByQMLJüri Valdmann2018-11-014-8/+10
| | | | | | | | | | Add new enum value QV4::Compiler::ContextType::ScriptImportedByQML, which behaves exactly the same as ContextType::Global. A follow-up patch will change the behavior slightly. Task-number: QTBUG-69408 Change-Id: I20d27804fd1433f2229704546bcd78a0ac108c01 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* Fix lookup of methods in the scope objectSimon Hausmann2018-10-221-5/+9
| | | | | | | | | | | | | Commit 939014cb9cad2f3357f47b28a4580397c17b913c improved performance of property lookups beyond the scope object, with the unfortunate side-effect that the previously polymorphic lookup of methods broke. Fix this by moving the handling to the caller side and falling back to the string lookup for functions. Fixes: QTBUG-71204 Change-Id: I2d9924034a9c14e7d161fa49d51b1f876ab5bc0f Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* QQmlScriptData: Extract qmlContextDataForContext from scriptValueForContextJüri Valdmann2018-10-171-0/+2
| | | | | | | | Refactoring only, no behavior changes. Task-number: QTBUG-69408 Change-Id: Ifd26957dca69bcd658ad5f989108a661b9996d6c Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* JS: Check if the rhs of an assignment had errors before using itErik Verbruggen2018-10-151-1/+4
| | | | | Change-Id: I34d70759732433b6f0ecccc5ae175d33ec8e1577 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* JS: Check lhs of an 'in' expression to be an lvalueErik Verbruggen2018-10-151-0/+4
| | | | | | | | | For example: 'for (foo() in something) {}' is not valid: a call expression is not an lvalue. Task-number: QTBUG-71086 Change-Id: Ia1498cd38526b073afb8e4524ceaea14dca3d65f Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* Remove useless assertErik Verbruggen2018-10-151-2/+0
| | | | | | | | There is a {{Q_UNREACHABLE}} right after it. Change-Id: Id69fb1403a5f99912e6fbcb4a397a78a9d6948d7 Reviewed-by: Lars Knoll <lars.knoll@qt.io> Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* Abort parsing on errorLars Knoll2018-10-151-17/+14
| | | | | | | | | | The visit() methods need to return false on parse errors, so that we don't continue iterating into that subtree of the AST, but rather exit as quickly as possible. Task-number: QTBUG-71090 Change-Id: I1912d955a0ffc86389a4cbbb3b6ac0209c3c556a Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* JS: Check expressions inside template literals for validityErik Verbruggen2018-10-121-0/+4
| | | | | | | | | And not use (a possibly invalid result) blindly, because this will cause assertion failures down the line. Task-number: QTBUG-71081 Change-Id: Id10149c55026094a355bd747f66014119c0e24f5 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* Fix error reporting when imports or re-exports in modules failSimon Hausmann2018-10-115-4/+28
| | | | | | | | Collect the location of the import/export statement and include it in the exception thrown. Change-Id: I7966dfd53ed67d2d7087acde2dd8ff67c64cb044 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* JS: Check array subscripts for validity when generating codeErik Verbruggen2018-10-111-0/+2
| | | | | | Task-number: QTBUG-71079 Change-Id: I999130f3994f513bb9d2ca8ddaa94688451937fc Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* Fix possibly uninitialized use of unionErik Verbruggen2018-10-091-2/+2
| | | | | | Task-number: QTBUG-71011 Change-Id: I42410364b45ecd38832a0e5abb82eb56f9828504 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* Merge remote-tracking branch 'origin/5.11' into 5.12Liang Qi2018-10-081-0/+4
|\ | | | | | | | | | | | | | | Conflicts: src/3rdparty/masm/yarr/YarrJIT.h src/quick/items/qquickwindow.cpp Change-Id: I551404e1558d56c0b0626346ad1c86406bff0ec7
| * Mark QML captured scope/context loads as having side effectsErik Verbruggen2018-10-041-0/+4
| | | | | | | | | | | | Task-number: QTBUG-69973 Change-Id: I8636d74c76db3859a6bd5134fd5e52f571340a71 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Make Codegen::Reference movableErik Verbruggen2018-10-072-67/+4
| | | | | | | | | | | | | | | | This removes the call to Reference::operator= and allows the constructor and assignment to be inlined. Change-Id: I173ae47127cc5c939300c1178c4c8637882f1c49 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Trim some #includesErik Verbruggen2018-10-073-14/+4
| | | | | | | | | | Change-Id: I5346fc36c89b7969c2bef3069f256f33bd4d9eb9 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | ES7: Detect Tail Position Calls and pass that to the runtimeErik Verbruggen2018-10-046-32/+150
| | | | | | | | | | | | | | Doing the tail call in the runtime will come in a follow-up patch Change-Id: I8224aac0edbdc765ee9b97703948edd52fd33f3e Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Make a method constErik Verbruggen2018-09-281-1/+1
| | | | | | | | | | Change-Id: I70043699d15daf858c47d30018060aef31810abb Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Refactor InternalClass::find()Lars Knoll2018-09-271-2/+2
| | | | | | | | | | | | | | | | | | Specialize find() into several methods for different purposes. Prepares for further cleanups and being able to split up getter and setter for accessor properties. Change-Id: Id4ec5509ac1a1361e2170bbfc2347b89b520c782 Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
* | Fix use of lexically scoped variables in modulesSimon Hausmann2018-09-231-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | Their use may trigger setting c->requiresExecutionContext on the module context, which is correct. However, unlike functions, modules at instantiation time always have their context created ahead of time (to populate imports). Therefore we must not emit call context creating byte code instructions where we'd end up storing exports in the wrong place. Change-Id: Id1264f1cfa6a7f1cd94247ffe71938bc9c5c3ff9 Fixes: QTBUG-70632 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* | Cleanups in Value/PrimitiveLars Knoll2018-09-172-18/+18
| | | | | | | | | | | | | | | | | | | | | | | | Get rid of Primitive and move the corresponding methods directly into Value. Mark many methods in Value as constexpr and turn Value into a POD type again. Keep Primitive as a pure alias to Value for source compatibility of other modules that might be using it. Change-Id: Icb47458947dd3482c8852e95782123ea4346f5ec Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>