aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2014-01-08 19:26:48 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-01-08 19:26:48 +0100
commitff18885e0a7f7527eb96a9f2047507e7f418db45 (patch)
tree37bd1970c31447c73862b81eae4429c7366ef1c7
parent439f31f128e70ecae16544ee7041695c60e0b2d6 (diff)
parent40722a7eaf6bb6d77d730dc3f8510718e2cad549 (diff)
Merge "Merge remote-tracking branch 'origin/stable' into dev" into refs/staging/dev
-rw-r--r--src/imports/testlib/signalspy.qdoc2
-rw-r--r--src/imports/testlib/testcase.qdoc2
-rw-r--r--src/qml/compiler/qv4ssa.cpp171
-rw-r--r--src/qml/doc/src/qmllanguageref/modules/cppplugins.qdoc5
-rw-r--r--src/qml/jsruntime/qv4arrayobject.cpp2
-rw-r--r--src/quick/items/qquickitem.cpp4
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp6
-rw-r--r--src/quick/scenegraph/coreapi/qsgrenderer.cpp2
-rw-r--r--src/quick/scenegraph/qsgadaptationlayer.cpp2
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop.cpp3
-rw-r--r--src/quick/scenegraph/qsgwindowsrenderloop.cpp2
-rw-r--r--src/quick/scenegraph/util/qsgatlastexture.cpp2
-rw-r--r--src/quick/scenegraph/util/qsgtexture.cpp4
-rw-r--r--tests/auto/qml/qjsengine/tst_qjsengine.cpp13
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"