summaryrefslogtreecommitdiffstats
path: root/doc/src/snippets/code/src_gui_image_qbitmap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'doc/src/snippets/code/src_gui_image_qbitmap.cpp')
0 files changed, 0 insertions, 0 deletions
- tests/auto/qsharedmemory/tst_qsharedmemory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qsharedmemory/tst_qsharedmemory.cpp b/tests/auto/qsharedmemory/tst_qsharedmemory.cpp index c4ff76c..db86c06 100644 --- a/tests/auto/qsharedmemory/tst_qsharedmemory.cpp +++ b/tests/auto/qsharedmemory/tst_qsharedmemory.cpp @@ -773,7 +773,7 @@ void tst_QSharedMemory::simpleProcessProducerConsumer() delete consumers.takeFirst(); } QCOMPARE(consumerFailed, false); - QCOMPARE(failedProcesses, unsigned int (0)); + QCOMPARE(failedProcesses, (unsigned int)(0)); } QTEST_MAIN(tst_QSharedMemory) -- cgit v0.12 From 5850ba16e9905677af58461bb5efc7fcb43a976a Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 5 Oct 2009 09:49:53 +0200 Subject: Compile on Visual Studio 2003 Don't add export declaration for the definition of the variable. Reviewed-by: Gunnar (cherry picked from commit 1aaa11708eb0f8281e6de2c4ea6f04e5d38813e0) --- src/corelib/kernel/qmath.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/kernel/qmath.cpp b/src/corelib/kernel/qmath.cpp index 24bec4a..7c1e726 100644 --- a/src/corelib/kernel/qmath.cpp +++ b/src/corelib/kernel/qmath.cpp @@ -43,7 +43,7 @@ QT_BEGIN_NAMESPACE -Q_CORE_EXPORT const qreal qt_sine_table[QT_SINE_TABLE_SIZE] = { +const qreal qt_sine_table[QT_SINE_TABLE_SIZE] = { 0.0, 0.024541228522912288, 0.049067674327418015, -- cgit v0.12 From a4245ded41a1710d1f6b140fde66af0b5121250d Mon Sep 17 00:00:00 2001 From: Janne Anttila Date: Mon, 5 Oct 2009 10:53:57 +0300 Subject: Fixed tst_qgraphicsitem.cpp compilation for Nokia X86 compiler. Nokia X86 compiler is not able to resolve correct templated qCompare functionfor derived types. So implicit casting does nto work corectly. I have tried to add template specilations for qCompare also, but then compiler complainf about unambiguous functions. The promlem for now is fixed by adding explicit cast to same type against which the comparuion is done. Reviewed-by: TrustMe (cherry picked from commit 7655e27047790d89f9af0132946ad5db5138e7bf) --- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 9545198..e2e8c5f 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -7631,7 +7631,7 @@ void tst_QGraphicsItem::hitTestGraphicsEffectItem() QVERIFY(items.isEmpty()); items = scene.items(QPointF(80, 80)); QCOMPARE(items.size(), 1); - QCOMPARE(items.at(0), static_cast(item3)); + QCOMPARE(items.at(0), static_cast(item3)); item1->repaints = 0; item2->repaints = 0; @@ -7654,7 +7654,7 @@ void tst_QGraphicsItem::hitTestGraphicsEffectItem() QVERIFY(items.isEmpty()); items = scene.items(QPointF(80, 80)); QCOMPARE(items.size(), 1); - QCOMPARE(items.at(0), static_cast(item3)); + QCOMPARE(items.at(0), static_cast(item3)); } void tst_QGraphicsItem::focusProxy() @@ -8384,7 +8384,7 @@ void tst_QGraphicsItem::ensureDirtySceneTransform() QGraphicsView view(&scene); view.show(); QTest::qWaitForWindowShown(&view); - QTRY_COMPARE(QApplication::activeWindow(), &view); + QTRY_COMPARE(QApplication::activeWindow(), static_cast(&view)); //We move the parent parent->move(); -- cgit v0.12 From b65da11b64615d558b007d4ebc821c435af24b0f Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Mon, 5 Oct 2009 10:01:44 +0200 Subject: Disable etched text on rich text labels When rendering etched text on disabled rich text labels we would previously draw distorted links. This is basically because anything that did not render with the text foreground role would be drawn twice as a shadow. Since there is no way to properly render this text etched we will rather disable it completely when the label uses rich text. Task-number: QTBUG-4543 Reviewed-by: Simon Hausmann (cherry picked from commit d1d661a1858e28befe5980c22009702f5ea82829) --- src/gui/widgets/qlabel.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gui/widgets/qlabel.cpp b/src/gui/widgets/qlabel.cpp index 5ba0571..3d908a1 100644 --- a/src/gui/widgets/qlabel.cpp +++ b/src/gui/widgets/qlabel.cpp @@ -1000,8 +1000,10 @@ void QLabel::paintEvent(QPaintEvent *) d->ensureTextLayouted(); QAbstractTextDocumentLayout::PaintContext context; - - if (!isEnabled() && style->styleHint(QStyle::SH_EtchDisabledText, &opt, this)) { + if (!isEnabled() && !d->control && + // We cannot support etched for rich text controls because custom + // colors and links will override the light palette + style->styleHint(QStyle::SH_EtchDisabledText, &opt, this)) { context.palette = opt.palette; context.palette.setColor(QPalette::Text, context.palette.light().color()); painter.save(); -- cgit v0.12 From a1a1e5f064647dd012790126fd3281d59ca05d18 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Mon, 5 Oct 2009 10:20:38 +0200 Subject: Make QEventTransition works with QGraphicsObject. QStateMachine framework installs QObject event filters to catch events in order to triggers the proper transition. But installing a QObject event filter on a QGraphicsObject gives nothing because QGraphicsView events filters works differently. In order to make this works we now post events using QApplication::postEvent in addition to the QGraphicsView events. Reviewed-by:andreas (cherry picked from commit 10dba674d366260589f3b742e5b1b87ce9ddd47c) --- src/corelib/kernel/qcoreevent.h | 1 - src/gui/graphicsview/qgraphicsscene.cpp | 12 +++++++++++- src/gui/graphicsview/qgraphicswidget.cpp | 6 ------ 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h index a039d32..d66cead 100644 --- a/src/corelib/kernel/qcoreevent.h +++ b/src/corelib/kernel/qcoreevent.h @@ -324,7 +324,6 @@ private: friend class QGraphicsView; friend class QGraphicsViewPrivate; friend class QGraphicsScenePrivate; - friend class QGraphicsWidget; }; class Q_CORE_EXPORT QTimerEvent : public QEvent diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 1226722..961f44f 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -254,6 +254,8 @@ QT_BEGIN_NAMESPACE +bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event); + static void _q_hoverFromMouseEvent(QGraphicsSceneHoverEvent *hover, const QGraphicsSceneMouseEvent *mouseEvent) { hover->setWidget(mouseEvent->widget()); @@ -1051,7 +1053,15 @@ bool QGraphicsScenePrivate::sendEvent(QGraphicsItem *item, QEvent *event) return false; if (filterDescendantEvent(item, event)) return false; - return (item && item->isEnabled() ? item->sceneEvent(event) : false); + if (!item || !item->isEnabled()) + return false; + if (QGraphicsObject *o = item->toGraphicsObject()) { + bool spont = event->spontaneous(); + if (spont ? qt_sendSpontaneousEvent(o, event) : QApplication::sendEvent(o, event)) + return true; + event->spont = spont; + } + return item->sceneEvent(event); } /*! diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index 224f50b..7764157 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -168,8 +168,6 @@ QT_BEGIN_NAMESPACE \sa QGraphicsProxyWidget, QGraphicsItem, {Widgets and Layouts} */ -bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event); - /*! Constructs a QGraphicsWidget instance. The optional \a parent argument is passed to QGraphicsItem's constructor. The optional \a wFlags argument @@ -1103,10 +1101,6 @@ QVariant QGraphicsWidget::propertyChange(const QString &propertyName, const QVar */ bool QGraphicsWidget::sceneEvent(QEvent *event) { - bool spont = event->spontaneous(); - if (spont ? qt_sendSpontaneousEvent(this, event) : QApplication::sendEvent(this, event)) - return true; - event->spont = spont; return QGraphicsItem::sceneEvent(event); } -- cgit v0.12 From 628946bb0912bd91f6936e87387792e068b19950 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 5 Oct 2009 11:12:59 +0200 Subject: Tooltip: reusing tooltips sometimes goes wrong We reuse tooltip whenever we can. But we forget to check if the format of the text changes inbetween (from html to plain). This causes the word wrap to fail sometimes. This change will fix that. Rev-By:MortenS (cherry picked from commit 80e47c92e0b4f506b2b57d0e58022903dc62ba3d) --- src/gui/kernel/qtooltip.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qtooltip.cpp b/src/gui/kernel/qtooltip.cpp index 2d0d209..4261808 100644 --- a/src/gui/kernel/qtooltip.cpp +++ b/src/gui/kernel/qtooltip.cpp @@ -183,7 +183,6 @@ QTipLabel::QTipLabel(const QString &text, QWidget *w) setFrameStyle(QFrame::NoFrame); setAlignment(Qt::AlignLeft); setIndent(1); - setWordWrap(Qt::mightBeRichText(text)); qApp->installEventFilter(this); setWindowOpacity(style()->styleHint(QStyle::SH_ToolTipLabel_Opacity, 0, this) / 255.0); setMouseTracking(true); @@ -208,6 +207,7 @@ void QTipLabel::reuseTip(const QString &text) } #endif + setWordWrap(Qt::mightBeRichText(text)); setText(text); QFontMetrics fm(font()); QSize extra(1, 0); -- cgit v0.12 From 314998dec983607a8af47ab247f2af40d81bb0db Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Mon, 5 Oct 2009 11:32:49 +0200 Subject: Doc fix. Reviewed-by:TrustMe (cherry picked from commit 144273fe9e2280f52f1dba0b5781a54f8b459d1e) --- src/gui/graphicsview/qsimplex_p.cpp | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/gui/graphicsview/qsimplex_p.cpp b/src/gui/graphicsview/qsimplex_p.cpp index 1ece8b1..00fc204 100644 --- a/src/gui/graphicsview/qsimplex_p.cpp +++ b/src/gui/graphicsview/qsimplex_p.cpp @@ -75,15 +75,24 @@ QT_BEGIN_NAMESPACE 3.c) Run simplex to optimize the original problem towards its optimal solution. */ +/*! + \internal +*/ QSimplex::QSimplex() : objective(0), rows(0), columns(0), firstArtificial(0), matrix(0) { } +/*! + \internal +*/ QSimplex::~QSimplex() { clearDataStructures(); } +/*! + \internal +*/ void QSimplex::clearDataStructures() { if (matrix == 0) @@ -312,11 +321,17 @@ void QSimplex::solveMaxHelper() while (iterate()) ; } +/*! + \internal +*/ void QSimplex::setObjective(QSimplexConstraint *newObjective) { objective = newObjective; } +/*! + \internal +*/ void QSimplex::clearRow(int rowIndex) { qreal *item = matrix + rowIndex * columns; @@ -324,6 +339,9 @@ void QSimplex::clearRow(int rowIndex) item[i] = 0.0; } +/*! + \internal +*/ void QSimplex::clearColumns(int first, int last) { for (int i = 0; i < rows; ++i) { @@ -333,6 +351,9 @@ void QSimplex::clearColumns(int first, int last) } } +/*! + \internal +*/ void QSimplex::dumpMatrix() { qDebug("---- Simplex Matrix ----\n"); @@ -352,6 +373,9 @@ void QSimplex::dumpMatrix() qDebug("------------------------\n"); } +/*! + \internal +*/ void QSimplex::combineRows(int toIndex, int fromIndex, qreal factor) { if (!factor) @@ -375,6 +399,9 @@ void QSimplex::combineRows(int toIndex, int fromIndex, qreal factor) } } +/*! + \internal +*/ int QSimplex::findPivotColumn() { qreal min = 0; @@ -429,6 +456,9 @@ int QSimplex::pivotRowForColumn(int column) return minIndex; } +/*! + \internal +*/ void QSimplex::reducedRowEchelon() { for (int i = 1; i < rows; ++i) { -- cgit v0.12 From 93f741bfe867b4644f4bb7d5bfc768273ed6f035 Mon Sep 17 00:00:00 2001 From: Jeremy Katz Date: Mon, 5 Oct 2009 11:32:10 +0200 Subject: fix creation of qws directory when app start preceeds qvfb Change authored by Rhys. Bug introduced by the change to allow user-specific cache and pipe directories. Reviewed-by: Jeremy (cherry picked from commit af1d916b86295543b8e20be79abf48453d9c55d0) --- src/gui/embedded/qvfbhdr.h | 2 +- src/gui/kernel/qapplication_qws.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/embedded/qvfbhdr.h b/src/gui/embedded/qvfbhdr.h index eff5fc2..73b13d3 100644 --- a/src/gui/embedded/qvfbhdr.h +++ b/src/gui/embedded/qvfbhdr.h @@ -70,7 +70,7 @@ QT_MODULE(Gui) .append("/qt_soundserver") #define QTE_PIPE(DISPLAY) QT_VFB_DATADIR(DISPLAY) \ .append("/QtEmbedded") -#define QTE_PIPE_QVFB QTE_PIPE +#define QTE_PIPE_QVFB(DISPLAY) QTE_PIPE(DISPLAY) #else #define QT_VFB_DATADIR(DISPLAY) QString("%1/qtembedded-%2") \ .arg(QT_QWS_TEMP_DIR).arg(DISPLAY) diff --git a/src/gui/kernel/qapplication_qws.cpp b/src/gui/kernel/qapplication_qws.cpp index 634f23a..167beb2 100644 --- a/src/gui/kernel/qapplication_qws.cpp +++ b/src/gui/kernel/qapplication_qws.cpp @@ -232,6 +232,7 @@ QString qws_dataDir() // Get the filename of the pipe Qt for Embedded Linux uses for server/client comms Q_GUI_EXPORT QString qws_qtePipeFilename() { + qws_dataDir(); return QTE_PIPE(qws_display_id); } -- cgit v0.12 From a30f64e613aa5899b3c80206a2f0d55f3116357e Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Mon, 5 Oct 2009 11:02:24 +0200 Subject: Added autotest for qFastSin() and qFastCos(). Reviewed-by: Trond (cherry picked from commit a3e74ba189475d606f2a7a07f52591fd312a45c9) --- tests/auto/auto.pro | 1 + tests/auto/qmath/qmath.pro | 6 ++++ tests/auto/qmath/tst_qmath.cpp | 67 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 tests/auto/qmath/qmath.pro create mode 100644 tests/auto/qmath/tst_qmath.cpp diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 9321e19..f3ecdae 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -203,6 +203,7 @@ SUBDIRS += \ qmainwindow \ qmake \ qmap \ + qmath \ qmatrixnxn \ qmdiarea \ qmdisubwindow \ diff --git a/tests/auto/qmath/qmath.pro b/tests/auto/qmath/qmath.pro new file mode 100644 index 0000000..03134ee --- /dev/null +++ b/tests/auto/qmath/qmath.pro @@ -0,0 +1,6 @@ +load(qttest_p4) + +QT = core + +SOURCES += tst_qmath.cpp +QT = core diff --git a/tests/auto/qmath/tst_qmath.cpp b/tests/auto/qmath/tst_qmath.cpp new file mode 100644 index 0000000..efc7cfa --- /dev/null +++ b/tests/auto/qmath/tst_qmath.cpp @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +static const qreal PI = 3.14159265358979323846264338327950288; + +class tst_QMath : public QObject +{ + Q_OBJECT +private slots: + void fastSinCos(); +}; + +void tst_QMath::fastSinCos() +{ + // Test evenly spaced angles from 0 to 2pi radians. + const int LOOP_COUNT = 100000; + for (int i = 0; i < LOOP_COUNT; ++i) { + qreal angle = i * 2 * PI / (LOOP_COUNT - 1); + QVERIFY(qAbs(qSin(angle) - qFastSin(angle)) < 1e-5); + QVERIFY(qAbs(qCos(angle) - qFastCos(angle)) < 1e-5); + } +} + +QTEST_APPLESS_MAIN(tst_QMath) + +#include "tst_qmath.moc" -- cgit v0.12 From f17dc09850525392bb373f5eeb432db32b618adb Mon Sep 17 00:00:00 2001 From: Janne Anttila Date: Mon, 5 Oct 2009 12:36:32 +0300 Subject: Changed Qt package name in pkg and generated sis files for Symbian. It was decided on weekly telco that Symbian pkg and sis files can use plain Qt name, since it is already clear that user is installing "Qt for Symbian" version of Qt. Task-number: QT-772 Reviewed-by: Miikka Heikkinen (cherry picked from commit a3ef6e080980e242dd7703c48a628ad821549991) --- mkspecs/features/symbian/qt.prf | 8 ++++---- src/s60installs/s60installs.pro | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/mkspecs/features/symbian/qt.prf b/mkspecs/features/symbian/qt.prf index 3b24355..0f5b08b 100644 --- a/mkspecs/features/symbian/qt.prf +++ b/mkspecs/features/symbian/qt.prf @@ -21,13 +21,13 @@ load(qt) # INCLUDEPATH = $$PREPEND_INCLUDEPATH $$INCLUDEPATH -# Add dependency to QtLibs package to all other projects besides QtLibs. -# Note: QtLibs with full capabilities has UID3 of 0x2001E61C, -# while self-signed version typically has temporary UID3 of 0xE001E61C. +# Add dependency to Qt package to all other projects besides Qt libs. +# Note: Qt libs with full capabilities has UID3 of 0x2001E61C, +# while self-signed version typically has temporary UID3 of 0xE001E61C. contains(CONFIG, qt):!contains(TARGET.UID3, 0x2001E61C):!contains(TARGET.UID3, 0xE001E61C) { default_deployment.pkg_prerules += \ "; Default dependency to Qt libraries" \ - "(0x2001E61C), $${QT_MAJOR_VERSION}, $${QT_MINOR_VERSION}, $${QT_PATCH_VERSION}, {\"QtLibs pre-release\"}" + "(0x2001E61C), $${QT_MAJOR_VERSION}, $${QT_MINOR_VERSION}, $${QT_PATCH_VERSION}, {\"Qt\"}" } isEmpty(TARGET.EPOCSTACKSIZE):TARGET.EPOCSTACKSIZE = 0x14000 diff --git a/src/s60installs/s60installs.pro b/src/s60installs/s60installs.pro index d21c524..3aef05e 100644 --- a/src/s60installs/s60installs.pro +++ b/src/s60installs/s60installs.pro @@ -7,7 +7,7 @@ symbian: { SUBDIRS= # WARNING: Changing TARGET name will break Symbian SISX upgrade functionality # DO NOT TOUCH TARGET VARIABLE IF YOU ARE NOT SURE WHAT YOU ARE DOING - TARGET = "Qt for S60" + TARGET = "Qt" TARGET.UID3 = 0x2001E61C VERSION=$${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION}.$${QT_PATCH_VERSION} @@ -29,12 +29,12 @@ symbian: { "ELSEIF package(0x102752AE)" \ " \"$${EPOCROOT}epoc32/release/$(PLATFORM)/$(TARGET)/qts60plugin_3_2.dll\" - \"!:\\sys\\bin\\qts60plugin_3_2.dll\"" \ "ELSEIF package(0x102032BE)" \ - " \"$${EPOCROOT}epoc32/release/$(PLATFORM)/$(TARGET)/qts60plugin_3_1.dll\" - \"!:\\sys\\bin\\qts60plugin_3_1.dll\"" \ - "ELSE" \ + " \"$${EPOCROOT}epoc32/release/$(PLATFORM)/$(TARGET)/qts60plugin_3_1.dll\" - \"!:\\sys\\bin\\qts60plugin_3_1.dll\"" \ + "ELSE" \ " \"$${EPOCROOT}epoc32/release/$(PLATFORM)/$(TARGET)/qts60plugin_5_0.dll\" - \"!:\\sys\\bin\\qts60plugin_5_0.dll\"" \ - "ENDIF" - qtlibraries.pkg_postrules += qts60plugindeployment - + "ENDIF" + qtlibraries.pkg_postrules += qts60plugindeployment + sqlitedeployment = \ "; EXISTS statement does not resolve !. Lets check the most common drives" \ "IF NOT EXISTS(\"c:\\sys\\bin\\sqlite3.dll\") AND NOT EXISTS(\"e:\\sys\\bin\\sqlite3.dll\") AND NOT EXISTS(\"z:\\sys\\bin\\sqlite3.dll\")" \ -- cgit v0.12 From e9a205a61f1c4a352e8a46d749b0a7984527e380 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 1 Oct 2009 11:29:34 +0200 Subject: Autotest: Don't run 15 and 35 threads on Windows CE. The device can't cope, so let's keep only the small thread count tests there. Reviewed-by: Trust Me (cherry picked from commit c5352705d933e76df6d40f01a5e6803bc4106b93) --- tests/auto/qsharedpointer/tst_qsharedpointer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp index fa63c4b..94c3aaa 100644 --- a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp @@ -1448,10 +1448,11 @@ void tst_QSharedPointer::threadStressTest_data() QTest::newRow("1+1") << 1 << 1; QTest::newRow("2+10") << 2 << 10; +#ifndef Q_OS_WINCE + // Windows CE cannot run this many threads QTest::newRow("5+10") << 5 << 10; QTest::newRow("5+30") << 5 << 30; -#ifndef Q_OS_WINCE QTest::newRow("100+100") << 100 << 100; #endif } -- cgit v0.12 From 6608061ac0235814ab9522fea84b1cf5366799c3 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 1 Oct 2009 11:36:19 +0200 Subject: Autotest: disable the forwardDeclared1 test in WinSCW too. It also invokes the destructor directly, even on forward-declared types. That must be an ABI convention. This test isn't reliable. Reviewed-by: TrustMe (cherry picked from commit 1d01065f3c88701eeed8018c2125b0170d057b52) --- tests/auto/qsharedpointer/tst_qsharedpointer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp index 94c3aaa..58eaacb 100644 --- a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp @@ -308,7 +308,7 @@ extern int forwardDeclaredDestructorRunCount; void tst_QSharedPointer::forwardDeclaration1() { -#if defined(Q_CC_SUN) +#if defined(Q_CC_SUN) || defined(Q_CC_WINSCW) || defined(Q_CC_RVCT) QSKIP("This type of forward declaration is not valid with this compiler", SkipAll); #else externalForwardDeclaration(); -- cgit v0.12 From 377160bbe4a61b9b358120006c8a7b152618ae1c Mon Sep 17 00:00:00 2001 From: "Andre Moreira Magalhaes (andrunko)" Date: Wed, 30 Sep 2009 16:20:17 -0300 Subject: Added operator== for QDBusArgument. Reviewed-By: Thiago Macieira Merge-Request: 1657 (cherry picked from commit 429c7c6760c100685e9800b89fca7f0afd2d8abc) --- src/dbus/qdbusextratypes.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/dbus/qdbusextratypes.h b/src/dbus/qdbusextratypes.h index c95537b..69dcc8a 100644 --- a/src/dbus/qdbusextratypes.h +++ b/src/dbus/qdbusextratypes.h @@ -174,6 +174,9 @@ inline QDBusVariant::QDBusVariant(const QVariant &dBusVariant) inline void QDBusVariant::setVariant(const QVariant &dBusVariant) { QVariant::operator=(dBusVariant); } +inline bool operator==(const QDBusVariant &v1, const QDBusVariant &v2) +{ return v1.variant() == v2.variant(); } + QT_END_NAMESPACE Q_DECLARE_METATYPE(QDBusVariant) -- cgit v0.12 From 136461523e1ff6f0266bec22b29f1cad3dc3d310 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Mon, 5 Oct 2009 11:49:54 +0200 Subject: Simplification and use of QGraphicsObject in sub-attas demo Reviewed-by: alexis (cherry picked from commit 32a9237c49fd126bee0cbe02c3c5bff5145a6e21) --- demos/sub-attaq/animationmanager.cpp | 6 +- demos/sub-attaq/boat.cpp | 92 ++++--------- demos/sub-attaq/boat.h | 12 +- demos/sub-attaq/boat_p.h | 50 ++----- demos/sub-attaq/bomb.cpp | 16 +-- demos/sub-attaq/bomb.h | 16 +-- demos/sub-attaq/custompropertyanimation.cpp | 108 --------------- demos/sub-attaq/custompropertyanimation.h | 114 ---------------- demos/sub-attaq/graphicsscene.cpp | 196 +++++++--------------------- demos/sub-attaq/graphicsscene.h | 13 +- demos/sub-attaq/mainwindow.cpp | 31 ++--- demos/sub-attaq/mainwindow.h | 1 - demos/sub-attaq/pixmapitem.cpp | 33 +++-- demos/sub-attaq/pixmapitem.h | 14 +- demos/sub-attaq/states.cpp | 39 ++---- demos/sub-attaq/states.h | 2 - demos/sub-attaq/sub-attaq.pro | 2 - demos/sub-attaq/submarine.cpp | 62 ++------- demos/sub-attaq/submarine.h | 11 +- demos/sub-attaq/submarine_p.h | 1 - demos/sub-attaq/torpedo.cpp | 20 +-- demos/sub-attaq/torpedo.h | 16 +-- 22 files changed, 181 insertions(+), 674 deletions(-) delete mode 100644 demos/sub-attaq/custompropertyanimation.cpp delete mode 100644 demos/sub-attaq/custompropertyanimation.h diff --git a/demos/sub-attaq/animationmanager.cpp b/demos/sub-attaq/animationmanager.cpp index 916dd21..eb5a125 100644 --- a/demos/sub-attaq/animationmanager.cpp +++ b/demos/sub-attaq/animationmanager.cpp @@ -77,16 +77,14 @@ void AnimationManager::unregisterAllAnimations() void AnimationManager::pauseAll() { - foreach (QAbstractAnimation* animation, animations) - { + foreach (QAbstractAnimation* animation, animations) { if (animation->state() == QAbstractAnimation::Running) animation->pause(); } } void AnimationManager::resumeAll() { - foreach (QAbstractAnimation* animation, animations) - { + foreach (QAbstractAnimation* animation, animations) { if (animation->state() == QAbstractAnimation::Paused) animation->resume(); } diff --git a/demos/sub-attaq/boat.cpp b/demos/sub-attaq/boat.cpp index 864a099..3b1bac7 100644 --- a/demos/sub-attaq/boat.cpp +++ b/demos/sub-attaq/boat.cpp @@ -46,7 +46,6 @@ #include "pixmapitem.h" #include "graphicsscene.h" #include "animationmanager.h" -#include "custompropertyanimation.h" #include "qanimationstate.h" //Qt @@ -60,79 +59,35 @@ static QAbstractAnimation *setupDestroyAnimation(Boat *boat) { QSequentialAnimationGroup *group = new QSequentialAnimationGroup(boat); -#if QT_VERSION >=0x040500 - PixmapItem *step1 = new PixmapItem(QString("explosion/boat/step1"),GraphicsScene::Big, boat); - step1->setZValue(6); - PixmapItem *step2 = new PixmapItem(QString("explosion/boat/step2"),GraphicsScene::Big, boat); - step2->setZValue(6); - PixmapItem *step3 = new PixmapItem(QString("explosion/boat/step3"),GraphicsScene::Big, boat); - step3->setZValue(6); - PixmapItem *step4 = new PixmapItem(QString("explosion/boat/step4"),GraphicsScene::Big, boat); - step4->setZValue(6); - step1->setOpacity(0); - step2->setOpacity(0); - step3->setOpacity(0); - step4->setOpacity(0); - CustomPropertyAnimation *anim1 = new CustomPropertyAnimation(boat); - anim1->setMemberFunctions((QGraphicsItem*)step1, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); - anim1->setDuration(100); - anim1->setEndValue(1); - CustomPropertyAnimation *anim2 = new CustomPropertyAnimation(boat); - anim2->setMemberFunctions((QGraphicsItem*)step2, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); - anim2->setDuration(100); - anim2->setEndValue(1); - CustomPropertyAnimation *anim3 = new CustomPropertyAnimation(boat); - anim3->setMemberFunctions((QGraphicsItem*)step3, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); - anim3->setDuration(100); - anim3->setEndValue(1); - CustomPropertyAnimation *anim4 = new CustomPropertyAnimation(boat); - anim4->setMemberFunctions((QGraphicsItem*)step4, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); - anim4->setDuration(100); - anim4->setEndValue(1); - CustomPropertyAnimation *anim5 = new CustomPropertyAnimation(boat); - anim5->setMemberFunctions((QGraphicsItem*)step1, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); - anim5->setDuration(100); - anim5->setEndValue(0); - CustomPropertyAnimation *anim6 = new CustomPropertyAnimation(boat); - anim6->setMemberFunctions((QGraphicsItem*)step2, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); - anim6->setDuration(100); - anim6->setEndValue(0); - CustomPropertyAnimation *anim7 = new CustomPropertyAnimation(boat); - anim7->setMemberFunctions((QGraphicsItem*)step3, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); - anim7->setDuration(100); - anim7->setEndValue(0); - CustomPropertyAnimation *anim8 = new CustomPropertyAnimation(boat); - anim8->setMemberFunctions((QGraphicsItem*)step4, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); - anim8->setDuration(100); - anim8->setEndValue(0); - group->addAnimation(anim1); - group->addAnimation(anim2); - group->addAnimation(anim3); - group->addAnimation(anim4); - group->addAnimation(anim5); - group->addAnimation(anim6); - group->addAnimation(anim7); - group->addAnimation(anim8); -#else - // work around for a bug where we don't transition if the duration is zero. - QtPauseAnimation *anim = new QtPauseAnimation(group); - anim->setDuration(1); - group->addAnimation(anim); -#endif + for (int i = 1; i <= 4; i++) { + PixmapItem *step = new PixmapItem(QString("explosion/boat/step%1").arg(i),GraphicsScene::Big, boat); + step->setZValue(6); + step->setOpacity(0); + + //fade-in + QPropertyAnimation *anim = new QPropertyAnimation(step, "opacity"); + anim->setEndValue(1); + anim->setDuration(100); + group->insertAnimationAt(i-1, anim); + + //and then fade-out + QPropertyAnimation *anim2 = new QPropertyAnimation(step, "opacity"); + anim2->setEndValue(0); + anim2->setDuration(100); + group->addAnimation(anim2); + } + AnimationManager::self()->registerAnimation(group); return group; } -Boat::Boat(QGraphicsItem * parent, Qt::WindowFlags wFlags) - : QGraphicsWidget(parent,wFlags), speed(0), bombsAlreadyLaunched(0), direction(Boat::None), movementAnimation(0) +Boat::Boat() : PixmapItem(QString("boat"), GraphicsScene::Big), + speed(0), bombsAlreadyLaunched(0), direction(Boat::None), movementAnimation(0) { - pixmapItem = new PixmapItem(QString("boat"),GraphicsScene::Big, this); setZValue(4); - setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsFocusable); - resize(pixmapItem->boundingRect().size()); + setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsFocusable); //The movement animation used to animate the boat movementAnimation = new QPropertyAnimation(this, "pos"); @@ -223,13 +178,13 @@ Boat::Boat(QGraphicsItem * parent, Qt::WindowFlags wFlags) destroyedState->setAnimation(destroyAnimation); //Play a nice animation when the boat is destroyed - moving->addTransition(this, SIGNAL(boatDestroyed()),destroyedState); + moving->addTransition(this, SIGNAL(boatDestroyed()), destroyedState); //Transition to final state when the destroyed animation is finished destroyedState->addTransition(destroyedState, SIGNAL(animationFinished()), final); //The machine has finished to be executed, then the boat is dead - connect(machine,SIGNAL(finished()),this, SIGNAL(boatExecutionFinished())); + connect(machine,SIGNAL(finished()), this, SIGNAL(boatExecutionFinished())); } @@ -255,7 +210,6 @@ void Boat::updateBoatMovement() } movementAnimation->stop(); - movementAnimation->setStartValue(pos()); if (direction == Boat::Left) { movementAnimation->setEndValue(QPointF(0,y())); diff --git a/demos/sub-attaq/boat.h b/demos/sub-attaq/boat.h index 0fe8ce4..0b4de1e 100644 --- a/demos/sub-attaq/boat.h +++ b/demos/sub-attaq/boat.h @@ -42,13 +42,8 @@ #ifndef __BOAT__H__ #define __BOAT__H__ -//Qt -#include -#include +#include "pixmapitem.h" -#include - -class PixmapItem; class Bomb; QT_BEGIN_NAMESPACE class QVariantAnimation; @@ -56,7 +51,7 @@ class QAbstractAnimation; class QStateMachine; QT_END_NAMESPACE -class Boat : public QGraphicsWidget +class Boat : public PixmapItem { Q_OBJECT public: @@ -66,7 +61,7 @@ public: Right }; enum { Type = UserType + 2 }; - Boat(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0); + Boat(); void destroy(); void run(); void stop(); @@ -95,7 +90,6 @@ private: QVariantAnimation *movementAnimation; QAbstractAnimation *destroyAnimation; QStateMachine *machine; - PixmapItem *pixmapItem; }; #endif //__BOAT__H__ diff --git a/demos/sub-attaq/boat_p.h b/demos/sub-attaq/boat_p.h index 692702b..6eb52b6 100644 --- a/demos/sub-attaq/boat_p.h +++ b/demos/sub-attaq/boat_p.h @@ -67,22 +67,16 @@ static const int MAX_BOMB = 5; class KeyStopTransition : public QKeyEventTransition { public: - KeyStopTransition(Boat *boat, QEvent::Type type, int key) - : QKeyEventTransition(boat, type, key) + KeyStopTransition(Boat *b, QEvent::Type t, int k) + : QKeyEventTransition(b, t, k), boat(b), key(k) { - this->boat = boat; - this->key = key; } protected: virtual bool eventTest(QEvent *event) { - Q_UNUSED(event); if (!QKeyEventTransition::eventTest(event)) return false; - if (boat->currentSpeed() == 1) - return true; - else - return false; + return (boat->currentSpeed() == 1); } private: Boat * boat; @@ -93,23 +87,16 @@ private: class KeyMoveTransition : public QKeyEventTransition { public: - KeyMoveTransition(Boat *boat, QEvent::Type type, int key) - : QKeyEventTransition(boat, type, key) + KeyMoveTransition(Boat *b, QEvent::Type t, int k) + : QKeyEventTransition(b, t, k), boat(b), key(k) { - this->boat = boat; - this->key = key; } protected: virtual bool eventTest(QEvent *event) { - Q_UNUSED(event); if (!QKeyEventTransition::eventTest(event)) return false; - if (boat->currentSpeed() >= 0) - return true; - else - return false; - + return (boat->currentSpeed() >= 0); } void onTransition(QEvent *) { @@ -132,22 +119,16 @@ private: { public: KeyLaunchTransition(Boat *boat, QEvent::Type type, int key) - : QKeyEventTransition(boat, type, key) + : QKeyEventTransition(boat, type, key), boat(boat), key(key) { - this->boat = boat; - this->key = key; } protected: virtual bool eventTest(QEvent *event) { - Q_UNUSED(event); if (!QKeyEventTransition::eventTest(event)) return false; //We have enough bomb? - if (boat->bombsLaunched() < MAX_BOMB) - return true; - else - return false; + return (boat->bombsLaunched() < MAX_BOMB); } private: Boat * boat; @@ -158,9 +139,8 @@ private: class MoveStateRight : public QState { public: - MoveStateRight(Boat *boat,QState *parent = 0) : QState(parent) + MoveStateRight(Boat *boat,QState *parent = 0) : QState(parent), boat(boat) { - this->boat = boat; } protected: void onEntry(QEvent *) @@ -176,9 +156,8 @@ private: class MoveStateLeft : public QState { public: - MoveStateLeft(Boat *boat,QState *parent = 0) : QState(parent) + MoveStateLeft(Boat *boat,QState *parent = 0) : QState(parent), boat(boat) { - this->boat = boat; } protected: void onEntry(QEvent *) @@ -194,9 +173,8 @@ private: class StopState : public QState { public: - StopState(Boat *boat,QState *parent = 0) : QState(parent) + StopState(Boat *boat,QState *parent = 0) : QState(parent), boat(boat) { - this->boat = boat; } protected: void onEntry(QEvent *) @@ -213,9 +191,8 @@ private: class LaunchStateRight : public QState { public: - LaunchStateRight(Boat *boat,QState *parent = 0) : QState(parent) + LaunchStateRight(Boat *boat,QState *parent = 0) : QState(parent), boat(boat) { - this->boat = boat; } protected: void onEntry(QEvent *) @@ -235,9 +212,8 @@ private: class LaunchStateLeft : public QState { public: - LaunchStateLeft(Boat *boat,QState *parent = 0) : QState(parent) + LaunchStateLeft(Boat *boat,QState *parent = 0) : QState(parent), boat(boat) { - this->boat = boat; } protected: void onEntry(QEvent *) diff --git a/demos/sub-attaq/bomb.cpp b/demos/sub-attaq/bomb.cpp index d17024f..acc3475 100644 --- a/demos/sub-attaq/bomb.cpp +++ b/demos/sub-attaq/bomb.cpp @@ -52,19 +52,14 @@ #include #include -Bomb::Bomb(QGraphicsItem * parent, Qt::WindowFlags wFlags) - : QGraphicsWidget(parent,wFlags), launchAnimation(0) +Bomb::Bomb() : PixmapItem(QString("bomb"), GraphicsScene::Big) { - pixmapItem = new PixmapItem(QString("bomb"),GraphicsScene::Big, this); - setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - setFlags(QGraphicsItem::ItemIsMovable); setZValue(2); - resize(pixmapItem->boundingRect().size()); } void Bomb::launch(Bomb::Direction direction) { - launchAnimation = new QSequentialAnimationGroup(); + QSequentialAnimationGroup *launchAnimation = new QSequentialAnimationGroup; AnimationManager::self()->registerAnimation(launchAnimation); qreal delta = direction == Right ? 20 : - 20; QPropertyAnimation *anim = new QPropertyAnimation(this, "pos"); @@ -80,7 +75,7 @@ void Bomb::launch(Bomb::Direction direction) anim->setDuration(y()/2*60); launchAnimation->addAnimation(anim); connect(anim,SIGNAL(valueChanged(const QVariant &)),this,SLOT(onAnimationLaunchValueChanged(const QVariant &))); - + connect(this, SIGNAL(bombExploded()), launchAnimation, SLOT(stop())); //We setup the state machine of the bomb QStateMachine *machine = new QStateMachine(this); @@ -94,7 +89,7 @@ void Bomb::launch(Bomb::Direction direction) machine->setInitialState(launched); //### Add a nice animation when the bomb is destroyed - launched->addTransition(this, SIGNAL(bombExplosed()),final); + launched->addTransition(this, SIGNAL(bombExploded()),final); //If the animation is finished, then we move to the final state launched->addTransition(launched, SIGNAL(animationFinished()), final); @@ -119,6 +114,5 @@ void Bomb::onAnimationLaunchValueChanged(const QVariant &) void Bomb::destroy() { - launchAnimation->stop(); - emit bombExplosed(); + emit bombExploded(); } diff --git a/demos/sub-attaq/bomb.h b/demos/sub-attaq/bomb.h index f5b221c..ec059b5 100644 --- a/demos/sub-attaq/bomb.h +++ b/demos/sub-attaq/bomb.h @@ -42,13 +42,9 @@ #ifndef __BOMB__H__ #define __BOMB__H__ -//Qt -#include -#include +#include "pixmapitem.h" -class PixmapItem; - -class Bomb : public QGraphicsWidget +class Bomb : public PixmapItem { Q_OBJECT public: @@ -56,20 +52,16 @@ public: Left = 0, Right }; - Bomb(QGraphicsItem * parent = 0, Qt::WindowFlags wFlags = 0); + Bomb(); void launch(Direction direction); void destroy(); signals: - void bombExplosed(); + void bombExploded(); void bombExecutionFinished(); private slots: void onAnimationLaunchValueChanged(const QVariant &); - -private: - QAnimationGroup *launchAnimation; - PixmapItem *pixmapItem; }; #endif //__BOMB__H__ diff --git a/demos/sub-attaq/custompropertyanimation.cpp b/demos/sub-attaq/custompropertyanimation.cpp deleted file mode 100644 index 9b435f0..0000000 --- a/demos/sub-attaq/custompropertyanimation.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "custompropertyanimation.h" - -// Qt -#include - -CustomPropertyAnimation::CustomPropertyAnimation(QObject *parent) : - QVariantAnimation(parent), animProp(0) -{ -} - -CustomPropertyAnimation::~CustomPropertyAnimation() -{ -} - -void CustomPropertyAnimation::setProperty(AbstractProperty *_animProp) -{ - if (animProp == _animProp) - return; - delete animProp; - animProp = _animProp; -} - -/*! - \reimp - */ -void CustomPropertyAnimation::updateCurrentValue(const QVariant &value) -{ - if (!animProp || state() == QAbstractAnimation::Stopped) - return; - - animProp->write(value); -} - - -/*! - \reimp -*/ -void CustomPropertyAnimation::updateState(QAbstractAnimation::State oldState, QAbstractAnimation::State newState) -{ - // Initialize start value - if (oldState == QAbstractAnimation::Stopped) { - if (!animProp) - return; - QVariant def = animProp->read(); - if (def.isValid()) { - const int t = def.userType(); - KeyValues values = keyValues(); - //this ensures that all the keyValues are of type t - for (int i = 0; i < values.count(); ++i) { - QVariantAnimation::KeyValue &pair = values[i]; - if (pair.second.userType() != t) - pair.second.convert(static_cast(t)); - } - //let's now update the key values - setKeyValues(values); - } - - if ((animProp && !startValue().isValid() && currentTime() == 0) - || (currentTime() == duration() && currentLoop() == (loopCount() - 1))) { - setStartValue(def); - } - } - - QVariantAnimation::updateState(oldState, newState); -} - -#include "moc_custompropertyanimation.cpp" diff --git a/demos/sub-attaq/custompropertyanimation.h b/demos/sub-attaq/custompropertyanimation.h deleted file mode 100644 index 0c97bf0..0000000 --- a/demos/sub-attaq/custompropertyanimation.h +++ /dev/null @@ -1,114 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef CUSTOMPROPERTYANIMATION_H -#define CUSTOMPROPERTYANIMATION_H - -#include - -QT_BEGIN_NAMESPACE -class QGraphicsItem; -QT_END_NAMESPACE - -struct AbstractProperty -{ - virtual QVariant read() const = 0; - virtual void write(const QVariant &value) = 0; -}; - - -class CustomPropertyAnimation : public QVariantAnimation -{ - Q_OBJECT - - template - class MemberFunctionProperty : public AbstractProperty - { - public: - typedef T (Target::*Getter)(void) const; - typedef void (Target::*Setter)(T2); - - MemberFunctionProperty(Target* target, Getter getter, Setter setter) - : m_target(target), m_getter(getter), m_setter(setter) {} - - virtual void write(const QVariant &value) - { - if (m_setter) (m_target->*m_setter)(qVariantValue(value)); - } - - virtual QVariant read() const - { - if (m_getter) return qVariantFromValue((m_target->*m_getter)()); - return QVariant(); - } - - private: - Target *m_target; - Getter m_getter; - Setter m_setter; - }; - -public: - CustomPropertyAnimation(QObject *parent = 0); - ~CustomPropertyAnimation(); - - template - void setMemberFunctions(Target* target, T (Target::*getter)() const, void (Target::*setter)(const T& )) - { - setProperty(new MemberFunctionProperty(target, getter, setter)); - } - - template - void setMemberFunctions(Target* target, T (Target::*getter)() const, void (Target::*setter)(T)) - { - setProperty(new MemberFunctionProperty(target, getter, setter)); - } - - void updateCurrentValue(const QVariant &value); - void updateState(QAbstractAnimation::State oldState, QAbstractAnimation::State newState); - void setProperty(AbstractProperty *animProp); - -private: - Q_DISABLE_COPY(CustomPropertyAnimation); - AbstractProperty *animProp; -}; - -#endif // CUSTOMPROPERTYANIMATION_H diff --git a/demos/sub-attaq/graphicsscene.cpp b/demos/sub-attaq/graphicsscene.cpp index e5d7aad..812eadf 100644 --- a/demos/sub-attaq/graphicsscene.cpp +++ b/demos/sub-attaq/graphicsscene.cpp @@ -47,7 +47,6 @@ #include "torpedo.h" #include "bomb.h" #include "pixmapitem.h" -#include "custompropertyanimation.h" #include "animationmanager.h" #include "qanimationstate.h" #include "progressitem.h" @@ -68,39 +67,10 @@ #include #include -//helper function that creates an animation for position and inserts it into group -static CustomPropertyAnimation *addGraphicsItemPosAnimation(QSequentialAnimationGroup *group, - QGraphicsItem *item, const QPointF &endPos) -{ - CustomPropertyAnimation *ret = new CustomPropertyAnimation(group); - ret->setMemberFunctions(item, &QGraphicsItem::pos, &QGraphicsItem::setPos); - ret->setEndValue(endPos); - ret->setDuration(200); - ret->setEasingCurve(QEasingCurve::OutElastic); - group->addPause(50); - return ret; -} - -//helper function that creates an animation for opacity and inserts it into group -static void addGraphicsItemFadeoutAnimation(QAnimationGroup *group, QGraphicsItem *item) -{ -#if QT_VERSION >=0x040500 - CustomPropertyAnimation *anim = new CustomPropertyAnimation(group); - anim->setMemberFunctions(item, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); - anim->setDuration(800); - anim->setEndValue(0); - anim->setEasingCurve(QEasingCurve::OutQuad); -#else - // work around for a bug where we don't transition if the duration is zero. - QtPauseAnimation *anim = new QtPauseAnimation(group); - anim->setDuration(1); -#endif -} - GraphicsScene::GraphicsScene(int x, int y, int width, int height, Mode mode) - : QGraphicsScene(x,y,width,height), mode(mode), newAction(0), quitAction(0), boat(0) + : QGraphicsScene(x , y, width, height), mode(mode), boat(new Boat) { - backgroundItem = new PixmapItem(QString("background"),mode); + PixmapItem *backgroundItem = new PixmapItem(QString("background"),mode); backgroundItem->setZValue(1); backgroundItem->setPos(0,0); addItem(backgroundItem); @@ -116,7 +86,6 @@ GraphicsScene::GraphicsScene(int x, int y, int width, int height, Mode mode) textInformationItem = new TextInformationItem(backgroundItem); textInformationItem->hide(); //We create the boat - boat = new Boat(); addItem(boat); boat->setPos(this->width()/2, sealLevel() - boat->size().height()); boat->hide(); @@ -130,28 +99,21 @@ GraphicsScene::GraphicsScene(int x, int y, int width, int height, Mode mode) while (!reader.atEnd()) { reader.readNext(); if (reader.tokenType() == QXmlStreamReader::StartElement) { - if (reader.name() == "submarine") - { + if (reader.name() == "submarine") { SubmarineDescription desc; desc.name = reader.attributes().value("name").toString(); desc.points = reader.attributes().value("points").toString().toInt(); desc.type = reader.attributes().value("type").toString().toInt(); submarinesData.append(desc); - } - if (reader.name() == "level") - { + } else if (reader.name() == "level") { currentLevel.id = reader.attributes().value("id").toString().toInt(); currentLevel.name = reader.attributes().value("name").toString(); + } else if (reader.name() == "subinstance") { + currentLevel.submarines.append(qMakePair(reader.attributes().value("type").toString().toInt(), reader.attributes().value("nb").toString().toInt())); } - if (reader.name() == "subinstance") - { - currentLevel.submarines.append(qMakePair(reader.attributes().value("type").toString().toInt(),reader.attributes().value("nb").toString().toInt())); - } - } - if (reader.tokenType() == QXmlStreamReader::EndElement) { - if (reader.name() == "level") - { - levelsData.insert(currentLevel.id,currentLevel); + } else if (reader.tokenType() == QXmlStreamReader::EndElement) { + if (reader.name() == "level") { + levelsData.insert(currentLevel.id, currentLevel); currentLevel.submarines.clear(); } } @@ -160,80 +122,52 @@ GraphicsScene::GraphicsScene(int x, int y, int width, int height, Mode mode) qreal GraphicsScene::sealLevel() const { - if (mode == Big) - return 220; - else - return 160; + return (mode == Big) ? 220 : 160; } -void GraphicsScene::setupScene(const QList &actions) +void GraphicsScene::setupScene(QAction *newAction, QAction *quitAction) { - newAction = actions.at(0); - quitAction = actions.at(1); - - QGraphicsItem *logo_s = addWelcomeItem(QPixmap(":/logo-s")); - QGraphicsItem *logo_u = addWelcomeItem(QPixmap(":/logo-u")); - QGraphicsItem *logo_b = addWelcomeItem(QPixmap(":/logo-b")); - QGraphicsItem *logo_dash = addWelcomeItem(QPixmap(":/logo-dash")); - QGraphicsItem *logo_a = addWelcomeItem(QPixmap(":/logo-a")); - QGraphicsItem *logo_t = addWelcomeItem(QPixmap(":/logo-t")); - QGraphicsItem *logo_t2 = addWelcomeItem(QPixmap(":/logo-t2")); - QGraphicsItem *logo_a2 = addWelcomeItem(QPixmap(":/logo-a2")); - QGraphicsItem *logo_q = addWelcomeItem(QPixmap(":/logo-q")); - QGraphicsItem *logo_excl = addWelcomeItem(QPixmap(":/logo-excl")); - logo_s->setZValue(3); - logo_u->setZValue(4); - logo_b->setZValue(5); - logo_dash->setZValue(6); - logo_a->setZValue(7); - logo_t->setZValue(8); - logo_t2->setZValue(9); - logo_a2->setZValue(10); - logo_q->setZValue(11); - logo_excl->setZValue(12); - logo_s->setPos(QPointF(-1000, -1000)); - logo_u->setPos(QPointF(-800, -1000)); - logo_b->setPos(QPointF(-600, -1000)); - logo_dash->setPos(QPointF(-400, -1000)); - logo_a->setPos(QPointF(1000, 2000)); - logo_t->setPos(QPointF(800, 2000)); - logo_t2->setPos(QPointF(600, 2000)); - logo_a2->setPos(QPointF(400, 2000)); - logo_q->setPos(QPointF(200, 2000)); - logo_excl->setPos(QPointF(0, 2000)); + static const int nLetters = 10; + static struct { + char *pix; + qreal initX, initY; + qreal destX, destY; + } logoData[nLetters] = { + {"s", -1000, -1000, 300, 150 }, + {"u", -800, -1000, 350, 150 }, + {"b", -600, -1000, 400, 120 }, + {"dash", -400, -1000, 460, 150 }, + {"a", 1000, 2000, 350, 250 }, + {"t", 800, 2000, 400, 250 }, + {"t2", 600, 2000, 430, 250 }, + {"a2", 400, 2000, 465, 250 }, + {"q", 200, 2000, 510, 250 }, + {"excl", 0, 2000, 570, 220 } }; QSequentialAnimationGroup * lettersGroupMoving = new QSequentialAnimationGroup(this); QParallelAnimationGroup * lettersGroupFading = new QParallelAnimationGroup(this); - //creation of the animations for moving letters - addGraphicsItemPosAnimation(lettersGroupMoving, logo_s, QPointF(300, 150)); - addGraphicsItemPosAnimation(lettersGroupMoving, logo_u, QPointF(350, 150)); - addGraphicsItemPosAnimation(lettersGroupMoving, logo_b, QPointF(400, 120)); - addGraphicsItemPosAnimation(lettersGroupMoving, logo_dash, QPointF(460, 150)); - addGraphicsItemPosAnimation(lettersGroupMoving, logo_a, QPointF(350, 250)); - addGraphicsItemPosAnimation(lettersGroupMoving, logo_t, QPointF(400, 250)); - addGraphicsItemPosAnimation(lettersGroupMoving, logo_t2, QPointF(430, 250)); - addGraphicsItemPosAnimation(lettersGroupMoving, logo_a2, QPointF(465, 250)); - addGraphicsItemPosAnimation(lettersGroupMoving, logo_q, QPointF(510, 250)); - addGraphicsItemPosAnimation(lettersGroupMoving, logo_excl, QPointF(570, 220)); - - //creation of the animations for fading out the letters - addGraphicsItemFadeoutAnimation(lettersGroupFading, logo_s); - addGraphicsItemFadeoutAnimation(lettersGroupFading, logo_u); - addGraphicsItemFadeoutAnimation(lettersGroupFading, logo_b); - addGraphicsItemFadeoutAnimation(lettersGroupFading, logo_dash); - addGraphicsItemFadeoutAnimation(lettersGroupFading, logo_a); - addGraphicsItemFadeoutAnimation(lettersGroupFading, logo_t); - addGraphicsItemFadeoutAnimation(lettersGroupFading, logo_t2); - addGraphicsItemFadeoutAnimation(lettersGroupFading, logo_a2); - addGraphicsItemFadeoutAnimation(lettersGroupFading, logo_q); - addGraphicsItemFadeoutAnimation(lettersGroupFading, logo_excl); - connect(lettersGroupFading, SIGNAL(finished()), this, SLOT(onIntroAnimationFinished())); + for (int i = 0; i < nLetters; ++i) { + PixmapItem *logo = new PixmapItem(QLatin1String(":/logo-") + logoData[i].pix, this); + logo->setPos(logoData[i].initX, logoData[i].initY); + logo->setZValue(i + 3); + //creation of the animations for moving letters + QPropertyAnimation *moveAnim = new QPropertyAnimation(logo, "pos", lettersGroupMoving); + moveAnim->setEndValue(QPointF(logoData[i].destX, logoData[i].destY)); + moveAnim->setDuration(200); + moveAnim->setEasingCurve(QEasingCurve::OutElastic); + lettersGroupMoving->addPause(50); + //creation of the animations for fading out the letters + QPropertyAnimation *fadeAnim = new QPropertyAnimation(logo, "opacity", lettersGroupFading); + fadeAnim->setDuration(800); + fadeAnim->setEndValue(0); + fadeAnim->setEasingCurve(QEasingCurve::OutQuad); + } QStateMachine *machine = new QStateMachine(this); //This state is when the player is playing - PlayState *gameState = new PlayState(this,machine); + PlayState *gameState = new PlayState(this, machine); //Final state QFinalState *final = new QFinalState(machine); @@ -263,7 +197,7 @@ void GraphicsScene::setupScene(const QList &actions) machine->start(); //We reach the final state, then we quit - connect(machine,SIGNAL(finished()),this, SLOT(onQuitGameTriggered())); + connect(machine, SIGNAL(finished()), qApp, SLOT(quit())); } void GraphicsScene::addItem(Bomb *bomb) @@ -292,16 +226,6 @@ void GraphicsScene::addItem(QGraphicsItem *item) QGraphicsScene::addItem(item); } -void GraphicsScene::mousePressEvent (QGraphicsSceneMouseEvent * event) -{ - event->ignore(); -} - -void GraphicsScene::onQuitGameTriggered() -{ - qApp->closeAllWindows(); -} - void GraphicsScene::onBombExecutionFinished() { Bomb *bomb = qobject_cast(sender()); @@ -322,32 +246,26 @@ void GraphicsScene::onSubMarineExecutionFinished() { SubMarine *submarine = qobject_cast(sender()); submarines.remove(submarine); - if (submarines.count() == 0) { + if (submarines.count() == 0) emit allSubMarineDestroyed(submarine->points()); - } else { + else emit subMarineDestroyed(submarine->points()); - } submarine->deleteLater(); } -int GraphicsScene::remainingSubMarines() const -{ - return submarines.count(); -} - void GraphicsScene::clearScene() { - foreach (SubMarine *sub,submarines) { + foreach (SubMarine *sub, submarines) { sub->destroy(); sub->deleteLater(); } - foreach (Torpedo *torpedo,torpedos) { + foreach (Torpedo *torpedo, torpedos) { torpedo->destroy(); torpedo->deleteLater(); } - foreach (Bomb *bomb,bombs) { + foreach (Bomb *bomb, bombs) { bomb->destroy(); bomb->deleteLater(); } @@ -361,17 +279,3 @@ void GraphicsScene::clearScene() boat->stop(); boat->hide(); } - -QGraphicsPixmapItem *GraphicsScene::addWelcomeItem(const QPixmap &pm) -{ - QGraphicsPixmapItem *item = addPixmap(pm); - welcomeItems << item; - return item; -} - -void GraphicsScene::onIntroAnimationFinished() -{ - qDeleteAll(welcomeItems); - welcomeItems.clear(); -} - diff --git a/demos/sub-attaq/graphicsscene.h b/demos/sub-attaq/graphicsscene.h index 7d7252d..ce2c91f 100644 --- a/demos/sub-attaq/graphicsscene.h +++ b/demos/sub-attaq/graphicsscene.h @@ -82,41 +82,30 @@ public: GraphicsScene(int x, int y, int width, int height, Mode mode = Big); qreal sealLevel() const; - void setupScene(const QList &actions); + void setupScene(QAction *newAction, QAction *quitAction); void addItem(Bomb *bomb); void addItem(Torpedo *torpedo); void addItem(SubMarine *submarine); void addItem(QGraphicsItem *item); - int remainingSubMarines() const; void clearScene(); - QGraphicsPixmapItem *addWelcomeItem(const QPixmap &pm); signals: void subMarineDestroyed(int); void allSubMarineDestroyed(int); -protected: - void mousePressEvent (QGraphicsSceneMouseEvent * event); - private slots: - void onQuitGameTriggered(); void onBombExecutionFinished(); void onTorpedoExecutionFinished(); void onSubMarineExecutionFinished(); - void onIntroAnimationFinished(); private: Mode mode; - PixmapItem *backgroundItem; ProgressItem *progressItem; TextInformationItem *textInformationItem; - QAction * newAction; - QAction * quitAction; Boat *boat; QSet submarines; QSet bombs; QSet torpedos; - QVector welcomeItems; QVector submarinesData; QHash levelsData; diff --git a/demos/sub-attaq/mainwindow.cpp b/demos/sub-attaq/mainwindow.cpp index 37129f8..45e5554 100644 --- a/demos/sub-attaq/mainwindow.cpp +++ b/demos/sub-attaq/mainwindow.cpp @@ -56,42 +56,27 @@ MainWindow::MainWindow() : QMainWindow(0) { - QMenuBar *menuBar = new QMenuBar; - QMenu *file = new QMenu(tr("&File"),menuBar); + QMenu *file = menuBar()->addMenu(tr("&File")); - QAction *newAction = new QAction(tr("New Game"),file); + QAction *newAction = file->addAction(tr("New Game")); newAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_N)); - file->addAction(newAction); - QAction *quitAction = new QAction(tr("Quit"),file); + QAction *quitAction = file->addAction(tr("Quit")); quitAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Q)); - file->addAction(quitAction); - menuBar->addMenu(file); - setMenuBar(menuBar); - - QStringList list = QApplication::arguments(); - if (list.contains("-fullscreen")) { - scene = new GraphicsScene(0, 0, 750, 400,GraphicsScene::Small); + if (QApplication::arguments().contains("-fullscreen")) { + scene = new GraphicsScene(0, 0, 750, 400, GraphicsScene::Small); setWindowState(Qt::WindowFullScreen); } else { scene = new GraphicsScene(0, 0, 880, 630); layout()->setSizeConstraint(QLayout::SetFixedSize); } - view = new QGraphicsView(scene,this); + view = new QGraphicsView(scene, this); view->setAlignment(Qt::AlignLeft | Qt::AlignTop); - QList actions; - actions << newAction << quitAction; - scene->setupScene(actions); + scene->setupScene(newAction, quitAction); #ifndef QT_NO_OPENGL - view->setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers))); + view->setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers))); #endif setCentralWidget(view); - -} - -MainWindow::~MainWindow() -{ } - diff --git a/demos/sub-attaq/mainwindow.h b/demos/sub-attaq/mainwindow.h index d626ad7..12a7364 100644 --- a/demos/sub-attaq/mainwindow.h +++ b/demos/sub-attaq/mainwindow.h @@ -54,7 +54,6 @@ class MainWindow : public QMainWindow Q_OBJECT public: MainWindow(); - ~MainWindow(); private: GraphicsScene *scene; diff --git a/demos/sub-attaq/pixmapitem.cpp b/demos/sub-attaq/pixmapitem.cpp index 9abf745..fcc7ce9 100644 --- a/demos/sub-attaq/pixmapitem.cpp +++ b/demos/sub-attaq/pixmapitem.cpp @@ -43,17 +43,34 @@ #include "pixmapitem.h" //Qt -#include +#include -PixmapItem::PixmapItem(const QString &fileName,GraphicsScene::Mode mode, QGraphicsItem * parent) : QGraphicsPixmapItem(parent),name(fileName) +PixmapItem::PixmapItem(const QString &fileName,GraphicsScene::Mode mode, QGraphicsItem * parent) : QGraphicsObject(parent) { - loadPixmap(mode); + if (mode == GraphicsScene::Big) + pix = ":/big/" + fileName; + else + pix = ":/small/" + fileName; } -void PixmapItem::loadPixmap(GraphicsScene::Mode mode) +PixmapItem::PixmapItem(const QString &fileName, QGraphicsScene *scene) : QGraphicsObject(), pix(fileName) { - if (mode == GraphicsScene::Big) - setPixmap(":/big/" + name); - else - setPixmap(":/small/" + name); + scene->addItem(this); } + +QSizeF PixmapItem::size() const +{ + return pix.size(); +} + +QRectF PixmapItem::boundingRect() const +{ + return QRectF(QPointF(0, 0), pix.size()); +} + +void PixmapItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) +{ + painter->drawPixmap(0, 0, pix); +} + + diff --git a/demos/sub-attaq/pixmapitem.h b/demos/sub-attaq/pixmapitem.h index b176215..57f831a 100644 --- a/demos/sub-attaq/pixmapitem.h +++ b/demos/sub-attaq/pixmapitem.h @@ -46,18 +46,18 @@ #include "graphicsscene.h" //Qt -#include +#include -class PixmapItem : public QGraphicsPixmapItem +class PixmapItem : public QGraphicsObject { public: PixmapItem(const QString &fileName, GraphicsScene::Mode mode, QGraphicsItem * parent = 0); - + PixmapItem(const QString &fileName, QGraphicsScene *scene); + QSizeF size() const; + QRectF boundingRect() const; + void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *); private: - void loadPixmap(GraphicsScene::Mode mode); - - QString name; - QPixmap pixmap; + QPixmap pix; }; #endif //__PIXMAPITEM__H__ diff --git a/demos/sub-attaq/states.cpp b/demos/sub-attaq/states.cpp index 7443ae7..742095e 100644 --- a/demos/sub-attaq/states.cpp +++ b/demos/sub-attaq/states.cpp @@ -67,8 +67,7 @@ PlayState::PlayState(GraphicsScene *scene, QState *parent) PlayState::~PlayState() { - if (machine) - delete machine; + delete machine; } void PlayState::onEntry(QEvent *) @@ -169,7 +168,7 @@ void LevelState::initializeLevel() scene->boat->setCurrentDirection(Boat::None); scene->boat->setBombsLaunched(0); scene->boat->show(); - scene->setFocusItem(scene->boat,Qt::OtherFocusReason); + scene->setFocusItem(scene->boat, Qt::OtherFocusReason); scene->boat->run(); scene->progressItem->setScore(game->score); @@ -276,13 +275,8 @@ void WinState::onExit(QEvent *) } /** UpdateScore State */ -UpdateScoreState::UpdateScoreState(PlayState *game, QState *parent) : QState(parent) -{ - this->game = game; -} -void UpdateScoreState::onEntry(QEvent *e) +UpdateScoreState::UpdateScoreState(PlayState *g, QState *parent) : QState(parent), game(g) { - QState::onEntry(e); } /** Win transition */ @@ -297,12 +291,10 @@ bool UpdateScoreTransition::eventTest(QEvent *event) { if (!QSignalTransition::eventTest(event)) return false; - else { - QStateMachine::SignalEvent *se = static_cast(event); - game->score += se->arguments().at(0).toInt(); - scene->progressItem->setScore(game->score); - return true; - } + QStateMachine::SignalEvent *se = static_cast(event); + game->score += se->arguments().at(0).toInt(); + scene->progressItem->setScore(game->score); + return true; } /** Win transition */ @@ -317,12 +309,10 @@ bool WinTransition::eventTest(QEvent *event) { if (!QSignalTransition::eventTest(event)) return false; - else { - QStateMachine::SignalEvent *se = static_cast(event); - game->score += se->arguments().at(0).toInt(); - scene->progressItem->setScore(game->score); - return true; - } + QStateMachine::SignalEvent *se = static_cast(event); + game->score += se->arguments().at(0).toInt(); + scene->progressItem->setScore(game->score); + return true; } /** Space transition */ @@ -334,12 +324,7 @@ CustomSpaceTransition::CustomSpaceTransition(QWidget *widget, PlayState *game, Q bool CustomSpaceTransition::eventTest(QEvent *event) { - Q_UNUSED(event); if (!QKeyEventTransition::eventTest(event)) return false; - if (game->currentLevel != 0) - return true; - else - return false; - + return (game->currentLevel != 0); } diff --git a/demos/sub-attaq/states.h b/demos/sub-attaq/states.h index 9e78ae4..f588e5d 100644 --- a/demos/sub-attaq/states.h +++ b/demos/sub-attaq/states.h @@ -136,8 +136,6 @@ class UpdateScoreState : public QState { public: UpdateScoreState(PlayState *game, QState *parent); -protected: - void onEntry(QEvent *); private: QPropertyAnimation *scoreAnimation; PlayState *game; diff --git a/demos/sub-attaq/sub-attaq.pro b/demos/sub-attaq/sub-attaq.pro index 8677ff5..b5aa465 100644 --- a/demos/sub-attaq/sub-attaq.pro +++ b/demos/sub-attaq/sub-attaq.pro @@ -10,7 +10,6 @@ HEADERS += boat.h \ states.h \ boat_p.h \ submarine_p.h \ - custompropertyanimation.h \ qanimationstate.h \ progressitem.h \ textinformationitem.h @@ -24,7 +23,6 @@ SOURCES += boat.cpp \ graphicsscene.cpp \ animationmanager.cpp \ states.cpp \ - custompropertyanimation.cpp \ qanimationstate.cpp \ progressitem.cpp \ textinformationitem.cpp diff --git a/demos/sub-attaq/submarine.cpp b/demos/sub-attaq/submarine.cpp index 3d8490f..f71b81c 100644 --- a/demos/sub-attaq/submarine.cpp +++ b/demos/sub-attaq/submarine.cpp @@ -46,7 +46,6 @@ #include "pixmapitem.h" #include "graphicsscene.h" #include "animationmanager.h" -#include "custompropertyanimation.h" #include "qanimationstate.h" #include @@ -57,62 +56,27 @@ static QAbstractAnimation *setupDestroyAnimation(SubMarine *sub) { QSequentialAnimationGroup *group = new QSequentialAnimationGroup(sub); -#if QT_VERSION >=0x040500 - PixmapItem *step1 = new PixmapItem(QString("explosion/submarine/step1"),GraphicsScene::Big, sub); - step1->setZValue(6); - PixmapItem *step2 = new PixmapItem(QString("explosion/submarine/step2"),GraphicsScene::Big, sub); - step2->setZValue(6); - PixmapItem *step3 = new PixmapItem(QString("explosion/submarine/step3"),GraphicsScene::Big, sub); - step3->setZValue(6); - PixmapItem *step4 = new PixmapItem(QString("explosion/submarine/step4"),GraphicsScene::Big, sub); - step4->setZValue(6); - step1->setOpacity(0); - step2->setOpacity(0); - step3->setOpacity(0); - step4->setOpacity(0); - CustomPropertyAnimation *anim1 = new CustomPropertyAnimation(sub); - anim1->setMemberFunctions((QGraphicsItem*)step1, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); - anim1->setDuration(100); - anim1->setEndValue(1); - CustomPropertyAnimation *anim2 = new CustomPropertyAnimation(sub); - anim2->setMemberFunctions((QGraphicsItem*)step2, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); - anim2->setDuration(100); - anim2->setEndValue(1); - CustomPropertyAnimation *anim3 = new CustomPropertyAnimation(sub); - anim3->setMemberFunctions((QGraphicsItem*)step3, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); - anim3->setDuration(100); - anim3->setEndValue(1); - CustomPropertyAnimation *anim4 = new CustomPropertyAnimation(sub); - anim4->setMemberFunctions((QGraphicsItem*)step4, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); - anim4->setDuration(100); - anim4->setEndValue(1); - group->addAnimation(anim1); - group->addAnimation(anim2); - group->addAnimation(anim3); - group->addAnimation(anim4); -#else - // work around for a bug where we don't transition if the duration is zero. - QtPauseAnimation *anim = new QtPauseAnimation(group); - anim->setDuration(1); - group->addAnimation(anim); -#endif + for (int i = 1; i <= 4; ++i) { + PixmapItem *step = new PixmapItem(QString::fromLatin1("explosion/submarine/step%1").arg(i), GraphicsScene::Big, sub); + step->setZValue(6); + step->setOpacity(0); + QPropertyAnimation *anim = new QPropertyAnimation(step, "opacity", group); + anim->setDuration(100); + anim->setEndValue(1); + } AnimationManager::self()->registerAnimation(group); return group; } -SubMarine::SubMarine(int type, const QString &name, int points, QGraphicsItem * parent, Qt::WindowFlags wFlags) - : QGraphicsWidget(parent,wFlags), subType(type), subName(name), subPoints(points), speed(0), direction(SubMarine::None) +SubMarine::SubMarine(int type, const QString &name, int points) : PixmapItem(QString("submarine"), GraphicsScene::Big), + subType(type), subName(name), subPoints(points), speed(0), direction(SubMarine::None) { - pixmapItem = new PixmapItem(QString("submarine"),GraphicsScene::Big, this); - setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); setZValue(5); - setFlags(QGraphicsItem::ItemIsMovable); - resize(pixmapItem->boundingRect().width(),pixmapItem->boundingRect().height()); setTransformOriginPoint(boundingRect().center()); graphicsRotation = new QGraphicsRotation(this); - graphicsRotation->setAxis(QVector3D(0, 1, 0)); + graphicsRotation->setAxis(Qt::YAxis); graphicsRotation->setOrigin(QVector3D(size().width()/2, size().height()/2, 0)); QList r; r.append(graphicsRotation); @@ -163,7 +127,7 @@ SubMarine::SubMarine(int type, const QString &name, int points, QGraphicsItem * machine->start(); } -int SubMarine::points() +int SubMarine::points() const { return subPoints; } @@ -202,7 +166,7 @@ void SubMarine::launchTorpedo(int speed) Torpedo * torp = new Torpedo(); GraphicsScene *scene = static_cast(this->scene()); scene->addItem(torp); - torp->setPos(x(), y()); + torp->setPos(pos()); torp->setCurrentSpeed(speed); torp->launch(); } diff --git a/demos/sub-attaq/submarine.h b/demos/sub-attaq/submarine.h index 1a3d2e5..326a1c8 100644 --- a/demos/sub-attaq/submarine.h +++ b/demos/sub-attaq/submarine.h @@ -43,15 +43,13 @@ #define __SUBMARINE__H__ //Qt -#include -#include #include -class PixmapItem; +#include "pixmapitem.h" class Torpedo; -class SubMarine : public QGraphicsWidget +class SubMarine : public PixmapItem { Q_OBJECT public: @@ -61,9 +59,9 @@ public: Right }; enum { Type = UserType + 1 }; - SubMarine(int type, const QString &name, int points, QGraphicsItem * parent = 0, Qt::WindowFlags wFlags = 0); + SubMarine(int type, const QString &name, int points); - int points(); + int points() const; void setCurrentDirection(Movement direction); enum Movement currentDirection() const; @@ -89,7 +87,6 @@ private: int subPoints; int speed; Movement direction; - PixmapItem *pixmapItem; QGraphicsRotation *graphicsRotation; }; diff --git a/demos/sub-attaq/submarine_p.h b/demos/sub-attaq/submarine_p.h index fa7430b..64a0cf7 100644 --- a/demos/sub-attaq/submarine_p.h +++ b/demos/sub-attaq/submarine_p.h @@ -94,7 +94,6 @@ protected: movementAnimation->setEndValue(QPointF(submarine->scene()->width()-submarine->size().width(),submarine->y())); movementAnimation->setDuration((submarine->scene()->width()-submarine->size().width()-submarine->x())/submarine->currentSpeed()*12); } - movementAnimation->setStartValue(submarine->pos()); QAnimationState::onEntry(e); } diff --git a/demos/sub-attaq/torpedo.cpp b/demos/sub-attaq/torpedo.cpp index cce430d..95f88e6 100644 --- a/demos/sub-attaq/torpedo.cpp +++ b/demos/sub-attaq/torpedo.cpp @@ -51,24 +51,21 @@ #include #include -Torpedo::Torpedo(QGraphicsItem * parent, Qt::WindowFlags wFlags) - : QGraphicsWidget(parent,wFlags), currentSpeed(0), launchAnimation(0) +Torpedo::Torpedo() : PixmapItem(QString::fromLatin1("torpedo"),GraphicsScene::Big), + currentSpeed(0) { - pixmapItem = new PixmapItem(QString::fromLatin1("torpedo"),GraphicsScene::Big, this); setZValue(2); - setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - setFlags(QGraphicsItem::ItemIsMovable); - resize(pixmapItem->boundingRect().size()); } void Torpedo::launch() { - launchAnimation = new QPropertyAnimation(this, "pos"); + QPropertyAnimation *launchAnimation = new QPropertyAnimation(this, "pos"); AnimationManager::self()->registerAnimation(launchAnimation); launchAnimation->setEndValue(QPointF(x(),qobject_cast(scene())->sealLevel() - 15)); launchAnimation->setEasingCurve(QEasingCurve::InQuad); launchAnimation->setDuration(y()/currentSpeed*10); connect(launchAnimation,SIGNAL(valueChanged(const QVariant &)),this,SLOT(onAnimationLaunchValueChanged(const QVariant &))); + connect(this,SIGNAL(torpedoExploded()), launchAnimation, SLOT(stop())); //We setup the state machine of the torpedo QStateMachine *machine = new QStateMachine(this); @@ -83,7 +80,7 @@ void Torpedo::launch() machine->setInitialState(launched); //### Add a nice animation when the torpedo is destroyed - launched->addTransition(this, SIGNAL(torpedoExplosed()),final); + launched->addTransition(this, SIGNAL(torpedoExploded()),final); //If the animation is finished, then we move to the final state launched->addTransition(launched, SIGNAL(animationFinished()), final); @@ -106,15 +103,12 @@ void Torpedo::setCurrentSpeed(int speed) void Torpedo::onAnimationLaunchValueChanged(const QVariant &) { foreach (QGraphicsItem *item , collidingItems(Qt::IntersectsItemBoundingRect)) { - if (item->type() == Boat::Type) { - Boat *b = static_cast(item); + if (Boat *b = qgraphicsitem_cast(item)) b->destroy(); - } } } void Torpedo::destroy() { - launchAnimation->stop(); - emit torpedoExplosed(); + emit torpedoExploded(); } diff --git a/demos/sub-attaq/torpedo.h b/demos/sub-attaq/torpedo.h index 2e654f4..03f277d 100644 --- a/demos/sub-attaq/torpedo.h +++ b/demos/sub-attaq/torpedo.h @@ -42,25 +42,19 @@ #ifndef __TORPEDO__H__ #define __TORPEDO__H__ -//Qt -#include +#include "pixmapitem.h" -#include -#include - -class PixmapItem; - -class Torpedo : public QGraphicsWidget +class Torpedo : public PixmapItem { Q_OBJECT public: - Torpedo(QGraphicsItem * parent = 0, Qt::WindowFlags wFlags = 0); + Torpedo(); void launch(); void setCurrentSpeed(int speed); void destroy(); signals: - void torpedoExplosed(); + void torpedoExploded(); void torpedoExecutionFinished(); private slots: @@ -68,8 +62,6 @@ private slots: private: int currentSpeed; - PixmapItem *pixmapItem; - QVariantAnimation *launchAnimation; }; #endif //__TORPEDO__H__ -- cgit v0.12 From dfce16a317e4e606b517ff206bb7a410bad7e0ca Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Mon, 5 Oct 2009 11:53:38 +0200 Subject: QPropertyAnimation now uses QMetaObject::metacall instead of qt_metacall This allows the animations to work with the newly integrated dynamic metaobject Reviewed-by: Michael Brasser (cherry picked from commit e548c48513546199c848e6cb08a60e8eccdab2c5) --- src/corelib/animation/qpropertyanimation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/animation/qpropertyanimation.cpp b/src/corelib/animation/qpropertyanimation.cpp index b64d7df..4742e54 100644 --- a/src/corelib/animation/qpropertyanimation.cpp +++ b/src/corelib/animation/qpropertyanimation.cpp @@ -132,9 +132,9 @@ void QPropertyAnimationPrivate::updateProperty(const QVariant &newValue) } if (newValue.userType() == propertyType) { - //no conversion is needed, we directly call the QObject::qt_metacall + //no conversion is needed, we directly call the QMetaObject::metacall void *data = const_cast(newValue.constData()); - targetValue->qt_metacall(QMetaObject::WriteProperty, propertyIndex, &data); + QMetaObject::metacall(targetValue, QMetaObject::WriteProperty, propertyIndex, &data); } else { targetValue->setProperty(propertyName.constData(), newValue); } -- cgit v0.12 From 0b3f1a313fb464741c987b188ab4169947d0eb78 Mon Sep 17 00:00:00 2001 From: Bernhard Rosenkraenzer Date: Mon, 5 Oct 2009 12:08:24 +0200 Subject: Adapt to libtiff 4.0 changes In libtiff 4.0, TIFF_VERSION has been replaced with TIFF_VERSION_CLASSIC (to indicate normal tiff support) and TIFF_VERSION_BIG (to indicate BigTIFF support) Merge-request: 1547 Reviewed-by: Thiago Macieira (cherry picked from commit 7ec805adeecb8d518c0eb01dad1c04ccea78b340) --- config.tests/unix/libtiff/libtiff.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/config.tests/unix/libtiff/libtiff.cpp b/config.tests/unix/libtiff/libtiff.cpp index 2d4b2af..7d41f25 100644 --- a/config.tests/unix/libtiff/libtiff.cpp +++ b/config.tests/unix/libtiff/libtiff.cpp @@ -41,6 +41,11 @@ #include +#if !defined(TIFF_VERSION) && defined(TIFF_VERSION_CLASSIC) +// libtiff 4.0 splits it into TIFF_VERSION_CLASSIC and TIFF_VERSION_BIG +# define TIFF_VERSION TIFF_VERSION_CLASSIC +#endif + #if !defined(TIFF_VERSION) # error "Required libtiff not found" #elif TIFF_VERSION < 42 -- cgit v0.12 From b50966121c3de0328f810b176e549b63985d974a Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 5 Oct 2009 12:10:28 +0200 Subject: Fix uninitialized read in QFormLayoutPrivate::setupVerticalLayoutData() Merge-request: 1541 Reviewed-by: Thiago Macieira (cherry picked from commit b0e6c5ca48c76fb17dca986e9e07adebde390e29) --- src/gui/kernel/qformlayout.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qformlayout.cpp b/src/gui/kernel/qformlayout.cpp index 6ceab07..3e5dadc 100644 --- a/src/gui/kernel/qformlayout.cpp +++ b/src/gui/kernel/qformlayout.cpp @@ -252,7 +252,7 @@ QFormLayoutPrivate::QFormLayoutPrivate() : fieldGrowthPolicy(DefaultFieldGrowthPolicy), rowWrapPolicy(DefaultRowWrapPolicy), has_hfw(false), dirty(true), sizesDirty(true), expandVertical(0), expandHorizontal(0), labelAlignment(0), formAlignment(0), - hfw_width(-1), hfw_sh_height(-1), min_width(-1), + layoutWidth(-1), hfw_width(-1), hfw_sh_height(-1), min_width(-1), sh_width(-1), thresh_width(QLAYOUTSIZE_MAX), hSpacing(-1), vSpacing(-1) { } -- cgit v0.12 From 9815de3fbdbca8bda881e939274b3133492933fb Mon Sep 17 00:00:00 2001 From: Jocelyn Turcotte Date: Mon, 5 Oct 2009 12:14:08 +0200 Subject: Exclude WebCore/jsc.pro and WebKit/qt/Plugins/ from 3rdparty/webkit Rubber-stamped by: Simon Hausmann (cherry picked from commit 5286a0211d9c76bf762c8041c1d596d8c9c9c08d) --- util/webkit/mkdist-javascriptcore | 1 + util/webkit/mkdist-webkit | 3 +++ 2 files changed, 4 insertions(+) diff --git a/util/webkit/mkdist-javascriptcore b/util/webkit/mkdist-javascriptcore index dc33f6c..07419ea 100755 --- a/util/webkit/mkdist-javascriptcore +++ b/util/webkit/mkdist-javascriptcore @@ -41,6 +41,7 @@ files_to_remove="" files_to_remove="$files_to_remove JavaScriptCore/AllInOneFile.cpp" files_to_remove="$files_to_remove JavaScriptCore/JavaScriptCoreSources.bkl" files_to_remove="$files_to_remove JavaScriptCore/jscore.bkl" +files_to_remove="$files_to_remove JavaScriptCore/jsc.pro" require_clean_work_tree() { # test if working tree is dirty diff --git a/util/webkit/mkdist-webkit b/util/webkit/mkdist-webkit index 34a2ec7..9611d38 100755 --- a/util/webkit/mkdist-webkit +++ b/util/webkit/mkdist-webkit @@ -143,6 +143,8 @@ excluded_directories="$excluded_directories WebCore/storage/wince" excluded_directories="$excluded_directories WebCore/platform/wx" excluded_directories="$excluded_directories WebCore/platform/wince" +excluded_directories="$excluded_directories WebKit/qt/Plugins" + excluded_directories="$excluded_directories WebKit/gtk" excluded_directories="$excluded_directories WebKit/win" excluded_directories="$excluded_directories WebKit/wx" @@ -204,6 +206,7 @@ files_to_remove="$files_to_remove WebKit/qt/QGVLauncher/main.cpp" files_to_remove="$files_to_remove JavaScriptCore/AllInOneFile.cpp" files_to_remove="$files_to_remove JavaScriptCore/JavaScriptCoreSources.bkl" files_to_remove="$files_to_remove JavaScriptCore/jscore.bkl" +files_to_remove="$files_to_remove JavaScriptCore/jsc.pro" files_to_remove="$files_to_remove WebCore/wscript" files_to_remove="$files_to_remove WebCore/WebCore.ContextMenus.exp" -- cgit v0.12 From 22f88f83b86cd0c8d9fc5b1daef62ec68807a81a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Mon, 5 Oct 2009 12:21:18 +0200 Subject: Made X11 QPixmap backend return proper pixmap in alphaChannel(). Reviewed-by: Gunnar (cherry picked from commit c1d24c6b87dcc4c6e2f6f258c0198fdb6b2795f0) --- src/gui/image/qpixmap_x11.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/gui/image/qpixmap_x11.cpp b/src/gui/image/qpixmap_x11.cpp index 6cde898..92a7e7d 100644 --- a/src/gui/image/qpixmap_x11.cpp +++ b/src/gui/image/qpixmap_x11.cpp @@ -1252,8 +1252,11 @@ void QX11PixmapData::release() QPixmap QX11PixmapData::alphaChannel() const { - if (!hasAlphaChannel()) - return QPixmap(); + if (!hasAlphaChannel()) { + QPixmap pm(w, h); + pm.fill(Qt::white); + return pm; + } QImage im(toImage()); return QPixmap::fromImage(im.alphaChannel(), Qt::OrderedDither); } -- cgit v0.12 From a12c32a8331466ea6d8edac5fb15c696b88437e3 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Mon, 5 Oct 2009 12:53:04 +0200 Subject: Update systemclip based on the correct parameters Reviewed-by: Samuel (cherry picked from commit 7cb0dea6d991a4d9f4a66b699dc5b353812b168d) --- src/opengl/qpaintengine_opengl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp index da490c0..3e4a8e7 100644 --- a/src/opengl/qpaintengine_opengl.cpp +++ b/src/opengl/qpaintengine_opengl.cpp @@ -2311,7 +2311,7 @@ void QOpenGLPaintEnginePrivate::updateDepthClip() void QOpenGLPaintEnginePrivate::systemStateChanged() { Q_Q(QOpenGLPaintEngine); - if (q->state()->hasClipping) + if (q->painter()->hasClipping()) q->updateClipRegion(q->painter()->clipRegion(), Qt::ReplaceClip); else q->updateClipRegion(QRegion(), Qt::NoClip); -- cgit v0.12 From 2831bdb96016a30f6a8cb0c00d82565468325019 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Fri, 2 Oct 2009 18:04:21 +0200 Subject: Doc: move new files into correct subdirectory. (cherry picked from commit 491a9879d349a67dbd5f00f1c0bb189fb92290e3) --- doc/src/exceptionsafety.qdoc | 156 ---------------- doc/src/howtos/exceptionsafety.qdoc | 156 ++++++++++++++++ doc/src/platforms/s60-introduction.qdoc | 151 ++++++++++++++++ doc/src/platforms/symbian-exceptionsafety.qdoc | 241 +++++++++++++++++++++++++ doc/src/s60-introduction.qdoc | 151 ---------------- doc/src/symbian-exceptionsafety.qdoc | 241 ------------------------- 6 files changed, 548 insertions(+), 548 deletions(-) delete mode 100644 doc/src/exceptionsafety.qdoc create mode 100644 doc/src/howtos/exceptionsafety.qdoc create mode 100644 doc/src/platforms/s60-introduction.qdoc create mode 100644 doc/src/platforms/symbian-exceptionsafety.qdoc delete mode 100644 doc/src/s60-introduction.qdoc delete mode 100644 doc/src/symbian-exceptionsafety.qdoc diff --git a/doc/src/exceptionsafety.qdoc b/doc/src/exceptionsafety.qdoc deleted file mode 100644 index b70df6b..0000000 --- a/doc/src/exceptionsafety.qdoc +++ /dev/null @@ -1,156 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \page exceptionsafety.html - \title Exception Safety - \ingroup architecture - \brief A guide to exception safety in Qt. - - \bold {Preliminary warning}: Exception safety is not feature complete! - Common cases should work, but classes might still leak or even crash. - - Qt itself will not throw exceptions. Instead, error codes are used. - In addition, some classes have user visible error messages, for example - \l QIODevice::errorString() or \l QSqlQuery::lastError(). - This has historical and practical reasons - turning on exceptions - can increase the library size by over 20%. - - The following sections describe Qt's behavior if exception support is - enabled at compile time. - - \tableofcontents - - \section1 Exception safe modules - - \section2 Containers - - Qt's \l{container classes} are generally exception neutral. They pass any - exception that happens within their contained type \c T to the user - while keeping their internal state valid. - - Example: - - \code - QList list; - ... - try { - list.append("hello"); - } catch (...) { - } - // list is safe to use - the exception did not affect it. - \endcode - - Exceptions to that rule are containers for types that can throw during assignment - or copy constructions. For those types, functions that modify the container as well as - returning a value, are unsafe to use: - - \code - MyType s = list.takeAt(2); - \endcode - - If an exception occurs during the assignment of \c s, the value at index 2 is already - removed from the container, but hasn't been assigned to \c s yet. It is lost - without chance of recovery. - - The correct way to write it: - - \code - MyType s = list.at(2); - list.removeAt(2); - \endcode - - If the assignment throws, the container still contains the value, no data loss occured. - - Note that implicitly shared Qt classes will not throw in their assignment - operators or copy constructors, so the limitation above does not apply. - - \section1 Out of Memory Handling - - Most desktop operating systems overcommit memory. This means that \c malloc() - or \c{operator new} return a valid pointer, even though there is not enough - memory available at allocation time. On such systems, no exception of type - \c std::bad_alloc is thrown. - - On all other operating systems, Qt will throw an exception of type std::bad_alloc - if any allocation fails. Allocations can fail if the system runs out of memory or - doesn't have enough continuous memory to allocate the requested size. - - Exceptions to that rule are documented. As an example, \l QImage::create() - returns false if not enough memory exists instead of throwing an exception. - - \section1 Recovering from exceptions - - Currently, the only supported use case for recovering from exceptions thrown - within Qt (for example due to out of memory) is to exit the event loop and do - some cleanup before exiting the application. - - Typical use case: - - \code - QApplication app(argc, argv); - ... - try { - app.exec(); - } catch (const std::bad_alloc &) { - // clean up here, e.g. save the session - // and close all config files. - - return 0; // exit the application - } - \endcode - - After an exception is thrown, the connection to the windowing server - might already be closed. It is not safe to call a GUI related function - after catching an exception. - - \section1 Platform-Specific Exception Handling - - \section2 Symbian (Qt for S60) - - The Symbian platform implements its own exception system that differs from the standard - C++ mechanism. When using Qt for S60, and especially when writing code to access Symbian - functionality directly, it may be necessary to know about the underlying implementation - and how it interacts with Qt. - - The \l{Exception Safety with Symbian} document shows how to use the facilities provided - by Qt to use exceptions as safely as possible. -*/ diff --git a/doc/src/howtos/exceptionsafety.qdoc b/doc/src/howtos/exceptionsafety.qdoc new file mode 100644 index 0000000..23bedf5 --- /dev/null +++ b/doc/src/howtos/exceptionsafety.qdoc @@ -0,0 +1,156 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page exceptionsafety.html + \title Exception Safety + \ingroup best-practices + \brief A guide to exception safety in Qt. + + \bold {Preliminary warning}: Exception safety is not feature complete! + Common cases should work, but classes might still leak or even crash. + + Qt itself will not throw exceptions. Instead, error codes are used. + In addition, some classes have user visible error messages, for example + \l QIODevice::errorString() or \l QSqlQuery::lastError(). + This has historical and practical reasons - turning on exceptions + can increase the library size by over 20%. + + The following sections describe Qt's behavior if exception support is + enabled at compile time. + + \tableofcontents + + \section1 Exception safe modules + + \section2 Containers + + Qt's \l{container classes} are generally exception neutral. They pass any + exception that happens within their contained type \c T to the user + while keeping their internal state valid. + + Example: + + \code + QList list; + ... + try { + list.append("hello"); + } catch (...) { + } + // list is safe to use - the exception did not affect it. + \endcode + + Exceptions to that rule are containers for types that can throw during assignment + or copy constructions. For those types, functions that modify the container as well as + returning a value, are unsafe to use: + + \code + MyType s = list.takeAt(2); + \endcode + + If an exception occurs during the assignment of \c s, the value at index 2 is already + removed from the container, but hasn't been assigned to \c s yet. It is lost + without chance of recovery. + + The correct way to write it: + + \code + MyType s = list.at(2); + list.removeAt(2); + \endcode + + If the assignment throws, the container still contains the value, no data loss occured. + + Note that implicitly shared Qt classes will not throw in their assignment + operators or copy constructors, so the limitation above does not apply. + + \section1 Out of Memory Handling + + Most desktop operating systems overcommit memory. This means that \c malloc() + or \c{operator new} return a valid pointer, even though there is not enough + memory available at allocation time. On such systems, no exception of type + \c std::bad_alloc is thrown. + + On all other operating systems, Qt will throw an exception of type std::bad_alloc + if any allocation fails. Allocations can fail if the system runs out of memory or + doesn't have enough continuous memory to allocate the requested size. + + Exceptions to that rule are documented. As an example, \l QImage::create() + returns false if not enough memory exists instead of throwing an exception. + + \section1 Recovering from exceptions + + Currently, the only supported use case for recovering from exceptions thrown + within Qt (for example due to out of memory) is to exit the event loop and do + some cleanup before exiting the application. + + Typical use case: + + \code + QApplication app(argc, argv); + ... + try { + app.exec(); + } catch (const std::bad_alloc &) { + // clean up here, e.g. save the session + // and close all config files. + + return 0; // exit the application + } + \endcode + + After an exception is thrown, the connection to the windowing server + might already be closed. It is not safe to call a GUI related function + after catching an exception. + + \section1 Platform-Specific Exception Handling + + \section2 Symbian (Qt for S60) + + The Symbian platform implements its own exception system that differs from the standard + C++ mechanism. When using Qt for S60, and especially when writing code to access Symbian + functionality directly, it may be necessary to know about the underlying implementation + and how it interacts with Qt. + + The \l{Exception Safety with Symbian} document shows how to use the facilities provided + by Qt to use exceptions as safely as possible. +*/ diff --git a/doc/src/platforms/s60-introduction.qdoc b/doc/src/platforms/s60-introduction.qdoc new file mode 100644 index 0000000..d0a1976 --- /dev/null +++ b/doc/src/platforms/s60-introduction.qdoc @@ -0,0 +1,151 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page s60-with-qt-introduction.html + + \title S60 - Introduction to using Qt + \brief An introduction to Qt for S60 developers. + \ingroup howto + \ingroup qts60 + + \tableofcontents + + \section1 Required tools + + See \l{Qt for S60 Requirements} to see what tools are required to use Qt for S60. + + \section1 Installing Qt and running demos + + Follow the instructions found in \l{Installing Qt on S60 using binary package} to learn how + to install Qt using binary package and how to build and run Qt demos. + + Follow the instructions found in \l{Installing Qt on S60} to learn how to install Qt using + using source package and how to build and run the Qt demos. + + \section1 Building your own applications + + If you are new to Qt development, have a look at \l{How to Learn Qt}. + In general, the difference between developing a + Qt application on S60 compared to any of the other platforms supported + by Qt is not that big. + + Once you have crated a \c .pro file for your project, generate the + Carbide specific \c Bld.inf and \c .mmp files this way: + + \snippet doc/src/snippets/code/doc_src_s60-introduction.qdoc 0 + + For more information on how to use qmake have a look at the \l + {qmake Tutorial}. + + Now you can build the Qt on S60 application with standard build + tools. By default, running \c make will produce binaries for the + emulator. However, S60 comes with several alternative build targets, + as shown in the table below: + + \table + \row \o \c debug-winscw \o Build debug binaries for the emulator (default). + It is currently not possible to build release + binaries for the emulator. + \row \o \c debug-gcce \o Build debug binaries for hardware using GCCE. + \row \o \c release-gcce \o Build release binaries for hardware using GCCE. + \row \o \c debug-armv5 \o Build debug binaries for hardware using RVCT. + \row \o \c release-armv5 \o Build release binaries for hardware using RVCT. + \row \o \c run \o Run the emulator binaries from the build directory. + \row \o \c sis \o Create signed \c .sis file for project. + \endtable + + The following lines perform a debug build for the emulator + and deploy all the needed files: + + \snippet doc/src/snippets/code/doc_src_s60-introduction.qdoc 1 + + To work on your project in Carbide, simply import the \c .pro file + by right clicking on the project explorer and executing "Import...". + + \section1 Installing your own applications + + To install your own applications on hardware, you need signed \c .sis file. + The signed \c .sis file can be created with \c make \c sis target. \c sis target + is only supported for executables or projects with \c DEPLOYMENT statements. + By default the \c sis target will create signed \c .sis file for last build + target. For example, the following sequence will generate the needed makefiles, + build the project for \c debug-winscw and \c release-armv5, and create + self-signed \c .sis file for \c release-armv5 target: + + \snippet doc/src/snippets/code/doc_src_s60-introduction.qdoc 2 + + If you want to use different certificate information or override the default + target for \c .sis file creation you can use the environment variables as + shown in the table below: + + \table + \row \o \c QT_SIS_OPTIONS \o Options accepted by \c .sis creation. + -i, install the package right away using PC suite. + -c=, read certificate information from a file. + Execute \c{perl createpackage.pl} for more information + about options. + By default no otions are given. + \row \o \c QT_SIS_TARGET \o Target for which \c .sis file is created. + Accepted values are build targets listed in + previous table. By default last build target. + \row \o \c QT_SIS_CERTIFICATE \o The certificate file used for signing. + By default self-signed certificate. + \row \o \c QT_SIS_KEY \o The certificate's private key file. + By default key is associated to self-signed certificate. + \row \o \c QT_SIS_PASSPHRASE \o The certificate's private key file's passphrase. + By default empty. + \endtable + + For example: + + \snippet doc/src/snippets/code/doc_src_s60-introduction.qdoc 4 + + The environment variables for \c make can also be given as parameters: + + \snippet doc/src/snippets/code/doc_src_s60-introduction.qdoc 3 + + If you want to install the program immediately, make sure that the device + is connected to the computer in "PC Suite" mode, and run \c sis target + with the \c QT_SIS_OPTIONS=-i, like this: + + \snippet doc/src/snippets/code/doc_src_s60-introduction.qdoc 5 +*/ diff --git a/doc/src/platforms/symbian-exceptionsafety.qdoc b/doc/src/platforms/symbian-exceptionsafety.qdoc new file mode 100644 index 0000000..88f4d03 --- /dev/null +++ b/doc/src/platforms/symbian-exceptionsafety.qdoc @@ -0,0 +1,241 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page symbianexceptionsafety.html + \title Exception Safety with Symbian + \ingroup qts60 + \brief A guide to integrating exception safety in Qt with Symbian. + + The following sections describe how Qt code can interoperate with Symbian's + exception safety system. + + \tableofcontents + + \section1 What the problem is + + Qt and Symbian have different exception systems. Qt works with standard C++ + exceptions, whereas Symbian has its TRAP/Leave/CleanupStack system. So, what would + happen if you mix the two systems? It could go wrong in a number of ways. + + Clean-up ordering would be different between the two. When Symbian code + leaves, the clean-up stack is cleaned up before anything else happens. After + that, the objects on the call stack would be cleaned up as with a normal + exception. So if there are any dependencies between stack-based and + objects owned by the clean-up stack, there could be problems due to this + ordering. + + Symbian's \c XLeaveException, which is used when Symbian implements leaves as + exceptions, is not derived from \c std::exception, so would not be caught in + Qt catch statements designed to catch \c std::exception. + + Qt's and standard C++'s \c std::exception derived exceptions result in program + termination if they fall back to a Symbian TRAP. + + These problems can be solved with barrier macros and helper functions that + will translate between the two exception systems. Use them, in Qt code, + whenever calling into or being called from Symbian code. + + \section1 Qt calls to Symbian + + When calling Symbian leaving functions from Qt code, we want to translate + Symbian leaves to standard C++ exceptions. The following help is provided: + + \list + \o \l qt_symbian_throwIfError() takes a Symbian + error code and throws an appropriate exception to represent it. + This will do nothing if the error code is not in fact an error. The + function is equivalent to Symbian's \c User::LeaveIfError. + \o \l q_check_ptr() takes a pointer and throws a std::bad_alloc + exception if it is 0, otherwise the pointer is returned. This can be + used to check the success of a non-throwing allocation, eg from + \c malloc(). The function is equivalent to Symbian's \c + User::LeaveIfNull. + \o \l QT_TRAP_THROWING() takes a Symbian leaving + code fragment f and runs it under a trap harness converting any resulting + error into an exception. + \o \c TRAP and \c TRAPD from the Symbian libraries can be used to convert + leaves to error codes. + \endlist + + \code + HBufC* buf=0; + // this will throw a std::bad_alloc because we've asked for too much memory + QT_TRAP_THROWING(buf = HBufC::NewL(100000000)); + + _LIT(KStr,"abc"); + TInt pos = KStr().Locate('c'); + // pos is a good value, >= 0, so no exception is thrown + qt_symbian_throwIfError(pos); + + pos = KStr().Locate('d'); + // pos == KErrNotFound, so this throws an exception + qt_symbian_throwIfError(pos); + + // we are asking for a lot of memory, HBufC::New may return NULL, so check it + HBufC *buffer = q_check_ptr(HBufC::New(1000000)); + \endcode + + \section2 Be careful with new and CBase + + When writing Qt code, \c new will normally throw a \c std::bad_alloc if the + allocation fails. However this may not happen if the object being created + has its own \c {operator new}. For example, CBase and derived classes have + their own \c {operator new} which returns 0 and the \c {new(ELeave)} + overload for a leaving \c {operator new}, neither of which does what we want. + When using 2-phase construction of CBase derived objects, use \c new and + \l q_check_ptr(). + + \oldcode + CFbsBitmap* fbsBitmap = new(ELeave) CFbsBitmap; + \newcode + CFbsBitmap* fbsBitmap = q_check_ptr(new CFbsBitmap); + \endcode + + \section1 Qt called from Symbian + + When Qt code is called from Symbian, we want to translate standard C++ + exceptions to Symbian leaves or error codes. The following help is + provided: + + \list + \o \l qt_symbian_exception2Error() - + this takes a standard exception and gives an appropriate Symbian + error code. If no mapping is known for the exception type, + \c KErrGeneral is returned. + \o \l qt_symbian_exception2LeaveL() - + this takes a standard exception and generates an appropriate Symbian + leave. + \o \l QT_TRYCATCH_ERROR() - this macro + takes the standard C++ code fragment \c f, catches any std::exceptions + thrown from it, and sets err to the corresponding Symbian error code. + err is set to \c KErrNone otherwise. + \o \l QT_TRYCATCH_LEAVING() - this macro takes the + standard C++ code fragment \c f, catches any std::exceptions thrown from + it, and throws a corresponding Symbian leave. + \endlist + + \code + TInt DoTickL() // called from an active object RunL, ie Symbian leaves expected + { + // without the translation to Symbian Leave, we get a USER:0 panic + QT_TRYCATCH_LEAVING({ + int* x = new int[100000000]; // compiled as Qt code, will throw std::bad_alloc + delete [] x; + }); + return 0; + } + \endcode + + \section1 Common sense things + + Try to minimise the interleaving of Symbian and Qt code, every switch + requires a barrier. Grouping the code styles in different blocks will + minimise the problems. For instance, examine the following code. + + \code + 1. TRAPD(err, m_playUtility = CMdaAudioPlayerUtility::NewL(*this); + 2. QString filepath = QFileInfo( m_sound->fileName() ).absoluteFilePath(); + 3. filepath = QDir::toNativeSeparators(filepath); + 4. m_playUtility->OpenFileL(qt_QString2TPtrC(filepath))); + \endcode + + Line 1 starts a Symbian leave handling block, which is good because it + also uses a Symbian leave generating function. + + Line 2 creates a \l QString, uses \l QFileInfo and various member functions. + These could all throw exceptions, which is not good inside a \c TRAP block. + + Line 3 is unclear as to whether it might throw an exception, but since + it's dealing with strings it probably does, again bad. + + Line 4 is tricky, it calls a leaving function which is ok within a \c TRAP, + but it also uses a helper function to convert string types. In this case + the helper function may cause an unwelcome exception. + + We could rewrite this with nested exception translations, but it's much + easier to refactor it. + + \code + QString filepath = QFileInfo( m_sound->fileName() ).absoluteFilePath(); + filepath = QDir::toNativeSeparators(filepath); + TPtrC filepathPtr(qt_QString2TPtrC(filepath)); + TRAPD(err, m_playUtility = CMdaAudioPlayerUtility::NewL(*this); + m_playUtility->OpenFileL(filepathPtr)); + \endcode + + Now the exception generating functions are separated from the leaving + functions. + + \section1 Advanced technique + When using Symbian APIs in Qt code, you may find that Symbian leaving + code and Qt exception throwing code are just too mixed up to have + them interoperate through barriers. In some circumstances you can allow + code to both leave and throw exceptions. But you must be aware of the + following issues: + + \list + \o Depending on whether a leave or exception is thrown, or a normal + exit happens, the cleanup order will vary. If the code leaves, + cleanup stack cleanup will happen first. On an exception however, + cleanup stack cleanup will happen last. + \o There must not be any destructor dependencies between different + code styles. That is, you must not have symbian objects using Qt + objects in their destructors, and vice versa. This is because the + cleanup order varies, and may result in objects being used after + they are deleted. + \o The cleanup stack must not refer to any stack based object. For + instance, in Symbian you may use \c CleanupClosePushL() to push + stack based R-classes onto the cleanup stack. However if the + stack has unwound due to an exception before the cleanup stack + cleanup happens, stack based objects will now be invalid. + Instead of using the cleanup stack, consider Symbian's new + \c LManagedHandle<> (or a custom cleanup object) to tie R-class + cleanup to the stack. + \o Mixed throwing code must be called within both a TRAP and a + try/catch harness. Standard exceptions must not propagate to + the TRAP and cleanup stack cleanup will only happen if a leave + is thrown, so the correct pattern is either \c {TRAPD(err, + QT_TRYCATCH_LEAVING( f ));} or \c {QT_TRAP_THROWING( + QT_TRYCATCH_LEAVING( f ));}, depending if you want an error + code or exception as a result. + \endlist +*/ diff --git a/doc/src/s60-introduction.qdoc b/doc/src/s60-introduction.qdoc deleted file mode 100644 index d0a1976..0000000 --- a/doc/src/s60-introduction.qdoc +++ /dev/null @@ -1,151 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \page s60-with-qt-introduction.html - - \title S60 - Introduction to using Qt - \brief An introduction to Qt for S60 developers. - \ingroup howto - \ingroup qts60 - - \tableofcontents - - \section1 Required tools - - See \l{Qt for S60 Requirements} to see what tools are required to use Qt for S60. - - \section1 Installing Qt and running demos - - Follow the instructions found in \l{Installing Qt on S60 using binary package} to learn how - to install Qt using binary package and how to build and run Qt demos. - - Follow the instructions found in \l{Installing Qt on S60} to learn how to install Qt using - using source package and how to build and run the Qt demos. - - \section1 Building your own applications - - If you are new to Qt development, have a look at \l{How to Learn Qt}. - In general, the difference between developing a - Qt application on S60 compared to any of the other platforms supported - by Qt is not that big. - - Once you have crated a \c .pro file for your project, generate the - Carbide specific \c Bld.inf and \c .mmp files this way: - - \snippet doc/src/snippets/code/doc_src_s60-introduction.qdoc 0 - - For more information on how to use qmake have a look at the \l - {qmake Tutorial}. - - Now you can build the Qt on S60 application with standard build - tools. By default, running \c make will produce binaries for the - emulator. However, S60 comes with several alternative build targets, - as shown in the table below: - - \table - \row \o \c debug-winscw \o Build debug binaries for the emulator (default). - It is currently not possible to build release - binaries for the emulator. - \row \o \c debug-gcce \o Build debug binaries for hardware using GCCE. - \row \o \c release-gcce \o Build release binaries for hardware using GCCE. - \row \o \c debug-armv5 \o Build debug binaries for hardware using RVCT. - \row \o \c release-armv5 \o Build release binaries for hardware using RVCT. - \row \o \c run \o Run the emulator binaries from the build directory. - \row \o \c sis \o Create signed \c .sis file for project. - \endtable - - The following lines perform a debug build for the emulator - and deploy all the needed files: - - \snippet doc/src/snippets/code/doc_src_s60-introduction.qdoc 1 - - To work on your project in Carbide, simply import the \c .pro file - by right clicking on the project explorer and executing "Import...". - - \section1 Installing your own applications - - To install your own applications on hardware, you need signed \c .sis file. - The signed \c .sis file can be created with \c make \c sis target. \c sis target - is only supported for executables or projects with \c DEPLOYMENT statements. - By default the \c sis target will create signed \c .sis file for last build - target. For example, the following sequence will generate the needed makefiles, - build the project for \c debug-winscw and \c release-armv5, and create - self-signed \c .sis file for \c release-armv5 target: - - \snippet doc/src/snippets/code/doc_src_s60-introduction.qdoc 2 - - If you want to use different certificate information or override the default - target for \c .sis file creation you can use the environment variables as - shown in the table below: - - \table - \row \o \c QT_SIS_OPTIONS \o Options accepted by \c .sis creation. - -i, install the package right away using PC suite. - -c=, read certificate information from a file. - Execute \c{perl createpackage.pl} for more information - about options. - By default no otions are given. - \row \o \c QT_SIS_TARGET \o Target for which \c .sis file is created. - Accepted values are build targets listed in - previous table. By default last build target. - \row \o \c QT_SIS_CERTIFICATE \o The certificate file used for signing. - By default self-signed certificate. - \row \o \c QT_SIS_KEY \o The certificate's private key file. - By default key is associated to self-signed certificate. - \row \o \c QT_SIS_PASSPHRASE \o The certificate's private key file's passphrase. - By default empty. - \endtable - - For example: - - \snippet doc/src/snippets/code/doc_src_s60-introduction.qdoc 4 - - The environment variables for \c make can also be given as parameters: - - \snippet doc/src/snippets/code/doc_src_s60-introduction.qdoc 3 - - If you want to install the program immediately, make sure that the device - is connected to the computer in "PC Suite" mode, and run \c sis target - with the \c QT_SIS_OPTIONS=-i, like this: - - \snippet doc/src/snippets/code/doc_src_s60-introduction.qdoc 5 -*/ diff --git a/doc/src/symbian-exceptionsafety.qdoc b/doc/src/symbian-exceptionsafety.qdoc deleted file mode 100644 index 88f4d03..0000000 --- a/doc/src/symbian-exceptionsafety.qdoc +++ /dev/null @@ -1,241 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \page symbianexceptionsafety.html - \title Exception Safety with Symbian - \ingroup qts60 - \brief A guide to integrating exception safety in Qt with Symbian. - - The following sections describe how Qt code can interoperate with Symbian's - exception safety system. - - \tableofcontents - - \section1 What the problem is - - Qt and Symbian have different exception systems. Qt works with standard C++ - exceptions, whereas Symbian has its TRAP/Leave/CleanupStack system. So, what would - happen if you mix the two systems? It could go wrong in a number of ways. - - Clean-up ordering would be different between the two. When Symbian code - leaves, the clean-up stack is cleaned up before anything else happens. After - that, the objects on the call stack would be cleaned up as with a normal - exception. So if there are any dependencies between stack-based and - objects owned by the clean-up stack, there could be problems due to this - ordering. - - Symbian's \c XLeaveException, which is used when Symbian implements leaves as - exceptions, is not derived from \c std::exception, so would not be caught in - Qt catch statements designed to catch \c std::exception. - - Qt's and standard C++'s \c std::exception derived exceptions result in program - termination if they fall back to a Symbian TRAP. - - These problems can be solved with barrier macros and helper functions that - will translate between the two exception systems. Use them, in Qt code, - whenever calling into or being called from Symbian code. - - \section1 Qt calls to Symbian - - When calling Symbian leaving functions from Qt code, we want to translate - Symbian leaves to standard C++ exceptions. The following help is provided: - - \list - \o \l qt_symbian_throwIfError() takes a Symbian - error code and throws an appropriate exception to represent it. - This will do nothing if the error code is not in fact an error. The - function is equivalent to Symbian's \c User::LeaveIfError. - \o \l q_check_ptr() takes a pointer and throws a std::bad_alloc - exception if it is 0, otherwise the pointer is returned. This can be - used to check the success of a non-throwing allocation, eg from - \c malloc(). The function is equivalent to Symbian's \c - User::LeaveIfNull. - \o \l QT_TRAP_THROWING() takes a Symbian leaving - code fragment f and runs it under a trap harness converting any resulting - error into an exception. - \o \c TRAP and \c TRAPD from the Symbian libraries can be used to convert - leaves to error codes. - \endlist - - \code - HBufC* buf=0; - // this will throw a std::bad_alloc because we've asked for too much memory - QT_TRAP_THROWING(buf = HBufC::NewL(100000000)); - - _LIT(KStr,"abc"); - TInt pos = KStr().Locate('c'); - // pos is a good value, >= 0, so no exception is thrown - qt_symbian_throwIfError(pos); - - pos = KStr().Locate('d'); - // pos == KErrNotFound, so this throws an exception - qt_symbian_throwIfError(pos); - - // we are asking for a lot of memory, HBufC::New may return NULL, so check it - HBufC *buffer = q_check_ptr(HBufC::New(1000000)); - \endcode - - \section2 Be careful with new and CBase - - When writing Qt code, \c new will normally throw a \c std::bad_alloc if the - allocation fails. However this may not happen if the object being created - has its own \c {operator new}. For example, CBase and derived classes have - their own \c {operator new} which returns 0 and the \c {new(ELeave)} - overload for a leaving \c {operator new}, neither of which does what we want. - When using 2-phase construction of CBase derived objects, use \c new and - \l q_check_ptr(). - - \oldcode - CFbsBitmap* fbsBitmap = new(ELeave) CFbsBitmap; - \newcode - CFbsBitmap* fbsBitmap = q_check_ptr(new CFbsBitmap); - \endcode - - \section1 Qt called from Symbian - - When Qt code is called from Symbian, we want to translate standard C++ - exceptions to Symbian leaves or error codes. The following help is - provided: - - \list - \o \l qt_symbian_exception2Error() - - this takes a standard exception and gives an appropriate Symbian - error code. If no mapping is known for the exception type, - \c KErrGeneral is returned. - \o \l qt_symbian_exception2LeaveL() - - this takes a standard exception and generates an appropriate Symbian - leave. - \o \l QT_TRYCATCH_ERROR() - this macro - takes the standard C++ code fragment \c f, catches any std::exceptions - thrown from it, and sets err to the corresponding Symbian error code. - err is set to \c KErrNone otherwise. - \o \l QT_TRYCATCH_LEAVING() - this macro takes the - standard C++ code fragment \c f, catches any std::exceptions thrown from - it, and throws a corresponding Symbian leave. - \endlist - - \code - TInt DoTickL() // called from an active object RunL, ie Symbian leaves expected - { - // without the translation to Symbian Leave, we get a USER:0 panic - QT_TRYCATCH_LEAVING({ - int* x = new int[100000000]; // compiled as Qt code, will throw std::bad_alloc - delete [] x; - }); - return 0; - } - \endcode - - \section1 Common sense things - - Try to minimise the interleaving of Symbian and Qt code, every switch - requires a barrier. Grouping the code styles in different blocks will - minimise the problems. For instance, examine the following code. - - \code - 1. TRAPD(err, m_playUtility = CMdaAudioPlayerUtility::NewL(*this); - 2. QString filepath = QFileInfo( m_sound->fileName() ).absoluteFilePath(); - 3. filepath = QDir::toNativeSeparators(filepath); - 4. m_playUtility->OpenFileL(qt_QString2TPtrC(filepath))); - \endcode - - Line 1 starts a Symbian leave handling block, which is good because it - also uses a Symbian leave generating function. - - Line 2 creates a \l QString, uses \l QFileInfo and various member functions. - These could all throw exceptions, which is not good inside a \c TRAP block. - - Line 3 is unclear as to whether it might throw an exception, but since - it's dealing with strings it probably does, again bad. - - Line 4 is tricky, it calls a leaving function which is ok within a \c TRAP, - but it also uses a helper function to convert string types. In this case - the helper function may cause an unwelcome exception. - - We could rewrite this with nested exception translations, but it's much - easier to refactor it. - - \code - QString filepath = QFileInfo( m_sound->fileName() ).absoluteFilePath(); - filepath = QDir::toNativeSeparators(filepath); - TPtrC filepathPtr(qt_QString2TPtrC(filepath)); - TRAPD(err, m_playUtility = CMdaAudioPlayerUtility::NewL(*this); - m_playUtility->OpenFileL(filepathPtr)); - \endcode - - Now the exception generating functions are separated from the leaving - functions. - - \section1 Advanced technique - When using Symbian APIs in Qt code, you may find that Symbian leaving - code and Qt exception throwing code are just too mixed up to have - them interoperate through barriers. In some circumstances you can allow - code to both leave and throw exceptions. But you must be aware of the - following issues: - - \list - \o Depending on whether a leave or exception is thrown, or a normal - exit happens, the cleanup order will vary. If the code leaves, - cleanup stack cleanup will happen first. On an exception however, - cleanup stack cleanup will happen last. - \o There must not be any destructor dependencies between different - code styles. That is, you must not have symbian objects using Qt - objects in their destructors, and vice versa. This is because the - cleanup order varies, and may result in objects being used after - they are deleted. - \o The cleanup stack must not refer to any stack based object. For - instance, in Symbian you may use \c CleanupClosePushL() to push - stack based R-classes onto the cleanup stack. However if the - stack has unwound due to an exception before the cleanup stack - cleanup happens, stack based objects will now be invalid. - Instead of using the cleanup stack, consider Symbian's new - \c LManagedHandle<> (or a custom cleanup object) to tie R-class - cleanup to the stack. - \o Mixed throwing code must be called within both a TRAP and a - try/catch harness. Standard exceptions must not propagate to - the TRAP and cleanup stack cleanup will only happen if a leave - is thrown, so the correct pattern is either \c {TRAPD(err, - QT_TRYCATCH_LEAVING( f ));} or \c {QT_TRAP_THROWING( - QT_TRYCATCH_LEAVING( f ));}, depending if you want an error - code or exception as a result. - \endlist -*/ -- cgit v0.12 From f22ba0345f04860f7ca936cc413bccdc77379b23 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Mon, 5 Oct 2009 13:40:36 +0200 Subject: Document Embedded Linux with X11 and Scratchbox environment as Tier 2. (cherry picked from commit b2ea3433f4a42e367fd0708f0198329754903086) --- doc/src/platforms/supported-platforms.qdoc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/src/platforms/supported-platforms.qdoc b/doc/src/platforms/supported-platforms.qdoc index 65d335b..4c3929a 100644 --- a/doc/src/platforms/supported-platforms.qdoc +++ b/doc/src/platforms/supported-platforms.qdoc @@ -128,6 +128,8 @@ \o Intel Compiler \row \o Embedded Linux QWS (Mips, PowerPC) \o gcc (\l{http:\\www.codesourcery.com}{Codesourcery version)} + \row \o Embedded Linux X11 (ARM) + \o gcc (\l{http://www.scratchbox.org/}{Scratchbox)} \row \o Windows CE 6.0 (ARMv4i, x86, MIPS) \o MSVC 2008 WinCE 6.0 Professional \endtable -- cgit v0.12 From 52d7cc6ececeda3c264ab0a6294aa5000365dec0 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Mon, 5 Oct 2009 13:47:52 +0200 Subject: Updated JavaScriptCore from /home/khansen/dev/qtwebkit to jsc-for-qtscript-4.6-staging-05102009 ( 38c2b17366f24220d9ae0456a7cfe2ac78a9f91c ) Adapt src/script to src/3rdparty/javascriptcore changes (cherry picked from commit 502c7d324141fb48a902ef475b4fd2932dc859c5) --- .../javascriptcore/JavaScriptCore/ChangeLog | 579 +++++++++++++++++++++ .../JavaScriptCore/JavaScriptCore.pri | 10 +- .../JavaScriptCore/assembler/MacroAssemblerARM.cpp | 27 + .../JavaScriptCore/assembler/MacroAssemblerARM.h | 15 + .../JavaScriptCore/assembler/MacroAssemblerARMv7.h | 12 + .../assembler/MacroAssemblerX86Common.h | 10 + .../JavaScriptCore/bytecode/EvalCodeCache.h | 2 +- .../JavaScriptCore/bytecode/SamplingTool.cpp | 30 +- .../JavaScriptCore/bytecode/SamplingTool.h | 22 +- .../bytecompiler/BytecodeGenerator.cpp | 8 +- .../bytecompiler/BytecodeGenerator.h | 9 +- .../JavaScriptCore/debugger/Debugger.cpp | 2 +- .../JavaScriptCore/debugger/DebuggerCallFrame.cpp | 2 +- .../JavaScriptCore/interpreter/Interpreter.cpp | 4 + .../javascriptcore/JavaScriptCore/jit/JIT.cpp | 6 +- .../javascriptcore/JavaScriptCore/jit/JIT.h | 17 +- .../JavaScriptCore/jit/JITArithmetic.cpp | 263 +++++++--- .../javascriptcore/JavaScriptCore/jit/JITCall.cpp | 24 +- .../JavaScriptCore/jit/JITInlineMethods.h | 43 +- .../JavaScriptCore/jit/JITOpcodes.cpp | 113 ++-- .../JavaScriptCore/jit/JITPropertyAccess.cpp | 128 +++-- .../javascriptcore/JavaScriptCore/jit/JITStubs.cpp | 24 +- .../javascriptcore/JavaScriptCore/jit/JITStubs.h | 1 - src/3rdparty/javascriptcore/JavaScriptCore/jsc.cpp | 41 +- .../javascriptcore/JavaScriptCore/parser/Nodes.cpp | 8 - .../JavaScriptCore/runtime/ArrayPrototype.cpp | 51 +- .../JavaScriptCore/runtime/Collector.cpp | 8 +- .../JavaScriptCore/runtime/Completion.cpp | 4 +- .../JavaScriptCore/runtime/Executable.cpp | 2 +- .../JavaScriptCore/runtime/Executable.h | 58 ++- .../JavaScriptCore/runtime/JSArray.cpp | 121 ++--- .../JavaScriptCore/runtime/JSArray.h | 19 +- .../runtime/JSGlobalObjectFunctions.cpp | 2 +- .../JavaScriptCore/runtime/JSValue.cpp | 5 +- .../JavaScriptCore/runtime/JSValue.h | 18 +- .../JavaScriptCore/runtime/Structure.cpp | 3 +- .../JavaScriptCore/runtime/TimeoutChecker.cpp | 25 +- .../JavaScriptCore/wtf/Assertions.cpp | 4 + .../javascriptcore/JavaScriptCore/wtf/Assertions.h | 12 + .../JavaScriptCore/wtf/FastMalloc.cpp | 12 +- .../javascriptcore/JavaScriptCore/wtf/FastMalloc.h | 5 + .../javascriptcore/JavaScriptCore/wtf/Forward.h | 5 +- .../JavaScriptCore/wtf/HashCountedSet.h | 38 +- .../javascriptcore/JavaScriptCore/wtf/Platform.h | 5 + .../JavaScriptCore/wtf/RandomNumber.cpp | 17 + .../javascriptcore/JavaScriptCore/wtf/TCSpinLock.h | 7 + .../JavaScriptCore/wtf/ThreadingPthreads.cpp | 2 +- .../JavaScriptCore/yarr/RegexJIT.cpp | 4 +- src/3rdparty/javascriptcore/VERSION | 4 +- src/3rdparty/javascriptcore/WebKit.pri | 9 +- src/script/api/qscriptengine.cpp | 2 +- 51 files changed, 1347 insertions(+), 495 deletions(-) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/ChangeLog b/src/3rdparty/javascriptcore/JavaScriptCore/ChangeLog index 84a2935..9dc7916 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/ChangeLog +++ b/src/3rdparty/javascriptcore/JavaScriptCore/ChangeLog @@ -1,3 +1,518 @@ +2009-10-02 Geoffrey Garen + + Reviewed by Sam Weinig. + + Removed the concept of a "fast access cutoff" in arrays, because it + punished some patterns of array access too much, and made things too + complex for inlining in some cases. + + 1.3% speedup on SunSpider. + + * jit/JITOpcodes.cpp: + (JSC::JIT::emitSlow_op_get_by_val): + (JSC::JIT::emitSlow_op_put_by_val): + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emit_op_get_by_val): + (JSC::JIT::emitSlow_op_get_by_val): + (JSC::JIT::emit_op_put_by_val): + (JSC::JIT::emitSlow_op_put_by_val): + * jit/JITStubs.cpp: + * jit/JITStubs.h: + (JSC::): Check m_vectorLength instead of m_fastAccessCutoff when + getting / putting from / to an array. Inline putting past the end of + the array. + + * runtime/JSArray.cpp: + (JSC::JSArray::JSArray): + (JSC::JSArray::getOwnPropertySlot): + (JSC::JSArray::getOwnPropertyDescriptor): + (JSC::JSArray::put): + (JSC::JSArray::putSlowCase): + (JSC::JSArray::deleteProperty): + (JSC::JSArray::getOwnPropertyNames): + (JSC::JSArray::increaseVectorLength): + (JSC::JSArray::setLength): + (JSC::JSArray::pop): + (JSC::JSArray::push): + (JSC::JSArray::sort): + (JSC::JSArray::fillArgList): + (JSC::JSArray::copyToRegisters): + (JSC::JSArray::compactForSorting): + (JSC::JSArray::checkConsistency): + * runtime/JSArray.h: + (JSC::JSArray::canGetIndex): + (JSC::JSArray::canSetIndex): + (JSC::JSArray::setIndex): + (JSC::JSArray::markChildrenDirect): Removed m_fastAccessCutoff, and + replaced with checks for JSValue() to detect reads and writes from / to + uninitialized parts of the array. + +2009-10-02 Jonni Rainisto + + Reviewed by Darin Adler. + + Math.random() gives too low values on Win32 when _CRT_RAND_S is not defined + https://bugs.webkit.org/show_bug.cgi?id=29956 + + * wtf/RandomNumber.cpp: + (WTF::randomNumber): Added PLATFORM(WIN_OS) to handle 15bit rand() + +2009-10-02 Geoffrey Garen + + Reviewed by Sam Weinig. + + Take one branch instead of two to test for JSValue(). + + 1.1% SunSpider speedup. + + * jit/JITCall.cpp: + (JSC::JIT::compileOpCall): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_to_jsnumber): + (JSC::JIT::emit_op_create_arguments): + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emitSlow_op_get_by_val): + (JSC::JIT::emit_op_put_by_val): Test for the empty value tag, instead + of testing for the cell tag with a 0 payload. + + * runtime/JSValue.cpp: + (JSC::JSValue::description): Added support for dumping the new empty value, + and deleted values, in debug builds. + + * runtime/JSValue.h: + (JSC::JSValue::JSValue()): Construct JSValue() with the empty value tag. + + (JSC::JSValue::JSValue(JSCell*)): Convert null pointer to the empty value + tag, to avoid having two different c++ versions of null / empty. + + (JSC::JSValue::operator bool): Test for the empty value tag, instead + of testing for the cell tag with a 0 payload. + +2009-10-01 Zoltan Horvath + + Reviewed by Simon Hausmann. + + [Qt] Allow custom memory allocation control for the whole JavaScriptCore + https://bugs.webkit.org/show_bug.cgi?id=27029 + + Since in JavaScriptCore almost every class which has been instantiated by operator new is + inherited from FastAllocBase (bug #20422), we disable customizing global operator new for the Qt-port + when USE_SYSTEM_MALLOC=0. + + Add #include to FastMalloc.cpp because it's used by TCMalloc_PageHeap::scavengerThread(). + (It's needed for the functionality of TCmalloc.) + + Add TCSystemAlloc.cpp to JavaScriptCore.pri if USE_SYSTEM_MALLOC is disabled. + + * JavaScriptCore.pri: + * wtf/FastMalloc.cpp: + (WTF::sleep): + * wtf/FastMalloc.h: + +2009-09-30 Oliver Hunt + + Reviewed by Geoff Garen. + + Devirtualise array toString conversion + + Tweak the implementation of Array.prototype.toString to have a fast path + when acting on a true JSArray. + + * runtime/ArrayPrototype.cpp: + (JSC::arrayProtoFuncToString): + +2009-09-30 Csaba Osztrogonac + + Reviewed by Geoffrey Garen. + + Buildfix for platforms using JSVALUE32. + https://bugs.webkit.org/show_bug.cgi?id=29915 + + After http://trac.webkit.org/changeset/48905 the build broke in JSVALUE32 case. + Also removed unreachable code. + + * jit/JITArithmetic.cpp: + (JSC::JIT::emit_op_add): + - Declaration of "OperandTypes types" moved before first use. + - Typos fixed: dst modified to result, regT2 added. + - Unreachable code removed. + (JSC::JIT::emitSlow_op_add): + - Missing declaration of "OperandTypes types" added. + +2009-09-30 Janne Koskinen + + Reviewed by Simon Hausmann. + + Fix CRASH() macro for Symbian build. + + * wtf/Assertions.h: Added missing } + +2009-09-29 Geoffrey Garen + + Reviewed by Sam Weinig. + + Standardized an optimization for adding non-numbers. + + SunSpider says maybe a tiny speedup. + + * jit/JITArithmetic.cpp: + (JSC::JIT::emit_op_add): + (JSC::JIT::emitSlow_op_add): + +2009-09-29 Janne Koskinen + + Reviewed by David Kilzer. + + [Qt] Assert messages prints visible in Symbian + https://bugs.webkit.org/show_bug.cgi?id=29808 + + Asserts use vprintf to print the messages to stderr. + In Symbian Open C it is not possible to see stderr so + I routed the messages to stdout instead. + + * wtf/Assertions.cpp: + +2009-09-29 Janne Koskinen + + Reviewed by Darin Adler. + + [Qt] Symbian CRASH macro implementation + + Added Symbian specific crash macro that + stops to crash line if JIT debugging is used. + Additional differentiation of access violation + (KERN-EXEC 3) and CRASH panic. + + * wtf/Assertions.h: + +2009-09-28 Mark Rowe + + Reviewed by Gavin Barraclough. + + JavaScriptCore fails to mark registers when built for x86_64 using LLVM GCC. + + * runtime/Collector.cpp: + (JSC::Heap::markCurrentThreadConservatively): Force jmp_buf to use the appropriate alignment for a pointer + to ensure that we correctly interpret the contents of registers during marking. + +<<<<<<< HEAD:JavaScriptCore/ChangeLog +======= +2009-09-29 Geoffrey Garen + + Reviewed by Gavin Barraclough. + + Inlined a few math operations. + + ~1% SunSpider speedup. + + * jit/JIT.h: + * jit/JITArithmetic.cpp: + (JSC::JIT::compileBinaryArithOpSlowCase): + (JSC::JIT::emitSlow_op_add): + (JSC::JIT::emitSlow_op_mul): + (JSC::JIT::emit_op_sub): + (JSC::JIT::emitSlow_op_sub): Don't take a stub call when operating on + a constant int and a double. + +2009-09-28 Oliver Hunt + + Reviewed by Geoff Garen. + + Hard dependency on SSE2 instruction set with JIT + https://bugs.webkit.org/show_bug.cgi?id=29779 + + Add floating point support checks to op_jfalse and op_jtrue, and + fix the logic for the slow case of op_add + + * jit/JITArithmetic.cpp: + (JSC::JIT::emitSlow_op_add): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_jfalse): + (JSC::JIT::emit_op_jtrue): + +2009-09-28 Yaar Schnitman + + Reviewed by Dimitri Glazkov. + + Chromium port - recognize we are being built independently + of chromium and look for dependencies under webkit/chromium rather + than chromium/src. + + https://bugs.webkit.org/show_bug.cgi?id=29722 + + * JavaScriptCore.gyp/JavaScriptCore.gyp: + +2009-09-28 Jakub Wieczorek + + Reviewed by Simon Hausmann. + + [Qt] Implement XSLT support with QtXmlPatterns. + https://bugs.webkit.org/show_bug.cgi?id=28303 + + * wtf/Platform.h: Add a WTF_USE_QXMLQUERY #define. + +2009-09-28 Yongjun Zhang + + Reviewed by Eric Seidel. + + https://bugs.webkit.org/show_bug.cgi?id=28054 + + Use derefInNotNull() to work around winscw compiler forward declaration bug + regarding templated classes. + + The compiler bug is reported at + https://xdabug001.ext.nokia.com/bugzilla/show_bug.cgi?id=9812. + + The change should be reverted when the above bug is fixed in winscw compiler. + + Add parenthesis around (RefPtr::*UnspecifiedBoolType) to make winscw compiler + work with the default UnSpecifiedBoolType() operator, which removes the winscw hack. + + * wtf/RefPtr.h: + (WTF::RefPtr::~RefPtr): + (WTF::RefPtr::clear): + (WTF::RefPtr::operator UnspecifiedBoolType): + +2009-09-28 Gabor Loki + + Reviewed by Simon Hausmann. + + Remove __clear_cache which is an internal function of GCC + https://bugs.webkit.org/show_bug.cgi?id=28886 + + Although __clear_cache is exported from GCC, this is an internal + function. GCC makes no promises about it. + + * jit/ExecutableAllocator.h: + (JSC::ExecutableAllocator::cacheFlush): + +2009-09-28 Sam Weinig + + Reviewed by Oliver Hunt. + + Fix an absolute path to somewhere in Oliver's machine to a relative path + for derived JSONObject.lut.h. + + * JavaScriptCore.xcodeproj/project.pbxproj: + +2009-09-28 Joerg Bornemann + + Reviewed by Simon Hausmann. + + Add ARM version detection for Windows CE. + + * wtf/Platform.h: + +2009-09-26 Yongjun Zhang + + Reviewed by Simon Hausmann. + + Add MarkStackSymbian.cpp to build JavascriptCore for Symbian. + + Re-use Windows shrinkAllocation implementation because Symbian doesn't + support releasing part of memory region. + + Use fastMalloc and fastFree to implement allocateStack and releaseStack + for Symbian port. + + * JavaScriptCore.pri: + * runtime/MarkStack.h: + (JSC::MarkStack::MarkStackArray::shrinkAllocation): + * runtime/MarkStackSymbian.cpp: Added. + (JSC::MarkStack::initializePagesize): + (JSC::MarkStack::allocateStack): + (JSC::MarkStack::releaseStack): + +>>>>>>> 8e5ea20... Hard dependency on SSE2 instruction set with JIT:JavaScriptCore/ChangeLog +2009-09-25 Gabor Loki + + Reviewed by Gavin Barraclough. + + Fix unaligned data access in YARR_JIT on ARMv5 and below. + https://bugs.webkit.org/show_bug.cgi?id=29695 + + On ARMv5 and below all data access should be naturally aligned. + In the YARR_JIT there is a case when character pairs are + loaded from the input string, but this data access is not + naturally aligned. This fix introduces load32WithUnalignedHalfWords + and branch32WithUnalignedHalfWords functions which contain + naturally aligned memory loads - half word loads - on ARMv5 and below. + + * assembler/MacroAssemblerARM.cpp: + (JSC::MacroAssemblerARM::load32WithUnalignedHalfWords): + * assembler/MacroAssemblerARM.h: + (JSC::MacroAssemblerARM::load32WithUnalignedHalfWords): + (JSC::MacroAssemblerARM::branch32WithUnalignedHalfWords): + * assembler/MacroAssemblerARMv7.h: + (JSC::MacroAssemblerARMv7::load32WithUnalignedHalfWords): + (JSC::MacroAssemblerARMv7::branch32): + (JSC::MacroAssemblerARMv7::branch32WithUnalignedHalfWords): + * assembler/MacroAssemblerX86Common.h: + (JSC::MacroAssemblerX86Common::load32WithUnalignedHalfWords): + (JSC::MacroAssemblerX86Common::branch32WithUnalignedHalfWords): + * wtf/Platform.h: + * yarr/RegexJIT.cpp: + (JSC::Yarr::RegexGenerator::generatePatternCharacterPair): + +2009-09-24 Oliver Hunt + + Reviewed by Gavin Barraclough. + + Division is needlessly slow in 64-bit + https://bugs.webkit.org/show_bug.cgi?id=29723 + + Add codegen for op_div on x86-64 + + * jit/JIT.cpp: + (JSC::JIT::privateCompileMainPass): + (JSC::JIT::privateCompileSlowCases): + * jit/JIT.h: + * jit/JITArithmetic.cpp: + (JSC::JIT::compileBinaryArithOpSlowCase): + (JSC::JIT::emit_op_div): + (JSC::JIT::emitSlow_op_div): + * jit/JITInlineMethods.h: + (JSC::JIT::isOperandConstantImmediateDouble): + (JSC::JIT::addressFor): + (JSC::JIT::emitLoadDouble): + (JSC::JIT::emitLoadInt32ToDouble): + (JSC::JIT::emitJumpSlowCaseIfNotImmediateNumber): + +2009-09-24 Yong Li + + Reviewed by Adam Barth. + + Replace platform-dependent code with WTF::currentTime() + https://bugs.webkit.org/show_bug.cgi?id=29148 + + * jsc.cpp: + (StopWatch::start): + (StopWatch::stop): + (StopWatch::getElapsedMS): + * runtime/TimeoutChecker.cpp: + (JSC::getCPUTime): + +2009-09-24 Mark Rowe + + Reviewed by Gavin Barraclough. + + Fix FastMalloc to build with assertions enabled. + + * wtf/FastMalloc.cpp: + (WTF::TCMalloc_Central_FreeList::ReleaseToSpans): + * wtf/TCSpinLock.h: + (TCMalloc_SpinLock::IsHeld): + +2009-09-24 Mark Rowe + + Reviewed by Sam Weinig. + + FastMalloc scavenging thread should be named + + * wtf/FastMalloc.cpp: + (WTF::TCMalloc_PageHeap::scavengerThread): Set the thread name. + * wtf/Platform.h: Move the knowledge of whether pthread_setname_np exists to here as HAVE(PTHREAD_SETNAME_NP). + * wtf/ThreadingPthreads.cpp: + (WTF::setThreadNameInternal): Use HAVE(PTHREAD_SETNAME_NP). + +2009-09-24 Geoffrey Garen + + Suggested by Darin Adler. + + Removed some unnecessary parameter names. + + * wtf/HashCountedSet.h: + +2009-09-22 Oliver Hunt + + Reviewed by Geoff Garen. + + Code sampling builds are broken. + https://bugs.webkit.org/show_bug.cgi?id=29662 + + Fix build. + + * bytecode/EvalCodeCache.h: + (JSC::EvalCodeCache::get): + * bytecode/SamplingTool.cpp: + (JSC::ScriptSampleRecord::sample): + (JSC::SamplingTool::doRun): + (JSC::SamplingTool::notifyOfScope): + (JSC::compareScriptSampleRecords): + (JSC::SamplingTool::dump): + * bytecode/SamplingTool.h: + (JSC::ScriptSampleRecord::ScriptSampleRecord): + (JSC::ScriptSampleRecord::~ScriptSampleRecord): + (JSC::SamplingTool::SamplingTool): + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::BytecodeGenerator): + (JSC::BytecodeGenerator::emitNewFunction): + (JSC::BytecodeGenerator::emitNewFunctionExpression): + * bytecompiler/BytecodeGenerator.h: + (JSC::BytecodeGenerator::makeFunction): + * debugger/Debugger.cpp: + (JSC::evaluateInGlobalCallFrame): + * debugger/DebuggerCallFrame.cpp: + (JSC::DebuggerCallFrame::evaluate): + * parser/Nodes.cpp: + (JSC::ScopeNode::ScopeNode): + * runtime/Completion.cpp: + (JSC::checkSyntax): + (JSC::evaluate): + * runtime/Executable.cpp: + (JSC::FunctionExecutable::fromGlobalCode): + * runtime/Executable.h: + (JSC::ScriptExecutable::ScriptExecutable): + (JSC::EvalExecutable::EvalExecutable): + (JSC::EvalExecutable::create): + (JSC::ProgramExecutable::ProgramExecutable): + (JSC::FunctionExecutable::create): + (JSC::FunctionExecutable::FunctionExecutable): + * runtime/JSGlobalObjectFunctions.cpp: + (JSC::globalFuncEval): + +2009-09-22 Darin Adler + + Reviewed by Sam Weinig. + + * wtf/Forward.h: Added PassOwnPtr. + +2009-09-22 Simon Hausmann + + Unreviewed build fix for Windows CE < 5 + + Define WINCEBASIC to disable the IsDebuggerPresent() code in + wtf/Assertions.cpp. + + * JavaScriptCore.pri: + +2009-10-02 Tor Arne Vestbø + + Rubber-stamped by Simon Hausmann. + + Fix the Qt on Mac OS X build. + + * wtf/FastMalloc.cpp: + +2009-10-02 Jørgen Lind + + Reviewed by Simon Hausmann. + + Allow enabling and disabling of the JIT through a qmake variable. + + Qt's configure may set this variable through .qmake.cache if a + commandline option is given and/or the compile test for hwcap.h + failed/succeeded. + + * JavaScriptCore.pri: + +2009-09-23 Geoffrey Garen + + A piece of my last patch that I forgot. + + * wtf/HashCountedSet.h: + (WTF::::clear): Added HashCountedSet::clear. + 2009-09-24 Gabor Loki Reviewed by Gavin Barraclough. @@ -28,6 +543,70 @@ * jit/ExecutableAllocator.h: (JSC::ExecutableAllocator::cacheFlush): +2009-09-21 Oliver Hunt + + Reviewed by Geoff Garen. + + REGRESSION (r48582): Crash in StructureStubInfo::initPutByIdTransition when reloading trac.webkit.org + https://bugs.webkit.org/show_bug.cgi?id=29599 + + It is unsafe to attempt to cache new property transitions on + dictionaries of any type. + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::tryCachePutByID): + * jit/JITStubs.cpp: + (JSC::JITThunks::tryCachePutByID): + +2009-09-21 Oliver Hunt + + RS=Maciej Stachowiak. + + Re-land SNES fix with corrected assertion. + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::resolveGlobal): + (JSC::Interpreter::tryCachePutByID): + (JSC::Interpreter::tryCacheGetByID): + * jit/JITStubs.cpp: + (JSC::JITThunks::tryCachePutByID): + (JSC::JITThunks::tryCacheGetByID): + (JSC::DEFINE_STUB_FUNCTION): + * runtime/BatchedTransitionOptimizer.h: + (JSC::BatchedTransitionOptimizer::BatchedTransitionOptimizer): + * runtime/JSObject.cpp: + (JSC::JSObject::removeDirect): + * runtime/Structure.cpp: + (JSC::Structure::Structure): + (JSC::Structure::getEnumerablePropertyNames): + (JSC::Structure::despecifyDictionaryFunction): + (JSC::Structure::addPropertyTransitionToExistingStructure): + (JSC::Structure::addPropertyTransition): + (JSC::Structure::removePropertyTransition): + (JSC::Structure::toDictionaryTransition): + (JSC::Structure::toCacheableDictionaryTransition): + (JSC::Structure::toUncacheableDictionaryTransition): + (JSC::Structure::fromDictionaryTransition): + (JSC::Structure::removePropertyWithoutTransition): + * runtime/Structure.h: + (JSC::Structure::isDictionary): + (JSC::Structure::isUncacheableDictionary): + (JSC::Structure::): + * runtime/StructureChain.cpp: + (JSC::StructureChain::isCacheable): + +2009-09-21 Adam Roben + + Revert r48573, as it caused many assertion failures + + * interpreter/Interpreter.cpp: + * jit/JITStubs.cpp: + * runtime/BatchedTransitionOptimizer.h: + * runtime/JSObject.cpp: + * runtime/Structure.cpp: + * runtime/Structure.h: + * runtime/StructureChain.cpp: + 2009-09-21 Gustavo Noronha Silva Unreviewed make dist build fix. Missing files. diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.pri b/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.pri index 965f3d6..5c1d518 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.pri +++ b/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.pri @@ -36,7 +36,6 @@ GENERATED_SOURCES_DIR_SLASH = $${GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP} win32-* { LIBS += -lwinmm } - contains(JAVASCRIPTCORE_JIT,yes): DEFINES+=ENABLE_JIT=1 contains(JAVASCRIPTCORE_JIT,no): DEFINES+=ENABLE_JIT=0 @@ -53,7 +52,10 @@ win32-* { } } -wince*: SOURCES += $$QT_SOURCE_TREE/src/3rdparty/ce-compat/ce_time.cpp +wince* { + SOURCES += $$QT_SOURCE_TREE/src/3rdparty/ce-compat/ce_time.cpp + DEFINES += WINCEBASIC +} include(pcre/pcre.pri) @@ -136,6 +138,10 @@ win32-*|wince* { runtime/MarkStackPosix.cpp } +!contains(DEFINES, USE_SYSTEM_MALLOC) { + SOURCES += wtf/TCSystemAlloc.cpp +} + # AllInOneFile.cpp helps gcc analize and optimize code # Other compilers may be able to do this at link time SOURCES += \ diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARM.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARM.cpp index 43648c4..d726ecd 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARM.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARM.cpp @@ -62,6 +62,33 @@ static bool isVFPPresent() const bool MacroAssemblerARM::s_isVFPPresent = isVFPPresent(); +#if defined(ARM_REQUIRE_NATURAL_ALIGNMENT) && ARM_REQUIRE_NATURAL_ALIGNMENT +void MacroAssemblerARM::load32WithUnalignedHalfWords(BaseIndex address, RegisterID dest) +{ + ARMWord op2; + + ASSERT(address.scale >= 0 && address.scale <= 3); + op2 = m_assembler.lsl(address.index, static_cast(address.scale)); + + if (address.offset >= 0 && address.offset + 0x2 <= 0xff) { + m_assembler.add_r(ARMRegisters::S0, address.base, op2); + m_assembler.ldrh_u(dest, ARMRegisters::S0, ARMAssembler::getOp2Byte(address.offset)); + m_assembler.ldrh_u(ARMRegisters::S0, ARMRegisters::S0, ARMAssembler::getOp2Byte(address.offset + 0x2)); + } else if (address.offset < 0 && address.offset >= -0xff) { + m_assembler.add_r(ARMRegisters::S0, address.base, op2); + m_assembler.ldrh_d(dest, ARMRegisters::S0, ARMAssembler::getOp2Byte(-address.offset)); + m_assembler.ldrh_d(ARMRegisters::S0, ARMRegisters::S0, ARMAssembler::getOp2Byte(-address.offset - 0x2)); + } else { + m_assembler.ldr_un_imm(ARMRegisters::S0, address.offset); + m_assembler.add_r(ARMRegisters::S0, ARMRegisters::S0, op2); + m_assembler.ldrh_r(dest, address.base, ARMRegisters::S0); + m_assembler.add_r(ARMRegisters::S0, ARMRegisters::S0, ARMAssembler::OP2_IMM | 0x2); + m_assembler.ldrh_r(ARMRegisters::S0, address.base, ARMRegisters::S0); + } + m_assembler.orr_r(dest, dest, m_assembler.lsl(ARMRegisters::S0, 16)); +} +#endif + } #endif // ENABLE(ASSEMBLER) && PLATFORM(ARM_TRADITIONAL) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARM.h b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARM.h index 0c696c9..aa8cbb0 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARM.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARM.h @@ -198,6 +198,15 @@ public: m_assembler.baseIndexTransfer32(true, dest, address.base, address.index, static_cast(address.scale), address.offset); } +#if defined(ARM_REQUIRE_NATURAL_ALIGNMENT) && ARM_REQUIRE_NATURAL_ALIGNMENT + void load32WithUnalignedHalfWords(BaseIndex address, RegisterID dest); +#else + void load32WithUnalignedHalfWords(BaseIndex address, RegisterID dest) + { + load32(address, dest); + } +#endif + DataLabel32 load32WithAddressOffsetPatch(Address address, RegisterID dest) { DataLabel32 dataLabel(this); @@ -364,6 +373,12 @@ public: return branch32(cond, ARMRegisters::S1, right); } + Jump branch32WithUnalignedHalfWords(Condition cond, BaseIndex left, Imm32 right) + { + load32WithUnalignedHalfWords(left, ARMRegisters::S1); + return branch32(cond, ARMRegisters::S1, right); + } + Jump branch16(Condition cond, BaseIndex left, RegisterID right) { UNUSED_PARAM(cond); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARMv7.h b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARMv7.h index 999056b..a549604 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARMv7.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARMv7.h @@ -375,6 +375,11 @@ public: load32(setupArmAddress(address), dest); } + void load32WithUnalignedHalfWords(BaseIndex address, RegisterID dest) + { + load32(setupArmAddress(address), dest); + } + void load32(void* address, RegisterID dest) { move(ImmPtr(address), addressTempRegister); @@ -717,6 +722,13 @@ public: return branch32(cond, addressTempRegister, right); } + Jump branch32WithUnalignedHalfWords(Condition cond, BaseIndex left, Imm32 right) + { + // use addressTempRegister incase the branch32 we call uses dataTempRegister. :-/ + load32WithUnalignedHalfWords(left, addressTempRegister); + return branch32(cond, addressTempRegister, right); + } + Jump branch32(Condition cond, AbsoluteAddress left, RegisterID right) { load32(left.m_ptr, dataTempRegister); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerX86Common.h b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerX86Common.h index 61e0e17..5ebefa7 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerX86Common.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerX86Common.h @@ -306,6 +306,11 @@ public: m_assembler.movl_mr(address.offset, address.base, address.index, address.scale, dest); } + void load32WithUnalignedHalfWords(BaseIndex address, RegisterID dest) + { + load32(address, dest); + } + DataLabel32 load32WithAddressOffsetPatch(Address address, RegisterID dest) { m_assembler.movl_mr_disp32(address.offset, address.base, dest); @@ -604,6 +609,11 @@ public: return Jump(m_assembler.jCC(x86Condition(cond))); } + Jump branch32WithUnalignedHalfWords(Condition cond, BaseIndex left, Imm32 right) + { + return branch32(cond, left, right); + } + Jump branch16(Condition cond, BaseIndex left, RegisterID right) { m_assembler.cmpw_rm(right, left.offset, left.base, left.index, left.scale); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/EvalCodeCache.h b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/EvalCodeCache.h index 0e1fb1e..05834fc 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/EvalCodeCache.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/EvalCodeCache.h @@ -50,7 +50,7 @@ namespace JSC { evalExecutable = m_cacheMap.get(evalSource.rep()); if (!evalExecutable) { - evalExecutable = EvalExecutable::create(makeSource(evalSource)); + evalExecutable = EvalExecutable::create(exec, makeSource(evalSource)); exceptionValue = evalExecutable->compile(exec, scopeChain); if (exceptionValue) return 0; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.cpp index 8d0faa1..865c919 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.cpp @@ -157,7 +157,7 @@ void SamplingThread::stop() } -void ScopeSampleRecord::sample(CodeBlock* codeBlock, Instruction* vPC) +void ScriptSampleRecord::sample(CodeBlock* codeBlock, Instruction* vPC) { if (!m_samples) { m_size = codeBlock->instructions().size(); @@ -196,8 +196,8 @@ void SamplingTool::doRun() #if ENABLE(CODEBLOCK_SAMPLING) if (CodeBlock* codeBlock = sample.codeBlock()) { - MutexLocker locker(m_scopeSampleMapMutex); - ScopeSampleRecord* record = m_scopeSampleMap->get(codeBlock->ownerExecutable()); + MutexLocker locker(m_scriptSampleMapMutex); + ScriptSampleRecord* record = m_scopeSampleMap->get(codeBlock->ownerExecutable()); ASSERT(record); record->sample(codeBlock, sample.vPC()); } @@ -209,13 +209,13 @@ void SamplingTool::sample() s_samplingTool->doRun(); } -void SamplingTool::notifyOfScope(ScopeNode* scope) +void SamplingTool::notifyOfScope(ScriptExecutable* script) { #if ENABLE(CODEBLOCK_SAMPLING) - MutexLocker locker(m_scopeSampleMapMutex); - m_scopeSampleMap->set(scope, new ScopeSampleRecord(scope)); + MutexLocker locker(m_scriptSampleMapMutex); + m_scopeSampleMap->set(script, new ScriptSampleRecord(script)); #else - UNUSED_PARAM(scope); + UNUSED_PARAM(script); #endif } @@ -254,10 +254,10 @@ static int compareLineCountInfoSampling(const void* left, const void* right) return (leftLineCount->line > rightLineCount->line) ? 1 : (leftLineCount->line < rightLineCount->line) ? -1 : 0; } -static int compareScopeSampleRecords(const void* left, const void* right) +static int compareScriptSampleRecords(const void* left, const void* right) { - const ScopeSampleRecord* const leftValue = *static_cast(left); - const ScopeSampleRecord* const rightValue = *static_cast(right); + const ScriptSampleRecord* const leftValue = *static_cast(left); + const ScriptSampleRecord* const rightValue = *static_cast(right); return (leftValue->m_sampleCount < rightValue->m_sampleCount) ? 1 : (leftValue->m_sampleCount > rightValue->m_sampleCount) ? -1 : 0; } @@ -318,26 +318,26 @@ void SamplingTool::dump(ExecState* exec) // (3) Build and sort 'codeBlockSamples' array. int scopeCount = m_scopeSampleMap->size(); - Vector codeBlockSamples(scopeCount); - ScopeSampleRecordMap::iterator iter = m_scopeSampleMap->begin(); + Vector codeBlockSamples(scopeCount); + ScriptSampleRecordMap::iterator iter = m_scopeSampleMap->begin(); for (int i = 0; i < scopeCount; ++i, ++iter) codeBlockSamples[i] = iter->second; - qsort(codeBlockSamples.begin(), scopeCount, sizeof(ScopeSampleRecord*), compareScopeSampleRecords); + qsort(codeBlockSamples.begin(), scopeCount, sizeof(ScriptSampleRecord*), compareScriptSampleRecords); // (4) Print data from 'codeBlockSamples' array. printf("\nCodeBlock samples\n\n"); for (int i = 0; i < scopeCount; ++i) { - ScopeSampleRecord* record = codeBlockSamples[i]; + ScriptSampleRecord* record = codeBlockSamples[i]; CodeBlock* codeBlock = record->m_codeBlock; double blockPercent = (record->m_sampleCount * 100.0) / m_sampleCount; if (blockPercent >= 1) { //Instruction* code = codeBlock->instructions().begin(); - printf("#%d: %s:%d: %d / %lld (%.3f%%)\n", i + 1, record->m_scope->sourceURL().UTF8String().c_str(), codeBlock->lineNumberForBytecodeOffset(exec, 0), record->m_sampleCount, m_sampleCount, blockPercent); + printf("#%d: %s:%d: %d / %lld (%.3f%%)\n", i + 1, record->m_executable->sourceURL().UTF8String().c_str(), codeBlock->lineNumberForBytecodeOffset(exec, 0), record->m_sampleCount, m_sampleCount, blockPercent); if (i < 10) { HashMap lineCounts; codeBlock->dump(exec); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.h b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.h index 1a3f7cf..711b086 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.h @@ -38,6 +38,8 @@ namespace JSC { + class ScriptExecutable; + class SamplingFlags { friend class JIT; public: @@ -92,9 +94,9 @@ namespace JSC { class ScopeNode; struct Instruction; - struct ScopeSampleRecord { - ScopeSampleRecord(ScopeNode* scope) - : m_scope(scope) + struct ScriptSampleRecord { + ScriptSampleRecord(ScriptExecutable* executable) + : m_executable(executable) , m_codeBlock(0) , m_sampleCount(0) , m_opcodeSampleCount(0) @@ -103,7 +105,7 @@ namespace JSC { { } - ~ScopeSampleRecord() + ~ScriptSampleRecord() { if (m_samples) free(m_samples); @@ -111,7 +113,7 @@ namespace JSC { void sample(CodeBlock*, Instruction*); - RefPtr m_scope; + ScriptExecutable* m_executable; CodeBlock* m_codeBlock; int m_sampleCount; int m_opcodeSampleCount; @@ -119,7 +121,7 @@ namespace JSC { unsigned m_size; }; - typedef WTF::HashMap ScopeSampleRecordMap; + typedef WTF::HashMap ScriptSampleRecordMap; class SamplingThread { public: @@ -193,7 +195,7 @@ namespace JSC { , m_sampleCount(0) , m_opcodeSampleCount(0) #if ENABLE(CODEBLOCK_SAMPLING) - , m_scopeSampleMap(new ScopeSampleRecordMap()) + , m_scopeSampleMap(new ScriptSampleRecordMap()) #endif { memset(m_opcodeSamples, 0, sizeof(m_opcodeSamples)); @@ -210,7 +212,7 @@ namespace JSC { void setup(); void dump(ExecState*); - void notifyOfScope(ScopeNode* scope); + void notifyOfScope(ScriptExecutable* scope); void sample(CodeBlock* codeBlock, Instruction* vPC) { @@ -266,8 +268,8 @@ namespace JSC { unsigned m_opcodeSamplesInCTIFunctions[numOpcodeIDs]; #if ENABLE(CODEBLOCK_SAMPLING) - Mutex m_scopeSampleMapMutex; - OwnPtr m_scopeSampleMap; + Mutex m_scriptSampleMapMutex; + OwnPtr m_scopeSampleMap; #endif }; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp index 74bf4f8..10a1136 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp @@ -273,7 +273,7 @@ BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, const Debugger* d } else { for (size_t i = 0; i < functionStack.size(); ++i) { FunctionBodyNode* function = functionStack[i]; - globalObject->putWithAttributes(exec, function->ident(), new (exec) JSFunction(exec, makeFunction(function), scopeChain.node()), DontDelete); + globalObject->putWithAttributes(exec, function->ident(), new (exec) JSFunction(exec, makeFunction(exec, function), scopeChain.node()), DontDelete); } for (size_t i = 0; i < varStack.size(); ++i) { if (globalObject->hasProperty(exec, *varStack[i].first)) @@ -399,7 +399,7 @@ BytecodeGenerator::BytecodeGenerator(EvalNode* evalNode, const Debugger* debugge const DeclarationStacks::FunctionStack& functionStack = evalNode->functionStack(); for (size_t i = 0; i < functionStack.size(); ++i) - m_codeBlock->addFunctionDecl(makeFunction(functionStack[i])); + m_codeBlock->addFunctionDecl(makeFunction(m_globalData, functionStack[i])); const DeclarationStacks::VarStack& varStack = evalNode->varStack(); unsigned numVariables = varStack.size(); @@ -1316,7 +1316,7 @@ RegisterID* BytecodeGenerator::emitNewArray(RegisterID* dst, ElementNode* elemen RegisterID* BytecodeGenerator::emitNewFunction(RegisterID* dst, FunctionBodyNode* function) { - unsigned index = m_codeBlock->addFunctionDecl(makeFunction(function)); + unsigned index = m_codeBlock->addFunctionDecl(makeFunction(m_globalData, function)); emitOpcode(op_new_func); instructions().append(dst->index()); @@ -1336,7 +1336,7 @@ RegisterID* BytecodeGenerator::emitNewRegExp(RegisterID* dst, RegExp* regExp) RegisterID* BytecodeGenerator::emitNewFunctionExpression(RegisterID* r0, FuncExprNode* n) { FunctionBodyNode* function = n->body(); - unsigned index = m_codeBlock->addFunctionExpr(makeFunction(function)); + unsigned index = m_codeBlock->addFunctionExpr(makeFunction(m_globalData, function)); emitOpcode(op_new_func_exp); instructions().append(r0->index()); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/bytecompiler/BytecodeGenerator.h b/src/3rdparty/javascriptcore/JavaScriptCore/bytecompiler/BytecodeGenerator.h index 935787c..f614f0b 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/bytecompiler/BytecodeGenerator.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/bytecompiler/BytecodeGenerator.h @@ -417,9 +417,14 @@ namespace JSC { RegisterID* addConstantValue(JSValue); unsigned addRegExp(RegExp*); - PassRefPtr makeFunction(FunctionBodyNode* body) + PassRefPtr makeFunction(ExecState* exec, FunctionBodyNode* body) { - return FunctionExecutable::create(body->ident(), body->source(), body->usesArguments(), body->parameters(), body->lineNo(), body->lastLine()); + return FunctionExecutable::create(exec, body->ident(), body->source(), body->usesArguments(), body->parameters(), body->lineNo(), body->lastLine()); + } + + PassRefPtr makeFunction(JSGlobalData* globalData, FunctionBodyNode* body) + { + return FunctionExecutable::create(globalData, body->ident(), body->source(), body->usesArguments(), body->parameters(), body->lineNo(), body->lastLine()); } Vector& instructions() { return m_codeBlock->instructions(); } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/debugger/Debugger.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/debugger/Debugger.cpp index 61167d4..db02329 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/debugger/Debugger.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/debugger/Debugger.cpp @@ -100,7 +100,7 @@ JSValue evaluateInGlobalCallFrame(const UString& script, JSValue& exception, JSG { CallFrame* globalCallFrame = globalObject->globalExec(); - EvalExecutable eval(makeSource(script)); + EvalExecutable eval(globalCallFrame, makeSource(script)); JSObject* error = eval.compile(globalCallFrame, globalCallFrame->scopeChain()); if (error) return error; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/debugger/DebuggerCallFrame.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/debugger/DebuggerCallFrame.cpp index 9c8ca2a..88b14e6 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/debugger/DebuggerCallFrame.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/debugger/DebuggerCallFrame.cpp @@ -79,7 +79,7 @@ JSValue DebuggerCallFrame::evaluate(const UString& script, JSValue& exception) c if (!m_callFrame->codeBlock()) return JSValue(); - EvalExecutable eval(makeSource(script)); + EvalExecutable eval(m_callFrame, makeSource(script)); JSObject* error = eval.compile(m_callFrame, m_callFrame->scopeChain()); if (error) return error; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Interpreter.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Interpreter.cpp index 76c8510..4f00b2b 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Interpreter.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Interpreter.cpp @@ -1026,6 +1026,10 @@ NEVER_INLINE void Interpreter::tryCachePutByID(CallFrame* callFrame, CodeBlock* // Structure transition, cache transition info if (slot.type() == PutPropertySlot::NewProperty) { + if (structure->isDictionary()) { + vPC[0] = getOpcode(op_put_by_id_generic); + return; + } vPC[0] = getOpcode(op_put_by_id_transition); vPC[4] = structure->previousID(); vPC[5] = structure; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JIT.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JIT.cpp index bf3a418..ea8434e 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JIT.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JIT.cpp @@ -195,7 +195,7 @@ void JIT::privateCompileMainPass() switch (m_interpreter->getOpcodeID(currentInstruction->u.opcode)) { DEFINE_BINARY_OP(op_del_by_val) -#if !USE(JSVALUE32_64) +#if USE(JSVALUE32) DEFINE_BINARY_OP(op_div) #endif DEFINE_BINARY_OP(op_in) @@ -230,7 +230,7 @@ void JIT::privateCompileMainPass() DEFINE_OP(op_create_arguments) DEFINE_OP(op_debug) DEFINE_OP(op_del_by_id) -#if USE(JSVALUE32_64) +#if !USE(JSVALUE32) DEFINE_OP(op_div) #endif DEFINE_OP(op_end) @@ -379,7 +379,7 @@ void JIT::privateCompileSlowCases() DEFINE_SLOWCASE_OP(op_construct) DEFINE_SLOWCASE_OP(op_construct_verify) DEFINE_SLOWCASE_OP(op_convert_this) -#if USE(JSVALUE32_64) +#if !USE(JSVALUE32) DEFINE_SLOWCASE_OP(op_div) #endif DEFINE_SLOWCASE_OP(op_eq) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JIT.h b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JIT.h index 5c58e9d..fcbc45e 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JIT.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JIT.h @@ -379,14 +379,18 @@ namespace JSC { enum CompileOpStrictEqType { OpStrictEq, OpNStrictEq }; void compileOpStrictEq(Instruction* instruction, CompileOpStrictEqType type); + bool isOperandConstantImmediateDouble(unsigned src); + + void emitLoadDouble(unsigned index, FPRegisterID value); + void emitLoadInt32ToDouble(unsigned index, FPRegisterID value); + + Address addressFor(unsigned index, RegisterID base = callFrameRegister); #if USE(JSVALUE32_64) Address tagFor(unsigned index, RegisterID base = callFrameRegister); Address payloadFor(unsigned index, RegisterID base = callFrameRegister); - Address addressFor(unsigned index, RegisterID base = callFrameRegister); bool getOperandConstantImmediateInt(unsigned op1, unsigned op2, unsigned& op, int32_t& constant); - bool isOperandConstantImmediateDouble(unsigned src); void emitLoadTag(unsigned index, RegisterID tag); void emitLoadPayload(unsigned index, RegisterID payload); @@ -394,8 +398,6 @@ namespace JSC { void emitLoad(const JSValue& v, RegisterID tag, RegisterID payload); void emitLoad(unsigned index, RegisterID tag, RegisterID payload, RegisterID base = callFrameRegister); void emitLoad2(unsigned index1, RegisterID tag1, RegisterID payload1, unsigned index2, RegisterID tag2, RegisterID payload2); - void emitLoadDouble(unsigned index, FPRegisterID value); - void emitLoadInt32ToDouble(unsigned index, FPRegisterID value); void emitStore(unsigned index, RegisterID tag, RegisterID payload, RegisterID base = callFrameRegister); void emitStore(unsigned index, const JSValue constant, RegisterID base = callFrameRegister); @@ -499,6 +501,7 @@ namespace JSC { JIT::Jump emitJumpIfNotImmediateInteger(RegisterID); JIT::Jump emitJumpIfNotImmediateIntegers(RegisterID, RegisterID, RegisterID); void emitJumpSlowCaseIfNotImmediateInteger(RegisterID); + void emitJumpSlowCaseIfNotImmediateNumber(RegisterID); void emitJumpSlowCaseIfNotImmediateIntegers(RegisterID, RegisterID, RegisterID); #if !USE(JSVALUE64) @@ -511,7 +514,11 @@ namespace JSC { void emitTagAsBoolImmediate(RegisterID reg); void compileBinaryArithOp(OpcodeID, unsigned dst, unsigned src1, unsigned src2, OperandTypes opi); - void compileBinaryArithOpSlowCase(OpcodeID, Vector::iterator&, unsigned dst, unsigned src1, unsigned src2, OperandTypes opi); +#if USE(JSVALUE64) + void compileBinaryArithOpSlowCase(OpcodeID, Vector::iterator&, unsigned dst, unsigned src1, unsigned src2, OperandTypes, bool op1HasImmediateIntFastCase, bool op2HasImmediateIntFastCase); +#else + void compileBinaryArithOpSlowCase(OpcodeID, Vector::iterator&, unsigned dst, unsigned src1, unsigned src2, OperandTypes); +#endif #if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) void compileGetByIdHotPath(int resultVReg, int baseVReg, Identifier* ident, unsigned propertyAccessInstructionIndex); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITArithmetic.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITArithmetic.cpp index 3be13cb..7afc1f2 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITArithmetic.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITArithmetic.cpp @@ -566,6 +566,14 @@ void JIT::emit_op_add(Instruction* currentInstruction) unsigned op2 = currentInstruction[3].u.operand; OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); + if (!types.first().mightBeNumber() || !types.second().mightBeNumber()) { + JITStubCall stubCall(this, cti_op_add); + stubCall.addArgument(op1); + stubCall.addArgument(op2); + stubCall.call(dst); + return; + } + JumpList notInt32Op1; JumpList notInt32Op2; @@ -630,19 +638,21 @@ void JIT::emitSlow_op_add(Instruction* currentInstruction, Vector unsigned op2 = currentInstruction[3].u.operand; OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); + if (!types.first().mightBeNumber() || !types.second().mightBeNumber()) + return; + unsigned op; int32_t constant; if (getOperandConstantImmediateInt(op1, op2, op, constant)) { linkSlowCase(iter); // overflow check - if (!supportsFloatingPoint()) { + if (!supportsFloatingPoint()) linkSlowCase(iter); // non-sse case - return; + else { + ResultType opType = op == op1 ? types.first() : types.second(); + if (!opType.definitelyIsNumber()) + linkSlowCase(iter); // double check } - - ResultType opType = op == op1 ? types.first() : types.second(); - if (!opType.definitelyIsNumber()) - linkSlowCase(iter); // double check } else { linkSlowCase(iter); // overflow check @@ -1932,55 +1942,87 @@ void JIT::compileBinaryArithOp(OpcodeID opcodeID, unsigned, unsigned op1, unsign emitFastArithIntToImmNoCheck(regT0, regT0); } -void JIT::compileBinaryArithOpSlowCase(OpcodeID opcodeID, Vector::iterator& iter, unsigned result, unsigned op1, unsigned, OperandTypes types) +void JIT::compileBinaryArithOpSlowCase(OpcodeID opcodeID, Vector::iterator& iter, unsigned result, unsigned op1, unsigned op2, OperandTypes types, bool op1HasImmediateIntFastCase, bool op2HasImmediateIntFastCase) { // We assume that subtracting TagTypeNumber is equivalent to adding DoubleEncodeOffset. COMPILE_ASSERT(((JSImmediate::TagTypeNumber + JSImmediate::DoubleEncodeOffset) == 0), TagTypeNumber_PLUS_DoubleEncodeOffset_EQUALS_0); - - Jump notImm1 = getSlowCase(iter); - Jump notImm2 = getSlowCase(iter); + + Jump notImm1; + Jump notImm2; + if (op1HasImmediateIntFastCase) { + notImm2 = getSlowCase(iter); + } else if (op2HasImmediateIntFastCase) { + notImm1 = getSlowCase(iter); + } else { + notImm1 = getSlowCase(iter); + notImm2 = getSlowCase(iter); + } linkSlowCase(iter); // Integer overflow case - we could handle this in JIT code, but this is likely rare. - if (opcodeID == op_mul) // op_mul has an extra slow case to handle 0 * negative number. + if (opcodeID == op_mul && !op1HasImmediateIntFastCase && !op2HasImmediateIntFastCase) // op_mul has an extra slow case to handle 0 * negative number. linkSlowCase(iter); emitGetVirtualRegister(op1, regT0); Label stubFunctionCall(this); JITStubCall stubCall(this, opcodeID == op_add ? cti_op_add : opcodeID == op_sub ? cti_op_sub : cti_op_mul); + if (op1HasImmediateIntFastCase || op2HasImmediateIntFastCase) { + emitGetVirtualRegister(op1, regT0); + emitGetVirtualRegister(op2, regT1); + } stubCall.addArgument(regT0); stubCall.addArgument(regT1); stubCall.call(result); Jump end = jump(); - // if we get here, eax is not an int32, edx not yet checked. - notImm1.link(this); - if (!types.first().definitelyIsNumber()) - emitJumpIfNotImmediateNumber(regT0).linkTo(stubFunctionCall, this); - if (!types.second().definitelyIsNumber()) - emitJumpIfNotImmediateNumber(regT1).linkTo(stubFunctionCall, this); - addPtr(tagTypeNumberRegister, regT0); - movePtrToDouble(regT0, fpRegT1); - Jump op2isDouble = emitJumpIfNotImmediateInteger(regT1); - convertInt32ToDouble(regT1, fpRegT2); - Jump op2wasInteger = jump(); - - // if we get here, eax IS an int32, edx is not. - notImm2.link(this); - if (!types.second().definitelyIsNumber()) - emitJumpIfNotImmediateNumber(regT1).linkTo(stubFunctionCall, this); - convertInt32ToDouble(regT0, fpRegT1); - op2isDouble.link(this); - addPtr(tagTypeNumberRegister, regT1); - movePtrToDouble(regT1, fpRegT2); - op2wasInteger.link(this); + if (op1HasImmediateIntFastCase) { + notImm2.link(this); + if (!types.second().definitelyIsNumber()) + emitJumpIfNotImmediateNumber(regT0).linkTo(stubFunctionCall, this); + emitGetVirtualRegister(op1, regT1); + convertInt32ToDouble(regT1, fpRegT1); + addPtr(tagTypeNumberRegister, regT0); + movePtrToDouble(regT0, fpRegT2); + } else if (op2HasImmediateIntFastCase) { + notImm1.link(this); + if (!types.first().definitelyIsNumber()) + emitJumpIfNotImmediateNumber(regT0).linkTo(stubFunctionCall, this); + emitGetVirtualRegister(op2, regT1); + convertInt32ToDouble(regT1, fpRegT1); + addPtr(tagTypeNumberRegister, regT0); + movePtrToDouble(regT0, fpRegT2); + } else { + // if we get here, eax is not an int32, edx not yet checked. + notImm1.link(this); + if (!types.first().definitelyIsNumber()) + emitJumpIfNotImmediateNumber(regT0).linkTo(stubFunctionCall, this); + if (!types.second().definitelyIsNumber()) + emitJumpIfNotImmediateNumber(regT1).linkTo(stubFunctionCall, this); + addPtr(tagTypeNumberRegister, regT0); + movePtrToDouble(regT0, fpRegT1); + Jump op2isDouble = emitJumpIfNotImmediateInteger(regT1); + convertInt32ToDouble(regT1, fpRegT2); + Jump op2wasInteger = jump(); + + // if we get here, eax IS an int32, edx is not. + notImm2.link(this); + if (!types.second().definitelyIsNumber()) + emitJumpIfNotImmediateNumber(regT1).linkTo(stubFunctionCall, this); + convertInt32ToDouble(regT0, fpRegT1); + op2isDouble.link(this); + addPtr(tagTypeNumberRegister, regT1); + movePtrToDouble(regT1, fpRegT2); + op2wasInteger.link(this); + } if (opcodeID == op_add) addDouble(fpRegT2, fpRegT1); else if (opcodeID == op_sub) subDouble(fpRegT2, fpRegT1); - else { - ASSERT(opcodeID == op_mul); + else if (opcodeID == op_mul) mulDouble(fpRegT2, fpRegT1); + else { + ASSERT(opcodeID == op_div); + divDouble(fpRegT2, fpRegT1); } moveDoubleToPtr(fpRegT1, regT0); subPtr(tagTypeNumberRegister, regT0); @@ -2025,16 +2067,14 @@ void JIT::emitSlow_op_add(Instruction* currentInstruction, Vector unsigned result = currentInstruction[1].u.operand; unsigned op1 = currentInstruction[2].u.operand; unsigned op2 = currentInstruction[3].u.operand; + OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); - if (isOperandConstantImmediateInt(op1) || isOperandConstantImmediateInt(op2)) { - linkSlowCase(iter); - linkSlowCase(iter); - JITStubCall stubCall(this, cti_op_add); - stubCall.addArgument(op1, regT2); - stubCall.addArgument(op2, regT2); - stubCall.call(result); - } else - compileBinaryArithOpSlowCase(op_add, iter, result, op1, op2, OperandTypes::fromInt(currentInstruction[4].u.operand)); + if (!types.first().mightBeNumber() || !types.second().mightBeNumber()) + return; + + bool op1HasImmediateIntFastCase = isOperandConstantImmediateInt(op1); + bool op2HasImmediateIntFastCase = !op1HasImmediateIntFastCase && isOperandConstantImmediateInt(op2); + compileBinaryArithOpSlowCase(op_add, iter, result, op1, op2, OperandTypes::fromInt(currentInstruction[4].u.operand), op1HasImmediateIntFastCase, op2HasImmediateIntFastCase); } void JIT::emit_op_mul(Instruction* currentInstruction) @@ -2069,17 +2109,106 @@ void JIT::emitSlow_op_mul(Instruction* currentInstruction, Vector unsigned op2 = currentInstruction[3].u.operand; OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); - if ((isOperandConstantImmediateInt(op1) && (getConstantOperandImmediateInt(op1) > 0)) - || (isOperandConstantImmediateInt(op2) && (getConstantOperandImmediateInt(op2) > 0))) { - linkSlowCase(iter); - linkSlowCase(iter); - // There is an extra slow case for (op1 * -N) or (-N * op2), to check for 0 since this should produce a result of -0. - JITStubCall stubCall(this, cti_op_mul); - stubCall.addArgument(op1, regT2); - stubCall.addArgument(op2, regT2); - stubCall.call(result); - } else - compileBinaryArithOpSlowCase(op_mul, iter, result, op1, op2, types); + bool op1HasImmediateIntFastCase = isOperandConstantImmediateInt(op1) && getConstantOperandImmediateInt(op1) > 0; + bool op2HasImmediateIntFastCase = !op1HasImmediateIntFastCase && isOperandConstantImmediateInt(op2) && getConstantOperandImmediateInt(op2) > 0; + compileBinaryArithOpSlowCase(op_mul, iter, result, op1, op2, OperandTypes::fromInt(currentInstruction[4].u.operand), op1HasImmediateIntFastCase, op2HasImmediateIntFastCase); +} + +void JIT::emit_op_div(Instruction* currentInstruction) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned op1 = currentInstruction[2].u.operand; + unsigned op2 = currentInstruction[3].u.operand; + OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); + + if (isOperandConstantImmediateDouble(op1)) { + emitGetVirtualRegister(op1, regT0); + addPtr(tagTypeNumberRegister, regT0); + movePtrToDouble(regT0, fpRegT0); + } else if (isOperandConstantImmediateInt(op1)) { + emitLoadInt32ToDouble(op1, fpRegT0); + } else { + emitGetVirtualRegister(op1, regT0); + if (!types.first().definitelyIsNumber()) + emitJumpSlowCaseIfNotImmediateNumber(regT0); + Jump notInt = emitJumpIfNotImmediateInteger(regT0); + convertInt32ToDouble(regT0, fpRegT0); + Jump skipDoubleLoad = jump(); + notInt.link(this); + addPtr(tagTypeNumberRegister, regT0); + movePtrToDouble(regT0, fpRegT0); + skipDoubleLoad.link(this); + } + + if (isOperandConstantImmediateDouble(op2)) { + emitGetVirtualRegister(op2, regT1); + addPtr(tagTypeNumberRegister, regT1); + movePtrToDouble(regT1, fpRegT1); + } else if (isOperandConstantImmediateInt(op2)) { + emitLoadInt32ToDouble(op2, fpRegT1); + } else { + emitGetVirtualRegister(op2, regT1); + if (!types.second().definitelyIsNumber()) + emitJumpSlowCaseIfNotImmediateNumber(regT1); + Jump notInt = emitJumpIfNotImmediateInteger(regT1); + convertInt32ToDouble(regT1, fpRegT1); + Jump skipDoubleLoad = jump(); + notInt.link(this); + addPtr(tagTypeNumberRegister, regT1); + movePtrToDouble(regT1, fpRegT1); + skipDoubleLoad.link(this); + } + divDouble(fpRegT1, fpRegT0); + + JumpList doubleResult; + Jump end; + bool attemptIntConversion = (!isOperandConstantImmediateInt(op1) || getConstantOperand(op1).asInt32() > 1) && isOperandConstantImmediateInt(op2); + if (attemptIntConversion) { + m_assembler.cvttsd2si_rr(fpRegT0, regT0); + doubleResult.append(branchTest32(Zero, regT0)); + m_assembler.ucomisd_rr(fpRegT1, fpRegT0); + + doubleResult.append(m_assembler.jne()); + doubleResult.append(m_assembler.jp()); + emitFastArithIntToImmNoCheck(regT0, regT0); + end = jump(); + } + + // Double result. + doubleResult.link(this); + moveDoubleToPtr(fpRegT0, regT0); + subPtr(tagTypeNumberRegister, regT0); + + if (attemptIntConversion) + end.link(this); + emitPutVirtualRegister(dst, regT0); +} + +void JIT::emitSlow_op_div(Instruction* currentInstruction, Vector::iterator& iter) +{ + unsigned result = currentInstruction[1].u.operand; + unsigned op1 = currentInstruction[2].u.operand; + unsigned op2 = currentInstruction[3].u.operand; + OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); + if (types.first().definitelyIsNumber() && types.second().definitelyIsNumber()) { +#ifndef NDEBUG + breakpoint(); +#endif + return; + } + if (!isOperandConstantImmediateDouble(op1) && !isOperandConstantImmediateInt(op1)) { + if (!types.first().definitelyIsNumber()) + linkSlowCase(iter); + } + if (!isOperandConstantImmediateDouble(op2) && !isOperandConstantImmediateInt(op2)) { + if (!types.second().definitelyIsNumber()) + linkSlowCase(iter); + } + // There is an extra slow case for (op1 * -N) or (-N * op2), to check for 0 since this should produce a result of -0. + JITStubCall stubCall(this, cti_op_div); + stubCall.addArgument(op1, regT2); + stubCall.addArgument(op2, regT2); + stubCall.call(result); } void JIT::emit_op_sub(Instruction* currentInstruction) @@ -2090,7 +2219,6 @@ void JIT::emit_op_sub(Instruction* currentInstruction) OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); compileBinaryArithOp(op_sub, result, op1, op2, types); - emitPutVirtualRegister(result); } @@ -2101,7 +2229,7 @@ void JIT::emitSlow_op_sub(Instruction* currentInstruction, Vector unsigned op2 = currentInstruction[3].u.operand; OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); - compileBinaryArithOpSlowCase(op_sub, iter, result, op1, op2, types); + compileBinaryArithOpSlowCase(op_sub, iter, result, op1, op2, types, false, false); } #else // USE(JSVALUE64) @@ -2284,6 +2412,15 @@ void JIT::emit_op_add(Instruction* currentInstruction) unsigned result = currentInstruction[1].u.operand; unsigned op1 = currentInstruction[2].u.operand; unsigned op2 = currentInstruction[3].u.operand; + OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); + + if (!types.first().mightBeNumber() || !types.second().mightBeNumber()) { + JITStubCall stubCall(this, cti_op_add); + stubCall.addArgument(op1, regT2); + stubCall.addArgument(op2, regT2); + stubCall.call(result); + return; + } if (isOperandConstantImmediateInt(op1)) { emitGetVirtualRegister(op2, regT0); @@ -2298,15 +2435,7 @@ void JIT::emit_op_add(Instruction* currentInstruction) signExtend32ToPtr(regT0, regT0); emitPutVirtualRegister(result); } else { - OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); - if (types.first().mightBeNumber() && types.second().mightBeNumber()) - compileBinaryArithOp(op_add, result, op1, op2, OperandTypes::fromInt(currentInstruction[4].u.operand)); - else { - JITStubCall stubCall(this, cti_op_add); - stubCall.addArgument(op1, regT2); - stubCall.addArgument(op2, regT2); - stubCall.call(result); - } + compileBinaryArithOp(op_add, result, op1, op2, OperandTypes::fromInt(currentInstruction[4].u.operand)); } } @@ -2316,6 +2445,10 @@ void JIT::emitSlow_op_add(Instruction* currentInstruction, Vector unsigned op1 = currentInstruction[2].u.operand; unsigned op2 = currentInstruction[3].u.operand; + OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); + if (!types.first().mightBeNumber() || !types.second().mightBeNumber()) + return; + if (isOperandConstantImmediateInt(op1)) { Jump notImm = getSlowCase(iter); linkSlowCase(iter); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITCall.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITCall.cpp index 5bcde42..f4f6e62 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITCall.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITCall.cpp @@ -242,16 +242,14 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned) int argCount = instruction[3].u.operand; int registerOffset = instruction[4].u.operand; - Jump wasEval1; - Jump wasEval2; + Jump wasEval; if (opcodeID == op_call_eval) { JITStubCall stubCall(this, cti_op_call_eval); stubCall.addArgument(callee); stubCall.addArgument(JIT::Imm32(registerOffset)); stubCall.addArgument(JIT::Imm32(argCount)); stubCall.call(); - wasEval1 = branchTest32(NonZero, regT0); - wasEval2 = branch32(NotEqual, regT1, Imm32(JSValue::CellTag)); + wasEval = branch32(Equal, regT1, Imm32(JSValue::EmptyValueTag)); } emitLoad(callee, regT1, regT2); @@ -277,10 +275,8 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned) emitNakedCall(m_globalData->jitStubs.ctiVirtualCall()); - if (opcodeID == op_call_eval) { - wasEval1.link(this); - wasEval2.link(this); - } + if (opcodeID == op_call_eval) + wasEval.link(this); emitStore(dst, regT1, regT0);; @@ -312,16 +308,14 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca int argCount = instruction[3].u.operand; int registerOffset = instruction[4].u.operand; - Jump wasEval1; - Jump wasEval2; + Jump wasEval; if (opcodeID == op_call_eval) { JITStubCall stubCall(this, cti_op_call_eval); stubCall.addArgument(callee); stubCall.addArgument(JIT::Imm32(registerOffset)); stubCall.addArgument(JIT::Imm32(argCount)); stubCall.call(); - wasEval1 = branchTest32(NonZero, regT0); - wasEval2 = branch32(NotEqual, regT1, Imm32(JSValue::CellTag)); + wasEval = branch32(NotEqual, regT1, Imm32(JSValue::EmptyValueTag)); } emitLoad(callee, regT1, regT0); @@ -365,10 +359,8 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca // Call to the callee m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathOther = emitNakedCall(); - if (opcodeID == op_call_eval) { - wasEval1.link(this); - wasEval2.link(this); - } + if (opcodeID == op_call_eval) + wasEval.link(this); // Put the return value in dst. In the interpreter, op_ret does this. emitStore(dst, regT1, regT0); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITInlineMethods.h b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITInlineMethods.h index e69e273..f26457a 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITInlineMethods.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITInlineMethods.h @@ -65,6 +65,11 @@ ALWAYS_INLINE void JIT::emitGetJITStubArg(unsigned argumentNumber, RegisterID ds peek(dst, argumentStackOffset); } +ALWAYS_INLINE bool JIT::isOperandConstantImmediateDouble(unsigned src) +{ + return m_codeBlock->isConstantRegisterIndex(src) && getConstantOperand(src).isDouble(); +} + ALWAYS_INLINE JSValue JIT::getConstantOperand(unsigned src) { ASSERT(m_codeBlock->isConstantRegisterIndex(src)); @@ -305,6 +310,11 @@ ALWAYS_INLINE void JIT::sampleCodeBlock(CodeBlock* codeBlock) #endif #endif +inline JIT::Address JIT::addressFor(unsigned index, RegisterID base) +{ + return Address(base, (index * sizeof(Register))); +} + #if USE(JSVALUE32_64) inline JIT::Address JIT::tagFor(unsigned index, RegisterID base) @@ -317,11 +327,6 @@ inline JIT::Address JIT::payloadFor(unsigned index, RegisterID base) return Address(base, (index * sizeof(Register)) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)); } -inline JIT::Address JIT::addressFor(unsigned index, RegisterID base) -{ - return Address(base, (index * sizeof(Register))); -} - inline void JIT::emitLoadTag(unsigned index, RegisterID tag) { RegisterID mappedTag; @@ -579,11 +584,6 @@ ALWAYS_INLINE bool JIT::getOperandConstantImmediateInt(unsigned op1, unsigned op return false; } -ALWAYS_INLINE bool JIT::isOperandConstantImmediateDouble(unsigned src) -{ - return m_codeBlock->isConstantRegisterIndex(src) && getConstantOperand(src).isDouble(); -} - /* Deprecated: Please use JITStubCall instead. */ ALWAYS_INLINE void JIT::emitPutJITStubArg(RegisterID tag, RegisterID payload, unsigned argumentNumber) @@ -732,6 +732,24 @@ ALWAYS_INLINE JIT::Jump JIT::emitJumpIfNotImmediateNumber(RegisterID reg) { return branchTestPtr(Zero, reg, tagTypeNumberRegister); } + +inline void JIT::emitLoadDouble(unsigned index, FPRegisterID value) +{ + if (m_codeBlock->isConstantRegisterIndex(index)) { + Register& inConstantPool = m_codeBlock->constantRegister(index); + loadDouble(&inConstantPool, value); + } else + loadDouble(addressFor(index), value); +} + +inline void JIT::emitLoadInt32ToDouble(unsigned index, FPRegisterID value) +{ + if (m_codeBlock->isConstantRegisterIndex(index)) { + Register& inConstantPool = m_codeBlock->constantRegister(index); + convertInt32ToDouble(AbsoluteAddress(&inConstantPool), value); + } else + convertInt32ToDouble(addressFor(index), value); +} #endif ALWAYS_INLINE JIT::Jump JIT::emitJumpIfImmediateInteger(RegisterID reg) @@ -769,6 +787,11 @@ ALWAYS_INLINE void JIT::emitJumpSlowCaseIfNotImmediateIntegers(RegisterID reg1, addSlowCase(emitJumpIfNotImmediateIntegers(reg1, reg2, scratch)); } +ALWAYS_INLINE void JIT::emitJumpSlowCaseIfNotImmediateNumber(RegisterID reg) +{ + addSlowCase(emitJumpIfNotImmediateNumber(reg)); +} + #if !USE(JSVALUE64) ALWAYS_INLINE void JIT::emitFastArithDeTagImmediate(RegisterID reg) { diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITOpcodes.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITOpcodes.cpp index 34debcb..b5f6597 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITOpcodes.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITOpcodes.cpp @@ -248,10 +248,8 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr* executable addPtr(Imm32(NativeCallFrameSize - sizeof(NativeFunctionCalleeSignature)), stackPointerRegister); // Check for an exception - // FIXME: Maybe we can optimize this comparison to JSValue(). move(ImmPtr(&globalData->exception), regT2); - Jump sawException1 = branch32(NotEqual, tagFor(0, regT2), Imm32(JSValue::CellTag)); - Jump sawException2 = branch32(NonZero, payloadFor(0, regT2), Imm32(0)); + Jump sawException = branch32(NotEqual, tagFor(0, regT2), Imm32(JSValue::EmptyValueTag)); // Grab the return address. emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT3); @@ -264,8 +262,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr* executable ret(); // Handle an exception - sawException1.link(this); - sawException2.link(this); + sawException.link(this); // Grab the return address. emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT1); move(ImmPtr(&globalData->exceptionLocation), regT2); @@ -794,14 +791,17 @@ void JIT::emit_op_jfalse(Instruction* currentInstruction) Jump isTrue2 = branch32(NotEqual, regT0, Imm32(0)); addJump(jump(), target + 2); - isNotInteger.link(this); + if (supportsFloatingPoint()) { + isNotInteger.link(this); - addSlowCase(branch32(Above, regT1, Imm32(JSValue::LowestTag))); + addSlowCase(branch32(Above, regT1, Imm32(JSValue::LowestTag))); + + zeroDouble(fpRegT0); + emitLoadDouble(cond, fpRegT1); + addJump(branchDouble(DoubleEqual, fpRegT0, fpRegT1), target + 2); + } else + addSlowCase(isNotInteger); - zeroDouble(fpRegT0); - emitLoadDouble(cond, fpRegT1); - addJump(branchDouble(DoubleEqual, fpRegT0, fpRegT1), target + 2); - isTrue.link(this); isTrue2.link(this); } @@ -832,14 +832,17 @@ void JIT::emit_op_jtrue(Instruction* currentInstruction) Jump isFalse2 = branch32(Equal, regT0, Imm32(0)); addJump(jump(), target + 2); - isNotInteger.link(this); + if (supportsFloatingPoint()) { + isNotInteger.link(this); - addSlowCase(branch32(Above, regT1, Imm32(JSValue::LowestTag))); + addSlowCase(branch32(Above, regT1, Imm32(JSValue::LowestTag))); + + zeroDouble(fpRegT0); + emitLoadDouble(cond, fpRegT1); + addJump(branchDouble(DoubleNotEqual, fpRegT0, fpRegT1), target + 2); + } else + addSlowCase(isNotInteger); - zeroDouble(fpRegT0); - emitLoadDouble(cond, fpRegT1); - addJump(branchDouble(DoubleNotEqual, fpRegT0, fpRegT1), target + 2); - isFalse.link(this); isFalse2.link(this); } @@ -1231,7 +1234,7 @@ void JIT::emit_op_to_jsnumber(Instruction* currentInstruction) emitLoad(src, regT1, regT0); Jump isInt32 = branch32(Equal, regT1, Imm32(JSValue::Int32Tag)); - addSlowCase(branch32(AboveOrEqual, regT1, Imm32(JSValue::DeletedValueTag))); + addSlowCase(branch32(AboveOrEqual, regT1, Imm32(JSValue::EmptyValueTag))); isInt32.link(this); if (src != dst) @@ -1381,8 +1384,7 @@ void JIT::emit_op_enter_with_activation(Instruction* currentInstruction) void JIT::emit_op_create_arguments(Instruction*) { - Jump argsNotCell = branch32(NotEqual, tagFor(RegisterFile::ArgumentsRegister, callFrameRegister), Imm32(JSValue::CellTag)); - Jump argsNotNull = branchTestPtr(NonZero, payloadFor(RegisterFile::ArgumentsRegister, callFrameRegister)); + Jump argsCreated = branch32(NotEqual, tagFor(RegisterFile::ArgumentsRegister, callFrameRegister), Imm32(JSValue::EmptyValueTag)); // If we get here the arguments pointer is a null cell - i.e. arguments need lazy creation. if (m_codeBlock->m_numParameters == 1) @@ -1390,8 +1392,7 @@ void JIT::emit_op_create_arguments(Instruction*) else JITStubCall(this, cti_op_create_arguments).call(); - argsNotCell.link(this); - argsNotNull.link(this); + argsCreated.link(this); } void JIT::emit_op_init_arguments(Instruction*) @@ -2707,32 +2708,20 @@ void JIT::emitSlow_op_to_primitive(Instruction* currentInstruction, Vector::iterator& iter) { - // The slow void JIT::emitSlow_that handles accesses to arrays (below) may jump back up to here. - Label beginGetByValSlow(this); + unsigned dst = currentInstruction[1].u.operand; + unsigned base = currentInstruction[2].u.operand; + unsigned property = currentInstruction[3].u.operand; - Jump notImm = getSlowCase(iter); - linkSlowCase(iter); - linkSlowCase(iter); - emitFastArithIntToImmNoCheck(regT1, regT1); + linkSlowCase(iter); // property int32 check + linkSlowCaseIfNotJSCell(iter, base); // base cell check + linkSlowCase(iter); // base array check + linkSlowCase(iter); // vector length check + linkSlowCase(iter); // empty value - notImm.link(this); JITStubCall stubCall(this, cti_op_get_by_val); - stubCall.addArgument(regT0); - stubCall.addArgument(regT1); - stubCall.call(currentInstruction[1].u.operand); - emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_get_by_val)); - - // This is slow void JIT::emitSlow_that handles accesses to arrays above the fast cut-off. - // First, check if this is an access to the vector - linkSlowCase(iter); - branch32(AboveOrEqual, regT1, Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_vectorLength)), beginGetByValSlow); - - // okay, missed the fast region, but it is still in the vector. Get the value. - loadPtr(BaseIndex(regT2, regT1, ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), regT2); - // Check whether the value loaded is zero; if so we need to return undefined. - branchTestPtr(Zero, regT2, beginGetByValSlow); - move(regT2, regT0); - emitPutVirtualRegister(currentInstruction[1].u.operand, regT0); + stubCall.addArgument(base, regT2); + stubCall.addArgument(property, regT2); + stubCall.call(dst); } void JIT::emitSlow_op_loop_if_less(Instruction* currentInstruction, Vector::iterator& iter) @@ -2789,30 +2778,20 @@ void JIT::emitSlow_op_loop_if_lesseq(Instruction* currentInstruction, Vector::iterator& iter) { - // Normal slow cases - either is not an immediate imm, or is an array. - Jump notImm = getSlowCase(iter); - linkSlowCase(iter); - linkSlowCase(iter); - emitFastArithIntToImmNoCheck(regT1, regT1); + unsigned base = currentInstruction[1].u.operand; + unsigned property = currentInstruction[2].u.operand; + unsigned value = currentInstruction[3].u.operand; - notImm.link(this); { - JITStubCall stubCall(this, cti_op_put_by_val); - stubCall.addArgument(regT0); - stubCall.addArgument(regT1); - stubCall.addArgument(currentInstruction[3].u.operand, regT2); - stubCall.call(); - emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_put_by_val)); - } + linkSlowCase(iter); // property int32 check + linkSlowCaseIfNotJSCell(iter, base); // base cell check + linkSlowCase(iter); // base not array check + linkSlowCase(iter); // in vector check - // slow cases for immediate int accesses to arrays - linkSlowCase(iter); - linkSlowCase(iter); { - JITStubCall stubCall(this, cti_op_put_by_val_array); - stubCall.addArgument(regT0); - stubCall.addArgument(regT1); - stubCall.addArgument(currentInstruction[3].u.operand, regT2); - stubCall.call(); - } + JITStubCall stubPutByValCall(this, cti_op_put_by_val); + stubPutByValCall.addArgument(regT0); + stubPutByValCall.addArgument(property, regT2); + stubPutByValCall.addArgument(value, regT2); + stubPutByValCall.call(); } void JIT::emitSlow_op_loop_if_true(Instruction* currentInstruction, Vector::iterator& iter) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITPropertyAccess.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITPropertyAccess.cpp index 08b3096..9edfd01 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITPropertyAccess.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITPropertyAccess.cpp @@ -273,11 +273,14 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction) addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag))); emitJumpSlowCaseIfNotJSCell(base, regT1); addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr))); - addSlowCase(branch32(AboveOrEqual, regT2, Address(regT0, OBJECT_OFFSETOF(JSArray, m_fastAccessCutoff)))); - loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT0); - load32(BaseIndex(regT0, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + 4), regT1); // tag - load32(BaseIndex(regT0, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), regT0); // payload + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT3); + addSlowCase(branch32(AboveOrEqual, regT2, Address(regT0, OBJECT_OFFSETOF(JSArray, m_vectorLength)))); + + load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + 4), regT1); // tag + load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), regT0); // payload + addSlowCase(branch32(Equal, regT1, Imm32(JSValue::EmptyValueTag))); + emitStore(dst, regT1, regT0); map(m_bytecodeIndex + OPCODE_LENGTH(op_get_by_val), dst, regT1, regT0); } @@ -288,35 +291,16 @@ void JIT::emitSlow_op_get_by_val(Instruction* currentInstruction, VectorjsArrayVPtr))); - loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT3); - - Jump inFastVector = branch32(Below, regT2, Address(regT0, OBJECT_OFFSETOF(JSArray, m_fastAccessCutoff))); + addSlowCase(branch32(AboveOrEqual, regT2, Address(regT0, OBJECT_OFFSETOF(JSArray, m_vectorLength)))); - // Check if the access is within the vector. - addSlowCase(branch32(AboveOrEqual, regT2, Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_vectorLength)))); - - // This is a write to the slow part of the vector; first, we have to check if this would be the first write to this location. - // FIXME: should be able to handle initial write to array; increment the the number of items in the array, and potentially update fast access cutoff. - Jump skip = branch32(NotEqual, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + 4), Imm32(JSValue::CellTag)); - addSlowCase(branch32(Equal, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), Imm32(0))); - skip.link(this); + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT3); - inFastVector.link(this); + Jump empty = branch32(Equal, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + 4), Imm32(JSValue::EmptyValueTag)); + Label storeResult(this); emitLoad(value, regT1, regT0); store32(regT0, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]))); // payload store32(regT1, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + 4)); // tag + Jump end = jump(); + + empty.link(this); + add32(Imm32(1), Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector))); + branch32(Below, regT2, Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_length))).linkTo(storeResult, this); + + add32(Imm32(1), regT2, regT0); + store32(regT0, Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_length))); + jump().linkTo(storeResult, this); + + end.link(this); } void JIT::emitSlow_op_put_by_val(Instruction* currentInstruction, Vector::iterator& iter) @@ -359,24 +346,13 @@ void JIT::emitSlow_op_put_by_val(Instruction* currentInstruction, VectorjsArrayVPtr))); - // This is an array; get the m_storage pointer into ecx, then check if the index is below the fast cutoff loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT2); - addSlowCase(branch32(AboveOrEqual, regT1, Address(regT0, OBJECT_OFFSETOF(JSArray, m_fastAccessCutoff)))); + addSlowCase(branch32(AboveOrEqual, regT1, Address(regT0, OBJECT_OFFSETOF(JSArray, m_vectorLength)))); - // Get the value from the vector loadPtr(BaseIndex(regT2, regT1, ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), regT0); - emitPutVirtualRegister(currentInstruction[1].u.operand); + addSlowCase(branchTestPtr(Zero, regT0)); + + emitPutVirtualRegister(dst); } void JIT::emit_op_put_by_val(Instruction* currentInstruction) { - emitGetVirtualRegisters(currentInstruction[1].u.operand, regT0, currentInstruction[2].u.operand, regT1); + unsigned base = currentInstruction[1].u.operand; + unsigned property = currentInstruction[2].u.operand; + unsigned value = currentInstruction[3].u.operand; + + emitGetVirtualRegisters(base, regT0, property, regT1); emitJumpSlowCaseIfNotImmediateInteger(regT1); #if USE(JSVALUE64) // See comment in op_get_by_val. @@ -993,23 +977,29 @@ void JIT::emit_op_put_by_val(Instruction* currentInstruction) #else emitFastArithImmToInt(regT1); #endif - emitJumpSlowCaseIfNotJSCell(regT0); + emitJumpSlowCaseIfNotJSCell(regT0, base); addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr))); + addSlowCase(branch32(AboveOrEqual, regT1, Address(regT0, OBJECT_OFFSETOF(JSArray, m_vectorLength)))); - // This is an array; get the m_storage pointer into ecx, then check if the index is below the fast cutoff loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT2); - Jump inFastVector = branch32(Below, regT1, Address(regT0, OBJECT_OFFSETOF(JSArray, m_fastAccessCutoff))); - // No; oh well, check if the access if within the vector - if so, we may still be okay. - addSlowCase(branch32(AboveOrEqual, regT1, Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_vectorLength)))); - // This is a write to the slow part of the vector; first, we have to check if this would be the first write to this location. - // FIXME: should be able to handle initial write to array; increment the the number of items in the array, and potentially update fast access cutoff. - addSlowCase(branchTestPtr(Zero, BaseIndex(regT2, regT1, ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])))); + Jump empty = branchTestPtr(Zero, BaseIndex(regT2, regT1, ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]))); - // All good - put the value into the array. - inFastVector.link(this); - emitGetVirtualRegister(currentInstruction[3].u.operand, regT0); + Label storeResult(this); + emitGetVirtualRegister(value, regT0); storePtr(regT0, BaseIndex(regT2, regT1, ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]))); + Jump end = jump(); + + empty.link(this); + add32(Imm32(1), Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector))); + branch32(Below, regT1, Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_length))).linkTo(storeResult, this); + + move(regT1, regT0); + add32(Imm32(1), regT0); + store32(regT0, Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_length))); + jump().linkTo(storeResult, this); + + end.link(this); } void JIT::emit_op_put_by_index(Instruction* currentInstruction) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.cpp index 08a4493..073b35a 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.cpp @@ -730,7 +730,7 @@ NEVER_INLINE void JITThunks::tryCachePutByID(CallFrame* callFrame, CodeBlock* co // Structure transition, cache transition info if (slot.type() == PutPropertySlot::NewProperty) { StructureChain* prototypeChain = structure->prototypeChain(callFrame); - if (!prototypeChain->isCacheable()) { + if (!prototypeChain->isCacheable() || structure->isDictionary()) { ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_put_by_id_generic)); return; } @@ -1983,28 +1983,6 @@ DEFINE_STUB_FUNCTION(void, op_put_by_val) CHECK_FOR_EXCEPTION_AT_END(); } -DEFINE_STUB_FUNCTION(void, op_put_by_val_array) -{ - STUB_INIT_STACK_FRAME(stackFrame); - - CallFrame* callFrame = stackFrame.callFrame; - JSValue baseValue = stackFrame.args[0].jsValue(); - int i = stackFrame.args[1].int32(); - JSValue value = stackFrame.args[2].jsValue(); - - ASSERT(isJSArray(stackFrame.globalData, baseValue)); - - if (LIKELY(i >= 0)) - asArray(baseValue)->JSArray::put(callFrame, i, value); - else { - Identifier property(callFrame, UString::from(i)); - PutPropertySlot slot; - baseValue.put(callFrame, property, value, slot); - } - - CHECK_FOR_EXCEPTION_AT_END(); -} - DEFINE_STUB_FUNCTION(void, op_put_by_val_byte_array) { STUB_INIT_STACK_FRAME(stackFrame); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.h b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.h index 3ae8f24..43975ff 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.h @@ -349,7 +349,6 @@ extern "C" { void JIT_STUB cti_op_put_by_id_generic(STUB_ARGS_DECLARATION); void JIT_STUB cti_op_put_by_index(STUB_ARGS_DECLARATION); void JIT_STUB cti_op_put_by_val(STUB_ARGS_DECLARATION); - void JIT_STUB cti_op_put_by_val_array(STUB_ARGS_DECLARATION); void JIT_STUB cti_op_put_by_val_byte_array(STUB_ARGS_DECLARATION); void JIT_STUB cti_op_put_getter(STUB_ARGS_DECLARATION); void JIT_STUB cti_op_put_setter(STUB_ARGS_DECLARATION); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jsc.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/jsc.cpp index 92b1e58..ee4e393 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/jsc.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/jsc.cpp @@ -24,6 +24,7 @@ #include "BytecodeGenerator.h" #include "Completion.h" +#include "CurrentTime.h" #include "InitializeThreading.h" #include "JSArray.h" #include "JSFunction.h" @@ -118,53 +119,23 @@ public: long getElapsedMS(); // call stop() first private: -#if PLATFORM(QT) - uint m_startTime; - uint m_stopTime; -#elif PLATFORM(WIN_OS) - DWORD m_startTime; - DWORD m_stopTime; -#else - // Windows does not have timeval, disabling this class for now (bug 7399) - timeval m_startTime; - timeval m_stopTime; -#endif + double m_startTime; + double m_stopTime; }; void StopWatch::start() { -#if PLATFORM(QT) - QDateTime t = QDateTime::currentDateTime(); - m_startTime = t.toTime_t() * 1000 + t.time().msec(); -#elif PLATFORM(WIN_OS) - m_startTime = timeGetTime(); -#else - gettimeofday(&m_startTime, 0); -#endif + m_startTime = currentTime(); } void StopWatch::stop() { -#if PLATFORM(QT) - QDateTime t = QDateTime::currentDateTime(); - m_stopTime = t.toTime_t() * 1000 + t.time().msec(); -#elif PLATFORM(WIN_OS) - m_stopTime = timeGetTime(); -#else - gettimeofday(&m_stopTime, 0); -#endif + m_stopTime = currentTime(); } long StopWatch::getElapsedMS() { -#if PLATFORM(WIN_OS) || PLATFORM(QT) - return m_stopTime - m_startTime; -#else - timeval elapsedTime; - timersub(&m_stopTime, &m_startTime, &elapsedTime); - - return elapsedTime.tv_sec * 1000 + lroundf(elapsedTime.tv_usec / 1000.0f); -#endif + return static_cast((m_stopTime - m_startTime) * 1000); } class GlobalObject : public JSGlobalObject { diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/parser/Nodes.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/parser/Nodes.cpp index 7170f73..89bbc11 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/parser/Nodes.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/parser/Nodes.cpp @@ -1899,10 +1899,6 @@ ScopeNode::ScopeNode(JSGlobalData* globalData) , ParserArenaRefCounted(globalData) , m_features(NoFeatures) { -#if ENABLE(CODEBLOCK_SAMPLING) - if (SamplingTool* sampler = globalData->interpreter->sampler()) - sampler->notifyOfScope(this); -#endif } ScopeNode::ScopeNode(JSGlobalData* globalData, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, CodeFeatures features, int numConstants) @@ -1912,10 +1908,6 @@ ScopeNode::ScopeNode(JSGlobalData* globalData, const SourceCode& source, SourceE , m_features(features) , m_source(source) { -#if ENABLE(CODEBLOCK_SAMPLING) - if (SamplingTool* sampler = globalData->interpreter->sampler()) - sampler->notifyOfScope(this); -#endif } inline void ScopeNode::emitStatementsBytecode(BytecodeGenerator& generator, RegisterID* dst) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayPrototype.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayPrototype.cpp index e1b1f34..c453b22 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayPrototype.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayPrototype.cpp @@ -149,10 +149,11 @@ static void putProperty(ExecState* exec, JSObject* obj, const Identifier& proper JSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { - if (!thisValue.inherits(&JSArray::info)) + bool isRealArray = isJSArray(&exec->globalData(), thisValue); + if (!isRealArray && !thisValue.inherits(&JSArray::info)) return throwError(exec, TypeError); - JSObject* thisObj = asArray(thisValue); - + JSArray* thisObj = asArray(thisValue); + HashSet& arrayVisitedElements = exec->globalData().arrayVisitedElements; if (arrayVisitedElements.size() >= MaxSecondaryThreadReentryDepth) { if (!isMainThread() || arrayVisitedElements.size() >= MaxMainThreadReentryDepth) @@ -163,34 +164,48 @@ JSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec, JSObject*, JSValue if (alreadyVisited) return jsEmptyString(exec); // return an empty string, avoiding infinite recursion. - Vector strBuffer; unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); + unsigned totalSize = length ? length - 1 : 0; + Vector, 256> strBuffer(length); for (unsigned k = 0; k < length; k++) { - if (k >= 1) - strBuffer.append(','); - if (!strBuffer.data()) { - JSObject* error = Error::create(exec, GeneralError, "Out of memory"); - exec->setException(error); - break; - } - - JSValue element = thisObj->get(exec, k); + JSValue element; + if (isRealArray && thisObj->canGetIndex(k)) + element = thisObj->getIndex(k); + else + element = thisObj->get(exec, k); + if (element.isUndefinedOrNull()) continue; - + UString str = element.toString(exec); - strBuffer.append(str.data(), str.size()); - + strBuffer[k] = str.rep(); + totalSize += str.size(); + if (!strBuffer.data()) { JSObject* error = Error::create(exec, GeneralError, "Out of memory"); exec->setException(error); } - + if (exec->hadException()) break; } arrayVisitedElements.remove(thisObj); - return jsString(exec, UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0)); + if (!totalSize) + return jsEmptyString(exec); + Vector buffer; + buffer.reserveCapacity(totalSize); + if (!buffer.data()) + return throwError(exec, GeneralError, "Out of memory"); + + for (unsigned i = 0; i < length; i++) { + if (i) + buffer.append(','); + if (RefPtr rep = strBuffer[i]) + buffer.append(rep->data(), rep->size()); + } + ASSERT(buffer.size() == totalSize); + unsigned finalSize = buffer.size(); + return jsString(exec, UString(buffer.releaseBuffer(), finalSize, false)); } JSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp index 3784da8..1e717cb 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp @@ -843,10 +843,16 @@ void NEVER_INLINE Heap::markCurrentThreadConservativelyInternal(MarkStack& markS markConservatively(markStack, stackPointer, stackBase); } +#if COMPILER(GCC) +#define REGISTER_BUFFER_ALIGNMENT __attribute__ ((aligned (sizeof(void*)))) +#else +#define REGISTER_BUFFER_ALIGNMENT +#endif + void Heap::markCurrentThreadConservatively(MarkStack& markStack) { // setjmp forces volatile registers onto the stack - jmp_buf registers; + jmp_buf registers REGISTER_BUFFER_ALIGNMENT; #if COMPILER(MSVC) #pragma warning(push) #pragma warning(disable: 4611) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Completion.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Completion.cpp index b75a7a5..3ad467d 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Completion.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Completion.cpp @@ -41,7 +41,7 @@ Completion checkSyntax(ExecState* exec, const SourceCode& source) { JSLock lock(exec); - ProgramExecutable program(source); + ProgramExecutable program(exec, source); JSObject* error = program.checkSyntax(exec); if (error) return Completion(Throw, error); @@ -53,7 +53,7 @@ Completion evaluate(ExecState* exec, ScopeChain& scopeChain, const SourceCode& s { JSLock lock(exec); - ProgramExecutable program(source); + ProgramExecutable program(exec, source); JSObject* error = program.compile(exec, scopeChain.node()); if (error) return Completion(Throw, error); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Executable.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Executable.cpp index 5e79794..7586746 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Executable.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Executable.cpp @@ -259,7 +259,7 @@ PassRefPtr FunctionExecutable::fromGlobalCode(const Identifi FunctionBodyNode* body = static_cast(funcExpr)->body(); ASSERT(body); - return FunctionExecutable::create(functionName, body->source(), body->usesArguments(), body->parameters(), body->lineNo(), body->lastLine()); + return FunctionExecutable::create(&exec->globalData(), functionName, body->source(), body->usesArguments(), body->parameters(), body->lineNo(), body->lastLine()); } UString FunctionExecutable::paramString() const diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Executable.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Executable.h index f3003dd..76764f9 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Executable.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Executable.h @@ -27,7 +27,9 @@ #define Executable_h #include "JSFunction.h" +#include "Interpreter.h" #include "Nodes.h" +#include "SamplingTool.h" namespace JSC { @@ -102,11 +104,30 @@ namespace JSC { class ScriptExecutable : public ExecutableBase { public: - ScriptExecutable(const SourceCode& source) + ScriptExecutable(JSGlobalData* globalData, const SourceCode& source) : ExecutableBase(NUM_PARAMETERS_NOT_COMPILED) , m_source(source) , m_features(0) { +#if ENABLE(CODEBLOCK_SAMPLING) + if (SamplingTool* sampler = globalData->interpreter->sampler()) + sampler->notifyOfScope(this); +#else + UNUSED_PARAM(globalData); +#endif + } + + ScriptExecutable(ExecState* exec, const SourceCode& source) + : ExecutableBase(NUM_PARAMETERS_NOT_COMPILED) + , m_source(source) + , m_features(0) + { +#if ENABLE(CODEBLOCK_SAMPLING) + if (SamplingTool* sampler = exec->globalData().interpreter->sampler()) + sampler->notifyOfScope(this); +#else + UNUSED_PARAM(exec); +#endif } const SourceCode& source() { return m_source; } @@ -137,8 +158,8 @@ namespace JSC { class EvalExecutable : public ScriptExecutable { public: - EvalExecutable(const SourceCode& source) - : ScriptExecutable(source) + EvalExecutable(ExecState* exec, const SourceCode& source) + : ScriptExecutable(exec, source) , m_evalCodeBlock(0) { } @@ -157,7 +178,7 @@ namespace JSC { JSObject* compile(ExecState*, ScopeChainNode*); ExceptionInfo* reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*); - static PassRefPtr create(const SourceCode& source) { return adoptRef(new EvalExecutable(source)); } + static PassRefPtr create(ExecState* exec, const SourceCode& source) { return adoptRef(new EvalExecutable(exec, source)); } private: EvalCodeBlock* m_evalCodeBlock; @@ -178,8 +199,8 @@ namespace JSC { class ProgramExecutable : public ScriptExecutable { public: - ProgramExecutable(const SourceCode& source) - : ScriptExecutable(source) + ProgramExecutable(ExecState* exec, const SourceCode& source) + : ScriptExecutable(exec, source) , m_programCodeBlock(0) { } @@ -221,9 +242,14 @@ namespace JSC { class FunctionExecutable : public ScriptExecutable { friend class JIT; public: - static PassRefPtr create(const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine) + static PassRefPtr create(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine) + { + return adoptRef(new FunctionExecutable(exec, name, source, forceUsesArguments, parameters, firstLine, lastLine)); + } + + static PassRefPtr create(JSGlobalData* globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine) { - return adoptRef(new FunctionExecutable(name, source, forceUsesArguments, parameters, firstLine, lastLine)); + return adoptRef(new FunctionExecutable(globalData, name, source, forceUsesArguments, parameters, firstLine, lastLine)); } ~FunctionExecutable(); @@ -264,8 +290,20 @@ namespace JSC { static PassRefPtr fromGlobalCode(const Identifier&, ExecState*, Debugger*, const SourceCode&, int* errLine = 0, UString* errMsg = 0); private: - FunctionExecutable(const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine) - : ScriptExecutable(source) + FunctionExecutable(JSGlobalData* globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine) + : ScriptExecutable(globalData, source) + , m_forceUsesArguments(forceUsesArguments) + , m_parameters(parameters) + , m_codeBlock(0) + , m_name(name) + , m_numVariables(0) + { + m_firstLine = firstLine; + m_lastLine = lastLine; + } + + FunctionExecutable(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine) + : ScriptExecutable(exec, source) , m_forceUsesArguments(forceUsesArguments) , m_parameters(parameters) , m_codeBlock(0) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSArray.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSArray.cpp index 1a4402c..9e0ab59 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSArray.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSArray.cpp @@ -136,9 +136,7 @@ JSArray::JSArray(PassRefPtr structure) unsigned initialCapacity = 0; m_storage = static_cast(fastZeroedMalloc(storageSize(initialCapacity))); - m_storage->m_vectorLength = initialCapacity; - - m_fastAccessCutoff = 0; + m_vectorLength = initialCapacity; checkConsistency(); } @@ -150,7 +148,7 @@ JSArray::JSArray(PassRefPtr structure, unsigned initialLength) m_storage = static_cast(fastMalloc(storageSize(initialCapacity))); m_storage->m_length = initialLength; - m_storage->m_vectorLength = initialCapacity; + m_vectorLength = initialCapacity; m_storage->m_numValuesInVector = 0; m_storage->m_sparseValueMap = 0; m_storage->lazyCreationData = 0; @@ -159,8 +157,6 @@ JSArray::JSArray(PassRefPtr structure, unsigned initialLength) for (size_t i = 0; i < initialCapacity; ++i) vector[i] = JSValue(); - m_fastAccessCutoff = 0; - checkConsistency(); Heap::heap(this)->reportExtraMemoryCost(initialCapacity * sizeof(JSValue)); @@ -173,7 +169,7 @@ JSArray::JSArray(PassRefPtr structure, const ArgList& list) m_storage = static_cast(fastMalloc(storageSize(initialCapacity))); m_storage->m_length = initialCapacity; - m_storage->m_vectorLength = initialCapacity; + m_vectorLength = initialCapacity; m_storage->m_numValuesInVector = initialCapacity; m_storage->m_sparseValueMap = 0; @@ -182,8 +178,6 @@ JSArray::JSArray(PassRefPtr structure, const ArgList& list) for (ArgList::const_iterator it = list.begin(); it != end; ++it, ++i) m_storage->m_vector[i] = *it; - m_fastAccessCutoff = initialCapacity; - checkConsistency(); Heap::heap(this)->reportExtraMemoryCost(storageSize(initialCapacity)); @@ -207,7 +201,7 @@ bool JSArray::getOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& slot return false; } - if (i < storage->m_vectorLength) { + if (i < m_vectorLength) { JSValue& valueSlot = storage->m_vector[i]; if (valueSlot) { slot.setValueSlot(&valueSlot); @@ -253,8 +247,8 @@ bool JSArray::getOwnPropertyDescriptor(ExecState* exec, const Identifier& proper if (isArrayIndex) { if (i >= m_storage->m_length) return false; - if (i < m_storage->m_vectorLength) { - JSValue value = m_storage->m_vector[i]; + if (i < m_vectorLength) { + JSValue& value = m_storage->m_vector[i]; if (value) { descriptor.setDescriptor(value, 0); return true; @@ -305,7 +299,7 @@ void JSArray::put(ExecState* exec, unsigned i, JSValue value) m_storage->m_length = length; } - if (i < m_storage->m_vectorLength) { + if (i < m_vectorLength) { JSValue& valueSlot = m_storage->m_vector[i]; if (valueSlot) { valueSlot = value; @@ -313,8 +307,7 @@ void JSArray::put(ExecState* exec, unsigned i, JSValue value) return; } valueSlot = value; - if (++m_storage->m_numValuesInVector == m_storage->m_length) - m_fastAccessCutoff = m_storage->m_length; + ++m_storage->m_numValuesInVector; checkConsistency(); return; } @@ -352,8 +345,7 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu if (increaseVectorLength(i + 1)) { storage = m_storage; storage->m_vector[i] = value; - if (++storage->m_numValuesInVector == storage->m_length) - m_fastAccessCutoff = storage->m_length; + ++storage->m_numValuesInVector; checkConsistency(); } else throwOutOfMemoryError(exec); @@ -363,7 +355,7 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu // Decide how many values it would be best to move from the map. unsigned newNumValuesInVector = storage->m_numValuesInVector + 1; unsigned newVectorLength = increasedVectorLength(i + 1); - for (unsigned j = max(storage->m_vectorLength, MIN_SPARSE_ARRAY_INDEX); j < newVectorLength; ++j) + for (unsigned j = max(m_vectorLength, MIN_SPARSE_ARRAY_INDEX); j < newVectorLength; ++j) newNumValuesInVector += map->contains(j); if (i >= MIN_SPARSE_ARRAY_INDEX) newNumValuesInVector -= map->contains(i); @@ -386,7 +378,7 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu return; } - unsigned vectorLength = storage->m_vectorLength; + unsigned vectorLength = m_vectorLength; Heap::heap(this)->reportExtraMemoryCost(storageSize(newVectorLength) - storageSize(vectorLength)); @@ -404,7 +396,7 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu storage->m_vector[i] = value; - storage->m_vectorLength = newVectorLength; + m_vectorLength = newVectorLength; storage->m_numValuesInVector = newNumValuesInVector; m_storage = storage; @@ -431,7 +423,7 @@ bool JSArray::deleteProperty(ExecState* exec, unsigned i, bool checkDontDelete) ArrayStorage* storage = m_storage; - if (i < storage->m_vectorLength) { + if (i < m_vectorLength) { JSValue& valueSlot = storage->m_vector[i]; if (!valueSlot) { checkConsistency(); @@ -439,8 +431,6 @@ bool JSArray::deleteProperty(ExecState* exec, unsigned i, bool checkDontDelete) } valueSlot = JSValue(); --storage->m_numValuesInVector; - if (m_fastAccessCutoff > i) - m_fastAccessCutoff = i; checkConsistency(); return true; } @@ -472,7 +462,7 @@ void JSArray::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNa ArrayStorage* storage = m_storage; - unsigned usedVectorLength = min(storage->m_length, storage->m_vectorLength); + unsigned usedVectorLength = min(storage->m_length, m_vectorLength); for (unsigned i = 0; i < usedVectorLength; ++i) { if (storage->m_vector[i]) propertyNames.add(Identifier::from(exec, i)); @@ -494,7 +484,7 @@ bool JSArray::increaseVectorLength(unsigned newLength) ArrayStorage* storage = m_storage; - unsigned vectorLength = storage->m_vectorLength; + unsigned vectorLength = m_vectorLength; ASSERT(newLength > vectorLength); ASSERT(newLength <= MAX_STORAGE_VECTOR_INDEX); unsigned newVectorLength = increasedVectorLength(newLength); @@ -503,7 +493,7 @@ bool JSArray::increaseVectorLength(unsigned newLength) return false; Heap::heap(this)->reportExtraMemoryCost(storageSize(newVectorLength) - storageSize(vectorLength)); - storage->m_vectorLength = newVectorLength; + m_vectorLength = newVectorLength; for (unsigned i = vectorLength; i < newVectorLength; ++i) storage->m_vector[i] = JSValue(); @@ -521,10 +511,7 @@ void JSArray::setLength(unsigned newLength) unsigned length = m_storage->m_length; if (newLength < length) { - if (m_fastAccessCutoff > newLength) - m_fastAccessCutoff = newLength; - - unsigned usedVectorLength = min(length, storage->m_vectorLength); + unsigned usedVectorLength = min(length, m_vectorLength); for (unsigned i = newLength; i < usedVectorLength; ++i) { JSValue& valueSlot = storage->m_vector[i]; bool hadValue = valueSlot; @@ -563,20 +550,13 @@ JSValue JSArray::pop() JSValue result; - if (m_fastAccessCutoff > length) { - JSValue& valueSlot = m_storage->m_vector[length]; - result = valueSlot; - ASSERT(result); - valueSlot = JSValue(); - --m_storage->m_numValuesInVector; - m_fastAccessCutoff = length; - } else if (length < m_storage->m_vectorLength) { + if (length < m_vectorLength) { JSValue& valueSlot = m_storage->m_vector[length]; - result = valueSlot; - valueSlot = JSValue(); - if (result) + if (valueSlot) { --m_storage->m_numValuesInVector; - else + result = valueSlot; + valueSlot = JSValue(); + } else result = jsUndefined(); } else { result = jsUndefined(); @@ -604,11 +584,10 @@ void JSArray::push(ExecState* exec, JSValue value) { checkConsistency(); - if (m_storage->m_length < m_storage->m_vectorLength) { - ASSERT(!m_storage->m_vector[m_storage->m_length]); + if (m_storage->m_length < m_vectorLength) { m_storage->m_vector[m_storage->m_length] = value; - if (++m_storage->m_numValuesInVector == ++m_storage->m_length) - m_fastAccessCutoff = m_storage->m_length; + ++m_storage->m_numValuesInVector; + ++m_storage->m_length; checkConsistency(); return; } @@ -618,8 +597,8 @@ void JSArray::push(ExecState* exec, JSValue value) if (!map || map->isEmpty()) { if (increaseVectorLength(m_storage->m_length + 1)) { m_storage->m_vector[m_storage->m_length] = value; - if (++m_storage->m_numValuesInVector == ++m_storage->m_length) - m_fastAccessCutoff = m_storage->m_length; + ++m_storage->m_numValuesInVector; + ++m_storage->m_length; checkConsistency(); return; } @@ -837,7 +816,7 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType, if (!m_storage->m_length) return; - unsigned usedVectorLength = min(m_storage->m_length, m_storage->m_vectorLength); + unsigned usedVectorLength = min(m_storage->m_length, m_vectorLength); AVLTree tree; // Depth 44 is enough for 2^31 items tree.abstractor().m_exec = exec; @@ -886,7 +865,7 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType, if (SparseArrayValueMap* map = m_storage->m_sparseValueMap) { newUsedVectorLength += map->size(); - if (newUsedVectorLength > m_storage->m_vectorLength) { + if (newUsedVectorLength > m_vectorLength) { // Check that it is possible to allocate an array large enough to hold all the entries. if ((newUsedVectorLength > MAX_STORAGE_VECTOR_LENGTH) || !increaseVectorLength(newUsedVectorLength)) { throwOutOfMemoryError(exec); @@ -926,7 +905,6 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType, for (unsigned i = newUsedVectorLength; i < usedVectorLength; ++i) m_storage->m_vector[i] = JSValue(); - m_fastAccessCutoff = newUsedVectorLength; m_storage->m_numValuesInVector = newUsedVectorLength; checkConsistency(SortConsistencyCheck); @@ -934,10 +912,16 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType, void JSArray::fillArgList(ExecState* exec, MarkedArgumentBuffer& args) { - unsigned fastAccessLength = min(m_storage->m_length, m_fastAccessCutoff); + JSValue* vector = m_storage->m_vector; + unsigned vectorEnd = min(m_storage->m_length, m_vectorLength); unsigned i = 0; - for (; i < fastAccessLength; ++i) - args.append(getIndex(i)); + for (; i < vectorEnd; ++i) { + JSValue& v = vector[i]; + if (!v) + break; + args.append(v); + } + for (; i < m_storage->m_length; ++i) args.append(get(exec, i)); } @@ -946,12 +930,17 @@ void JSArray::copyToRegisters(ExecState* exec, Register* buffer, uint32_t maxSiz { ASSERT(m_storage->m_length == maxSize); UNUSED_PARAM(maxSize); - unsigned fastAccessLength = min(m_storage->m_length, m_fastAccessCutoff); + JSValue* vector = m_storage->m_vector; + unsigned vectorEnd = min(m_storage->m_length, m_vectorLength); unsigned i = 0; - for (; i < fastAccessLength; ++i) - buffer[i] = getIndex(i); - uint32_t size = m_storage->m_length; - for (; i < size; ++i) + for (; i < vectorEnd; ++i) { + JSValue& v = vector[i]; + if (!v) + break; + buffer[i] = v; + } + + for (; i < m_storage->m_length; ++i) buffer[i] = get(exec, i); } @@ -961,7 +950,7 @@ unsigned JSArray::compactForSorting() ArrayStorage* storage = m_storage; - unsigned usedVectorLength = min(m_storage->m_length, storage->m_vectorLength); + unsigned usedVectorLength = min(m_storage->m_length, m_vectorLength); unsigned numDefined = 0; unsigned numUndefined = 0; @@ -985,7 +974,7 @@ unsigned JSArray::compactForSorting() if (SparseArrayValueMap* map = storage->m_sparseValueMap) { newUsedVectorLength += map->size(); - if (newUsedVectorLength > storage->m_vectorLength) { + if (newUsedVectorLength > m_vectorLength) { // Check that it is possible to allocate an array large enough to hold all the entries - if not, // exception is thrown by caller. if ((newUsedVectorLength > MAX_STORAGE_VECTOR_LENGTH) || !increaseVectorLength(newUsedVectorLength)) @@ -1006,7 +995,6 @@ unsigned JSArray::compactForSorting() for (unsigned i = newUsedVectorLength; i < usedVectorLength; ++i) storage->m_vector[i] = JSValue(); - m_fastAccessCutoff = newUsedVectorLength; storage->m_numValuesInVector = newUsedVectorLength; checkConsistency(SortConsistencyCheck); @@ -1032,30 +1020,27 @@ void JSArray::checkConsistency(ConsistencyCheckType type) if (type == SortConsistencyCheck) ASSERT(!m_storage->m_sparseValueMap); - ASSERT(m_fastAccessCutoff <= m_storage->m_length); - ASSERT(m_fastAccessCutoff <= m_storage->m_numValuesInVector); - unsigned numValuesInVector = 0; - for (unsigned i = 0; i < m_storage->m_vectorLength; ++i) { + for (unsigned i = 0; i < m_vectorLength; ++i) { if (JSValue value = m_storage->m_vector[i]) { ASSERT(i < m_storage->m_length); if (type != DestructorConsistencyCheck) value->type(); // Likely to crash if the object was deallocated. ++numValuesInVector; } else { - ASSERT(i >= m_fastAccessCutoff); if (type == SortConsistencyCheck) ASSERT(i >= m_storage->m_numValuesInVector); } } ASSERT(numValuesInVector == m_storage->m_numValuesInVector); + ASSERT(numValuesInVector <= m_storage->m_length); if (m_storage->m_sparseValueMap) { SparseArrayValueMap::iterator end = m_storage->m_sparseValueMap->end(); for (SparseArrayValueMap::iterator it = m_storage->m_sparseValueMap->begin(); it != end; ++it) { unsigned index = it->first; ASSERT(index < m_storage->m_length); - ASSERT(index >= m_storage->m_vectorLength); + ASSERT(index >= m_vectorLength); ASSERT(index <= MAX_ARRAY_INDEX); ASSERT(it->second); if (type != DestructorConsistencyCheck) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSArray.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSArray.h index 37ed72b..2613991 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSArray.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSArray.h @@ -29,7 +29,6 @@ namespace JSC { struct ArrayStorage { unsigned m_length; - unsigned m_vectorLength; unsigned m_numValuesInVector; SparseArrayValueMap* m_sparseValueMap; void* lazyCreationData; // A JSArray subclass can use this to fill the vector lazily. @@ -63,18 +62,24 @@ namespace JSC { void push(ExecState*, JSValue); JSValue pop(); - bool canGetIndex(unsigned i) { return i < m_fastAccessCutoff; } + bool canGetIndex(unsigned i) { return i < m_vectorLength && m_storage->m_vector[i]; } JSValue getIndex(unsigned i) { ASSERT(canGetIndex(i)); return m_storage->m_vector[i]; } - bool canSetIndex(unsigned i) { return i < m_fastAccessCutoff; } - JSValue setIndex(unsigned i, JSValue v) + bool canSetIndex(unsigned i) { return i < m_vectorLength; } + void setIndex(unsigned i, JSValue v) { ASSERT(canSetIndex(i)); - return m_storage->m_vector[i] = v; + JSValue& x = m_storage->m_vector[i]; + if (!x) { + ++m_storage->m_numValuesInVector; + if (i >= m_storage->m_length) + m_storage->m_length = i + 1; + } + x = v; } void fillArgList(ExecState*, MarkedArgumentBuffer&); @@ -110,7 +115,7 @@ namespace JSC { enum ConsistencyCheckType { NormalConsistencyCheck, DestructorConsistencyCheck, SortConsistencyCheck }; void checkConsistency(ConsistencyCheckType = NormalConsistencyCheck); - unsigned m_fastAccessCutoff; + unsigned m_vectorLength; ArrayStorage* m_storage; }; @@ -144,7 +149,7 @@ namespace JSC { ArrayStorage* storage = m_storage; - unsigned usedVectorLength = std::min(storage->m_length, storage->m_vectorLength); + unsigned usedVectorLength = std::min(storage->m_length, m_vectorLength); markStack.appendValues(storage->m_vector, usedVectorLength, MayContainNullValues); if (SparseArrayValueMap* map = storage->m_sparseValueMap) { diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp index b11070f..5ded370 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp @@ -286,7 +286,7 @@ JSValue JSC_HOST_CALL globalFuncEval(ExecState* exec, JSObject* function, JSValu if (JSValue parsedObject = preparser.tryLiteralParse()) return parsedObject; - EvalExecutable eval(makeSource(s)); + EvalExecutable eval(exec, makeSource(s)); JSObject* error = eval.compile(exec, static_cast(unwrappedObject)->globalScopeChain().node()); if (error) return throwError(exec, error); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSValue.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSValue.cpp index 39a4093..699c1cd 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSValue.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSValue.cpp @@ -110,7 +110,10 @@ char* JSValue::description() { static const size_t size = 32; static char description[size]; - if (isInt32()) + + if (!*this) + snprintf(description, size, ""); + else if (isInt32()) snprintf(description, size, "Int32: %d", asInt32()); else if (isDouble()) snprintf(description, size, "Double: %lf", asDouble()); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSValue.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSValue.h index 58e74b1..3c511d8 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSValue.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSValue.h @@ -213,7 +213,8 @@ namespace JSC { enum { FalseTag = 0xfffffffc }; enum { NullTag = 0xfffffffb }; enum { UndefinedTag = 0xfffffffa }; - enum { DeletedValueTag = 0xfffffff9 }; + enum { EmptyValueTag = 0xfffffff9 }; + enum { DeletedValueTag = 0xfffffff8 }; enum { LowestTag = DeletedValueTag }; @@ -427,7 +428,7 @@ namespace JSC { inline JSValue::JSValue() { - u.asBits.tag = CellTag; + u.asBits.tag = EmptyValueTag; u.asBits.payload = 0; } @@ -463,19 +464,26 @@ namespace JSC { inline JSValue::JSValue(JSCell* ptr) { - u.asBits.tag = CellTag; + if (ptr) + u.asBits.tag = CellTag; + else + u.asBits.tag = EmptyValueTag; u.asBits.payload = reinterpret_cast(ptr); } inline JSValue::JSValue(const JSCell* ptr) { - u.asBits.tag = CellTag; + if (ptr) + u.asBits.tag = CellTag; + else + u.asBits.tag = EmptyValueTag; u.asBits.payload = reinterpret_cast(const_cast(ptr)); } inline JSValue::operator bool() const { - return u.asBits.payload || tag() != CellTag; + ASSERT(tag() != DeletedValueTag); + return tag() != EmptyValueTag; } inline bool JSValue::operator==(const JSValue& other) const diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Structure.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Structure.cpp index f7bda9e..a509122 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Structure.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Structure.cpp @@ -46,6 +46,7 @@ #define DO_PROPERTYMAP_CONSTENCY_CHECK 0 #endif +using namespace std; using namespace WTF; namespace JSC { @@ -555,7 +556,7 @@ PassRefPtr Structure::getterSetterTransition(Structure* structure) PassRefPtr Structure::toDictionaryTransition(Structure* structure, DictionaryKind kind) { - ASSERT(!structure->isDictionary()); + ASSERT(!structure->isUncacheableDictionary()); RefPtr transition = create(structure->m_prototype, structure->typeInfo()); transition->m_dictionaryKind = kind; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/TimeoutChecker.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/TimeoutChecker.cpp index d7fca33..0a8bbd3 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/TimeoutChecker.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/TimeoutChecker.cpp @@ -35,18 +35,10 @@ #if PLATFORM(DARWIN) #include -#endif - -#if HAVE(SYS_TIME_H) -#include -#endif - -#if PLATFORM(WIN_OS) +#elif PLATFORM(WIN_OS) #include -#endif - -#if PLATFORM(QT) -#include +#else +#include "CurrentTime.h" #endif using namespace std; @@ -75,14 +67,6 @@ static inline unsigned getCPUTime() time += info.system_time.seconds * 1000 + info.system_time.microseconds / 1000; return time; -#elif HAVE(SYS_TIME_H) - // FIXME: This should probably use getrusage with the RUSAGE_THREAD flag. - struct timeval tv; - gettimeofday(&tv, 0); - return tv.tv_sec * 1000 + tv.tv_usec / 1000; -#elif PLATFORM(QT) - QDateTime t = QDateTime::currentDateTime(); - return t.toTime_t() * 1000 + t.time().msec(); #elif PLATFORM(WIN_OS) union { FILETIME fileTime; @@ -97,7 +81,8 @@ static inline unsigned getCPUTime() return userTime.fileTimeAsLong / 10000 + kernelTime.fileTimeAsLong / 10000; #else -#error Platform does not have getCurrentTime function + // FIXME: We should return the time the current thread has spent executing. + return currentTime() * 1000; #endif } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Assertions.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Assertions.cpp index 54daf23..5af1377 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Assertions.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Assertions.cpp @@ -108,7 +108,11 @@ static void vprintf_stderr_common(const char* format, va_list args) } while (size > 1024); } #endif +#if PLATFORM(SYMBIAN) + vfprintf(stdout, format, args); +#else vfprintf(stderr, format, args); +#endif } WTF_ATTRIBUTE_PRINTF(1, 2) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Assertions.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Assertions.h index b68e70c..f529a62 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Assertions.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Assertions.h @@ -50,6 +50,11 @@ #include #endif +#if PLATFORM(SYMBIAN) +#include +#include +#endif + #ifdef NDEBUG #define ASSERTIONS_DISABLED_DEFAULT 1 #else @@ -120,11 +125,18 @@ void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChann /* CRASH -- gets us into the debugger or the crash reporter -- signals are ignored by the crash reporter so we must do better */ #ifndef CRASH +#if PLATFORM(SYMBIAN) +#define CRASH() do { \ + __DEBUGGER(); \ + User::Panic(_L("Webkit CRASH"),0); \ + } while(false) +#else #define CRASH() do { \ *(int *)(uintptr_t)0xbbadbeef = 0; \ ((void(*)())0)(); /* More reliable, but doesn't say BBADBEEF */ \ } while(false) #endif +#endif /* ASSERT, ASSERT_WITH_MESSAGE, ASSERT_NOT_REACHED */ diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/FastMalloc.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/FastMalloc.cpp index afb0220..6cd8ef0 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/FastMalloc.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/FastMalloc.cpp @@ -379,6 +379,9 @@ extern "C" const int jscore_fastmalloc_introspection = 0; #include #include #include +#if PLATFORM(UNIX) +#include +#endif #if COMPILER(MSVC) #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN @@ -391,6 +394,7 @@ extern "C" const int jscore_fastmalloc_introspection = 0; #if PLATFORM(DARWIN) #include "MallocZoneSupport.h" #include +#include #endif #ifndef PRIuS @@ -2274,7 +2278,7 @@ static inline TCMalloc_PageHeap* getPageHeap() #define pageheap getPageHeap() #if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY -#if PLATFORM(WIN) +#if PLATFORM(WIN_OS) static void sleep(unsigned seconds) { ::Sleep(seconds * 1000); @@ -2283,6 +2287,10 @@ static void sleep(unsigned seconds) void TCMalloc_PageHeap::scavengerThread() { +#if HAVE(PTHREAD_SETNAME_NP) + pthread_setname_np("JavaScriptCore: FastMalloc scavenger"); +#endif + while (1) { if (!shouldContinueScavenging()) { pthread_mutex_lock(&m_scavengeMutex); @@ -2388,7 +2396,7 @@ ALWAYS_INLINE void TCMalloc_Central_FreeList::ReleaseToSpans(void* object) { // The following check is expensive, so it is disabled by default if (false) { // Check that object does not occur in list - int got = 0; + unsigned got = 0; for (void* p = span->objects; p != NULL; p = *((void**) p)) { ASSERT(p != object); got++; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/FastMalloc.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/FastMalloc.h index b23e7b0..ca0961c 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/FastMalloc.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/FastMalloc.h @@ -213,6 +213,9 @@ using WTF::fastMallocAllow; // debug-only code to make sure we don't use the system malloc via the default operator // new by accident. +// We musn't customize the global operator new and delete for the Qt port. +#if !PLATFORM(QT) + WTF_PRIVATE_INLINE void* operator new(size_t size) { return fastMalloc(size); } WTF_PRIVATE_INLINE void* operator new(size_t size, const std::nothrow_t&) throw() { return fastMalloc(size); } WTF_PRIVATE_INLINE void operator delete(void* p) { fastFree(p); } @@ -224,4 +227,6 @@ WTF_PRIVATE_INLINE void operator delete[](void* p, const std::nothrow_t&) throw( #endif +#endif + #endif /* WTF_FastMalloc_h */ diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Forward.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Forward.h index 67dc3be..448de7d 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Forward.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Forward.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006 Apple Computer, Inc. + * Copyright (C) 2006, 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -27,6 +27,7 @@ namespace WTF { template class ListRefPtr; template class OwnArrayPtr; template class OwnPtr; + template class PassOwnPtr; template class PassRefPtr; template class RefPtr; template class Vector; @@ -35,9 +36,9 @@ namespace WTF { using WTF::ListRefPtr; using WTF::OwnArrayPtr; using WTF::OwnPtr; +using WTF::PassOwnPtr; using WTF::PassRefPtr; using WTF::RefPtr; using WTF::Vector; #endif // WTF_Forward_h - diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/HashCountedSet.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/HashCountedSet.h index 1a422d8..5fb6da8 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/HashCountedSet.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/HashCountedSet.h @@ -49,23 +49,28 @@ namespace WTF { const_iterator begin() const; const_iterator end() const; - iterator find(const ValueType& value); - const_iterator find(const ValueType& value) const; - bool contains(const ValueType& value) const; - unsigned count(const ValueType& value) const; + iterator find(const ValueType&); + const_iterator find(const ValueType&) const; + bool contains(const ValueType&) const; + unsigned count(const ValueType&) const; // increases the count if an equal value is already present // the return value is a pair of an interator to the new value's location, // and a bool that is true if an new entry was added - std::pair add(const ValueType &value); + std::pair add(const ValueType&); // reduces the count of the value, and removes it if count // goes down to zero - void remove(const ValueType& value); - void remove(iterator it); + void remove(const ValueType&); + void remove(iterator); - void clear(); - + // removes the value, regardless of its count + void clear(iterator); + void clear(const ValueType&); + + // clears the whole set + void clear(); + private: ImplType m_impl; }; @@ -166,6 +171,21 @@ namespace WTF { } template + inline void HashCountedSet::clear(const ValueType& value) + { + clear(find(value)); + } + + template + inline void HashCountedSet::clear(iterator it) + { + if (it == end()) + return; + + m_impl.remove(it); + } + + template inline void HashCountedSet::clear() { m_impl.clear(); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Platform.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Platform.h index 39cafab..73212db 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Platform.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Platform.h @@ -278,6 +278,10 @@ #undef ARM_ARCH_VERSION #define ARM_ARCH_VERSION 7 #endif +/* On ARMv5 and below the natural alignment is required. */ +#if !defined(ARM_REQUIRE_NATURAL_ALIGNMENT) && ARM_ARCH_VERSION <= 5 +#define ARM_REQUIRE_NATURAL_ALIGNMENT 1 +#endif /* Defines two pseudo-platforms for ARM and Thumb-2 instruction set. */ #if !defined(WTF_PLATFORM_ARM_TRADITIONAL) && !defined(WTF_PLATFORM_ARM_THUMB2) # if defined(thumb2) || defined(__thumb2__) @@ -560,6 +564,7 @@ #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !PLATFORM(IPHONE) #define HAVE_MADV_FREE_REUSE 1 #define HAVE_MADV_FREE 1 +#define HAVE_PTHREAD_SETNAME_NP 1 #endif #if PLATFORM(IPHONE) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/RandomNumber.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/RandomNumber.cpp index 0e6e208..52fb130 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/RandomNumber.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/RandomNumber.cpp @@ -82,6 +82,23 @@ double randomNumber() return static_cast(fullRandom)/static_cast(1LL << 53); #elif PLATFORM(WINCE) return genrand_res53(); +#elif PLATFORM(WIN_OS) + uint32_t part1 = rand() & (RAND_MAX - 1); + uint32_t part2 = rand() & (RAND_MAX - 1); + uint32_t part3 = rand() & (RAND_MAX - 1); + uint32_t part4 = rand() & (RAND_MAX - 1); + // rand only provides 15 bits on Win32 + uint64_t fullRandom = part1; + fullRandom <<= 15; + fullRandom |= part2; + fullRandom <<= 15; + fullRandom |= part3; + fullRandom <<= 15; + fullRandom |= part4; + + // Mask off the low 53bits + fullRandom &= (1LL << 53) - 1; + return static_cast(fullRandom)/static_cast(1LL << 53); #else uint32_t part1 = rand() & (RAND_MAX - 1); uint32_t part2 = rand() & (RAND_MAX - 1); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TCSpinLock.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TCSpinLock.h index ced2283..4cf30c2 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TCSpinLock.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TCSpinLock.h @@ -209,6 +209,13 @@ struct TCMalloc_SpinLock { inline void Unlock() { if (pthread_mutex_unlock(&private_lock_) != 0) CRASH(); } + bool IsHeld() { + if (pthread_mutex_trylock(&private_lock_)) + return true; + + Unlock(); + return false; + } }; #define SPINLOCK_INITIALIZER { PTHREAD_MUTEX_INITIALIZER } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadingPthreads.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadingPthreads.cpp index c241bd9..e4fb419 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadingPthreads.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadingPthreads.cpp @@ -186,7 +186,7 @@ ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, con void setThreadNameInternal(const char* threadName) { -#if PLATFORM(DARWIN) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !PLATFORM(IPHONE) +#if HAVE(PTHREAD_SETNAME_NP) pthread_setname_np(threadName); #else UNUSED_PARAM(threadName); diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexJIT.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexJIT.cpp index 4390b5b..d777424 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexJIT.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexJIT.cpp @@ -549,11 +549,11 @@ class RegexGenerator : private MacroAssembler { } if (mask) { - load32(BaseIndex(input, index, TimesTwo, state.inputOffset() * sizeof(UChar)), character); + load32WithUnalignedHalfWords(BaseIndex(input, index, TimesTwo, state.inputOffset() * sizeof(UChar)), character); or32(Imm32(mask), character); state.jumpToBacktrack(branch32(NotEqual, character, Imm32(chPair | mask)), this); } else - state.jumpToBacktrack(branch32(NotEqual, BaseIndex(input, index, TimesTwo, state.inputOffset() * sizeof(UChar)), Imm32(chPair)), this); + state.jumpToBacktrack(branch32WithUnalignedHalfWords(NotEqual, BaseIndex(input, index, TimesTwo, state.inputOffset() * sizeof(UChar)), Imm32(chPair)), this); } void generatePatternCharacterFixed(TermGenerationState& state) diff --git a/src/3rdparty/javascriptcore/VERSION b/src/3rdparty/javascriptcore/VERSION index 3d9c27c..3815dfb 100644 --- a/src/3rdparty/javascriptcore/VERSION +++ b/src/3rdparty/javascriptcore/VERSION @@ -4,8 +4,8 @@ This is a snapshot of JavaScriptCore from The commit imported was from the - jsc-for-qtscript-4.6-staging-01102009 branch/tag + jsc-for-qtscript-4.6-staging-05102009 branch/tag and has the sha1 checksum - 79e88e90aab6674098b6d73b1b41998117164499 + 38c2b17366f24220d9ae0456a7cfe2ac78a9f91c diff --git a/src/3rdparty/javascriptcore/WebKit.pri b/src/3rdparty/javascriptcore/WebKit.pri index fd918c9..f5276b3 100644 --- a/src/3rdparty/javascriptcore/WebKit.pri +++ b/src/3rdparty/javascriptcore/WebKit.pri @@ -31,7 +31,10 @@ building-libs { DEPENDPATH += $$PWD/WebKit/qt/Api } -DEFINES += USE_SYSTEM_MALLOC +!win32:!mac:!unix { + DEFINES += USE_SYSTEM_MALLOC +} + CONFIG(release, debug|release) { DEFINES += NDEBUG } @@ -48,7 +51,7 @@ symbian|*-armcc { RVCT_COMMON_CFLAGS = --gnu --diag_suppress 68,111,177,368,830,1293 RVCT_COMMON_CXXFLAGS = $$RVCT_COMMON_CFLAGS --no_parse_templates DEFINES *= QT_NO_UITOOLS -} +} *-armcc { QMAKE_CFLAGS += $$RVCT_COMMON_CFLAGS @@ -63,7 +66,7 @@ contains(DEFINES, QT_NO_UITOOLS): CONFIG -= uitools # Disable a few warnings on Windows. The warnings are also # disabled in WebKitLibraries/win/tools/vsprops/common.vsprops -win32-msvc*: QMAKE_CXXFLAGS += -wd4291 -wd4344 -wd4396 -wd4503 -wd4800 -wd4819 -wd4996 +win32-msvc*: QMAKE_CXXFLAGS += -wd4291 -wd4344 -wd4503 -wd4800 -wd4819 -wd4996 # # For builds inside Qt we interpret the output rule and the input of each extra compiler manually diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index fb14940..09042e1 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -2168,7 +2168,7 @@ QScriptValue QScriptEngine::evaluate(const QString &program, const QString &file exec->clearException(); JSC::DynamicGlobalObjectScope dynamicGlobalObjectScope(exec, exec->scopeChain()->globalObject()); - JSC::EvalExecutable executable(source); + JSC::EvalExecutable executable(exec, source); JSC::JSObject* error = executable.compile(exec, exec->scopeChain()); if (error) { exec->setException(error); -- cgit v0.12 From fd8fda4db4446e394db137ce572a9f2508d12bf2 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Mon, 5 Oct 2009 13:44:54 +0200 Subject: Fixed pixeldust in translucent toplevel proxy widgets on Mac Reviewed-by: Bjoern Erik Nilsen (cherry picked from commit 0ae8f0b63e6705790ad0bdb0f90644b557b5ac67) --- src/gui/kernel/qwidget.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 2359812..4cbf762 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -5130,7 +5130,8 @@ void QWidgetPrivate::render_helper(QPainter *painter, const QPoint &targetOffset return; QPixmap pixmap(size); - if (!(renderFlags & QWidget::DrawWindowBackground)) + if (!(renderFlags & QWidget::DrawWindowBackground) + || !q->palette().brush(q->backgroundRole()).isOpaque()) pixmap.fill(Qt::transparent); q->render(&pixmap, QPoint(), toBePainted, renderFlags); @@ -11447,7 +11448,7 @@ QWidget *QWidgetPrivate::widgetInNavigationDirection(Direction direction) const QRect targetCandidateRect = targetCandidate->rect().translated(targetCandidate->mapToGlobal(QPoint())); - // For focus proxies, the child widget handling the focus can have keypad navigation focus, + // For focus proxies, the child widget handling the focus can have keypad navigation focus, // but the owner of the proxy cannot. // Additionally, empty widgets should be ignored. if (targetCandidate->focusProxy() || targetCandidateRect.isEmpty()) -- cgit v0.12 From 105f17800e4a12e12d728f6f319ebbe9be7fd433 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 5 Oct 2009 14:13:53 +0200 Subject: QAbstractItemView: Make sure the view is updated when a delegate is set. The test tst_QListView::task254449_draggingItemToNegativeCoordinates was failing in cocoa because of this. (on, cocoa, the call to show was doing the first paintEvent) Reviewed-by: Thierry (cherry picked from commit e1fbf1e016cbbf203964f3606ee2a34afe33bbd7) --- src/gui/itemviews/qabstractitemview.cpp | 4 +++- tests/auto/qlistview/tst_qlistview.cpp | 7 ++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index 18cab13..27528de 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -751,7 +751,6 @@ void QAbstractItemView::setItemDelegate(QAbstractItemDelegate *delegate) } } - if (delegate) { if (d->delegateRefCount(delegate) == 0) { connect(delegate, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)), @@ -762,6 +761,7 @@ void QAbstractItemView::setItemDelegate(QAbstractItemDelegate *delegate) } } d->itemDelegate = delegate; + update(); } /*! @@ -826,6 +826,7 @@ void QAbstractItemView::setItemDelegateForRow(int row, QAbstractItemDelegate *de } d->rowDelegates.insert(row, delegate); } + update(); } /*! @@ -882,6 +883,7 @@ void QAbstractItemView::setItemDelegateForColumn(int column, QAbstractItemDelega } d->columnDelegates.insert(column, delegate); } + update(); } /*! diff --git a/tests/auto/qlistview/tst_qlistview.cpp b/tests/auto/qlistview/tst_qlistview.cpp index d9cab02..cba1776 100644 --- a/tests/auto/qlistview/tst_qlistview.cpp +++ b/tests/auto/qlistview/tst_qlistview.cpp @@ -1617,6 +1617,8 @@ void tst_QListView::task254449_draggingItemToNegativeCoordinates() list.setModel(&model); list.setViewMode(QListView::IconMode); list.show(); + QTest::qWaitForWindowShown(&list); + class MyItemDelegate : public QStyledItemDelegate { public: @@ -1631,10 +1633,9 @@ void tst_QListView::task254449_draggingItemToNegativeCoordinates() mutable int numPaints; } delegate; list.setItemDelegate(&delegate); - delegate.numPaints = 0; - QTest::qWaitForWindowShown(&list); //makes sure the layout is done - QTRY_VERIFY(delegate.numPaints > 0); + QApplication::processEvents(); + QTRY_VERIFY(delegate.numPaints > 0); //makes sure the layout is done const QPoint topLeft(-6, 0); list.setPositionForIndex(topLeft, index); -- cgit v0.12 From 5f1728eb5a6b3e6654f75b4af0812eb3b800989f Mon Sep 17 00:00:00 2001 From: axis Date: Mon, 5 Oct 2009 14:21:32 +0200 Subject: Stopped using bitfields for S60 and Symbian versions. There is no reason for it, since they will never overlap. Left a little space between numbers in case of patch releases. RevBy: Iain (cherry picked from commit 19a6d4245ca152758d8dbc7f7d9ee0f0654c04f7) --- src/corelib/global/qglobal.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index dcd4397..5720505 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -1478,17 +1478,17 @@ public: #ifdef Q_OS_SYMBIAN enum SymbianVersion { SV_Unknown = 0x0000, - SV_9_2 = 0x0001, - SV_9_3 = 0x0002, - SV_9_4 = 0x0004 + SV_9_2 = 10, + SV_9_3 = 20, + SV_9_4 = 30 }; static SymbianVersion symbianVersion(); enum S60Version { - SV_S60_None = 0x0000, - SV_S60_Unknown = 0x0001, - SV_S60_3_1 = 0x0002, - SV_S60_3_2 = 0x0004, - SV_S60_5_0 = 0x0008 + SV_S60_None = 0, + SV_S60_Unknown = 1, + SV_S60_3_1 = 10, + SV_S60_3_2 = 20, + SV_S60_5_0 = 30 }; static S60Version s60Version(); #endif -- cgit v0.12 From 6ee7369737feba856e5f2b94f6fa02dce3e489f8 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Mon, 5 Oct 2009 14:33:08 +0200 Subject: doc: fix two errors in statemachine snippets (cherry picked from commit b73f1b3d88927b0c51c0624f67695cfd80167d38) --- doc/src/snippets/statemachine/main2.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/src/snippets/statemachine/main2.cpp b/doc/src/snippets/statemachine/main2.cpp index d882400..2419dc2 100644 --- a/doc/src/snippets/statemachine/main2.cpp +++ b/doc/src/snippets/statemachine/main2.cpp @@ -57,7 +57,7 @@ int main(int argv, char **args) //![0] //![2] - s12>addTransition(quitButton, SIGNAL(clicked()), s12); + s12->addTransition(quitButton, SIGNAL(clicked()), s12); //![2] //![1] @@ -71,7 +71,7 @@ int main(int argv, char **args) QButton *interruptButton = new QPushButton("Interrupt Button"); //![3] - QHistoryState *s1h = s1->addHistoryState(); + QHistoryState *s1h = new QHistoryState(s1); QState *s3 = new QState(); s3->assignProperty(label, "text", "In s3"); -- cgit v0.12 From 4d1823e5a1e0f21dcf296700638db285376742da Mon Sep 17 00:00:00 2001 From: Janne Anttila Date: Mon, 5 Oct 2009 16:07:30 +0300 Subject: Fixes to qpixmapcache test cases, test case now adapts to cache_limit. The default cache_limit in different platforms have different value. For example in Symbian the default is currently 1024 KB where as for desktop platforms the default is 10 MB. The purpose of modified qpixmapcache test cases was to do operations until cache_limit was reached. This was achieved by hard coded 40000 iterations. However this hard-coded value is fargile for cache limit changes, and in addition it unnecessarily made the test exectuion to take very long time on platforms which had smaller cache limit. This patch changes the test so that number of expected items to fit in cache is calculated and then 1000 extra items is tried to put in cache to make sure limit is exceeded. Reviewed-by: Alexis Menard (cherry picked from commit bfe0e5c0d47780542b174dc96973920fba11c451) --- tests/auto/qpixmapcache/tst_qpixmapcache.cpp | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/tests/auto/qpixmapcache/tst_qpixmapcache.cpp b/tests/auto/qpixmapcache/tst_qpixmapcache.cpp index b487d74..9775d36 100644 --- a/tests/auto/qpixmapcache/tst_qpixmapcache.cpp +++ b/tests/auto/qpixmapcache/tst_qpixmapcache.cpp @@ -244,16 +244,23 @@ void tst_QPixmapCache::insert() QPixmap p2(10, 10); p2.fill(Qt::yellow); + // Calcuate estimated num of items what fits to cache + int estimatedNum = (1024 * QPixmapCache::cacheLimit()) + / ((p1.width() * p1.height() * p1.depth()) / 8); + + // Mare sure we will put enough items to reach the cache limit + const int numberOfKeys = estimatedNum + 1000; + // make sure it doesn't explode - for (int i = 0; i < 20000; ++i) + for (int i = 0; i < numberOfKeys; ++i) QPixmapCache::insert("0", p1); // ditto - for (int j = 0; j < 40000; ++j) + for (int j = 0; j < numberOfKeys; ++j) QPixmapCache::insert(QString::number(j), p1); int num = 0; - for (int k = 0; k < 40000; ++k) { + for (int k = 0; k < numberOfKeys; ++k) { if (QPixmapCache::find(QString::number(k))) ++num; } @@ -261,9 +268,6 @@ void tst_QPixmapCache::insert() if (QPixmapCache::find("0")) ++num; - int estimatedNum = (1024 * QPixmapCache::cacheLimit()) - / ((p1.width() * p1.height() * p1.depth()) / 8); - QVERIFY(num <= estimatedNum); QPixmap p3; QPixmapCache::insert("null", p3); @@ -281,11 +285,11 @@ void tst_QPixmapCache::insert() //The int part of the API // make sure it doesn't explode QList keys; - for (int i = 0; i < 40000; ++i) + for (int i = 0; i < numberOfKeys; ++i) keys.append(QPixmapCache::insert(p1)); num = 0; - for (int k = 0; k < 40000; ++k) { + for (int k = 0; k < numberOfKeys; ++k) { if (QPixmapCache::find(keys.at(k), &p2)) ++num; } @@ -393,7 +397,12 @@ void tst_QPixmapCache::clear() QPixmap p1(10, 10); p1.fill(Qt::red); - const int numberOfKeys = 40000; + // Calcuate estimated num of items what fits to cache + int estimatedNum = (1024 * QPixmapCache::cacheLimit()) + / ((p1.width() * p1.height() * p1.depth()) / 8); + + // Mare sure we will put enough items to reach the cache limit + const int numberOfKeys = estimatedNum + 1000; for (int i = 0; i < numberOfKeys; ++i) QVERIFY(QPixmapCache::find("x" + QString::number(i)) == 0); -- cgit v0.12 From b8b407a1f19d0521db93e7e5a7fbd03db7f6825c Mon Sep 17 00:00:00 2001 From: mae Date: Mon, 5 Oct 2009 15:07:10 +0200 Subject: Fix QKeySequence::DeleteEndOfWord and QKeySequence::DeleteStartOfWord QTextControl showed inconsistent behaviour with DeleteEndOfWord and DeleteStartOfWord when the cursor had a selection. With this patch, the commands will simply delete the existing selection, which is consistent behaviour with in other IDEs. Reviewed-by: Simon Hausmann (cherry picked from commit 6ce698050bbe9a4ec5198f1e08b94d51b8a6c9bd) --- src/gui/text/qtextcontrol.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp index 6def06e..db4c07c 100644 --- a/src/gui/text/qtextcontrol.cpp +++ b/src/gui/text/qtextcontrol.cpp @@ -1223,11 +1223,13 @@ void QTextControlPrivate::keyPressEvent(QKeyEvent *e) cursor.deleteChar(); } else if (e == QKeySequence::DeleteEndOfWord) { - cursor.movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor); + if (!cursor.hasSelection()) + cursor.movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor); cursor.removeSelectedText(); } else if (e == QKeySequence::DeleteStartOfWord) { - cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor); + if (!cursor.hasSelection()) + cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor); cursor.removeSelectedText(); } else if (e == QKeySequence::DeleteEndOfLine) { -- cgit v0.12 From 7e89d6d5b98fddd62572f87d61f7137c9fca21f6 Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Mon, 5 Oct 2009 14:55:50 +0200 Subject: Fixed noisy looking textures in Basic Drawing example with GL2 engine. When running the Basic Drawing example with the GL2 paint engine and antialiasing enabled, textures looked noisy. When antialiasing was enabled, the example translated the painter half a pixel to get sharp lines. This caused the textures to be sampled at texel corners. Without linear interpolation, sampling textures at texel corners is unpredictable. The fix is to not translate the painter. Reviewed-by: Gunnar (cherry picked from commit 30f413b74f883f7e3984dfe39d825aa6c5f16132) --- examples/painting/basicdrawing/renderarea.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/painting/basicdrawing/renderarea.cpp b/examples/painting/basicdrawing/renderarea.cpp index e8222af..4f07a2d 100644 --- a/examples/painting/basicdrawing/renderarea.cpp +++ b/examples/painting/basicdrawing/renderarea.cpp @@ -136,11 +136,9 @@ void RenderArea::paintEvent(QPaintEvent * /* event */) QPainter painter(this); painter.setPen(pen); painter.setBrush(brush); - if (antialiased) { + if (antialiased) painter.setRenderHint(QPainter::Antialiasing, true); //! [9] - painter.translate(+0.5, +0.5); - } //! [10] for (int x = 0; x < width(); x += 100) { @@ -202,6 +200,7 @@ void RenderArea::paintEvent(QPaintEvent * /* event */) } } + painter.setRenderHint(QPainter::Antialiasing, false); painter.setPen(palette().dark().color()); painter.setBrush(Qt::NoBrush); painter.drawRect(QRect(0, 0, width() - 1, height() - 1)); -- cgit v0.12 From 92b07d2b7054025a661a4c2de226d84a5be4d48f Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Mon, 5 Oct 2009 15:38:01 +0200 Subject: Updated JavaScriptCore from /home/khansen/dev/qtwebkit to jsc-for-qtscript-4.6-staging-05102009 ( ed678069ebd06579a26b4fb8cc944f06d6b0d55c ) (cherry picked from commit 3e574dc0d1b7b2ac351bdf077b86979c85de7972) --- src/3rdparty/javascriptcore/JavaScriptCore/jsc.pro | 31 ---------------------- src/3rdparty/javascriptcore/VERSION | 2 +- src/3rdparty/javascriptcore/WebKit.pri | 2 +- 3 files changed, 2 insertions(+), 33 deletions(-) delete mode 100644 src/3rdparty/javascriptcore/JavaScriptCore/jsc.pro diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jsc.pro b/src/3rdparty/javascriptcore/JavaScriptCore/jsc.pro deleted file mode 100644 index ba880ff..0000000 --- a/src/3rdparty/javascriptcore/JavaScriptCore/jsc.pro +++ /dev/null @@ -1,31 +0,0 @@ -TEMPLATE = app -TARGET = jsc -DESTDIR = . -SOURCES = jsc.cpp -QT -= gui -CONFIG -= app_bundle -CONFIG += building-libs -win32-*: CONFIG += console -win32-msvc*: CONFIG += exceptions_off stl_off - -include($$PWD/../WebKit.pri) - -CONFIG += link_pkgconfig - -QMAKE_RPATHDIR