aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler
Commit message (Collapse)AuthorAgeFilesLines
* Avoid std::function in qqmlirbuilder.cppUlf Hermann2019-05-072-22/+18
| | | | | | | | | | | Some compilers seem to miscompile this construction. Furthermore, it doesn't really add to the readability of the code. Inline the code in question at the only place it's used and avoid most of the const_cast by adding a non-const accessor to CompiledData::Unit. Fixes: QTBUG-75392 Change-Id: I015317f28a92817d08d616cc35956745758d7847 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* Fix coverity warningSimon Hausmann2019-04-291-2/+3
| | | | | | | | | | Commit bc00353cffbfe0f74b602a16452f2e7bcd588152 accidentally removed the assert that expressed how objectForId will always succeed with the alias target. That caused coverity to complain that objectAt() may be called with a negative (then array) index. Change-Id: I8651e0826c92e41ab00bf8a44f1abfd1cbfb0e06 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* QML: Check for (valid) compilation units while hashingErik Verbruggen2019-04-161-0/+2
| | | | | | | | | When an error occurred while creating a compilation unit, the pointer might be set to null. Subsequent use in hashing should check for this, and not use a nullptr. Change-Id: I62650917a740c9c1be29608285670153bed8703c Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* QMLJS: Remove unused boolean field hasTry from compiler contextErik Verbruggen2019-04-151-1/+0
| | | | | | | | All uses have been refactored out in previous commits, so now also remove the field. Change-Id: Ic6fb92f70a0451db04ddf40344239a69312faf8f Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* Prevent CoW detaches from happeningErik Verbruggen2019-04-151-12/+15
| | | | | Change-Id: Ia42c0d732e0f6ccfa2c70b86edccd9eb471aac7c Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* Only create the imports array if importCount is greater than 0Andy Shaw2019-04-141-2/+4
| | | | | | | | | | | Since it is possible that CompilationUnit::instantiate() might be called more than once when the importCount is 0 then it should only create the imports array when it is greater than 0. This prevents a memory leak due to the recreation of this array each time it is called even though there is no imports to assign. Change-Id: I5d84b01de10bff2ca25248251e8337839e434bd5 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* Detect and reject cyclic aliasesUlf Hermann2019-04-091-10/+30
| | | | | | | | Previously those would result in infinite recursion. Fixes: QTBUG-74867 Change-Id: I6c0043b43e72fe7bc3a2a139ca600af2d5bca5ad Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* Enable lookups for imported scripts and worker scriptsSimon Hausmann2019-03-251-1/+1
| | | | | | | | | | | | | This is straight-forward to enable, with the minor adjustment that we need to handle the case where a global lookup is done without a calling qml context (worker script). We don't know at compile time whether a script will be imported directly or used as a worker script, so we have to generate the global qml lookup instruction regardless and handle it at run-time. Change-Id: Ia033afa214d919d906c676498dd3eceb1c5639d8 Reviewed-by: Michael Brasser <michael.brasser@live.com> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Fix memory "leaks" in qmlcachegenSimon Hausmann2019-03-222-5/+9
| | | | | | | | | | | | | The CompilationUnit class owns the unit data. An exception was made in bootstrap builds, where it was up to the caller to free the memory. This lead to cases in qmlcachegen where we didn't free the memory. This is best fixed by unifying the behavior. This fixes the build when using an ASAN enabled build, as the runtime aborts after calling qmlcachegen due to "leaks". Change-Id: I8b55b4e302a9569a1d4e09eeb488c479368b50f0 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* Initialize TranslationData padding before writing cache filesUlf Hermann2019-03-211-0/+2
| | | | | | | | Otherwise the resulting files differ subtly. Fixes: QTBUG-74532 Change-Id: I12b4f1ba6dda781d63ad50cce87861ba24582bf7 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* V4: Do not invert non-reflexive comparison binopsErik Verbruggen2019-03-211-49/+36
| | | | | | | | | This is only useful for the few (4) comparisons where we have specialized instructions, and it's very error-prone. Change-Id: I37efe94f54ba0adf393d9236df2d13aa6685eb46 Fixes: QTBUG-74476 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* Accelerate access to scope object properties in lookupsMichael Brasser2019-03-201-0/+5
| | | | | | Task-number: QTBUG-69898 Change-Id: I94bf1aa85c9b2302894f3224e41de81a456211f9 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* 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>