diff options
-rw-r--r-- | src/imports/testlib/signalspy.qdoc | 2 | ||||
-rw-r--r-- | src/imports/testlib/testcase.qdoc | 2 | ||||
-rw-r--r-- | src/qml/compiler/qv4ssa.cpp | 171 | ||||
-rw-r--r-- | src/qml/doc/src/qmllanguageref/modules/cppplugins.qdoc | 5 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4arrayobject.cpp | 2 | ||||
-rw-r--r-- | src/quick/items/qquickitem.cpp | 4 | ||||
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp | 6 | ||||
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgrenderer.cpp | 2 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgadaptationlayer.cpp | 2 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgthreadedrenderloop.cpp | 3 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgwindowsrenderloop.cpp | 2 | ||||
-rw-r--r-- | src/quick/scenegraph/util/qsgatlastexture.cpp | 2 | ||||
-rw-r--r-- | src/quick/scenegraph/util/qsgtexture.cpp | 4 | ||||
-rw-r--r-- | tests/auto/qml/qjsengine/tst_qjsengine.cpp | 13 |
14 files changed, 196 insertions, 24 deletions
diff --git a/src/imports/testlib/signalspy.qdoc b/src/imports/testlib/signalspy.qdoc index d6f8621c23..c20e268138 100644 --- a/src/imports/testlib/signalspy.qdoc +++ b/src/imports/testlib/signalspy.qdoc @@ -75,7 +75,7 @@ synchronously. For asynchronous signals, the wait() method can be used to block the test until the signal occurs (or a timeout expires). - \sa TestCase + \sa TestCase, {Qt Quick Test Reference Documentation} */ /*! diff --git a/src/imports/testlib/testcase.qdoc b/src/imports/testlib/testcase.qdoc index 4506209f8e..74d2c57098 100644 --- a/src/imports/testlib/testcase.qdoc +++ b/src/imports/testlib/testcase.qdoc @@ -205,7 +205,7 @@ will fail. Use the \l when and windowShown properties to track when the main window has been shown. - \sa SignalSpy + \sa SignalSpy, {Qt Quick Test Reference Documentation} */ /*! diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp index 679cf1b3a7..31a1e4cdc4 100644 --- a/src/qml/compiler/qv4ssa.cpp +++ b/src/qml/compiler/qv4ssa.cpp @@ -259,6 +259,152 @@ inline Temp *unescapableTemp(Expr *e, bool variablesCanEscape) } } +class BasicBlockSet +{ + typedef std::vector<int> Numbers; + typedef std::vector<bool> Flags; + + Numbers *blockNumbers; + Flags *blockFlags; + QVector<BasicBlock *> allBlocks; + enum { MaxVectorCapacity = 8 }; + + // Q_DISABLE_COPY(BasicBlockSet); disabled because MSVC wants assignment operator for std::vector + +public: + class const_iterator + { + const BasicBlockSet &set; + // ### These two members could go into a union, but clang won't compile (https://codereview.qt-project.org/#change,74259) + Numbers::const_iterator numberIt; + size_t flagIt; + + friend class BasicBlockSet; + const_iterator(const BasicBlockSet &set, bool end) + : set(set) + { + if (end) { + if (set.blockNumbers) + numberIt = set.blockNumbers->end(); + else + flagIt = set.blockFlags->size(); + } else { + if (set.blockNumbers) { + numberIt = set.blockNumbers->begin(); + } else { + flagIt = 0; + size_t eIt = set.blockFlags->size(); + while (flagIt != eIt) { + if (set.blockFlags->operator[](flagIt)) + break; + else + ++flagIt; + } + } + } + } + + public: + BasicBlock *operator*() const + { + if (set.blockNumbers) + return set.allBlocks[*numberIt]; + else + return set.allBlocks[flagIt]; + } + + bool operator==(const const_iterator &other) const + { + if (&set != &other.set) + return false; + if (set.blockNumbers) + return numberIt == other.numberIt; + else + return flagIt == other.flagIt; + } + + bool operator!=(const const_iterator &other) const + { return !(*this == other); } + + const_iterator &operator++() + { + if (set.blockNumbers) { + ++numberIt; + } else { + size_t eIt = set.blockFlags->size(); + while (flagIt != eIt) { + ++flagIt; + if (flagIt == eIt || set.blockFlags->operator[](flagIt)) + break; + } + } + + return *this; + } + }; + + friend class const_iterator; + +public: + BasicBlockSet(): blockNumbers(0), blockFlags(0) {} +#ifdef Q_COMPILER_RVALUE_REFS + BasicBlockSet(BasicBlockSet &&other): blockNumbers(0), blockFlags(0) + { + std::swap(blockNumbers, other.blockNumbers); + std::swap(blockFlags, other.blockFlags); + std::swap(allBlocks, other.allBlocks); + } + +#endif // Q_COMPILER_RVALUE_REFS + ~BasicBlockSet() { delete blockNumbers; delete blockFlags; } + + void init(const QVector<BasicBlock *> &nodes) + { + Q_ASSERT(allBlocks.isEmpty()); + allBlocks = nodes; + blockNumbers = new Numbers; + blockNumbers->reserve(MaxVectorCapacity); + } + + void insert(BasicBlock *bb) + { + if (blockFlags) { + (*blockFlags)[bb->index] = true; + return; + } + + for (std::vector<int>::const_iterator i = blockNumbers->begin(), ei = blockNumbers->end(); + i != ei; ++i) + if (*i == bb->index) + return; + + if (blockNumbers->size() == MaxVectorCapacity) { + blockFlags = new Flags(allBlocks.size(), false); + for (std::vector<int>::const_iterator i = blockNumbers->begin(), ei = blockNumbers->end(); + i != ei; ++i) + blockFlags->operator[](*i) = true; + delete blockNumbers; + blockNumbers = 0; + blockFlags->operator[](bb->index) = true; + } else { + blockNumbers->push_back(bb->index); + } + } + + const_iterator begin() const { return const_iterator(*this, false); } + const_iterator end() const { return const_iterator(*this, true); } + + QList<BasicBlock *> values() const + { + QList<BasicBlock *> result; + + for (const_iterator it = begin(), eit = end(); it != eit; ++it) + result.append(*it); + + return result; + } +}; + class DominatorTree { typedef int BasicBlockIndex; enum { InvalidBasicBlockIndex = -1 }; @@ -273,7 +419,7 @@ class DominatorTree { std::vector<BasicBlockIndex> semi; // BasicBlock index -> semi dominator BasicBlock index std::vector<BasicBlockIndex> idom; // BasicBlock index -> immediate dominator BasicBlock index std::vector<BasicBlockIndex> samedom; // BasicBlock index -> same dominator BasicBlock index - std::vector<QSet<BasicBlock *> > DF; // BasicBlock index -> dominator frontier + std::vector<BasicBlockSet> DF; // BasicBlock index -> dominator frontier struct DFSTodo { BasicBlockIndex node, parent; @@ -485,18 +631,20 @@ class DominatorTree { } if (np.todo.empty()) { - QSet<BasicBlock *> S; + BasicBlockSet &S = DF[node]; + S.init(nodes); foreach (BasicBlock *y, nodes[node]->out) if (idom[y->index] != node) S.insert(y); foreach (BasicBlockIndex child, np.children) { - foreach (BasicBlock *w, DF[child]) { + const BasicBlockSet &ws = DF[child]; + for (BasicBlockSet::const_iterator it = ws.begin(), eit = ws.end(); it != eit; ++it) { + BasicBlock *w = *it; const BasicBlockIndex wIndex = w->index; if (node == wIndex || !dominates(node, w->index)) S.insert(w); } } - DF[node] = S; DF_done[node] = true; worklist.pop_back(); } @@ -517,7 +665,9 @@ class DominatorTree { #endif // SHOW_SSA #if !defined(QT_NO_DEBUG) && defined(CAN_TAKE_LOSTS_OF_TIME) foreach (BasicBlock *n, nodes) { - foreach (BasicBlock *fBlock, DF[n->index]) { + const BasicBlockSet &fBlocks = DF[n->index]; + for (BasicBlockSet::const_iterator it = fBlocks.begin(), eit = fBlocks.end(); it != eit; ++it) { + BasicBlock *fBlock = *it; Q_ASSERT(!dominates(n, fBlock) || fBlock == n); bool hasDominatedSucc = false; foreach (BasicBlock *succ, fBlock->in) { @@ -545,7 +695,11 @@ public: computeDF(); } - QSet<BasicBlock *> operator[](BasicBlock *n) const { +// QSet<BasicBlock *> operator[](BasicBlock *n) const { +// return DF[n->index]; +// } + + const BasicBlockSet &dominatorFrontier(BasicBlock *n) const { return DF[n->index]; } @@ -1085,7 +1239,10 @@ void convertToSSA(Function *function, const DominatorTree &df) while (!W.isEmpty()) { BasicBlock *n = W.first(); W.removeFirst(); - foreach (BasicBlock *y, df[n]) { + const BasicBlockSet &dominatorFrontierForN = df.dominatorFrontier(n); + for (BasicBlockSet::const_iterator it = dominatorFrontierForN.begin(), eit = dominatorFrontierForN.end(); + it != eit; ++it) { + BasicBlock *y = *it; if (!A_phi[y].contains(a)) { insertPhiNode(a, y, function); A_phi[y].insert(a); diff --git a/src/qml/doc/src/qmllanguageref/modules/cppplugins.qdoc b/src/qml/doc/src/qmllanguageref/modules/cppplugins.qdoc index 7ac1d400eb..b5fe941f9f 100644 --- a/src/qml/doc/src/qmllanguageref/modules/cppplugins.qdoc +++ b/src/qml/doc/src/qmllanguageref/modules/cppplugins.qdoc @@ -34,8 +34,9 @@ The \l{QQmlEngine}{QML engine} load C++ plugins for QML. Such plugins are usually provided in a QML extension module, and can - provide types and functionality for use by clients in QML documents - which import the module. + provide types for use by clients in QML documents which import the module. + A module requires at least one type registered in order to be considered + valid. QQmlExtensionPlugin is a plugin interface that makes it possible to create QML extensions that can be loaded dynamically into QML applications. diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp index 9c7cb43351..0fc7f2ddb9 100644 --- a/src/qml/jsruntime/qv4arrayobject.cpp +++ b/src/qml/jsruntime/qv4arrayobject.cpp @@ -276,7 +276,7 @@ ReturnedValue ArrayPrototype::method_pop(CallContext *ctx) if (scope.hasException()) return Encode::undefined(); if (instance->isArrayObject()) - instance->setArrayLengthUnchecked(len - 1); + instance->setArrayLength(len - 1); else instance->put(ctx->engine->id_length, ScopedValue(scope, Primitive::fromDouble(len - 1))); return result.asReturnedValue(); diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 8a11e31b9f..110a8b7586 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -851,7 +851,7 @@ bool QQuickKeysAttached::isConnected(const char *signalName) \list 1 \li Items specified in \c forwardTo \li specific key handlers, e.g. onReturnPressed - \li onKeyPress, onKeyRelease handlers + \li onPressed, onReleased handlers \li Item specific key handling, e.g. TextInput key handling \li parent item \endlist @@ -862,7 +862,7 @@ bool QQuickKeysAttached::isConnected(const char *signalName) \li Item specific key handling, e.g. TextInput key handling \li Items specified in \c forwardTo \li specific key handlers, e.g. onReturnPressed - \li onKeyPress, onKeyRelease handlers + \li onPressed, onReleased handlers \li parent item \endlist diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index 8ff68e20bc..b1464a26cc 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp @@ -169,7 +169,7 @@ ShaderManager::Shader *ShaderManager::prepareMaterial(QSGMaterial *material) #ifndef QSG_NO_RENDER_TIMING if (qsg_render_timing) - printf(" - compiling material: %dms\n", (int) qsg_renderer_timer.elapsed()); + qDebug(" - compiling material: %dms", (int) qsg_renderer_timer.elapsed()); if (QQmlProfilerService::enabled) { QQmlProfilerService::sceneGraphFrame( @@ -208,7 +208,7 @@ ShaderManager::Shader *ShaderManager::prepareMaterialNoRewrite(QSGMaterial *mate #ifndef QSG_NO_RENDER_TIMING if (qsg_render_timing) - printf(" - compiling material: %dms\n", (int) qsg_renderer_timer.elapsed()); + qDebug(" - compiling material: %dms", (int) qsg_renderer_timer.elapsed()); if (QQmlProfilerService::enabled) { QQmlProfilerService::sceneGraphFrame( @@ -2249,7 +2249,7 @@ void Renderer::preprocess() void Renderer::render() { if (Q_UNLIKELY(debug_dump)) { - printf("\n\n"); + qDebug("\n"); QSGNodeDumper::dump(rootNode()); } diff --git a/src/quick/scenegraph/coreapi/qsgrenderer.cpp b/src/quick/scenegraph/coreapi/qsgrenderer.cpp index df70b5c5eb..e35bfe5494 100644 --- a/src/quick/scenegraph/coreapi/qsgrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgrenderer.cpp @@ -279,7 +279,7 @@ void QSGRenderer::renderScene(const QSGBindable &bindable) #ifndef QSG_NO_RENDER_TIMING if (qsg_render_timing) { - printf(" - Breakdown of render time: preprocess=%d, updates=%d, binding=%d, render=%d, total=%d\n", + qDebug(" - Breakdown of render time: preprocess=%d, updates=%d, binding=%d, render=%d, total=%d", int(preprocessTime / 1000000), int((updatePassTime - preprocessTime) / 1000000), int((bindTime - updatePassTime) / 1000000), diff --git a/src/quick/scenegraph/qsgadaptationlayer.cpp b/src/quick/scenegraph/qsgadaptationlayer.cpp index 58c843a286..cb9e4bdf88 100644 --- a/src/quick/scenegraph/qsgadaptationlayer.cpp +++ b/src/quick/scenegraph/qsgadaptationlayer.cpp @@ -189,7 +189,7 @@ void QSGDistanceFieldGlyphCache::update() #ifndef QSG_NO_RENDER_TIMING if (qsg_render_timing) { - printf(" - glyphs: count=%d, render=%d, store=%d, total=%d\n", + qDebug(" - glyphs: count=%d, render=%d, store=%d, total=%d", count, int(renderTime/1000000), (int) qsg_render_timer.elapsed() - int(renderTime/1000000), diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp index d779285a44..d8fe947122 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp +++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp @@ -1136,7 +1136,8 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w) #ifndef QSG_NO_RENDER_TIMING if (qsg_render_timing) - qDebug(" - on GUI: polish=%d, lock=%d, block/sync=%d -- animations=%d", + qDebug(" - Gui Thread: window=%p, polish=%d, lock=%d, block/sync=%d -- animations=%d", + w->window, int(polishTime/1000000), int((waitTime - polishTime)/1000000), int((syncTime - waitTime)/1000000), diff --git a/src/quick/scenegraph/qsgwindowsrenderloop.cpp b/src/quick/scenegraph/qsgwindowsrenderloop.cpp index 0b6d42aca6..5d9583cafb 100644 --- a/src/quick/scenegraph/qsgwindowsrenderloop.cpp +++ b/src/quick/scenegraph/qsgwindowsrenderloop.cpp @@ -61,7 +61,7 @@ extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_ #ifdef QSG_RENDER_LOOP_DEBUG static QElapsedTimer qsg_debug_timer; -# define RLDEBUG(x) printf("(%6d) %s : %4d - %s\n", (int) qsg_debug_timer.elapsed(), __FILE__, __LINE__, x) +# define RLDEBUG(x) qDebug("(%6d) %s : %4d - %s", (int) qsg_debug_timer.elapsed(), __FILE__, __LINE__, x) #else # define RLDEBUG(x) #endif diff --git a/src/quick/scenegraph/util/qsgatlastexture.cpp b/src/quick/scenegraph/util/qsgatlastexture.cpp index 75bf0b6e3c..389945849f 100644 --- a/src/quick/scenegraph/util/qsgatlastexture.cpp +++ b/src/quick/scenegraph/util/qsgatlastexture.cpp @@ -375,7 +375,7 @@ bool Atlas::bind(QSGTexture::Filtering filtering) #ifndef QSG_NO_RENDER_TIMING if (qsg_render_timing) { - printf(" - AtlasTexture(%dx%d), uploaded in %d ms\n", + qDebug(" - AtlasTexture(%dx%d), uploaded in %d ms", m_pending_uploads.at(i)->image().width(), m_pending_uploads.at(i)->image().height(), (int) (qsg_renderer_timer.elapsed())); diff --git a/src/quick/scenegraph/util/qsgtexture.cpp b/src/quick/scenegraph/util/qsgtexture.cpp index 51b3bafaf7..df724d8a01 100644 --- a/src/quick/scenegraph/util/qsgtexture.cpp +++ b/src/quick/scenegraph/util/qsgtexture.cpp @@ -629,7 +629,7 @@ void QSGPlainTexture::bind() glDeleteTextures(1, &m_texture_id); #ifndef QSG_NO_RENDER_TIMING if (qsg_render_timing) { - printf(" - texture deleted in %dms (size: %dx%d)\n", + qDebug(" - texture deleted in %dms (size: %dx%d)", (int) qsg_renderer_timer.elapsed(), m_texture_size.width(), m_texture_size.height()); @@ -725,7 +725,7 @@ void QSGPlainTexture::bind() if (qsg_render_timing) { mipmapTime = qsg_renderer_timer.nsecsElapsed(); - printf(" - plaintexture(%dx%d) bind=%d, convert=%d, swizzle=%d (%s->%s), upload=%d, mipmap=%d, total=%d\n", + qDebug(" - plaintexture(%dx%d) bind=%d, convert=%d, swizzle=%d (%s->%s), upload=%d, mipmap=%d, total=%d", m_texture_size.width(), m_texture_size.height(), int(bindTime/1000000), int((convertTime - bindTime)/1000000), diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp index 726f8636b6..a1662b495c 100644 --- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp +++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp @@ -146,6 +146,8 @@ private slots: void threadedEngine(); void functionDeclarationsInConditionals(); + + void arrayPop_QTBUG_35979(); }; tst_QJSEngine::tst_QJSEngine() @@ -2692,6 +2694,17 @@ void tst_QJSEngine::functionDeclarationsInConditionals() QCOMPARE(result.toBool(), true); } +void tst_QJSEngine::arrayPop_QTBUG_35979() +{ + QJSEngine eng; + QJSValue result = eng.evaluate("" + "var x = [1, 2]\n" + "x.pop()\n" + "x[1] = 3\n" + "x.toString()\n"); + QCOMPARE(result.toString(), QString("1,3")); +} + QTEST_MAIN(tst_QJSEngine) #include "tst_qjsengine.moc" |