diff options
author | Simon Hausmann <simon.hausmann@qt.io> | 2017-03-23 14:37:05 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2017-03-23 14:43:46 +0100 |
commit | 24d0266ee45cf6a3c5b9142453966199702fbf90 (patch) | |
tree | 3484070112f5d4cbd1da4683398d0b41d748be65 | |
parent | 12569460e765ea01935ab60e06b5a5acf770ebe7 (diff) | |
parent | 8f5366aed675ce7928448be2f6d739d0548b350e (diff) |
Merge remote-tracking branch 'origin/5.9' into HEAD
Conflicts:
src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
src/qml/jit/qv4assembler.cpp
src/qml/jit/qv4assembler_p.h
src/qml/jit/qv4isel_masm.cpp
src/qml/jsruntime/qv4context.cpp
src/qml/jsruntime/qv4context_p.h
src/qml/jsruntime/qv4engine.cpp
src/qml/jsruntime/qv4vme_moth.cpp
src/qml/memory/qv4mmdefs_p.h
Change-Id: I9966750b7cd9106b78e4c4779f12b95a481cca40
92 files changed, 1206 insertions, 765 deletions
diff --git a/examples/quick/demos/stocqt/content/StockListModel.qml b/examples/quick/demos/stocqt/content/StockListModel.qml index 9b48124bda..02ece32a49 100644 --- a/examples/quick/demos/stocqt/content/StockListModel.qml +++ b/examples/quick/demos/stocqt/content/StockListModel.qml @@ -82,27 +82,28 @@ ListModel { xhr.onreadystatechange = function() { if (xhr.readyState === XMLHttpRequest.LOADING || xhr.readyState === XMLHttpRequest.DONE) { var records = xhr.responseText.split('\n'); + var unknown = "n/a"; + set(index, {"value": unknown, "change": unknown, "changePercentage": unknown}); if (records.length > 0 && xhr.status == 200) { var r = records[1].split(','); var today = parseFloat(r[4]); - setProperty(index, "value", today.toFixed(2)); + if (!isNaN(today)) + setProperty(index, "value", today.toFixed(2)); + if (records.length > 2) { + r = records[2].split(','); + var yesterday = parseFloat(r[4]); + var change = today - yesterday; + if (change >= 0.0) + setProperty(index, "change", "+" + change.toFixed(2)); + else + setProperty(index, "change", change.toFixed(2)); - r = records[2].split(','); - var yesterday = parseFloat(r[4]); - var change = today - yesterday; - if (change >= 0.0) - setProperty(index, "change", "+" + change.toFixed(2)); - else - setProperty(index, "change", change.toFixed(2)); - - var changePercentage = (change / yesterday) * 100.0; - if (changePercentage >= 0.0) - setProperty(index, "changePercentage", "+" + changePercentage.toFixed(2) + "%"); - else - setProperty(index, "changePercentage", changePercentage.toFixed(2) + "%"); - } else { - var unknown = "n/a"; - set(index, {"value": unknown, "change": unknown, "changePercentage": unknown}); + var changePercentage = (change / yesterday) * 100.0; + if (changePercentage >= 0.0) + setProperty(index, "changePercentage", "+" + changePercentage.toFixed(2) + "%"); + else + setProperty(index, "changePercentage", changePercentage.toFixed(2) + "%"); + } } } } diff --git a/src/imports/builtins/builtins.qmltypes b/src/imports/builtins/builtins.qmltypes index 88e3ac6634..ac95a8837b 100644 --- a/src/imports/builtins/builtins.qmltypes +++ b/src/imports/builtins/builtins.qmltypes @@ -150,6 +150,25 @@ Module { } } Enum { + name: "TextFlag" + values: { + "TextSingleLine": 256, + "TextDontClip": 512, + "TextExpandTabs": 1024, + "TextShowMnemonic": 2048, + "TextWordWrap": 4096, + "TextWrapAnywhere": 8192, + "TextDontPrint": 16384, + "TextIncludeTrailingSpaces": 134217728, + "TextHideMnemonic": 32768, + "TextJustificationForced": 65536, + "TextForceLeftToRight": 131072, + "TextForceRightToLeft": 262144, + "TextLongestVariant": 524288, + "TextBypassShaping": 1048576 + } + } + Enum { name: "TextElideMode" values: { "ElideLeft": 0, @@ -440,7 +459,8 @@ Module { "AA_SynthesizeMouseForUnhandledTabletEvents": 24, "AA_CompressHighFrequencyEvents": 25, "AA_DontCheckOpenGLContextThreadAffinity": 26, - "AA_AttributeCount": 27 + "AA_DisableShaderDiskCache": 27, + "AA_AttributeCount": 28 } } Enum { @@ -1096,7 +1116,8 @@ Module { "SystemLocaleLongDate": 5, "DefaultLocaleShortDate": 6, "DefaultLocaleLongDate": 7, - "RFC2822Date": 8 + "RFC2822Date": 8, + "ISODateWithMs": 9 } } Enum { @@ -1607,6 +1628,13 @@ Module { "MouseEventFlagMask": 255 } } + Enum { + name: "ChecksumType" + values: { + "ChecksumIso3309": 0, + "ChecksumItuV41": 1 + } + } } Component { name: "QEasingCurve"; prototype: "QQmlEasingValueType" } } diff --git a/src/imports/imports.pro b/src/imports/imports.pro index 0ba949f070..d16ac05669 100644 --- a/src/imports/imports.pro +++ b/src/imports/imports.pro @@ -20,7 +20,7 @@ qtHaveModule(quick) { sharedimage \ testlib - qtConfig(quick-shadereffect):qtConfig(quick-sprite):qtConfig(opengl(es1|es2)?): \ + qtConfig(quick-particles): \ SUBDIRS += particles } diff --git a/src/imports/particles/plugins.qmltypes b/src/imports/particles/plugins.qmltypes index 5c4bd01980..6c7c98cc71 100644 --- a/src/imports/particles/plugins.qmltypes +++ b/src/imports/particles/plugins.qmltypes @@ -275,11 +275,11 @@ Module { Parameter { name: "arg"; type: "double" } } Method { - name: "setAcceleration" + name: "setMagnitude" Parameter { name: "arg"; type: "double" } } Method { - name: "setMagnitude" + name: "setAcceleration" Parameter { name: "arg"; type: "double" } } Method { @@ -552,7 +552,7 @@ Module { Parameter { name: "arg"; type: "bool" } } Method { - name: "setmirrored" + name: "setMirrored" Parameter { name: "arg"; type: "bool" } } } diff --git a/src/imports/qtquick2/plugins.qmltypes b/src/imports/qtquick2/plugins.qmltypes index 441cd743aa..a9534b5ccc 100644 --- a/src/imports/qtquick2/plugins.qmltypes +++ b/src/imports/qtquick2/plugins.qmltypes @@ -4,7 +4,7 @@ import QtQuick.tooling 1.2 // It is used for QML tooling purposes only. // // This file was auto-generated by: -// 'qmlplugindump -nonrelocatable -noforceqtquick QtQuick 2.8' +// 'qmlplugindump -nonrelocatable -noforceqtquick QtQuick 2.9' Module { dependencies: [] @@ -440,6 +440,13 @@ Module { } } Component { + name: "QPointingDeviceUniqueId" + exports: ["QtQuick/PointingDeviceUniqueId 2.9"] + isCreatable: false + exportMetaObjectRevisions: [0] + Property { name: "numericId"; type: "qlonglong"; isReadonly: true } + } + Component { name: "QQmlApplication" prototype: "QObject" Property { name: "arguments"; type: "QStringList"; isReadonly: true } @@ -1159,6 +1166,8 @@ Module { Property { name: "supportsMultipleWindows"; type: "bool"; isReadonly: true } Property { name: "state"; type: "Qt::ApplicationState"; isReadonly: true } Property { name: "font"; type: "QFont"; isReadonly: true } + Property { name: "displayName"; type: "string" } + Property { name: "screens"; type: "QQuickScreenInfo"; isList: true; isReadonly: true } Signal { name: "stateChanged" Parameter { name: "state"; type: "Qt::ApplicationState" } @@ -1168,9 +1177,13 @@ Module { name: "QQuickBasePositioner" defaultProperty: "data" prototype: "QQuickImplicitSizeItem" - exports: ["QtQuick/Positioner 2.0", "QtQuick/Positioner 2.6"] + exports: [ + "QtQuick/Positioner 2.0", + "QtQuick/Positioner 2.6", + "QtQuick/Positioner 2.9" + ] isCreatable: false - exportMetaObjectRevisions: [0, 6] + exportMetaObjectRevisions: [0, 6, 9] attachedType: "QQuickPositionerAttached" Property { name: "spacing"; type: "double" } Property { name: "populate"; type: "QQuickTransition"; isPointer: true } @@ -1186,6 +1199,8 @@ Module { Signal { name: "leftPaddingChanged"; revision: 6 } Signal { name: "rightPaddingChanged"; revision: 6 } Signal { name: "bottomPaddingChanged"; revision: 6 } + Signal { name: "positioningComplete"; revision: 9 } + Method { name: "forceLayout"; revision: 9 } } Component { name: "QQuickBehavior" @@ -1502,8 +1517,8 @@ Module { name: "QQuickFlickable" defaultProperty: "flickableData" prototype: "QQuickItem" - exports: ["QtQuick/Flickable 2.0"] - exportMetaObjectRevisions: [0] + exports: ["QtQuick/Flickable 2.0", "QtQuick/Flickable 2.9"] + exportMetaObjectRevisions: [0, 9] Enum { name: "BoundsBehavior" values: { @@ -1563,6 +1578,8 @@ Module { isPointer: true } Property { name: "pixelAligned"; type: "bool" } + Property { name: "horizontalOvershoot"; revision: 9; type: "double"; isReadonly: true } + Property { name: "verticalOvershoot"; revision: 9; type: "double"; isReadonly: true } Property { name: "flickableData"; type: "QObject"; isList: true; isReadonly: true } Property { name: "flickableChildren"; type: "QQuickItem"; isList: true; isReadonly: true } Signal { name: "isAtBoundaryChanged" } @@ -1572,6 +1589,8 @@ Module { Signal { name: "flickEnded" } Signal { name: "dragStarted" } Signal { name: "dragEnded" } + Signal { name: "horizontalOvershootChanged"; revision: 9 } + Signal { name: "verticalOvershootChanged"; revision: 9 } Method { name: "resizeContent" Parameter { name: "w"; type: "double" } @@ -2084,8 +2103,13 @@ Module { name: "QQuickItem" defaultProperty: "data" prototype: "QObject" - exports: ["QtQuick/Item 2.0", "QtQuick/Item 2.1", "QtQuick/Item 2.4"] - exportMetaObjectRevisions: [0, 1, 2] + exports: [ + "QtQuick/Item 2.0", + "QtQuick/Item 2.1", + "QtQuick/Item 2.4", + "QtQuick/Item 2.7" + ] + exportMetaObjectRevisions: [0, 1, 2, 7] Enum { name: "TransformOrigin" values: { @@ -2210,23 +2234,21 @@ Module { Parameter { name: "point"; type: "QPointF" } } Method { - name: "mapToGlobal" - revision: 7 - type: "QPointF" - Parameter { name: "point"; type: "QPointF" } + name: "mapFromItem" + Parameter { type: "QQmlV4Function"; isPointer: true } } Method { - name: "mapFromGlobal" - revision: 7 - type: "QPointF" - Parameter { name: "point"; type: "QPointF" } + name: "mapToItem" + Parameter { type: "QQmlV4Function"; isPointer: true } } Method { - name: "mapFromItem" + name: "mapFromGlobal" + revision: 7 Parameter { type: "QQmlV4Function"; isPointer: true } } Method { - name: "mapToItem" + name: "mapToGlobal" + revision: 7 Parameter { type: "QQmlV4Function"; isPointer: true } } Method { name: "forceActiveFocus" } @@ -2259,6 +2281,11 @@ Module { type: "bool" Parameter { name: "fileName"; type: "string" } } + Method { + name: "saveToFile" + type: "bool" + Parameter { name: "fileName"; type: "string" } + } } Component { name: "QQuickItemLayer" @@ -2318,9 +2345,13 @@ Module { name: "QQuickItemView" defaultProperty: "flickableData" prototype: "QQuickFlickable" - exports: ["QtQuick/ItemView 2.1", "QtQuick/ItemView 2.3"] + exports: [ + "QtQuick/ItemView 2.1", + "QtQuick/ItemView 2.3", + "QtQuick/ItemView 2.7" + ] isCreatable: false - exportMetaObjectRevisions: [1, 2] + exportMetaObjectRevisions: [1, 2, 7] Enum { name: "LayoutDirection" values: { @@ -2495,6 +2526,10 @@ Module { Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true } } Signal { + name: "shortcutOverride" + Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true } + } + Signal { name: "digit0Pressed" Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true } } @@ -2757,9 +2792,10 @@ Module { exports: [ "QtQuick/MouseArea 2.0", "QtQuick/MouseArea 2.4", - "QtQuick/MouseArea 2.5" + "QtQuick/MouseArea 2.5", + "QtQuick/MouseArea 2.9" ] - exportMetaObjectRevisions: [0, 1, 2] + exportMetaObjectRevisions: [0, 1, 2, 9] Property { name: "mouseX"; type: "double"; isReadonly: true } Property { name: "mouseY"; type: "double"; isReadonly: true } Property { name: "containsMouse"; type: "bool"; isReadonly: true } @@ -2774,6 +2810,7 @@ Module { Property { name: "propagateComposedEvents"; type: "bool" } Property { name: "cursorShape"; type: "Qt::CursorShape" } Property { name: "containsPress"; revision: 1; type: "bool"; isReadonly: true } + Property { name: "pressAndHoldInterval"; revision: 9; type: "int" } Signal { name: "hoveredChanged" } Signal { name: "scrollGestureEnabledChanged"; revision: 2 } Signal { @@ -2816,6 +2853,7 @@ Module { Signal { name: "exited" } Signal { name: "canceled" } Signal { name: "containsPressChanged"; revision: 1 } + Signal { name: "pressAndHoldIntervalChanged"; revision: 9 } } Component { name: "QQuickMultiPointTouchArea" @@ -3600,14 +3638,20 @@ Module { Component { name: "QQuickShortcut" prototype: "QObject" - exports: ["QtQuick/Shortcut 2.5", "QtQuick/Shortcut 2.6"] - exportMetaObjectRevisions: [0, 1] + exports: [ + "QtQuick/Shortcut 2.5", + "QtQuick/Shortcut 2.6", + "QtQuick/Shortcut 2.9" + ] + exportMetaObjectRevisions: [0, 1, 9] Property { name: "sequence"; type: "QVariant" } + Property { name: "sequences"; revision: 9; type: "QVariantList" } Property { name: "nativeText"; revision: 1; type: "string"; isReadonly: true } Property { name: "portableText"; revision: 1; type: "string"; isReadonly: true } Property { name: "enabled"; type: "bool" } Property { name: "autoRepeat"; type: "bool" } Property { name: "context"; type: "Qt::ShortcutContext" } + Signal { name: "sequencesChanged"; revision: 9 } Signal { name: "activated" } Signal { name: "activatedAmbiguously" } } @@ -3926,9 +3970,10 @@ Module { "QtQuick/Text 2.0", "QtQuick/Text 2.2", "QtQuick/Text 2.3", - "QtQuick/Text 2.6" + "QtQuick/Text 2.6", + "QtQuick/Text 2.9" ] - exportMetaObjectRevisions: [0, 2, 3, 6] + exportMetaObjectRevisions: [0, 2, 3, 6, 9] Enum { name: "HAlignment" values: { @@ -4038,6 +4083,7 @@ Module { Property { name: "leftPadding"; revision: 6; type: "double" } Property { name: "rightPadding"; revision: 6; type: "double" } Property { name: "bottomPadding"; revision: 6; type: "double" } + Property { name: "fontInfo"; revision: 9; type: "QJSValue"; isReadonly: true } Signal { name: "textChanged" Parameter { name: "text"; type: "string" } @@ -4093,7 +4139,9 @@ Module { Signal { name: "leftPaddingChanged"; revision: 6 } Signal { name: "rightPaddingChanged"; revision: 6 } Signal { name: "bottomPaddingChanged"; revision: 6 } + Signal { name: "fontInfoChanged"; revision: 9 } Method { name: "doLayout" } + Method { name: "forceLayout"; revision: 9 } Method { name: "linkAt" revision: 3 @@ -4390,9 +4438,10 @@ Module { "QtQuick/TextInput 2.2", "QtQuick/TextInput 2.4", "QtQuick/TextInput 2.6", - "QtQuick/TextInput 2.7" + "QtQuick/TextInput 2.7", + "QtQuick/TextInput 2.9" ] - exportMetaObjectRevisions: [0, 2, 3, 6, 7] + exportMetaObjectRevisions: [0, 2, 3, 6, 7, 9] Enum { name: "EchoMode" values: { @@ -4497,6 +4546,7 @@ Module { Property { name: "bottomPadding"; revision: 6; type: "double" } Signal { name: "accepted" } Signal { name: "editingFinished"; revision: 2 } + Signal { name: "textEdited"; revision: 9 } Signal { name: "fontChanged" Parameter { name: "font"; type: "QFont" } @@ -4657,13 +4707,16 @@ Module { Component { name: "QQuickTouchPoint" prototype: "QObject" - exports: ["QtQuick/TouchPoint 2.0"] - exportMetaObjectRevisions: [0] + exports: ["QtQuick/TouchPoint 2.0", "QtQuick/TouchPoint 2.9"] + exportMetaObjectRevisions: [0, 0] Property { name: "pointId"; type: "int"; isReadonly: true } + Property { name: "uniqueId"; revision: 9; type: "QPointingDeviceUniqueId"; isReadonly: true } Property { name: "pressed"; type: "bool"; isReadonly: true } Property { name: "x"; type: "double"; isReadonly: true } Property { name: "y"; type: "double"; isReadonly: true } + Property { name: "ellipseDiameters"; revision: 9; type: "QSizeF"; isReadonly: true } Property { name: "pressure"; type: "double"; isReadonly: true } + Property { name: "rotation"; revision: 9; type: "double"; isReadonly: true } Property { name: "velocity"; type: "QVector2D"; isReadonly: true } Property { name: "area"; type: "QRectF"; isReadonly: true } Property { name: "startX"; type: "double"; isReadonly: true } @@ -4672,6 +4725,9 @@ Module { Property { name: "previousY"; type: "double"; isReadonly: true } Property { name: "sceneX"; type: "double"; isReadonly: true } Property { name: "sceneY"; type: "double"; isReadonly: true } + Signal { name: "uniqueIdChanged"; revision: 9 } + Signal { name: "ellipseDiametersChanged"; revision: 9 } + Signal { name: "rotationChanged"; revision: 9 } } Component { name: "QQuickTransform"; prototype: "QObject" } Component { diff --git a/src/imports/testlib/plugins.qmltypes b/src/imports/testlib/plugins.qmltypes index 563778e55e..5d7ca51adc 100644 --- a/src/imports/testlib/plugins.qmltypes +++ b/src/imports/testlib/plugins.qmltypes @@ -4,11 +4,45 @@ import QtQuick.tooling 1.2 // It is used for QML tooling purposes only. // // This file was auto-generated by: -// 'qmlplugindump -nonrelocatable -noforceqtquick QtTest 1.1' +// 'qmlplugindump -nonrelocatable -noforceqtquick QtTest 1.2' Module { dependencies: ["QtQuick 2.0"] Component { + name: "QQuickTouchEventSequence" + prototype: "QObject" + Method { + name: "press" + type: "QObject*" + Parameter { name: "touchId"; type: "int" } + Parameter { name: "item"; type: "QObject"; isPointer: true } + Parameter { name: "x"; type: "double" } + Parameter { name: "y"; type: "double" } + } + Method { + name: "move" + type: "QObject*" + Parameter { name: "touchId"; type: "int" } + Parameter { name: "item"; type: "QObject"; isPointer: true } + Parameter { name: "x"; type: "double" } + Parameter { name: "y"; type: "double" } + } + Method { + name: "release" + type: "QObject*" + Parameter { name: "touchId"; type: "int" } + Parameter { name: "item"; type: "QObject"; isPointer: true } + Parameter { name: "x"; type: "double" } + Parameter { name: "y"; type: "double" } + } + Method { + name: "stationary" + type: "QObject*" + Parameter { name: "touchId"; type: "int" } + } + Method { name: "commit"; type: "QObject*" } + } + Component { name: "QuickTestEvent" prototype: "QObject" exports: ["QtTest/TestEvent 1.0"] @@ -127,6 +161,12 @@ Module { Parameter { name: "yDelta"; type: "int" } Parameter { name: "delay"; type: "int" } } + Method { + name: "touchEvent" + type: "QQuickTouchEventSequence*" + Parameter { name: "item"; type: "QObject"; isPointer: true } + } + Method { name: "touchEvent"; type: "QQuickTouchEventSequence*" } } Component { name: "QuickTestResult" diff --git a/src/imports/window/plugins.qmltypes b/src/imports/window/plugins.qmltypes index a79bd8c332..cea2a910a7 100644 --- a/src/imports/window/plugins.qmltypes +++ b/src/imports/window/plugins.qmltypes @@ -4,7 +4,7 @@ import QtQuick.tooling 1.2 // It is used for QML tooling purposes only. // // This file was auto-generated by: -// 'qmlplugindump -nonrelocatable QtQuick.Window 2.2' +// 'qmlplugindump -nonrelocatable QtQuick.Window 2.3' Module { dependencies: ["QtQuick 2.8"] @@ -24,14 +24,28 @@ Module { Component { name: "QQuickScreen" prototype: "QObject" - exports: ["QtQuick.Window/Screen 2.0"] + exports: ["QtQuick.Window/Screen 2.0", "QtQuick.Window/Screen 2.3"] isCreatable: false - exportMetaObjectRevisions: [0] + exportMetaObjectRevisions: [0, 1] attachedType: "QQuickScreenAttached" } Component { name: "QQuickScreenAttached" + prototype: "QQuickScreenInfo" + Property { name: "orientationUpdateMask"; type: "Qt::ScreenOrientations" } + Method { + name: "angleBetween" + type: "int" + Parameter { name: "a"; type: "int" } + Parameter { name: "b"; type: "int" } + } + } + Component { + name: "QQuickScreenInfo" prototype: "QObject" + exports: ["QtQuick.Window/ScreenInfo 2.3"] + isCreatable: false + exportMetaObjectRevisions: [2] Property { name: "name"; type: "string"; isReadonly: true } Property { name: "width"; type: "int"; isReadonly: true } Property { name: "height"; type: "int"; isReadonly: true } @@ -42,25 +56,18 @@ Module { Property { name: "devicePixelRatio"; type: "double"; isReadonly: true } Property { name: "primaryOrientation"; type: "Qt::ScreenOrientation"; isReadonly: true } Property { name: "orientation"; type: "Qt::ScreenOrientation"; isReadonly: true } - Property { name: "orientationUpdateMask"; type: "Qt::ScreenOrientations" } + Property { name: "virtualX"; revision: 1; type: "int"; isReadonly: true } + Property { name: "virtualY"; revision: 1; type: "int"; isReadonly: true } Signal { name: "desktopGeometryChanged" } - Method { - name: "angleBetween" - type: "int" - Parameter { name: "a"; type: "int" } - Parameter { name: "b"; type: "int" } - } + Signal { name: "virtualXChanged"; revision: 1 } + Signal { name: "virtualYChanged"; revision: 1 } } Component { name: "QQuickWindow" defaultProperty: "data" prototype: "QWindow" - exports: [ - "QtQuick.Window/Window 2.0", - "QtQuick.Window/Window 2.1", - "QtQuick.Window/Window 2.2" - ] - exportMetaObjectRevisions: [0, 1, 2] + exports: ["QtQuick.Window/Window 2.0"] + exportMetaObjectRevisions: [0] Enum { name: "SceneGraphError" values: { @@ -125,11 +132,16 @@ Module { name: "QQuickWindowQmlImpl" defaultProperty: "data" prototype: "QQuickWindow" - exports: ["QtQuick.Window/Window 2.1", "QtQuick.Window/Window 2.2"] - exportMetaObjectRevisions: [0, 1] + exports: [ + "QtQuick.Window/Window 2.1", + "QtQuick.Window/Window 2.2", + "QtQuick.Window/Window 2.3" + ] + exportMetaObjectRevisions: [0, 1, 2] attachedType: "QQuickWindowAttached" Property { name: "visible"; type: "bool" } Property { name: "visibility"; type: "Visibility" } + Property { name: "screen"; revision: 2; type: "QObject"; isPointer: true } Signal { name: "visibleChanged" Parameter { name: "arg"; type: "bool" } @@ -138,6 +150,7 @@ Module { name: "visibilityChanged" Parameter { name: "visibility"; type: "QWindow::Visibility" } } + Signal { name: "screenChanged"; revision: 2 } } Component { name: "QWindow" @@ -153,6 +166,13 @@ Module { "FullScreen": 5 } } + Enum { + name: "AncestorMode" + values: { + "ExcludeTransients": 0, + "IncludeTransients": 1 + } + } Property { name: "title"; type: "string" } Property { name: "modality"; type: "Qt::WindowModality" } Property { name: "flags"; type: "Qt::WindowFlags" } diff --git a/src/particles/particles.pri b/src/particles/particles.pri index af71634ec6..576d826903 100644 --- a/src/particles/particles.pri +++ b/src/particles/particles.pri @@ -1,6 +1,5 @@ HEADERS += \ $$PWD/qquickangledirection_p.h \ - $$PWD/qquickcustomparticle_p.h \ $$PWD/qquickcustomaffector_p.h \ $$PWD/qquickellipseextruder_p.h \ $$PWD/qquicktrailemitter_p.h \ @@ -33,7 +32,6 @@ HEADERS += \ SOURCES += \ $$PWD/qquickangledirection.cpp \ - $$PWD/qquickcustomparticle.cpp \ $$PWD/qquickcustomaffector.cpp \ $$PWD/qquickellipseextruder.cpp \ $$PWD/qquicktrailemitter.cpp \ @@ -63,6 +61,14 @@ SOURCES += \ $$PWD/qquickparticlegroup.cpp \ $$PWD/qquickgroupgoal.cpp +qtConfig(quick-shadereffect) { +HEADERS += \ + $$PWD/qquickcustomparticle_p.h + +SOURCES += \ + $$PWD/qquickcustomparticle.cpp +} + OTHER_FILES += \ $$PWD/shaders/customparticletemplate.vert \ $$PWD/shaders/customparticle.vert \ diff --git a/src/particles/qquickparticlesmodule.cpp b/src/particles/qquickparticlesmodule.cpp index accdb668de..03f47a3961 100644 --- a/src/particles/qquickparticlesmodule.cpp +++ b/src/particles/qquickparticlesmodule.cpp @@ -37,8 +37,12 @@ ** ****************************************************************************/ +#include <private/qtquickglobal_p.h> + #include "qquickangledirection_p.h" +#if QT_CONFIG(quick_shadereffect) #include "qquickcustomparticle_p.h" +#endif #include "qquickellipseextruder_p.h" #include "qquicktrailemitter_p.h" #include "qquickfriction_p.h" @@ -84,7 +88,9 @@ void QQuickParticlesModule::defineModule() qmlRegisterType<QQuickParticleGroup>(uri, 2, 0, "ParticleGroup"); qmlRegisterType<QQuickImageParticle>(uri, 2, 0, "ImageParticle"); +#if QT_CONFIG(quick_shadereffect) qmlRegisterType<QQuickCustomParticle>(uri, 2, 0, "CustomParticle"); +#endif qmlRegisterType<QQuickItemParticle>(uri, 2, 0, "ItemParticle"); qmlRegisterType<QQuickParticleEmitter>(uri, 2, 0, "Emitter"); diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp index b76cd8e65a..430ba4f255 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp +++ b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp @@ -95,7 +95,7 @@ QVector<QV4::Heap::ExecutionContext::ContextType> QV4DataCollector::getScopeType QV4::ScopedContext it(scope, sctxt); for (; it; it = it->d()->outer) - types.append(it->d()->type); + types.append(QV4::Heap::ExecutionContext::ContextType(it->d()->type)); return types; } @@ -118,15 +118,18 @@ int QV4DataCollector::encodeScopeType(QV4::Heap::ExecutionContext::ContextType s } } -QV4DataCollector::QV4DataCollector(QV4::ExecutionEngine *engine) : m_engine(engine) +QV4DataCollector::QV4DataCollector(QV4::ExecutionEngine *engine) + : m_engine(engine), m_namesAsObjects(true), m_redundantRefs(true) { m_values.set(engine, engine->newArrayObject()); } +// TODO: Directly call addRef() once we don't need to support redundantRefs anymore QV4DataCollector::Ref QV4DataCollector::collect(const QV4::ScopedValue &value) { Ref ref = addRef(value); - m_collectedRefs.append(ref); + if (m_redundantRefs) + m_collectedRefs.append(ref); return ref; } @@ -184,30 +187,48 @@ const QV4::Object *collectProperty(const QV4::ScopedValue &value, QV4::Execution case QV4::Value::Integer_Type: dict.insert(valueKey, value->integerValue()); return 0; - default: // double - dict.insert(valueKey, value->doubleValue()); + default: {// double + const double val = value->doubleValue(); + if (qIsFinite(val)) + dict.insert(valueKey, val); + else if (qIsNaN(val)) + dict.insert(valueKey, QStringLiteral("NaN")); + else if (val < 0) + dict.insert(valueKey, QStringLiteral("-Infinity")); + else + dict.insert(valueKey, QStringLiteral("Infinity")); return 0; } + } } -QJsonObject QV4DataCollector::lookupRef(Ref ref) +QJsonObject QV4DataCollector::lookupRef(Ref ref, bool deep) { QJsonObject dict; - if (lookupSpecialRef(ref, &dict)) - return dict; + + if (m_namesAsObjects) { + if (lookupSpecialRef(ref, &dict)) + return dict; + } + + if (m_redundantRefs) + deep = true; dict.insert(QStringLiteral("handle"), qint64(ref)); QV4::Scope scope(engine()); QV4::ScopedValue value(scope, getValue(ref)); - if (const QV4::Object *o = collectProperty(value, engine(), dict)) - dict.insert(QStringLiteral("properties"), collectProperties(o)); + const QV4::Object *object = collectProperty(value, engine(), dict); + if (deep && object) + dict.insert(QStringLiteral("properties"), collectProperties(object)); return dict; } +// TODO: Drop this method once we don't need to support namesAsObjects anymore QV4DataCollector::Ref QV4DataCollector::addFunctionRef(const QString &functionName) { + Q_ASSERT(m_namesAsObjects); Ref ref = addRef(QV4::Primitive::emptyValue(), false); QJsonObject dict; @@ -220,8 +241,10 @@ QV4DataCollector::Ref QV4DataCollector::addFunctionRef(const QString &functionNa return ref; } +// TODO: Drop this method once we don't need to support namesAsObjects anymore QV4DataCollector::Ref QV4DataCollector::addScriptRef(const QString &scriptName) { + Q_ASSERT(m_namesAsObjects); Ref ref = addRef(QV4::Primitive::emptyValue(), false); QJsonObject dict; @@ -250,6 +273,7 @@ bool QV4DataCollector::collectScope(QJsonObject *dict, int frameNr, int scopeNr) if (!ctxt) return false; + Refs collectedRefs; QV4::ScopedValue v(scope); int nFormals = ctxt->formalCount(); for (unsigned i = 0, ei = nFormals; i != ei; ++i) { @@ -258,7 +282,7 @@ bool QV4DataCollector::collectScope(QJsonObject *dict, int frameNr, int scopeNr) qName = name->string; names.append(qName); v = ctxt->argument(i); - collect(v); + collectedRefs.append(collect(v)); } for (unsigned i = 0, ei = ctxt->variableCount(); i != ei; ++i) { @@ -267,21 +291,26 @@ bool QV4DataCollector::collectScope(QJsonObject *dict, int frameNr, int scopeNr) qName = name->string; names.append(qName); v = ctxt->d()->locals[i]; - collect(v); + collectedRefs.append(collect(v)); } QV4::ScopedObject scopeObject(scope, engine()->newObject()); - Q_ASSERT(names.size() == m_collectedRefs.size()); + Q_ASSERT(names.size() == collectedRefs.size()); QV4::ScopedString propName(scope); - for (int i = 0, ei = m_collectedRefs.size(); i != ei; ++i) { + for (int i = 0, ei = collectedRefs.size(); i != ei; ++i) { propName = engine()->newString(names.at(i)); - scopeObject->put(propName, QV4::Value::fromReturnedValue(getValue(m_collectedRefs.at(i)))); + scopeObject->put(propName, QV4::Value::fromReturnedValue(getValue(collectedRefs.at(i)))); } Ref scopeObjectRef = addRef(scopeObject); - dict->insert(QStringLiteral("ref"), qint64(scopeObjectRef)); - m_collectedRefs.append(scopeObjectRef); + if (m_redundantRefs) { + dict->insert(QStringLiteral("ref"), qint64(scopeObjectRef)); + m_collectedRefs.append(scopeObjectRef); + } else { + *dict = lookupRef(scopeObjectRef, true); + } + return true; } @@ -293,15 +322,16 @@ QJsonObject toRef(QV4DataCollector::Ref ref) { QJsonObject QV4DataCollector::buildFrame(const QV4::StackFrame &stackFrame, int frameNr) { - QV4DataCollector::Ref ref; - QJsonObject frame; frame[QLatin1String("index")] = frameNr; frame[QLatin1String("debuggerFrame")] = false; - ref = addFunctionRef(stackFrame.function); - frame[QLatin1String("func")] = toRef(ref); - ref = addScriptRef(stackFrame.source); - frame[QLatin1String("script")] = toRef(ref); + if (m_namesAsObjects) { + frame[QLatin1String("func")] = toRef(addFunctionRef(stackFrame.function)); + frame[QLatin1String("script")] = toRef(addScriptRef(stackFrame.source)); + } else { + frame[QLatin1String("func")] = stackFrame.function; + frame[QLatin1String("script")] = stackFrame.source; + } frame[QLatin1String("line")] = stackFrame.line - 1; if (stackFrame.column >= 0) frame[QLatin1String("column")] = stackFrame.column; @@ -340,15 +370,17 @@ QJsonObject QV4DataCollector::buildFrame(const QV4::StackFrame &stackFrame, int return frame; } +// TODO: Drop this method once we don't need to support redundantRefs anymore QJsonArray QV4DataCollector::flushCollectedRefs() { + Q_ASSERT(m_redundantRefs); QJsonArray refs; std::sort(m_collectedRefs.begin(), m_collectedRefs.end()); for (int i = 0, ei = m_collectedRefs.size(); i != ei; ++i) { QV4DataCollector::Ref ref = m_collectedRefs.at(i); if (i > 0 && ref == m_collectedRefs.at(i - 1)) continue; - refs.append(lookupRef(ref)); + refs.append(lookupRef(ref, true)); } m_collectedRefs.clear(); @@ -360,6 +392,8 @@ void QV4DataCollector::clear() m_values.set(engine(), engine()->newArrayObject()); m_collectedRefs.clear(); m_specialRefs.clear(); + m_namesAsObjects = true; + m_redundantRefs = true; } QV4DataCollector::Ref QV4DataCollector::addRef(QV4::Value value, bool deduplicate) @@ -403,8 +437,10 @@ QV4::ReturnedValue QV4DataCollector::getValue(Ref ref) return array->getIndexed(ref, Q_NULLPTR); } +// TODO: Drop this method once we don't need to support namesAsObjects anymore bool QV4DataCollector::lookupSpecialRef(Ref ref, QJsonObject *dict) { + Q_ASSERT(m_namesAsObjects); SpecialRefs::const_iterator it = m_specialRefs.constFind(ref); if (it == m_specialRefs.cend()) return false; @@ -442,7 +478,8 @@ QJsonObject QV4DataCollector::collectAsJson(const QString &name, const QV4::Scop if (value->isManaged() && !value->isString()) { Ref ref = addRef(value); dict.insert(QStringLiteral("ref"), qint64(ref)); - m_collectedRefs.append(ref); + if (m_redundantRefs) + m_collectedRefs.append(ref); } collectProperty(value, engine(), dict); diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h index 09a0d683ba..de12e8d527 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h +++ b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h @@ -66,34 +66,42 @@ public: QV4DataCollector(QV4::ExecutionEngine *engine); - Ref collect(const QV4::ScopedValue &value); - Ref addFunctionRef(const QString &functionName); - Ref addScriptRef(const QString &scriptName); + Ref collect(const QV4::ScopedValue &value); // only for redundantRefs + Ref addFunctionRef(const QString &functionName); // only for namesAsObjects + Ref addScriptRef(const QString &scriptName); // only for namesAsObjects + + void setNamesAsObjects(bool namesAsObjects) { m_namesAsObjects = namesAsObjects; } + bool namesAsObjects() const { return m_namesAsObjects; } + + void setRedundantRefs(bool redundantRefs) { m_redundantRefs = redundantRefs; } + bool redundantRefs() const { return m_redundantRefs; } bool isValidRef(Ref ref) const; - QJsonObject lookupRef(Ref ref); + QJsonObject lookupRef(Ref ref, bool deep); bool collectScope(QJsonObject *dict, int frameNr, int scopeNr); QJsonObject buildFrame(const QV4::StackFrame &stackFrame, int frameNr); QV4::ExecutionEngine *engine() const { return m_engine; } - QJsonArray flushCollectedRefs(); + QJsonArray flushCollectedRefs(); // only for redundantRefs void clear(); private: Ref addRef(QV4::Value value, bool deduplicate = true); QV4::ReturnedValue getValue(Ref ref); - bool lookupSpecialRef(Ref ref, QJsonObject *dict); + bool lookupSpecialRef(Ref ref, QJsonObject *dict); // only for namesAsObjects QJsonArray collectProperties(const QV4::Object *object); QJsonObject collectAsJson(const QString &name, const QV4::ScopedValue &value); void collectArgumentsInContext(); QV4::ExecutionEngine *m_engine; - Refs m_collectedRefs; + Refs m_collectedRefs; // only for redundantRefs QV4::PersistentValue m_values; - typedef QHash<Ref, QJsonObject> SpecialRefs; - SpecialRefs m_specialRefs; + typedef QHash<Ref, QJsonObject> SpecialRefs; // only for namesAsObjects + SpecialRefs m_specialRefs; // only for namesAsObjects + bool m_namesAsObjects; + bool m_redundantRefs; }; QT_END_NAMESPACE diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp index d5fadad50a..107ec60943 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp +++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp @@ -151,7 +151,7 @@ void BacktraceJob::run() result.insert(QStringLiteral("toFrame"), fromFrame + frameArray.size()); result.insert(QStringLiteral("frames"), frameArray); } - collectedRefs = collector->flushCollectedRefs(); + flushRedundantRefs(); } FrameJob::FrameJob(QV4DataCollector *collector, int frameNr) : @@ -166,7 +166,7 @@ void FrameJob::run() success = false; } else { result = collector->buildFrame(frames[frameNr], frameNr); - collectedRefs = collector->flushCollectedRefs(); + flushRedundantRefs(); success = true; } } @@ -196,7 +196,7 @@ void ScopeJob::run() result[QLatin1String("index")] = scopeNr; result[QLatin1String("frameIndex")] = frameNr; result[QLatin1String("object")] = object; - collectedRefs = collector->flushCollectedRefs(); + flushRedundantRefs(); } bool ScopeJob::wasSuccessful() const @@ -226,9 +226,9 @@ void ValueLookupJob::run() exception = QString::fromLatin1("Invalid Ref: %1").arg(ref); break; } - result[QString::number(ref)] = collector->lookupRef(ref); + result[QString::number(ref)] = collector->lookupRef(ref, true); } - collectedRefs = collector->flushCollectedRefs(); + flushRedundantRefs(); if (scopeObject) engine->popContext(); } @@ -249,8 +249,9 @@ void ExpressionEvalJob::handleResult(QV4::ScopedValue &value) { if (hasExeption()) exception = value->toQStringNoThrow(); - result = collector->lookupRef(collector->collect(value)); - collectedRefs = collector->flushCollectedRefs(); + result = collector->lookupRef(collector->collect(value), true); + if (collector->redundantRefs()) + collectedRefs = collector->flushCollectedRefs(); } const QString &ExpressionEvalJob::exceptionMessage() const @@ -263,8 +264,10 @@ const QJsonObject &ExpressionEvalJob::returnValue() const return result; } +// TODO: Drop this method once we don't need to support redundantRefs anymore const QJsonArray &ExpressionEvalJob::refs() const { + Q_ASSERT(collector->redundantRefs()); return collectedRefs; } diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.h b/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.h index 00d3e6206a..eca8710e15 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.h +++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.h @@ -78,11 +78,24 @@ class CollectJob : public QV4DebugJob protected: QV4DataCollector *collector; QJsonObject result; - QJsonArray collectedRefs; + QJsonArray collectedRefs; // only for redundantRefs + + void flushRedundantRefs() + { + if (collector->redundantRefs()) + collectedRefs = collector->flushCollectedRefs(); + } + public: CollectJob(QV4DataCollector *collector) : collector(collector) {} const QJsonObject &returnValue() const { return result; } - const QJsonArray &refs() const { return collectedRefs; } + + // TODO: Drop this method once we don't need to support redundantRefs anymore + const QJsonArray &refs() const + { + Q_ASSERT(collector->redundantRefs()); + return collectedRefs; + } }; class BacktraceJob: public CollectJob @@ -133,7 +146,7 @@ class ExpressionEvalJob: public JavaScriptJob QV4DataCollector *collector; QString exception; QJsonObject result; - QJsonArray collectedRefs; + QJsonArray collectedRefs; // only for redundantRefs public: ExpressionEvalJob(QV4::ExecutionEngine *engine, int frameNr, int context, @@ -141,7 +154,7 @@ public: void handleResult(QV4::ScopedValue &value) override; const QString &exceptionMessage() const; const QJsonObject &returnValue() const; - const QJsonArray &refs() const; + const QJsonArray &refs() const; // only for redundantRefs }; class GatherSourcesJob: public QV4DebugJob diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp index 1d2cc092dc..68cdb57a44 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp +++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp @@ -121,8 +121,18 @@ protected: response.insert(QStringLiteral("running"), debugService->debuggerAgent.isRunning()); } + QV4DataCollector *saneCollector(QV4Debugger *debugger) + { + QV4DataCollector *collector = debugger->collector(); + collector->setNamesAsObjects(debugService->clientRequiresNamesAsObjects()); + collector->setRedundantRefs(debugService->clientRequiresRedundantRefs()); + return collector; + } + + // TODO: drop this method once we don't need to support redundantRefs anymore. void addRefs(const QJsonArray &refs) { + Q_ASSERT(debugService->clientRequiresRedundantRefs()); response.insert(QStringLiteral("refs"), refs); } @@ -286,7 +296,7 @@ public: return; } - BacktraceJob job(debugger->collector(), fromFrame, toFrame); + BacktraceJob job(saneCollector(debugger), fromFrame, toFrame); debugger->runInEngine(&job); // response: @@ -295,7 +305,8 @@ public: addSuccess(true); addRunning(); addBody(job.returnValue()); - addRefs(job.refs()); + if (debugService->clientRequiresRedundantRefs()) + addRefs(job.refs()); } }; @@ -322,7 +333,7 @@ public: return; } - FrameJob job(debugger->collector(), frameNr); + FrameJob job(saneCollector(debugger), frameNr); debugger->runInEngine(&job); if (!job.wasSuccessful()) { createErrorResponse(QStringLiteral("frame retrieval failed")); @@ -337,7 +348,8 @@ public: addSuccess(true); addRunning(); addBody(job.returnValue()); - addRefs(job.refs()); + if (debugService->clientRequiresRedundantRefs()) + addRefs(job.refs()); } }; @@ -369,7 +381,7 @@ public: return; } - ScopeJob job(debugger->collector(), frameNr, scopeNr); + ScopeJob job(saneCollector(debugger), frameNr, scopeNr); debugger->runInEngine(&job); if (!job.wasSuccessful()) { createErrorResponse(QStringLiteral("scope retrieval failed")); @@ -382,7 +394,8 @@ public: addSuccess(true); addRunning(); addBody(job.returnValue()); - addRefs(job.refs()); + if (debugService->clientRequiresRedundantRefs()) + addRefs(job.refs()); } }; @@ -410,7 +423,7 @@ public: debugger = debuggers.first(); } - ValueLookupJob job(handles, debugger->collector()); + ValueLookupJob job(handles, saneCollector(debugger)); debugger->runInEngine(&job); if (!job.exceptionMessage().isEmpty()) { createErrorResponse(job.exceptionMessage()); @@ -421,7 +434,8 @@ public: addSuccess(true); addRunning(); addBody(job.returnValue()); - addRefs(job.refs()); + if (debugService->clientRequiresRedundantRefs()) + addRefs(job.refs()); } } }; @@ -630,7 +644,7 @@ public: } ExpressionEvalJob job(debugger->engine(), frame, context, expression, - debugger->collector()); + saneCollector(debugger)); debugger->runInEngine(&job); if (job.hasExeption()) { createErrorResponse(job.exceptionMessage()); @@ -640,7 +654,8 @@ public: addSuccess(true); addRunning(); addBody(job.returnValue()); - addRefs(job.refs()); + if (debugService->clientRequiresRedundantRefs()) + addRefs(job.refs()); } } }; @@ -662,7 +677,7 @@ V8CommandHandler *QV4DebugServiceImpl::v8CommandHandler(const QString &command) QV4DebugServiceImpl::QV4DebugServiceImpl(QObject *parent) : QQmlConfigurableDebugService<QV4DebugService>(1, parent), - debuggerAgent(this), theSelectedFrame(0), + debuggerAgent(this), theSelectedFrame(0), redundantRefs(true), namesAsObjects(true), unknownV8CommandHandler(new UnknownV8CommandHandler) { addHandler(new V8VersionRequest); @@ -766,6 +781,14 @@ void QV4DebugServiceImpl::messageReceived(const QByteArray &message) TRACE_PROTOCOL(qDebug() << "... type:" << type); if (type == V4_CONNECT) { + QJsonObject parameters = QJsonDocument::fromJson(payload).object(); + namesAsObjects = true; + redundantRefs = true; + if (parameters.contains("namesAsObjects")) + namesAsObjects = parameters.value("namesAsObjects").toBool(); + if (parameters.contains("redundantRefs")) + redundantRefs = parameters.value("redundantRefs").toBool(); + emit messageToClient(name(), packMessage(type)); stopWaiting(); } else if (type == V4_PAUSE) { diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h index 69e32189b8..bb13890ae4 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h +++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h @@ -86,6 +86,9 @@ public: int selectedFrame() const; void selectFrame(int frameNr); + bool clientRequiresRedundantRefs() const { return redundantRefs; } + bool clientRequiresNamesAsObjects() const { return namesAsObjects; } + QV4DebuggerAgent debuggerAgent; protected: @@ -105,6 +108,9 @@ private: static int sequence; int theSelectedFrame; + bool redundantRefs; + bool namesAsObjects; + void addHandler(V8CommandHandler* handler); QHash<QString, V8CommandHandler*> handlers; QScopedPointer<UnknownV8CommandHandler> unknownV8CommandHandler; diff --git a/src/plugins/scenegraph/openvg/openvg.pro b/src/plugins/scenegraph/openvg/openvg.pro index 6d5b190b37..43c2636343 100644 --- a/src/plugins/scenegraph/openvg/openvg.pro +++ b/src/plugins/scenegraph/openvg/openvg.pro @@ -31,7 +31,6 @@ HEADERS += \ qsgopenvghelpers.h \ qsgopenvgfontglyphcache.h \ qsgopenvgpainternode.h \ - qsgopenvgspritenode.h \ qsgopenvgrenderable.h \ qopenvgoffscreensurface.h @@ -52,6 +51,10 @@ SOURCES += \ qsgopenvghelpers.cpp \ qsgopenvgfontglyphcache.cpp \ qsgopenvgpainternode.cpp \ - qsgopenvgspritenode.cpp \ qsgopenvgrenderable.cpp \ qopenvgoffscreensurface.cpp + +qtConfig(quick-sprite) { + HEADERS += qsgopenvgspritenode.h + SOURCES += qsgopenvgspritenode.cpp +} diff --git a/src/plugins/scenegraph/openvg/qsgopenvgcontext.cpp b/src/plugins/scenegraph/openvg/qsgopenvgcontext.cpp index 41fce7c7fc..76ebb7c4ee 100644 --- a/src/plugins/scenegraph/openvg/qsgopenvgcontext.cpp +++ b/src/plugins/scenegraph/openvg/qsgopenvgcontext.cpp @@ -45,7 +45,9 @@ #include "qsgopenvgglyphnode_p.h" #include "qsgopenvgfontglyphcache.h" #include "qsgopenvgpainternode.h" +#if QT_CONFIG(quick_sprite) #include "qsgopenvgspritenode.h" +#endif #include "qopenvgcontext_p.h" @@ -171,11 +173,12 @@ int QSGOpenVGRenderContext::maxTextureSize() const return qMin(width, height); } - +#if QT_CONFIG(quick_sprite) QSGSpriteNode *QSGOpenVGContext::createSpriteNode() { return new QSGOpenVGSpriteNode(); } +#endif QSGRendererInterface *QSGOpenVGContext::rendererInterface(QSGRenderContext *renderContext) { diff --git a/src/plugins/scenegraph/openvg/qsgopenvgcontext_p.h b/src/plugins/scenegraph/openvg/qsgopenvgcontext_p.h index fa9939a253..31a1e8643f 100644 --- a/src/plugins/scenegraph/openvg/qsgopenvgcontext_p.h +++ b/src/plugins/scenegraph/openvg/qsgopenvgcontext_p.h @@ -95,7 +95,9 @@ public: QSurfaceFormat defaultSurfaceFormat() const override; QSGInternalRectangleNode *createInternalRectangleNode() override; QSGInternalImageNode *createInternalImageNode() override; +#if QT_CONFIG(quick_sprite) QSGSpriteNode *createSpriteNode() override; +#endif QSGRendererInterface *rendererInterface(QSGRenderContext *renderContext) override; }; diff --git a/src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.cpp b/src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.cpp index 8aa179f705..41606c653a 100644 --- a/src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.cpp +++ b/src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.cpp @@ -43,7 +43,9 @@ #include "qsgopenvgpublicnodes.h" #include "qsgopenvgglyphnode_p.h" #include "qsgopenvgpainternode.h" +#if QT_CONFIG(quick_sprite) #include "qsgopenvgspritenode.h" +#endif #include "qsgopenvgrenderable.h" #include "qopenvgcontext_p.h" @@ -209,6 +211,7 @@ void QSGOpenVGNodeVisitor::endVisit(QSGRootNode *) { } +#if QT_CONFIG(quick_sprite) bool QSGOpenVGNodeVisitor::visit(QSGSpriteNode *node) { renderRenderableNode(static_cast<QSGOpenVGSpriteNode*>(node)); @@ -218,6 +221,7 @@ bool QSGOpenVGNodeVisitor::visit(QSGSpriteNode *node) void QSGOpenVGNodeVisitor::endVisit(QSGSpriteNode *) { } +#endif bool QSGOpenVGNodeVisitor::visit(QSGRenderNode *) { diff --git a/src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.h b/src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.h index 4805d63024..c6461ca67d 100644 --- a/src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.h +++ b/src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.h @@ -73,8 +73,10 @@ public: void endVisit(QSGGlyphNode *) override; bool visit(QSGRootNode *) override; void endVisit(QSGRootNode *) override; +#if QT_CONFIG(quick_sprite) bool visit(QSGSpriteNode *) override; void endVisit(QSGSpriteNode *) override; +#endif bool visit(QSGRenderNode *) override; void endVisit(QSGRenderNode *) override; diff --git a/src/plugins/scenegraph/openvg/qsgopenvgspritenode.h b/src/plugins/scenegraph/openvg/qsgopenvgspritenode.h index 3ade2ef8ad..d47b389a0b 100644 --- a/src/plugins/scenegraph/openvg/qsgopenvgspritenode.h +++ b/src/plugins/scenegraph/openvg/qsgopenvgspritenode.h @@ -43,6 +43,8 @@ #include <private/qsgadaptationlayer_p.h> #include "qsgopenvgrenderable.h" +QT_REQUIRE_CONFIG(quick_sprite); + QT_BEGIN_NAMESPACE class QSGOpenVGTexture; class QSGOpenVGSpriteNode : public QSGSpriteNode, public QSGOpenVGRenderable diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp index ecec0cf49a..3234e7ee63 100644 --- a/src/qml/compiler/qv4codegen.cpp +++ b/src/qml/compiler/qv4codegen.cpp @@ -1497,7 +1497,7 @@ IR::Expr *Codegen::identifier(const QString &name, int line, int col) IR::Function *f = _function; while (f && e->parent) { - if (f->insideWithOrCatch || (f->isNamedExpression && f->name == name)) + if (f->insideWithOrCatch || (f->isNamedExpression && QStringRef(f->name) == name)) return _block->NAME(name, line, col); int index = e->findMember(name); @@ -1508,7 +1508,7 @@ IR::Expr *Codegen::identifier(const QString &name, int line, int col) al->isArgumentsOrEval = true; return al; } - const int argIdx = f->indexOfArgument(&name); + const int argIdx = f->indexOfArgument(QStringRef(&name)); if (argIdx != -1) return _block->ARG(argIdx, scope); diff --git a/src/qml/compiler/qv4compilationunitmapper.cpp b/src/qml/compiler/qv4compilationunitmapper.cpp index 1ae0fb190c..d94f7ac238 100644 --- a/src/qml/compiler/qv4compilationunitmapper.cpp +++ b/src/qml/compiler/qv4compilationunitmapper.cpp @@ -59,7 +59,7 @@ CompilationUnitMapper::~CompilationUnitMapper() close(); } -bool CompilationUnitMapper::verifyHeader(const CompiledData::Unit *header, const QString &sourcePath, QString *errorString) +bool CompilationUnitMapper::verifyHeader(const CompiledData::Unit *header, QDateTime sourceTimeStamp, QString *errorString) { if (strncmp(header->magic, CompiledData::magic_str, sizeof(header->magic))) { *errorString = QStringLiteral("Magic bytes in the header do not match"); @@ -77,11 +77,6 @@ bool CompilationUnitMapper::verifyHeader(const CompiledData::Unit *header, const } if (header->sourceTimeStamp) { - QFileInfo sourceCode(sourcePath); - QDateTime sourceTimeStamp; - if (sourceCode.exists()) - sourceTimeStamp = sourceCode.lastModified(); - // Files from the resource system do not have any time stamps, so fall back to the application // executable. if (!sourceTimeStamp.isValid()) diff --git a/src/qml/compiler/qv4compilationunitmapper_p.h b/src/qml/compiler/qv4compilationunitmapper_p.h index 5b6939f1cf..b24f98df7c 100644 --- a/src/qml/compiler/qv4compilationunitmapper_p.h +++ b/src/qml/compiler/qv4compilationunitmapper_p.h @@ -68,11 +68,11 @@ public: CompilationUnitMapper(); ~CompilationUnitMapper(); - CompiledData::Unit *open(const QString &cacheFilePath, const QString &sourcePath, QString *errorString); + CompiledData::Unit *open(const QString &cacheFilePath, const QDateTime &sourceTimeStamp, QString *errorString); void close(); private: - static bool verifyHeader(const QV4::CompiledData::Unit *header, const QString &sourcePath, QString *errorString); + static bool verifyHeader(const QV4::CompiledData::Unit *header, QDateTime sourceTimeStamp, QString *errorString); #if defined(Q_OS_UNIX) size_t length; diff --git a/src/qml/compiler/qv4compilationunitmapper_unix.cpp b/src/qml/compiler/qv4compilationunitmapper_unix.cpp index 1aa3e05f5f..38dabc41cf 100644 --- a/src/qml/compiler/qv4compilationunitmapper_unix.cpp +++ b/src/qml/compiler/qv4compilationunitmapper_unix.cpp @@ -43,6 +43,7 @@ #include <functional> #include <private/qcore_unix_p.h> #include <private/qdeferredcleanup_p.h> +#include <QDateTime> #include "qv4compileddata_p.h" @@ -50,7 +51,7 @@ QT_BEGIN_NAMESPACE using namespace QV4; -CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, const QString &sourcePath, QString *errorString) +CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, const QDateTime &sourceTimeStamp, QString *errorString) { close(); @@ -72,7 +73,7 @@ CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, co return nullptr; } - if (!verifyHeader(&header, sourcePath, errorString)) + if (!verifyHeader(&header, sourceTimeStamp, errorString)) return nullptr; // Data structure and qt version matched, so now we can access the rest of the file safely. diff --git a/src/qml/compiler/qv4compilationunitmapper_win.cpp b/src/qml/compiler/qv4compilationunitmapper_win.cpp index 37cac846a0..d7a93ae233 100644 --- a/src/qml/compiler/qv4compilationunitmapper_win.cpp +++ b/src/qml/compiler/qv4compilationunitmapper_win.cpp @@ -49,7 +49,7 @@ QT_BEGIN_NAMESPACE using namespace QV4; -CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, const QString &sourcePath, QString *errorString) +CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, const QDateTime &sourceTimeStamp, QString *errorString) { close(); @@ -87,7 +87,7 @@ CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, co return nullptr; } - if (!verifyHeader(&header, sourcePath, errorString)) + if (!verifyHeader(&header, sourceTimeStamp, errorString)) return nullptr; const uint mappingFlags = header.flags & QV4::CompiledData::Unit::ContainsMachineCode diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp index 0cee2996d7..edb5edb0bc 100644 --- a/src/qml/compiler/qv4compileddata.cpp +++ b/src/qml/compiler/qv4compileddata.cpp @@ -95,7 +95,6 @@ static QString cacheFilePath(const QUrl &url) #ifndef V4_BOOTSTRAP CompilationUnit::CompilationUnit() : data(0) - , runtimeStrings(0) , engine(0) , runtimeLookups(0) , runtimeRegularExpressions(0) @@ -351,7 +350,7 @@ bool CompilationUnit::verifyChecksum(QQmlEngine *engine, sizeof(data->dependencyMD5Checksum)) == 0; } -bool CompilationUnit::loadFromDisk(const QUrl &url, EvalISelFactory *iselFactory, QString *errorString) +bool CompilationUnit::loadFromDisk(const QUrl &url, const QDateTime &sourceTimeStamp, EvalISelFactory *iselFactory, QString *errorString) { if (!QQmlFile::isLocalFile(url)) { *errorString = QStringLiteral("File has to be a local file."); @@ -361,7 +360,7 @@ bool CompilationUnit::loadFromDisk(const QUrl &url, EvalISelFactory *iselFactory const QString sourcePath = QQmlFile::urlToLocalFileOrQrc(url); QScopedPointer<CompilationUnitMapper> cacheFile(new CompilationUnitMapper()); - CompiledData::Unit *mappedUnit = cacheFile->open(cacheFilePath(url), sourcePath, errorString); + CompiledData::Unit *mappedUnit = cacheFile->open(cacheFilePath(url), sourceTimeStamp, errorString); if (!mappedUnit) return false; @@ -784,7 +783,7 @@ void Unit::generateChecksum() #ifndef V4_BOOTSTRAP QCryptographicHash hash(QCryptographicHash::Md5); - const int checksummableDataOffset = qOffsetOf(QV4::CompiledData::Unit, md5Checksum) + sizeof(md5Checksum); + const int checksummableDataOffset = offsetof(QV4::CompiledData::Unit, md5Checksum) + sizeof(md5Checksum); const char *dataPtr = reinterpret_cast<const char *>(this) + checksummableDataOffset; hash.addData(dataPtr, unitSize - checksummableDataOffset); diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h index 48c78c6a01..9c21d5e9ae 100644 --- a/src/qml/compiler/qv4compileddata_p.h +++ b/src/qml/compiler/qv4compileddata_p.h @@ -71,7 +71,7 @@ QT_BEGIN_NAMESPACE // Bump this whenever the compiler data structures change in an incompatible way. -#define QV4_DATA_STRUCTURE_VERSION 0x09 +#define QV4_DATA_STRUCTURE_VERSION 0x11 class QIODevice; class QQmlPropertyCache; @@ -796,11 +796,15 @@ typedef QVector<QQmlPropertyData*> BindingPropertyData; // This is how this hooks into the existing structures: -//VM::Function -// CompilationUnit * (for functions that need to clean up) -// CompiledData::Function *compiledFunction +struct Q_QML_PRIVATE_EXPORT CompilationUnitBase +{ + QV4::Heap::String **runtimeStrings = 0; // Array +}; -struct Q_QML_PRIVATE_EXPORT CompilationUnit : public QQmlRefCount +Q_STATIC_ASSERT(std::is_standard_layout<CompilationUnitBase>::value); +Q_STATIC_ASSERT(offsetof(CompilationUnitBase, runtimeStrings) == 0); + +struct Q_QML_PRIVATE_EXPORT CompilationUnit : public CompilationUnitBase, public QQmlRefCount { #ifdef V4_BOOTSTRAP CompilationUnit() @@ -817,8 +821,6 @@ struct Q_QML_PRIVATE_EXPORT CompilationUnit : public QQmlRefCount // Called only when building QML, when we build the header for JS first and append QML data virtual QV4::CompiledData::Unit *createUnitData(QmlIR::Document *irDocument); - QV4::Heap::String **runtimeStrings; // Array - #ifndef V4_BOOTSTRAP ExecutionEngine *engine; @@ -898,7 +900,7 @@ struct Q_QML_PRIVATE_EXPORT CompilationUnit : public QQmlRefCount void destroy() Q_DECL_OVERRIDE; - bool loadFromDisk(const QUrl &url, EvalISelFactory *iselFactory, QString *errorString); + bool loadFromDisk(const QUrl &url, const QDateTime &sourceTimeStamp, EvalISelFactory *iselFactory, QString *errorString); protected: virtual void linkBackendToEngine(QV4::ExecutionEngine *engine) = 0; diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp index e9709f5fb4..b81d724fe7 100644 --- a/src/qml/compiler/qv4compiler.cpp +++ b/src/qml/compiler/qv4compiler.cpp @@ -427,7 +427,7 @@ QV4::CompiledData::Unit QV4::Compiler::JSUnitGenerator::generateHeader(QV4::Comp } unit.indexOfRootFunction = -1; unit.sourceFileIndex = getStringId(irModule->fileName); - unit.sourceTimeStamp = irModule->sourceTimeStamp; + unit.sourceTimeStamp = irModule->sourceTimeStamp.isValid() ? irModule->sourceTimeStamp.toMSecsSinceEpoch() : 0; unit.nImports = 0; unit.offsetToImports = 0; unit.nObjects = 0; diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h index 53d9956315..fbd6ac8f99 100644 --- a/src/qml/compiler/qv4instr_moth_p.h +++ b/src/qml/compiler/qv4instr_moth_p.h @@ -690,7 +690,7 @@ union Instr }; struct instr_binop { MOTH_INSTR_HEADER - uint alu; // offset inside the runtime methods + int alu; // QV4::Runtime::RuntimeMethods enum value Param lhs; Param rhs; Param result; diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp index 04844302d9..aefb084971 100644 --- a/src/qml/compiler/qv4isel_moth.cpp +++ b/src/qml/compiler/qv4isel_moth.cpp @@ -55,70 +55,70 @@ using namespace QV4::Moth; namespace { -inline uint aluOpFunction(IR::AluOp op) +inline QV4::Runtime::RuntimeMethods aluOpFunction(IR::AluOp op) { switch (op) { case IR::OpInvalid: - return 0; + return QV4::Runtime::InvalidRuntimeMethod; case IR::OpIfTrue: - return 0; + return QV4::Runtime::InvalidRuntimeMethod; case IR::OpNot: - return 0; + return QV4::Runtime::InvalidRuntimeMethod; case IR::OpUMinus: - return 0; + return QV4::Runtime::InvalidRuntimeMethod; case IR::OpUPlus: - return 0; + return QV4::Runtime::InvalidRuntimeMethod; case IR::OpCompl: - return 0; + return QV4::Runtime::InvalidRuntimeMethod; case IR::OpBitAnd: - return offsetof(QV4::Runtime, bitAnd); + return QV4::Runtime::bitAnd; case IR::OpBitOr: - return offsetof(QV4::Runtime, bitOr); + return QV4::Runtime::bitOr; case IR::OpBitXor: - return offsetof(QV4::Runtime, bitXor); + return QV4::Runtime::bitXor; case IR::OpAdd: - return 0; + return QV4::Runtime::InvalidRuntimeMethod; case IR::OpSub: - return offsetof(QV4::Runtime, sub); + return QV4::Runtime::sub; case IR::OpMul: - return offsetof(QV4::Runtime, mul); + return QV4::Runtime::mul; case IR::OpDiv: - return offsetof(QV4::Runtime, div); + return QV4::Runtime::div; case IR::OpMod: - return offsetof(QV4::Runtime, mod); + return QV4::Runtime::mod; case IR::OpLShift: - return offsetof(QV4::Runtime, shl); + return QV4::Runtime::shl; case IR::OpRShift: - return offsetof(QV4::Runtime, shr); + return QV4::Runtime::shr; case IR::OpURShift: - return offsetof(QV4::Runtime, ushr); + return QV4::Runtime::ushr; case IR::OpGt: - return offsetof(QV4::Runtime, greaterThan); + return QV4::Runtime::greaterThan; case IR::OpLt: - return offsetof(QV4::Runtime, lessThan); + return QV4::Runtime::lessThan; case IR::OpGe: - return offsetof(QV4::Runtime, greaterEqual); + return QV4::Runtime::greaterEqual; case IR::OpLe: - return offsetof(QV4::Runtime, lessEqual); + return QV4::Runtime::lessEqual; case IR::OpEqual: - return offsetof(QV4::Runtime, equal); + return QV4::Runtime::equal; case IR::OpNotEqual: - return offsetof(QV4::Runtime, notEqual); + return QV4::Runtime::notEqual; case IR::OpStrictEqual: - return offsetof(QV4::Runtime, strictEqual); + return QV4::Runtime::strictEqual; case IR::OpStrictNotEqual: - return offsetof(QV4::Runtime, strictNotEqual); + return QV4::Runtime::strictNotEqual; case IR::OpInstanceof: - return 0; + return QV4::Runtime::InvalidRuntimeMethod; case IR::OpIn: - return 0; + return QV4::Runtime::InvalidRuntimeMethod; case IR::OpAnd: - return 0; + return QV4::Runtime::InvalidRuntimeMethod; case IR::OpOr: - return 0; + return QV4::Runtime::InvalidRuntimeMethod; default: Q_ASSERT(!"Unknown AluOp"); - return 0; + return QV4::Runtime::InvalidRuntimeMethod; } }; @@ -889,24 +889,25 @@ Param InstructionSelection::binopHelper(IR::AluOp oper, IR::Expr *leftSource, IR if (oper == IR::OpInstanceof || oper == IR::OpIn || oper == IR::OpAdd) { Instruction::BinopContext binop; if (oper == IR::OpInstanceof) - binop.alu = offsetof(QV4::Runtime, instanceof); + binop.alu = QV4::Runtime::instanceof; else if (oper == IR::OpIn) - binop.alu = offsetof(QV4::Runtime, in); + binop.alu = QV4::Runtime::in; else - binop.alu = offsetof(QV4::Runtime, add); + binop.alu = QV4::Runtime::add; binop.lhs = getParam(leftSource); binop.rhs = getParam(rightSource); binop.result = getResultParam(target); - Q_ASSERT(binop.alu); + Q_ASSERT(binop.alu != QV4::Runtime::InvalidRuntimeMethod); addInstruction(binop); return binop.result; } else { + auto binopFunc = aluOpFunction(oper); + Q_ASSERT(binopFunc != QV4::Runtime::InvalidRuntimeMethod); Instruction::Binop binop; - binop.alu = aluOpFunction(oper); + binop.alu = binopFunc; binop.lhs = getParam(leftSource); binop.rhs = getParam(rightSource); binop.result = getResultParam(target); - Q_ASSERT(binop.alu); addInstruction(binop); return binop.result; } diff --git a/src/qml/compiler/qv4isel_moth_p.h b/src/qml/compiler/qv4isel_moth_p.h index 41469f1985..4b84bd2831 100644 --- a/src/qml/compiler/qv4isel_moth_p.h +++ b/src/qml/compiler/qv4isel_moth_p.h @@ -179,7 +179,7 @@ private: int scratchTempIndex() const { return _function->tempCount; } int callDataStart() const { return scratchTempIndex() + 1; } - int outgoingArgumentTempStart() const { return callDataStart() + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value); } + int outgoingArgumentTempStart() const { return callDataStart() + offsetof(QV4::CallData, args)/sizeof(QV4::Value); } int frameSize() const { return outgoingArgumentTempStart() + _function->maxNumberOfArguments; } template <int Instr> diff --git a/src/qml/compiler/qv4jsir_p.h b/src/qml/compiler/qv4jsir_p.h index 756d90a033..f7c7b76ea8 100644 --- a/src/qml/compiler/qv4jsir_p.h +++ b/src/qml/compiler/qv4jsir_p.h @@ -61,6 +61,7 @@ #include <QtCore/QBitArray> #include <QtCore/qurl.h> #include <QtCore/QVarLengthArray> +#include <QtCore/QDateTime> #include <qglobal.h> #if defined(CONST) && defined(Q_OS_WIN) @@ -942,7 +943,7 @@ struct Q_QML_PRIVATE_EXPORT Module { QVector<Function *> functions; Function *rootFunction; QString fileName; - qint64 sourceTimeStamp; + QDateTime sourceTimeStamp; bool isQmlModule; // implies rootFunction is always 0 uint unitFlags; // flags merged into CompiledData::Unit::flags #ifdef QT_NO_QML_DEBUGGER @@ -955,7 +956,6 @@ struct Q_QML_PRIVATE_EXPORT Module { Module(bool debugMode) : rootFunction(0) - , sourceTimeStamp(0) , isQmlModule(false) , unitFlags(0) #ifndef QT_NO_QML_DEBUGGER diff --git a/src/qml/configure.json b/src/qml/configure.json index d22ba3b8f0..2c4887365f 100644 --- a/src/qml/configure.json +++ b/src/qml/configure.json @@ -22,6 +22,19 @@ "label": "QML network support", "purpose": "Provides network transparency for QML", "output": [ "publicFeature" ] + }, + "qml-profiler": { + "label": "Command line QML Profiler", + "purpose": "The QML Profiler retrieves QML tracing data from an application.", + "condition": [ + "features.commandlineparser", + "features.localserver", + "features.process", + "features.qml-debug", + "features.qml-network", + "features.xmlstreamwriter" + ], + "output": [ "privateFeature" ] } }, diff --git a/src/qml/jit/qv4assembler.cpp b/src/qml/jit/qv4assembler.cpp index 687c35adfa..81d34701a9 100644 --- a/src/qml/jit/qv4assembler.cpp +++ b/src/qml/jit/qv4assembler.cpp @@ -276,9 +276,15 @@ Assembler<TargetConfiguration>::loadArgLocalAddressForWriting(RegisterID baseReg int32_t offset = 0; int scope = al->scope; - loadPtr(Address(EngineRegister, qOffsetOf(ExecutionEngine, current)), baseReg); + loadPtr(Address(EngineRegister, targetStructureOffset(offsetof(EngineBase, current))), baseReg); + + const qint32 outerOffset = targetStructureOffset(Heap::ExecutionContextData::baseOffset + offsetof(Heap::ExecutionContextData, outer)); + const qint32 localsOffset = targetStructureOffset(Heap::CallContextData::baseOffset + offsetof(Heap::CallContextData, function)) + + 8 // locals is always 8 bytes away from function, regardless of pointer size. + + offsetof(ValueArray<0>, values); + while (scope) { - loadPtr(Address(baseReg, qOffsetOf(ExecutionContext::Data, outer)), baseReg); + loadPtr(Address(baseReg, outerOffset), baseReg); --scope; } switch (al->kind) { @@ -287,16 +293,17 @@ Assembler<TargetConfiguration>::loadArgLocalAddressForWriting(RegisterID baseReg if (barrier && *barrier == WriteBarrier::Barrier) { // if we need a barrier, the baseReg has to point to the ExecutionContext // callData comes directly after locals, calculate the offset using that - offset = qOffsetOf(CallContext::Data, locals.values) + _function->localsCountForScope(al) * sizeof(Value); + offset = localsOffset + _function->localsCountForScope(al) * sizeof(Value); offset += sizeof(CallData) + (al->index - 1) * sizeof(Value); } else { - loadPtr(Address(baseReg, qOffsetOf(ExecutionContext::Data, callData)), baseReg); + const qint32 callDataOffset = targetStructureOffset(Heap::ExecutionContextData::baseOffset + offsetof(Heap::ExecutionContextData, callData)); + loadPtr(Address(baseReg, callDataOffset), baseReg); offset = sizeof(CallData) + (al->index - 1) * sizeof(Value); } } break; case IR::ArgLocal::Local: case IR::ArgLocal::ScopedLocal: { - offset = qOffsetOf(CallContext::Data, locals.values) + al->index * sizeof(Value); + offset = localsOffset + al->index * sizeof(Value); } break; default: Q_UNREACHABLE(); @@ -307,9 +314,9 @@ Assembler<TargetConfiguration>::loadArgLocalAddressForWriting(RegisterID baseReg template <typename TargetConfiguration> typename Assembler<TargetConfiguration>::Pointer Assembler<TargetConfiguration>::loadStringAddress(RegisterID reg, const QString &string) { - loadPtr(Address(Assembler::EngineRegister, qOffsetOf(QV4::ExecutionEngine, current)), Assembler::ScratchRegister); - loadPtr(Address(Assembler::ScratchRegister, qOffsetOf(QV4::Heap::ExecutionContext, compilationUnit)), Assembler::ScratchRegister); - loadPtr(Address(Assembler::ScratchRegister, qOffsetOf(QV4::CompiledData::CompilationUnit, runtimeStrings)), reg); + loadPtr(Address(Assembler::EngineRegister, targetStructureOffset(offsetof(QV4::EngineBase, current))), Assembler::ScratchRegister); + loadPtr(Address(Assembler::ScratchRegister, targetStructureOffset(Heap::ExecutionContextData::baseOffset + offsetof(Heap::ExecutionContextData, compilationUnit))), Assembler::ScratchRegister); + loadPtr(Address(Assembler::ScratchRegister, offsetof(CompiledData::CompilationUnitBase, runtimeStrings)), reg); const int id = _jsGenerator->registerString(string); return Pointer(reg, id * sizeof(QV4::String*)); } @@ -323,8 +330,8 @@ typename Assembler<TargetConfiguration>::Address Assembler<TargetConfiguration>: template <typename TargetConfiguration> typename Assembler<TargetConfiguration>::Address Assembler<TargetConfiguration>::loadConstant(const Primitive &v, RegisterID baseReg) { - loadPtr(Address(Assembler::EngineRegister, qOffsetOf(QV4::ExecutionEngine, current)), baseReg); - loadPtr(Address(baseReg, qOffsetOf(QV4::Heap::ExecutionContext, constantTable)), baseReg); + loadPtr(Address(Assembler::EngineRegister, targetStructureOffset(offsetof(QV4::EngineBase, current))), baseReg); + loadPtr(Address(baseReg, targetStructureOffset(Heap::ExecutionContextData::baseOffset + offsetof(Heap::ExecutionContextData, constantTable))), baseReg); const int index = _jsGenerator->registerConstant(v.asReturnedValue()); return Address(baseReg, index * sizeof(QV4::Value)); } @@ -528,9 +535,9 @@ void Assembler<TargetConfiguration>::returnFromFunction(IR::Ret *s, RegisterInfo const int locals = stackLayout().calculateJSStackFrameSize(); subPtr(TrustedImm32(sizeof(QV4::Value)*locals), JITTargetPlatform::LocalsRegister); - loadPtr(Address(JITTargetPlatform::EngineRegister, qOffsetOf(QV4::ExecutionEngine, current)), JITTargetPlatform::ScratchRegister); - loadPtr(Address(JITTargetPlatform::ScratchRegister, qOffsetOf(ExecutionContext::Data, engine)), JITTargetPlatform::ScratchRegister); - storePtr(JITTargetPlatform::LocalsRegister, Address(JITTargetPlatform::ScratchRegister, qOffsetOf(ExecutionEngine, jsStackTop))); + loadPtr(Address(JITTargetPlatform::EngineRegister, targetStructureOffset(offsetof(QV4::EngineBase, current))), JITTargetPlatform::ScratchRegister); + loadPtr(Address(JITTargetPlatform::ScratchRegister, targetStructureOffset(Heap::ExecutionContextData::baseOffset + offsetof(Heap::ExecutionContextData, engine))), JITTargetPlatform::ScratchRegister); + storePtr(JITTargetPlatform::LocalsRegister, Address(JITTargetPlatform::ScratchRegister, targetStructureOffset(offsetof(EngineBase, jsStackTop)))); leaveStandardStackFrame(regularRegistersToSave, fpRegistersToSave); ret(); diff --git a/src/qml/jit/qv4assembler_p.h b/src/qml/jit/qv4assembler_p.h index d56b54f491..addbfc12a3 100644 --- a/src/qml/jit/qv4assembler_p.h +++ b/src/qml/jit/qv4assembler_p.h @@ -132,7 +132,7 @@ typedef AssemblerTargetConfiguration<DefaultPlatformMacroAssembler, NoOperatingS #define isel_stringIfy(s) isel_stringIfyx(s) #define generateRuntimeCall(as, t, function, ...) \ - as->generateFunctionCallImp(Runtime::Method_##function##_NeedsExceptionCheck, t, "Runtime::" isel_stringIfy(function), typename JITAssembler::RuntimeCall(qOffsetOf(QV4::Runtime, function)), __VA_ARGS__) + as->generateFunctionCallImp(Runtime::Method_##function##_NeedsExceptionCheck, t, "Runtime::" isel_stringIfy(function), typename JITAssembler::RuntimeCall(QV4::Runtime::function), __VA_ARGS__) template <typename JITAssembler, typename MacroAssembler, typename TargetPlatform, int RegisterSize> @@ -845,6 +845,12 @@ public: using JITTargetPlatform::platformFinishEnteringStandardStackFrame; using JITTargetPlatform::platformLeaveStandardStackFrame; + static qint32 targetStructureOffset(qint32 hostOffset) + { + Q_ASSERT(hostOffset % QT_POINTER_SIZE == 0); + return (hostOffset * RegisterSize) / QT_POINTER_SIZE; + } + using RegisterSizeDependentOps = RegisterSizeDependentAssembler<Assembler<TargetConfiguration>, MacroAssembler, JITTargetPlatform, RegisterSize>; struct LookupCall { @@ -860,7 +866,7 @@ public: struct RuntimeCall { Address addr; - inline RuntimeCall(uint offset = uint(INT_MIN)); + inline RuntimeCall(Runtime::RuntimeMethods method = Runtime::InvalidRuntimeMethod); bool isValid() const { return addr.offset >= 0; } }; @@ -1406,7 +1412,7 @@ public: const RegisterInformation &fpRegistersToSave); void checkException() { - this->load8(Address(EngineRegister, qOffsetOf(QV4::ExecutionEngine, hasException)), ScratchRegister); + this->load8(Address(EngineRegister, targetStructureOffset(offsetof(QV4::EngineBase, hasException))), ScratchRegister); Jump exceptionThrown = branch32(RelationalCondition::NotEqual, ScratchRegister, TrustedImm32(0)); if (catchBlock) addPatch(catchBlock, exceptionThrown); @@ -1474,8 +1480,8 @@ public: // IMPORTANT! See generateLookupCall in qv4isel_masm_p.h for details! // load the table from the context - loadPtr(Address(EngineRegister, qOffsetOf(QV4::ExecutionEngine, current)), ScratchRegister); - loadPtr(Address(ScratchRegister, qOffsetOf(QV4::Heap::ExecutionContext, lookups)), + loadPtr(Address(EngineRegister, targetStructureOffset(offsetof(QV4::EngineBase, current))), ScratchRegister); + loadPtr(Address(ScratchRegister, targetStructureOffset(Heap::ExecutionContextData::baseOffset + offsetof(Heap::ExecutionContextData, lookups))), lookupCall.addr.base); // pre-calculate the indirect address for the lookupCall table: if (lookupCall.addr.offset) @@ -1778,9 +1784,9 @@ public: const int locals = _stackLayout->calculateJSStackFrameSize(); if (locals <= 0) return; - loadPtr(Address(JITTargetPlatform::EngineRegister, qOffsetOf(ExecutionEngine, jsStackTop)), JITTargetPlatform::LocalsRegister); + loadPtr(Address(JITTargetPlatform::EngineRegister, targetStructureOffset(offsetof(EngineBase, jsStackTop))), JITTargetPlatform::LocalsRegister); RegisterSizeDependentOps::initializeLocalVariables(this, locals); - storePtr(JITTargetPlatform::LocalsRegister, Address(JITTargetPlatform::EngineRegister, qOffsetOf(ExecutionEngine, jsStackTop))); + storePtr(JITTargetPlatform::LocalsRegister, Address(JITTargetPlatform::EngineRegister, targetStructureOffset(offsetof(EngineBase, jsStackTop)))); } Label exceptionReturnLabel; @@ -1841,8 +1847,9 @@ void Assembler<TargetConfiguration>::copyValue(Result result, IR::Expr* source, } template <typename TargetConfiguration> -inline Assembler<TargetConfiguration>::RuntimeCall::RuntimeCall(uint offset) - : addr(Assembler::EngineRegister, offset + qOffsetOf(QV4::ExecutionEngine, runtime)) +inline Assembler<TargetConfiguration>::RuntimeCall::RuntimeCall(Runtime::RuntimeMethods method) + : addr(Assembler::EngineRegister, + method == Runtime::InvalidRuntimeMethod ? -1 : (Assembler<TargetConfiguration>::targetStructureOffset(offsetof(EngineBase, runtime) + Runtime::runtimeMethodOffset(method)))) { } diff --git a/src/qml/jit/qv4binop.cpp b/src/qml/jit/qv4binop.cpp index 0e180eb4cc..a1c65f644c 100644 --- a/src/qml/jit/qv4binop.cpp +++ b/src/qml/jit/qv4binop.cpp @@ -165,17 +165,17 @@ struct ArchitectureSpecificBinaryOperation<Assembler<AssemblerTargetConfiguratio #endif #define OP(op) \ - { "Runtime::" isel_stringIfy(op), offsetof(QV4::Runtime, op), INT_MIN, 0, 0, QV4::Runtime::Method_##op##_NeedsExceptionCheck } + { "Runtime::" isel_stringIfy(op), QV4::Runtime::op, QV4::Runtime::InvalidRuntimeMethod, 0, 0, QV4::Runtime::Method_##op##_NeedsExceptionCheck } #define OPCONTEXT(op) \ - { "Runtime::" isel_stringIfy(op), INT_MIN, offsetof(QV4::Runtime, op), 0, 0, QV4::Runtime::Method_##op##_NeedsExceptionCheck } + { "Runtime::" isel_stringIfy(op), QV4::Runtime::InvalidRuntimeMethod, QV4::Runtime::op, 0, 0, QV4::Runtime::Method_##op##_NeedsExceptionCheck } #define INLINE_OP(op, memOp, immOp) \ - { "Runtime::" isel_stringIfy(op), offsetof(QV4::Runtime, op), INT_MIN, memOp, immOp, QV4::Runtime::Method_##op##_NeedsExceptionCheck } + { "Runtime::" isel_stringIfy(op), QV4::Runtime::op, QV4::Runtime::InvalidRuntimeMethod, memOp, immOp, QV4::Runtime::Method_##op##_NeedsExceptionCheck } #define INLINE_OPCONTEXT(op, memOp, immOp) \ - { "Runtime::" isel_stringIfy(op), INT_MIN, offsetof(QV4::Runtime, op), memOp, immOp, QV4::Runtime::Method_##op##_NeedsExceptionCheck } + { "Runtime::" isel_stringIfy(op), QV4::Runtime::InvalidRuntimeMethod, QV4::Runtime::op, memOp, immOp, QV4::Runtime::Method_##op##_NeedsExceptionCheck } #define NULL_OP \ - { 0, 0, 0, 0, 0, false } + { 0, QV4::Runtime::InvalidRuntimeMethod, QV4::Runtime::InvalidRuntimeMethod, 0, 0, false } template <typename JITAssembler> const typename Binop<JITAssembler>::OpInfo Binop<JITAssembler>::operations[IR::LastAluOp + 1] = { diff --git a/src/qml/jit/qv4binop_p.h b/src/qml/jit/qv4binop_p.h index d2d9ba7753..1b1ab7f24d 100644 --- a/src/qml/jit/qv4binop_p.h +++ b/src/qml/jit/qv4binop_p.h @@ -88,8 +88,8 @@ struct Binop { struct OpInfo { const char *name; - int fallbackImplementation; // offsetOf(Runtime,...) - int contextImplementation; // offsetOf(Runtime,...) + Runtime::RuntimeMethods fallbackImplementation; + Runtime::RuntimeMethods contextImplementation; MemRegOp inlineMemRegOp; ImmRegOp inlineImmRegOp; bool needsExceptionCheck; diff --git a/src/qml/jit/qv4isel_masm.cpp b/src/qml/jit/qv4isel_masm.cpp index 5b57d29bca..9841620481 100644 --- a/src/qml/jit/qv4isel_masm.cpp +++ b/src/qml/jit/qv4isel_masm.cpp @@ -132,8 +132,8 @@ void InstructionSelection<JITAssembler>::run(int functionIndex) for (IR::Stmt *s : _block->statements()) { if (s->location.isValid()) { if (int(s->location.startLine) != lastLine) { - _as->loadPtr(Address(JITTargetPlatform::EngineRegister, qOffsetOf(QV4::ExecutionEngine, current)), JITTargetPlatform::ScratchRegister); - Address lineAddr(JITTargetPlatform::ScratchRegister, qOffsetOf(QV4::ExecutionContext::Data, lineNumber)); + _as->loadPtr(Address(JITTargetPlatform::EngineRegister, JITAssembler::targetStructureOffset(offsetof(QV4::EngineBase, current))), JITTargetPlatform::ScratchRegister); + Address lineAddr(JITTargetPlatform::ScratchRegister, JITAssembler::targetStructureOffset(Heap::ExecutionContextData::baseOffset + offsetof(Heap::ExecutionContextData, lineNumber))); _as->store32(TrustedImm32(s->location.startLine), lineAddr); lastLine = s->location.startLine; } @@ -449,9 +449,9 @@ void InstructionSelection<JITAssembler>::loadThisObject(IR::Expr *temp) { WriteBarrier::Type barrier; Pointer addr = _as->loadAddressForWriting(JITTargetPlatform::ScratchRegister, temp, &barrier); - _as->loadPtr(Address(JITTargetPlatform::EngineRegister, qOffsetOf(QV4::ExecutionEngine, current)), JITTargetPlatform::ReturnValueRegister); - _as->loadPtr(Address(JITTargetPlatform::ReturnValueRegister, qOffsetOf(ExecutionContext::Data, callData)), JITTargetPlatform::ReturnValueRegister); - _as->copyValue(addr, Address(JITTargetPlatform::ReturnValueRegister, qOffsetOf(CallData, thisObject)), barrier); + _as->loadPtr(Address(JITTargetPlatform::EngineRegister, JITAssembler::targetStructureOffset(offsetof(QV4::EngineBase, current))), JITTargetPlatform::ReturnValueRegister); + _as->loadPtr(Address(JITTargetPlatform::ReturnValueRegister,JITAssembler::targetStructureOffset(Heap::ExecutionContextData::baseOffset + offsetof(Heap::ExecutionContextData, callData))), JITTargetPlatform::ReturnValueRegister); + _as->copyValue(addr, Address(JITTargetPlatform::ReturnValueRegister, offsetof(CallData, thisObject)), barrier); } template <typename JITAssembler> @@ -522,7 +522,7 @@ void InstructionSelection<JITAssembler>::getActivationProperty(const IR::Name *n { if (useFastLookups && name->global) { uint index = registerGlobalGetterLookup(*name->id); - generateLookupCall(target, index, qOffsetOf(QV4::Lookup, globalGetter), JITTargetPlatform::EngineRegister, JITAssembler::Void); + generateLookupCall(target, index, offsetof(QV4::Lookup, globalGetter), JITTargetPlatform::EngineRegister, JITAssembler::Void); return; } generateRuntimeCall(_as, target, getActivationProperty, JITTargetPlatform::EngineRegister, StringToIndex(*name->id)); @@ -548,7 +548,7 @@ void InstructionSelection<JITAssembler>::getProperty(IR::Expr *base, const QStri { if (useFastLookups) { uint index = registerGetterLookup(name); - generateLookupCall(target, index, qOffsetOf(QV4::Lookup, getter), JITTargetPlatform::EngineRegister, PointerToValue(base), JITAssembler::Void); + generateLookupCall(target, index, offsetof(QV4::Lookup, getter), JITTargetPlatform::EngineRegister, PointerToValue(base), JITAssembler::Void); } else { generateRuntimeCall(_as, target, getProperty, JITTargetPlatform::EngineRegister, PointerToValue(base), StringToIndex(name)); @@ -587,7 +587,7 @@ void InstructionSelection<JITAssembler>::setProperty(IR::Expr *source, IR::Expr { if (useFastLookups) { uint index = registerSetterLookup(targetName); - generateLookupCall(JITAssembler::Void, index, qOffsetOf(QV4::Lookup, setter), + generateLookupCall(JITAssembler::Void, index, offsetof(QV4::Lookup, setter), JITTargetPlatform::EngineRegister, PointerToValue(targetBase), PointerToValue(source)); @@ -623,7 +623,7 @@ void InstructionSelection<JITAssembler>::getElement(IR::Expr *base, IR::Expr *in { if (useFastLookups) { uint lookup = registerIndexedGetterLookup(); - generateLookupCall(target, lookup, qOffsetOf(QV4::Lookup, indexedGetter), + generateLookupCall(target, lookup, offsetof(QV4::Lookup, indexedGetter), JITTargetPlatform::EngineRegister, PointerToValue(base), PointerToValue(index)); @@ -639,7 +639,7 @@ void InstructionSelection<JITAssembler>::setElement(IR::Expr *source, IR::Expr * { if (useFastLookups) { uint lookup = registerIndexedSetterLookup(); - generateLookupCall(JITAssembler::Void, lookup, qOffsetOf(QV4::Lookup, indexedSetter), + generateLookupCall(JITAssembler::Void, lookup, offsetof(QV4::Lookup, indexedSetter), JITTargetPlatform::EngineRegister, PointerToValue(targetBase), PointerToValue(targetIndex), PointerToValue(source)); @@ -799,12 +799,12 @@ void InstructionSelection<JITAssembler>::swapValues(IR::Expr *source, IR::Expr * #define setOp(op, opName, operation) \ do { \ - op = typename JITAssembler::RuntimeCall(qOffsetOf(QV4::Runtime, operation)); opName = "Runtime::" isel_stringIfy(operation); \ + op = typename JITAssembler::RuntimeCall(QV4::Runtime::operation); opName = "Runtime::" isel_stringIfy(operation); \ needsExceptionCheck = QV4::Runtime::Method_##operation##_NeedsExceptionCheck; \ } while (0) #define setOpContext(op, opName, operation) \ do { \ - opContext = typename JITAssembler::RuntimeCall(qOffsetOf(QV4::Runtime, operation)); opName = "Runtime::" isel_stringIfy(operation); \ + opContext = typename JITAssembler::RuntimeCall(QV4::Runtime::operation); opName = "Runtime::" isel_stringIfy(operation); \ needsExceptionCheck = QV4::Runtime::Method_##operation##_NeedsExceptionCheck; \ } while (0) @@ -1321,11 +1321,11 @@ int InstructionSelection<JITAssembler>::prepareCallData(IR::ExprList* args, IR:: ++argc; } - Pointer p = _as->stackLayout().callDataAddress(qOffsetOf(CallData, tag)); + Pointer p = _as->stackLayout().callDataAddress(offsetof(CallData, tag)); _as->store32(TrustedImm32(QV4::Value::Integer_Type_Internal), p); - p = _as->stackLayout().callDataAddress(qOffsetOf(CallData, argc)); + p = _as->stackLayout().callDataAddress(offsetof(CallData, argc)); _as->store32(TrustedImm32(argc), p); - p = _as->stackLayout().callDataAddress(qOffsetOf(CallData, thisObject)); + p = _as->stackLayout().callDataAddress(offsetof(CallData, thisObject)); if (!thisObject) _as->storeValue(QV4::Primitive::undefinedValue(), p, WriteBarrier::NoBarrier); else diff --git a/src/qml/jit/qv4unop.cpp b/src/qml/jit/qv4unop.cpp index 76c6457d67..896be07ed5 100644 --- a/src/qml/jit/qv4unop.cpp +++ b/src/qml/jit/qv4unop.cpp @@ -48,7 +48,7 @@ using namespace JIT; #define stringIfy(s) stringIfyx(s) #define setOp(operation) \ do { \ - call = typename JITAssembler::RuntimeCall(qOffsetOf(QV4::Runtime, operation)); name = "Runtime::" stringIfy(operation); \ + call = typename JITAssembler::RuntimeCall(QV4::Runtime::operation); name = "Runtime::" stringIfy(operation); \ needsExceptionCheck = Runtime::Method_##operation##_NeedsExceptionCheck; \ } while (0) diff --git a/src/qml/jsruntime/qv4arraydata.cpp b/src/qml/jsruntime/qv4arraydata.cpp index f8c2d3f82b..4a619858b4 100644 --- a/src/qml/jsruntime/qv4arraydata.cpp +++ b/src/qml/jsruntime/qv4arraydata.cpp @@ -678,7 +678,7 @@ bool ArrayElementLessThan::operator()(Value v1, Value v2) const callData->thisObject = Primitive::undefinedValue(); callData->args[0] = v1; callData->args[1] = v2; - result = scope.engine->runtime.callValue(scope.engine, m_comparefn, callData); + result = QV4::Runtime::method_callValue(scope.engine, m_comparefn, callData); return result->toNumber() < 0; } diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp index d2f2529979..b71e71b92f 100644 --- a/src/qml/jsruntime/qv4context.cpp +++ b/src/qml/jsruntime/qv4context.cpp @@ -75,8 +75,8 @@ Heap::CallContext *ExecutionContext::newCallContext(Function *function, CallData c->outer.set(d()->engine, this->d()); c->compilationUnit = function->compilationUnit; - c->lookups = c->compilationUnit->runtimeLookups; - c->constantTable = c->compilationUnit->constants; + c->lookups = function->compilationUnit->runtimeLookups; + c->constantTable = function->compilationUnit->constants; const CompiledData::Function *compiledFunction = function->compiledFunction; uint nLocals = compiledFunction->nLocals; diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h index 79e5f74d8f..3b37ea69dc 100644 --- a/src/qml/jsruntime/qv4context_p.h +++ b/src/qml/jsruntime/qv4context_p.h @@ -61,7 +61,7 @@ class QQmlContextData; namespace QV4 { namespace CompiledData { -struct CompilationUnit; +struct CompilationUnitBase; struct Function; } @@ -74,6 +74,8 @@ struct WithContext; struct QmlContext; struct QmlContextWrapper; +// Attention: Make sure that this structure is the same size on 32-bit and 64-bit +// architecture or you'll have to change the JIT code. struct CallData { // below is to be compatible with Value. Initialize tag to 0 @@ -92,15 +94,27 @@ struct CallData Value args[1]; }; +Q_STATIC_ASSERT(std::is_standard_layout<CallData>::value); +Q_STATIC_ASSERT(offsetof(CallData, thisObject) == 8); +Q_STATIC_ASSERT(offsetof(CallData, args) == 16); + namespace Heap { struct QmlContext; #define ExecutionContextMembers(class, Member) \ - Member(class, Pointer, ExecutionContext *, outer) + Member(class, NoMark, CallData *, callData) \ + Member(class, NoMark, ExecutionEngine *, engine) \ + Member(class, Pointer, ExecutionContext *, outer) \ + Member(class, NoMark, Lookup *, lookups) \ + Member(class, NoMark, const QV4::Value *, constantTable) \ + Member(class, NoMark, CompiledData::CompilationUnitBase *, compilationUnit) \ + Member(class, NoMark, int, lineNumber) // as member of non-pointer size this has to come last to preserve the ability to + // translate offsetof of it between 64-bit and 32-bit. DECLARE_HEAP_OBJECT(ExecutionContext, Base) { DECLARE_MARK_TABLE(ExecutionContext); + enum ContextType { Type_GlobalContext = 0x1, Type_CatchContext = 0x2, @@ -119,18 +133,25 @@ DECLARE_HEAP_OBJECT(ExecutionContext, Base) { lineNumber = -1; } - CallData *callData; - - ExecutionEngine *engine; - Lookup *lookups; - const QV4::Value *constantTable; - CompiledData::CompilationUnit *compilationUnit; - - ContextType type : 8; + quint8 type; bool strictMode : 8; - int lineNumber; +#if QT_POINTER_SIZE == 8 + quint8 padding_[6]; +#else + quint8 padding_[2]; +#endif }; V4_ASSERT_IS_TRIVIAL(ExecutionContext) +Q_STATIC_ASSERT(sizeof(ExecutionContext) == sizeof(Base) + sizeof(ExecutionContextData) + QT_POINTER_SIZE); + +Q_STATIC_ASSERT(std::is_standard_layout<ExecutionContextData>::value); +Q_STATIC_ASSERT(offsetof(ExecutionContextData, callData) == 0); +Q_STATIC_ASSERT(offsetof(ExecutionContextData, engine) == offsetof(ExecutionContextData, callData) + QT_POINTER_SIZE); +Q_STATIC_ASSERT(offsetof(ExecutionContextData, outer) == offsetof(ExecutionContextData, engine) + QT_POINTER_SIZE); +Q_STATIC_ASSERT(offsetof(ExecutionContextData, lookups) == offsetof(ExecutionContextData, outer) + QT_POINTER_SIZE); +Q_STATIC_ASSERT(offsetof(ExecutionContextData, constantTable) == offsetof(ExecutionContextData, lookups) + QT_POINTER_SIZE); +Q_STATIC_ASSERT(offsetof(ExecutionContextData, compilationUnit) == offsetof(ExecutionContextData, constantTable) + QT_POINTER_SIZE); +Q_STATIC_ASSERT(offsetof(ExecutionContextData, lineNumber) == offsetof(ExecutionContextData, compilationUnit) + QT_POINTER_SIZE); #define SimpleCallContextMembers(class, Member) \ Member(class, Pointer, Object *, activation) \ @@ -148,10 +169,22 @@ DECLARE_HEAP_OBJECT(SimpleCallContext, ExecutionContext) { }; V4_ASSERT_IS_TRIVIAL(SimpleCallContext) +Q_STATIC_ASSERT(std::is_standard_layout<SimpleCallContextData>::value); +Q_STATIC_ASSERT(offsetof(SimpleCallContextData, activation) == 0); +Q_STATIC_ASSERT(offsetof(SimpleCallContextData, v4Function) == offsetof(SimpleCallContextData, activation) + QT_POINTER_SIZE); +Q_STATIC_ASSERT(sizeof(SimpleCallContextData) == 2 * QT_POINTER_SIZE); +Q_STATIC_ASSERT(sizeof(SimpleCallContext) == sizeof(ExecutionContext) + sizeof(SimpleCallContextData)); +#if QT_POINTER_SIZE == 8 +#define CallContextMembers(class, Member) \ + Member(class, Pointer, FunctionObject *, function) \ + Member(class, ValueArray, ValueArray, locals) +#else #define CallContextMembers(class, Member) \ Member(class, Pointer, FunctionObject *, function) \ - Member(class, ValueArray, ValueArray, locals) \ + Member(class, NoMark, void *, padding) \ + Member(class, ValueArray, ValueArray, locals) +#endif DECLARE_HEAP_OBJECT(CallContext, SimpleCallContext) { DECLARE_MARK_TABLE(CallContext); @@ -159,6 +192,13 @@ DECLARE_HEAP_OBJECT(CallContext, SimpleCallContext) { using SimpleCallContext::formalParameterCount; }; +Q_STATIC_ASSERT(std::is_standard_layout<CallContextData>::value); +Q_STATIC_ASSERT(offsetof(CallContextData, function) == 0); +// IMPORTANT: we cannot do offsetof(CallContextData, locals) in the JIT as the offset does not scale with +// the pointer size. On 32-bit ARM the offset of the ValueArray is aligned to 8 bytes, on 32-bit x86 for +// example it is not. Therefore we have a padding in place and always have a distance of 8 bytes. +Q_STATIC_ASSERT(offsetof(CallContextData, locals) == offsetof(CallContextData, function) + 8); + #define GlobalContextMembers(class, Member) \ Member(class, Pointer, Object *, global) diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 899fd499df..679cd41ce0 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -131,7 +131,6 @@ qint32 ExecutionEngine::maxCallDepth = -1; ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) : callDepth(0) - , memoryManager(new QV4::MemoryManager(this)) , executableAllocator(new QV4::ExecutableAllocator) , regExpAllocator(new QV4::ExecutableAllocator) , currentContext(0) @@ -151,6 +150,8 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) { writeBarrierActive = true; + memoryManager = new QV4::MemoryManager(this); + if (maxCallDepth == -1) { bool ok = false; maxCallDepth = qEnvironmentVariableIntValue("QV4_MAX_CALL_DEPTH", &ok); diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h index 18571d88f2..1160d69c6c 100644 --- a/src/qml/jsruntime/qv4engine_p.h +++ b/src/qml/jsruntime/qv4engine_p.h @@ -54,7 +54,6 @@ #include "private/qv4isel_p.h" #include "qv4managed_p.h" #include "qv4context_p.h" -#include "qv4runtimeapi_p.h" #include <private/qintrusivelist_p.h> #ifndef V4_BOOTSTRAP @@ -99,7 +98,6 @@ private: public: qint32 callDepth; - MemoryManager *memoryManager; ExecutableAllocator *executableAllocator; ExecutableAllocator *regExpAllocator; QScopedPointer<EvalISelFactory> iselFactory; @@ -108,8 +106,6 @@ public: Value *jsStackLimit; - Runtime runtime; - WTF::BumpPointerAllocator *bumperPointerAllocator; // Used by Yarr Regex engine. enum { JSStackLimit = 4*1024*1024 }; diff --git a/src/qml/jsruntime/qv4global_p.h b/src/qml/jsruntime/qv4global_p.h index cd8fb91f7a..0665295287 100644 --- a/src/qml/jsruntime/qv4global_p.h +++ b/src/qml/jsruntime/qv4global_p.h @@ -89,8 +89,6 @@ inline bool signbit(double d) { return _copysign(1.0, d) < 0; } inline double trunc(double d) { return d > 0 ? floor(d) : ceil(d); } #endif -#define qOffsetOf(s, m) ((size_t)((((char *)&(((s *)64)->m)) - 64))) - // Decide whether to enable or disable the JIT // White list architectures diff --git a/src/qml/jsruntime/qv4lookup_p.h b/src/qml/jsruntime/qv4lookup_p.h index 1b1c307530..daf3c71e27 100644 --- a/src/qml/jsruntime/qv4lookup_p.h +++ b/src/qml/jsruntime/qv4lookup_p.h @@ -140,6 +140,12 @@ struct Lookup { }; +Q_STATIC_ASSERT(std::is_standard_layout<Lookup>::value); +// Ensure that these offsets are always at this point to keep generated code compatible +// across 32-bit and 64-bit (matters when cross-compiling). +Q_STATIC_ASSERT(offsetof(Lookup, indexedGetter) == 0); +Q_STATIC_ASSERT(offsetof(Lookup, getter) == 0); + } QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index 2e833eda7b..3b92096386 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -219,6 +219,14 @@ void RuntimeCounters::count(const char *func, uint tag1, uint tag2) #endif // QV4_COUNT_RUNTIME_FUNCTIONS #ifndef V4_BOOTSTRAP + +Runtime::Runtime() +{ +#define INIT_METHOD(returnvalue, name, args) runtimeMethods[name] = reinterpret_cast<void*>(&method_##name); +FOR_EACH_RUNTIME_METHOD(INIT_METHOD) +#undef INIT_METHOD +} + void RuntimeHelpers::numberToString(QString *result, double num, int radix) { Q_ASSERT(result); @@ -300,7 +308,7 @@ void RuntimeHelpers::numberToString(QString *result, double num, int radix) ReturnedValue Runtime::method_closure(ExecutionEngine *engine, int functionId) { - QV4::Function *clos = engine->current->compilationUnit->runtimeFunctions[functionId]; + QV4::Function *clos = static_cast<CompiledData::CompilationUnit*>(engine->current->compilationUnit)->runtimeFunctions[functionId]; Q_ASSERT(clos); return FunctionObject::createScriptFunction(engine->currentContext, clos)->asReturnedValue(); } @@ -1301,7 +1309,7 @@ ReturnedValue Runtime::method_arrayLiteral(ExecutionEngine *engine, Value *value ReturnedValue Runtime::method_objectLiteral(ExecutionEngine *engine, const QV4::Value *args, int classId, int arrayValueCount, int arrayGetterSetterCountAndFlags) { Scope scope(engine); - QV4::InternalClass *klass = engine->current->compilationUnit->runtimeClasses[classId]; + QV4::InternalClass *klass = static_cast<CompiledData::CompilationUnit*>(engine->current->compilationUnit)->runtimeClasses[classId]; ScopedObject o(scope, engine->newObject(klass, engine->objectPrototype())); { @@ -1413,7 +1421,7 @@ ReturnedValue Runtime::method_getQmlContext(NoThrowEngine *engine) ReturnedValue Runtime::method_regexpLiteral(ExecutionEngine *engine, int id) { - return engine->current->compilationUnit->runtimeRegularExpressions[id].asReturnedValue(); + return static_cast<CompiledData::CompilationUnit*>(engine->current->compilationUnit)->runtimeRegularExpressions[id].asReturnedValue(); } ReturnedValue Runtime::method_getQmlQObjectProperty(ExecutionEngine *engine, const Value &object, int propertyIndex, bool captureRequired) diff --git a/src/qml/jsruntime/qv4runtimeapi_p.h b/src/qml/jsruntime/qv4runtimeapi_p.h index 355b7890b6..302facba06 100644 --- a/src/qml/jsruntime/qv4runtimeapi_p.h +++ b/src/qml/jsruntime/qv4runtimeapi_p.h @@ -56,6 +56,7 @@ QT_BEGIN_NAMESPACE namespace QV4 { +typedef uint Bool; struct NoThrowEngine; namespace { @@ -90,256 +91,169 @@ struct ExceptionCheck<void (*)(QV4::NoThrowEngine *, A, B, C)> { }; } // anonymous namespace -#define RUNTIME_METHOD(returnvalue, name, args) \ - typedef returnvalue (*Method_##name)args; \ - enum { Method_##name##_NeedsExceptionCheck = ExceptionCheck<Method_##name>::NeedsCheck }; \ - static returnvalue method_##name args; \ - const Method_##name name - -#define INIT_RUNTIME_METHOD(name) \ - name(method_##name) +#define FOR_EACH_RUNTIME_METHOD(F) \ + /* call */ \ + F(ReturnedValue, callGlobalLookup, (ExecutionEngine *engine, uint index, CallData *callData)) \ + F(ReturnedValue, callActivationProperty, (ExecutionEngine *engine, int nameIndex, CallData *callData)) \ + F(ReturnedValue, callQmlScopeObjectProperty, (ExecutionEngine *engine, int propertyIndex, CallData *callData)) \ + F(ReturnedValue, callQmlContextObjectProperty, (ExecutionEngine *engine, int propertyIndex, CallData *callData)) \ + F(ReturnedValue, callProperty, (ExecutionEngine *engine, int nameIndex, CallData *callData)) \ + F(ReturnedValue, callPropertyLookup, (ExecutionEngine *engine, uint index, CallData *callData)) \ + F(ReturnedValue, callElement, (ExecutionEngine *engine, const Value &index, CallData *callData)) \ + F(ReturnedValue, callValue, (ExecutionEngine *engine, const Value &func, CallData *callData)) \ + \ + /* construct */ \ + F(ReturnedValue, constructGlobalLookup, (ExecutionEngine *engine, uint index, CallData *callData)) \ + F(ReturnedValue, constructActivationProperty, (ExecutionEngine *engine, int nameIndex, CallData *callData)) \ + F(ReturnedValue, constructProperty, (ExecutionEngine *engine, int nameIndex, CallData *callData)) \ + F(ReturnedValue, constructPropertyLookup, (ExecutionEngine *engine, uint index, CallData *callData)) \ + F(ReturnedValue, constructValue, (ExecutionEngine *engine, const Value &func, CallData *callData)) \ + \ + /* set & get */ \ + F(void, setActivationProperty, (ExecutionEngine *engine, int nameIndex, const Value &value)) \ + F(void, setProperty, (ExecutionEngine *engine, const Value &object, int nameIndex, const Value &value)) \ + F(void, setElement, (ExecutionEngine *engine, const Value &object, const Value &index, const Value &value)) \ + F(ReturnedValue, getProperty, (ExecutionEngine *engine, const Value &object, int nameIndex)) \ + F(ReturnedValue, getActivationProperty, (ExecutionEngine *engine, int nameIndex)) \ + F(ReturnedValue, getElement, (ExecutionEngine *engine, const Value &object, const Value &index)) \ + \ + /* typeof */ \ + F(ReturnedValue, typeofValue, (ExecutionEngine *engine, const Value &val)) \ + F(ReturnedValue, typeofName, (ExecutionEngine *engine, int nameIndex)) \ + F(ReturnedValue, typeofScopeObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex)) \ + F(ReturnedValue, typeofContextObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex)) \ + F(ReturnedValue, typeofMember, (ExecutionEngine *engine, const Value &base, int nameIndex)) \ + F(ReturnedValue, typeofElement, (ExecutionEngine *engine, const Value &base, const Value &index)) \ + \ + /* delete */ \ + F(ReturnedValue, deleteElement, (ExecutionEngine *engine, const Value &base, const Value &index)) \ + F(ReturnedValue, deleteMember, (ExecutionEngine *engine, const Value &base, int nameIndex)) \ + F(ReturnedValue, deleteMemberString, (ExecutionEngine *engine, const Value &base, String *name)) \ + F(ReturnedValue, deleteName, (ExecutionEngine *engine, int nameIndex)) \ + \ + /* exceptions & scopes */ \ + F(void, throwException, (ExecutionEngine *engine, const Value &value)) \ + F(ReturnedValue, unwindException, (ExecutionEngine *engine)) \ + F(void, pushWithScope, (const Value &o, NoThrowEngine *engine)) \ + F(void, pushCatchScope, (NoThrowEngine *engine, int exceptionVarNameIndex)) \ + F(void, popScope, (NoThrowEngine *engine)) \ + \ + /* closures */ \ + F(ReturnedValue, closure, (ExecutionEngine *engine, int functionId)) \ + \ + /* function header */ \ + F(void, declareVar, (ExecutionEngine *engine, bool deletable, int nameIndex)) \ + F(ReturnedValue, setupArgumentsObject, (ExecutionEngine *engine)) \ + F(void, convertThisToObject, (ExecutionEngine *engine)) \ + \ + /* literals */ \ + F(ReturnedValue, arrayLiteral, (ExecutionEngine *engine, Value *values, uint length)) \ + F(ReturnedValue, objectLiteral, (ExecutionEngine *engine, const Value *args, int classId, int arrayValueCount, int arrayGetterSetterCountAndFlags)) \ + F(ReturnedValue, regexpLiteral, (ExecutionEngine *engine, int id)) \ + \ + /* foreach */ \ + F(ReturnedValue, foreachIterator, (ExecutionEngine *engine, const Value &in)) \ + F(ReturnedValue, foreachNextPropertyName, (const Value &foreach_iterator)) \ + \ + /* unary operators */ \ + F(ReturnedValue, uPlus, (const Value &value)) \ + F(ReturnedValue, uMinus, (const Value &value)) \ + F(ReturnedValue, uNot, (const Value &value)) \ + F(ReturnedValue, complement, (const Value &value)) \ + F(ReturnedValue, increment, (const Value &value)) \ + F(ReturnedValue, decrement, (const Value &value)) \ + \ + /* binary operators */ \ + F(ReturnedValue, instanceof, (ExecutionEngine *engine, const Value &left, const Value &right)) \ + F(ReturnedValue, in, (ExecutionEngine *engine, const Value &left, const Value &right)) \ + F(ReturnedValue, add, (ExecutionEngine *engine, const Value &left, const Value &right)) \ + F(ReturnedValue, addString, (ExecutionEngine *engine, const Value &left, const Value &right)) \ + F(ReturnedValue, bitOr, (const Value &left, const Value &right)) \ + F(ReturnedValue, bitXor, (const Value &left, const Value &right)) \ + F(ReturnedValue, bitAnd, (const Value &left, const Value &right)) \ + F(ReturnedValue, sub, (const Value &left, const Value &right)) \ + F(ReturnedValue, mul, (const Value &left, const Value &right)) \ + F(ReturnedValue, div, (const Value &left, const Value &right)) \ + F(ReturnedValue, mod, (const Value &left, const Value &right)) \ + F(ReturnedValue, shl, (const Value &left, const Value &right)) \ + F(ReturnedValue, shr, (const Value &left, const Value &right)) \ + F(ReturnedValue, ushr, (const Value &left, const Value &right)) \ + F(ReturnedValue, greaterThan, (const Value &left, const Value &right)) \ + F(ReturnedValue, lessThan, (const Value &left, const Value &right)) \ + F(ReturnedValue, greaterEqual, (const Value &left, const Value &right)) \ + F(ReturnedValue, lessEqual, (const Value &left, const Value &right)) \ + F(ReturnedValue, equal, (const Value &left, const Value &right)) \ + F(ReturnedValue, notEqual, (const Value &left, const Value &right)) \ + F(ReturnedValue, strictEqual, (const Value &left, const Value &right)) \ + F(ReturnedValue, strictNotEqual, (const Value &left, const Value &right)) \ + \ + /* comparisons */ \ + F(Bool, compareGreaterThan, (const Value &l, const Value &r)) \ + F(Bool, compareLessThan, (const Value &l, const Value &r)) \ + F(Bool, compareGreaterEqual, (const Value &l, const Value &r)) \ + F(Bool, compareLessEqual, (const Value &l, const Value &r)) \ + F(Bool, compareEqual, (const Value &left, const Value &right)) \ + F(Bool, compareNotEqual, (const Value &left, const Value &right)) \ + F(Bool, compareStrictEqual, (const Value &left, const Value &right)) \ + F(Bool, compareStrictNotEqual, (const Value &left, const Value &right)) \ + \ + F(Bool, compareInstanceof, (ExecutionEngine *engine, const Value &left, const Value &right)) \ + F(Bool, compareIn, (ExecutionEngine *engine, const Value &left, const Value &right)) \ + \ + /* conversions */ \ + F(Bool, toBoolean, (const Value &value)) \ + F(ReturnedValue, toDouble, (const Value &value)) \ + F(int, toInt, (const Value &value)) \ + F(int, doubleToInt, (const double &d)) \ + F(unsigned, toUInt, (const Value &value)) \ + F(unsigned, doubleToUInt, (const double &d)) \ + \ + /* qml */ \ + F(ReturnedValue, getQmlContext, (NoThrowEngine *engine)) \ + F(ReturnedValue, getQmlImportedScripts, (NoThrowEngine *engine)) \ + F(ReturnedValue, getQmlSingleton, (NoThrowEngine *engine, int nameIndex)) \ + F(ReturnedValue, getQmlAttachedProperty, (ExecutionEngine *engine, int attachedPropertiesId, int propertyIndex)) \ + F(ReturnedValue, getQmlScopeObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, bool captureRequired)) \ + F(ReturnedValue, getQmlContextObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, bool captureRequired)) \ + F(ReturnedValue, getQmlQObjectProperty, (ExecutionEngine *engine, const Value &object, int propertyIndex, bool captureRequired)) \ + F(ReturnedValue, getQmlSingletonQObjectProperty, (ExecutionEngine *engine, const Value &object, int propertyIndex, bool captureRequired)) \ + F(ReturnedValue, getQmlIdObject, (ExecutionEngine *engine, const Value &context, uint index)) \ + \ + F(void, setQmlScopeObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, const Value &value)) \ + F(void, setQmlContextObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, const Value &value)) \ + F(void, setQmlQObjectProperty, (ExecutionEngine *engine, const Value &object, int propertyIndex, const Value &value)) struct Q_QML_PRIVATE_EXPORT Runtime { - Runtime() - : INIT_RUNTIME_METHOD(callGlobalLookup) - , INIT_RUNTIME_METHOD(callActivationProperty) - , INIT_RUNTIME_METHOD(callQmlScopeObjectProperty) - , INIT_RUNTIME_METHOD(callQmlContextObjectProperty) - , INIT_RUNTIME_METHOD(callProperty) - , INIT_RUNTIME_METHOD(callPropertyLookup) - , INIT_RUNTIME_METHOD(callElement) - , INIT_RUNTIME_METHOD(callValue) - , INIT_RUNTIME_METHOD(constructGlobalLookup) - , INIT_RUNTIME_METHOD(constructActivationProperty) - , INIT_RUNTIME_METHOD(constructProperty) - , INIT_RUNTIME_METHOD(constructPropertyLookup) - , INIT_RUNTIME_METHOD(constructValue) - , INIT_RUNTIME_METHOD(setActivationProperty) - , INIT_RUNTIME_METHOD(setProperty) - , INIT_RUNTIME_METHOD(setElement) - , INIT_RUNTIME_METHOD(getProperty) - , INIT_RUNTIME_METHOD(getActivationProperty) - , INIT_RUNTIME_METHOD(getElement) - , INIT_RUNTIME_METHOD(typeofValue) - , INIT_RUNTIME_METHOD(typeofName) - , INIT_RUNTIME_METHOD(typeofScopeObjectProperty) - , INIT_RUNTIME_METHOD(typeofContextObjectProperty) - , INIT_RUNTIME_METHOD(typeofMember) - , INIT_RUNTIME_METHOD(typeofElement) - , INIT_RUNTIME_METHOD(deleteElement) - , INIT_RUNTIME_METHOD(deleteMember) - , INIT_RUNTIME_METHOD(deleteMemberString) - , INIT_RUNTIME_METHOD(deleteName) - , INIT_RUNTIME_METHOD(throwException) - , INIT_RUNTIME_METHOD(unwindException) - , INIT_RUNTIME_METHOD(pushWithScope) - , INIT_RUNTIME_METHOD(pushCatchScope) - , INIT_RUNTIME_METHOD(popScope) - , INIT_RUNTIME_METHOD(closure) - , INIT_RUNTIME_METHOD(declareVar) - , INIT_RUNTIME_METHOD(setupArgumentsObject) - , INIT_RUNTIME_METHOD(convertThisToObject) - , INIT_RUNTIME_METHOD(arrayLiteral) - , INIT_RUNTIME_METHOD(objectLiteral) - , INIT_RUNTIME_METHOD(regexpLiteral) - , INIT_RUNTIME_METHOD(foreachIterator) - , INIT_RUNTIME_METHOD(foreachNextPropertyName) - , INIT_RUNTIME_METHOD(uPlus) - , INIT_RUNTIME_METHOD(uMinus) - , INIT_RUNTIME_METHOD(uNot) - , INIT_RUNTIME_METHOD(complement) - , INIT_RUNTIME_METHOD(increment) - , INIT_RUNTIME_METHOD(decrement) - , INIT_RUNTIME_METHOD(instanceof) - , INIT_RUNTIME_METHOD(in) - , INIT_RUNTIME_METHOD(add) - , INIT_RUNTIME_METHOD(addString) - , INIT_RUNTIME_METHOD(bitOr) - , INIT_RUNTIME_METHOD(bitXor) - , INIT_RUNTIME_METHOD(bitAnd) - , INIT_RUNTIME_METHOD(sub) - , INIT_RUNTIME_METHOD(mul) - , INIT_RUNTIME_METHOD(div) - , INIT_RUNTIME_METHOD(mod) - , INIT_RUNTIME_METHOD(shl) - , INIT_RUNTIME_METHOD(shr) - , INIT_RUNTIME_METHOD(ushr) - , INIT_RUNTIME_METHOD(greaterThan) - , INIT_RUNTIME_METHOD(lessThan) - , INIT_RUNTIME_METHOD(greaterEqual) - , INIT_RUNTIME_METHOD(lessEqual) - , INIT_RUNTIME_METHOD(equal) - , INIT_RUNTIME_METHOD(notEqual) - , INIT_RUNTIME_METHOD(strictEqual) - , INIT_RUNTIME_METHOD(strictNotEqual) - , INIT_RUNTIME_METHOD(compareGreaterThan) - , INIT_RUNTIME_METHOD(compareLessThan) - , INIT_RUNTIME_METHOD(compareGreaterEqual) - , INIT_RUNTIME_METHOD(compareLessEqual) - , INIT_RUNTIME_METHOD(compareEqual) - , INIT_RUNTIME_METHOD(compareNotEqual) - , INIT_RUNTIME_METHOD(compareStrictEqual) - , INIT_RUNTIME_METHOD(compareStrictNotEqual) - , INIT_RUNTIME_METHOD(compareInstanceof) - , INIT_RUNTIME_METHOD(compareIn) - , INIT_RUNTIME_METHOD(toBoolean) - , INIT_RUNTIME_METHOD(toDouble) - , INIT_RUNTIME_METHOD(toInt) - , INIT_RUNTIME_METHOD(doubleToInt) - , INIT_RUNTIME_METHOD(toUInt) - , INIT_RUNTIME_METHOD(doubleToUInt) - , INIT_RUNTIME_METHOD(getQmlContext) - , INIT_RUNTIME_METHOD(getQmlImportedScripts) - , INIT_RUNTIME_METHOD(getQmlSingleton) - , INIT_RUNTIME_METHOD(getQmlAttachedProperty) - , INIT_RUNTIME_METHOD(getQmlScopeObjectProperty) - , INIT_RUNTIME_METHOD(getQmlContextObjectProperty) - , INIT_RUNTIME_METHOD(getQmlQObjectProperty) - , INIT_RUNTIME_METHOD(getQmlSingletonQObjectProperty) - , INIT_RUNTIME_METHOD(getQmlIdObject) - , INIT_RUNTIME_METHOD(setQmlScopeObjectProperty) - , INIT_RUNTIME_METHOD(setQmlContextObjectProperty) - , INIT_RUNTIME_METHOD(setQmlQObjectProperty) - { } - - // call - RUNTIME_METHOD(ReturnedValue, callGlobalLookup, (ExecutionEngine *engine, uint index, CallData *callData)); - RUNTIME_METHOD(ReturnedValue, callActivationProperty, (ExecutionEngine *engine, int nameIndex, CallData *callData)); - RUNTIME_METHOD(ReturnedValue, callQmlScopeObjectProperty, (ExecutionEngine *engine, int propertyIndex, CallData *callData)); - RUNTIME_METHOD(ReturnedValue, callQmlContextObjectProperty, (ExecutionEngine *engine, int propertyIndex, CallData *callData)); - RUNTIME_METHOD(ReturnedValue, callProperty, (ExecutionEngine *engine, int nameIndex, CallData *callData)); - RUNTIME_METHOD(ReturnedValue, callPropertyLookup, (ExecutionEngine *engine, uint index, CallData *callData)); - RUNTIME_METHOD(ReturnedValue, callElement, (ExecutionEngine *engine, const Value &index, CallData *callData)); - RUNTIME_METHOD(ReturnedValue, callValue, (ExecutionEngine *engine, const Value &func, CallData *callData)); - - // construct - RUNTIME_METHOD(ReturnedValue, constructGlobalLookup, (ExecutionEngine *engine, uint index, CallData *callData)); - RUNTIME_METHOD(ReturnedValue, constructActivationProperty, (ExecutionEngine *engine, int nameIndex, CallData *callData)); - RUNTIME_METHOD(ReturnedValue, constructProperty, (ExecutionEngine *engine, int nameIndex, CallData *callData)); - RUNTIME_METHOD(ReturnedValue, constructPropertyLookup, (ExecutionEngine *engine, uint index, CallData *callData)); - RUNTIME_METHOD(ReturnedValue, constructValue, (ExecutionEngine *engine, const Value &func, CallData *callData)); - - // set & get - RUNTIME_METHOD(void, setActivationProperty, (ExecutionEngine *engine, int nameIndex, const Value &value)); - RUNTIME_METHOD(void, setProperty, (ExecutionEngine *engine, const Value &object, int nameIndex, const Value &value)); - RUNTIME_METHOD(void, setElement, (ExecutionEngine *engine, const Value &object, const Value &index, const Value &value)); - RUNTIME_METHOD(ReturnedValue, getProperty, (ExecutionEngine *engine, const Value &object, int nameIndex)); - RUNTIME_METHOD(ReturnedValue, getActivationProperty, (ExecutionEngine *engine, int nameIndex)); - RUNTIME_METHOD(ReturnedValue, getElement, (ExecutionEngine *engine, const Value &object, const Value &index)); - - // typeof - RUNTIME_METHOD(ReturnedValue, typeofValue, (ExecutionEngine *engine, const Value &val)); - RUNTIME_METHOD(ReturnedValue, typeofName, (ExecutionEngine *engine, int nameIndex)); - RUNTIME_METHOD(ReturnedValue, typeofScopeObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex)); - RUNTIME_METHOD(ReturnedValue, typeofContextObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex)); - RUNTIME_METHOD(ReturnedValue, typeofMember, (ExecutionEngine *engine, const Value &base, int nameIndex)); - RUNTIME_METHOD(ReturnedValue, typeofElement, (ExecutionEngine *engine, const Value &base, const Value &index)); - - // delete - RUNTIME_METHOD(ReturnedValue, deleteElement, (ExecutionEngine *engine, const Value &base, const Value &index)); - RUNTIME_METHOD(ReturnedValue, deleteMember, (ExecutionEngine *engine, const Value &base, int nameIndex)); - RUNTIME_METHOD(ReturnedValue, deleteMemberString, (ExecutionEngine *engine, const Value &base, String *name)); - RUNTIME_METHOD(ReturnedValue, deleteName, (ExecutionEngine *engine, int nameIndex)); - - // exceptions & scopes - RUNTIME_METHOD(void, throwException, (ExecutionEngine *engine, const Value &value)); - RUNTIME_METHOD(ReturnedValue, unwindException, (ExecutionEngine *engine)); - RUNTIME_METHOD(void, pushWithScope, (const Value &o, NoThrowEngine *engine)); - RUNTIME_METHOD(void, pushCatchScope, (NoThrowEngine *engine, int exceptionVarNameIndex)); - RUNTIME_METHOD(void, popScope, (NoThrowEngine *engine)); - - // closures - RUNTIME_METHOD(ReturnedValue, closure, (ExecutionEngine *engine, int functionId)); + Runtime(); - // function header - RUNTIME_METHOD(void, declareVar, (ExecutionEngine *engine, bool deletable, int nameIndex)); - RUNTIME_METHOD(ReturnedValue, setupArgumentsObject, (ExecutionEngine *engine)); - RUNTIME_METHOD(void, convertThisToObject, (ExecutionEngine *engine)); - - // literals - RUNTIME_METHOD(ReturnedValue, arrayLiteral, (ExecutionEngine *engine, Value *values, uint length)); - RUNTIME_METHOD(ReturnedValue, objectLiteral, (ExecutionEngine *engine, const Value *args, int classId, int arrayValueCount, int arrayGetterSetterCountAndFlags)); - RUNTIME_METHOD(ReturnedValue, regexpLiteral, (ExecutionEngine *engine, int id)); - - // foreach - RUNTIME_METHOD(ReturnedValue, foreachIterator, (ExecutionEngine *engine, const Value &in)); - RUNTIME_METHOD(ReturnedValue, foreachNextPropertyName, (const Value &foreach_iterator)); - - // unary operators typedef ReturnedValue (*UnaryOperation)(const Value &value); - RUNTIME_METHOD(ReturnedValue, uPlus, (const Value &value)); - RUNTIME_METHOD(ReturnedValue, uMinus, (const Value &value)); - RUNTIME_METHOD(ReturnedValue, uNot, (const Value &value)); - RUNTIME_METHOD(ReturnedValue, complement, (const Value &value)); - RUNTIME_METHOD(ReturnedValue, increment, (const Value &value)); - RUNTIME_METHOD(ReturnedValue, decrement, (const Value &value)); - - // binary operators typedef ReturnedValue (*BinaryOperation)(const Value &left, const Value &right); typedef ReturnedValue (*BinaryOperationContext)(ExecutionEngine *engine, const Value &left, const Value &right); - RUNTIME_METHOD(ReturnedValue, instanceof, (ExecutionEngine *engine, const Value &left, const Value &right)); - RUNTIME_METHOD(ReturnedValue, in, (ExecutionEngine *engine, const Value &left, const Value &right)); - RUNTIME_METHOD(ReturnedValue, add, (ExecutionEngine *engine, const Value &left, const Value &right)); - RUNTIME_METHOD(ReturnedValue, addString, (ExecutionEngine *engine, const Value &left, const Value &right)); - RUNTIME_METHOD(ReturnedValue, bitOr, (const Value &left, const Value &right)); - RUNTIME_METHOD(ReturnedValue, bitXor, (const Value &left, const Value &right)); - RUNTIME_METHOD(ReturnedValue, bitAnd, (const Value &left, const Value &right)); - RUNTIME_METHOD(ReturnedValue, sub, (const Value &left, const Value &right)); - RUNTIME_METHOD(ReturnedValue, mul, (const Value &left, const Value &right)); - RUNTIME_METHOD(ReturnedValue, div, (const Value &left, const Value &right)); - RUNTIME_METHOD(ReturnedValue, mod, (const Value &left, const Value &right)); - RUNTIME_METHOD(ReturnedValue, shl, (const Value &left, const Value &right)); - RUNTIME_METHOD(ReturnedValue, shr, (const Value &left, const Value &right)); - RUNTIME_METHOD(ReturnedValue, ushr, (const Value &left, const Value &right)); - RUNTIME_METHOD(ReturnedValue, greaterThan, (const Value &left, const Value &right)); - RUNTIME_METHOD(ReturnedValue, lessThan, (const Value &left, const Value &right)); - RUNTIME_METHOD(ReturnedValue, greaterEqual, (const Value &left, const Value &right)); - RUNTIME_METHOD(ReturnedValue, lessEqual, (const Value &left, const Value &right)); - RUNTIME_METHOD(ReturnedValue, equal, (const Value &left, const Value &right)); - RUNTIME_METHOD(ReturnedValue, notEqual, (const Value &left, const Value &right)); - RUNTIME_METHOD(ReturnedValue, strictEqual, (const Value &left, const Value &right)); - RUNTIME_METHOD(ReturnedValue, strictNotEqual, (const Value &left, const Value &right)); - - // comparisons - RUNTIME_METHOD(Bool, compareGreaterThan, (const Value &l, const Value &r)); - RUNTIME_METHOD(Bool, compareLessThan, (const Value &l, const Value &r)); - RUNTIME_METHOD(Bool, compareGreaterEqual, (const Value &l, const Value &r)); - RUNTIME_METHOD(Bool, compareLessEqual, (const Value &l, const Value &r)); - RUNTIME_METHOD(Bool, compareEqual, (const Value &left, const Value &right)); - RUNTIME_METHOD(Bool, compareNotEqual, (const Value &left, const Value &right)); - RUNTIME_METHOD(Bool, compareStrictEqual, (const Value &left, const Value &right)); - RUNTIME_METHOD(Bool, compareStrictNotEqual, (const Value &left, const Value &right)); +#define DEFINE_RUNTIME_METHOD_ENUM(returnvalue, name, args) name, + enum RuntimeMethods { + FOR_EACH_RUNTIME_METHOD(DEFINE_RUNTIME_METHOD_ENUM) + RuntimeMethodCount, + InvalidRuntimeMethod = RuntimeMethodCount + }; +#undef DEFINE_RUNTIME_METHOD_ENUM - RUNTIME_METHOD(Bool, compareInstanceof, (ExecutionEngine *engine, const Value &left, const Value &right)); - RUNTIME_METHOD(Bool, compareIn, (ExecutionEngine *engine, const Value &left, const Value &right)); + void *runtimeMethods[RuntimeMethodCount]; - // conversions - RUNTIME_METHOD(Bool, toBoolean, (const Value &value)); - RUNTIME_METHOD(ReturnedValue, toDouble, (const Value &value)); - RUNTIME_METHOD(int, toInt, (const Value &value)); - RUNTIME_METHOD(int, doubleToInt, (const double &d)); - RUNTIME_METHOD(unsigned, toUInt, (const Value &value)); - RUNTIME_METHOD(unsigned, doubleToUInt, (const double &d)); + static uint runtimeMethodOffset(RuntimeMethods method) { return method*QT_POINTER_SIZE; } - // qml - RUNTIME_METHOD(ReturnedValue, getQmlContext, (NoThrowEngine *engine)); - RUNTIME_METHOD(ReturnedValue, getQmlImportedScripts, (NoThrowEngine *engine)); - RUNTIME_METHOD(ReturnedValue, getQmlSingleton, (NoThrowEngine *engine, int nameIndex)); - RUNTIME_METHOD(ReturnedValue, getQmlAttachedProperty, (ExecutionEngine *engine, int attachedPropertiesId, int propertyIndex)); - RUNTIME_METHOD(ReturnedValue, getQmlScopeObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, bool captureRequired)); - RUNTIME_METHOD(ReturnedValue, getQmlContextObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, bool captureRequired)); - RUNTIME_METHOD(ReturnedValue, getQmlQObjectProperty, (ExecutionEngine *engine, const Value &object, int propertyIndex, bool captureRequired)); - RUNTIME_METHOD(ReturnedValue, getQmlSingletonQObjectProperty, (ExecutionEngine *engine, const Value &object, int propertyIndex, bool captureRequired)); - RUNTIME_METHOD(ReturnedValue, getQmlIdObject, (ExecutionEngine *engine, const Value &context, uint index)); +#define RUNTIME_METHOD(returnvalue, name, args) \ + typedef returnvalue (*Method_##name)args; \ + enum { Method_##name##_NeedsExceptionCheck = ExceptionCheck<Method_##name>::NeedsCheck }; \ + static returnvalue method_##name args; + FOR_EACH_RUNTIME_METHOD(RUNTIME_METHOD) +#undef RUNTIME_METHOD - RUNTIME_METHOD(void, setQmlScopeObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, const Value &value)); - RUNTIME_METHOD(void, setQmlContextObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, const Value &value)); - RUNTIME_METHOD(void, setQmlQObjectProperty, (ExecutionEngine *engine, const Value &object, int propertyIndex, const Value &value)); }; -#undef RUNTIME_METHOD -#undef INIT_RUNTIME_METHOD +static_assert(std::is_standard_layout<Runtime>::value, "Runtime needs to be standard layout in order for us to be able to use offsetof"); +static_assert(offsetof(Runtime, runtimeMethods) == 0, "JIT expects this to be the first member"); +static_assert(sizeof(Runtime::BinaryOperation) == sizeof(void*), "JIT expects a function pointer to fit into a regular pointer, for cross-compilation offset translation"); } // namespace QV4 diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h index 6775028272..894434be16 100644 --- a/src/qml/jsruntime/qv4scopedvalue_p.h +++ b/src/qml/jsruntime/qv4scopedvalue_p.h @@ -366,7 +366,7 @@ struct Scoped struct ScopedCallData { ScopedCallData(const Scope &scope, int argc = 0) { - int size = qMax(argc, (int)QV4::Global::ReservedArgumentCount) + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value); + int size = qMax(argc, QV4::Global::ReservedArgumentCount + int(offsetof(QV4::CallData, args)/sizeof(QV4::Value))); ptr = reinterpret_cast<CallData *>(scope.alloc(size)); ptr->tag = QV4::Value::Integer_Type_Internal; ptr->argc = argc; diff --git a/src/qml/jsruntime/qv4script_p.h b/src/qml/jsruntime/qv4script_p.h index f96f0254a5..4ebe2dd609 100644 --- a/src/qml/jsruntime/qv4script_p.h +++ b/src/qml/jsruntime/qv4script_p.h @@ -72,7 +72,7 @@ struct ContextStateSaver { bool strictMode; Lookup *lookups; const QV4::Value *constantTable; - CompiledData::CompilationUnit *compilationUnit; + CompiledData::CompilationUnitBase *compilationUnit; int lineNumber; ContextStateSaver(const Scope &scope, ExecutionContext *context) diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h index 6d98692e94..11d75dde99 100644 --- a/src/qml/jsruntime/qv4value_p.h +++ b/src/qml/jsruntime/qv4value_p.h @@ -68,8 +68,6 @@ namespace Heap { struct Base; } -typedef uint Bool; - struct Q_QML_PRIVATE_EXPORT Value { private: diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp index 09f767dc13..8d523f17e9 100644 --- a/src/qml/jsruntime/qv4vme_moth.cpp +++ b/src/qml/jsruntime/qv4vme_moth.cpp @@ -412,7 +412,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code }; Q_ALLOCA_VAR(Scopes, scopes, sizeof(Scopes)*(2 + 2*scopeDepth)); { - scopes[0] = { const_cast<QV4::Value *>(context->d()->compilationUnit->constants), 0 }; + scopes[0] = { const_cast<QV4::Value *>(static_cast<CompiledData::CompilationUnit*>(context->d()->compilationUnit)->constants), 0 }; // stack gets setup in push instruction scopes[1] = { 0, 0 }; QV4::Heap::ExecutionContext *scope = context->d(); @@ -463,16 +463,16 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code MOTH_BEGIN_INSTR(LoadRegExp) // TRACE(value, "%s", instr.value.toString(context)->toQString().toUtf8().constData()); - VALUE(instr.result) = context->d()->compilationUnit->runtimeRegularExpressions[instr.regExpId]; + VALUE(instr.result) = static_cast<CompiledData::CompilationUnit*>(context->d()->compilationUnit)->runtimeRegularExpressions[instr.regExpId]; MOTH_END_INSTR(LoadRegExp) MOTH_BEGIN_INSTR(LoadClosure) - STOREVALUE(instr.result, engine->runtime.closure(engine, instr.value)); + STOREVALUE(instr.result, Runtime::method_closure(engine, instr.value)); MOTH_END_INSTR(LoadClosure) MOTH_BEGIN_INSTR(LoadName) TRACE(inline, "property name = %s", runtimeStrings[instr.name]->toQString().toUtf8().constData()); - STOREVALUE(instr.result, engine->runtime.getActivationProperty(engine, instr.name)); + STOREVALUE(instr.result, Runtime::method_getActivationProperty(engine, instr.name)); MOTH_END_INSTR(LoadName) MOTH_BEGIN_INSTR(GetGlobalLookup) @@ -482,12 +482,12 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code MOTH_BEGIN_INSTR(StoreName) TRACE(inline, "property name = %s", runtimeStrings[instr.name]->toQString().toUtf8().constData()); - engine->runtime.setActivationProperty(engine, instr.name, VALUE(instr.source)); + Runtime::method_setActivationProperty(engine, instr.name, VALUE(instr.source)); CHECK_EXCEPTION; MOTH_END_INSTR(StoreName) MOTH_BEGIN_INSTR(LoadElement) - STOREVALUE(instr.result, engine->runtime.getElement(engine, VALUE(instr.base), VALUE(instr.index))); + STOREVALUE(instr.result, Runtime::method_getElement(engine, VALUE(instr.base), VALUE(instr.index))); MOTH_END_INSTR(LoadElement) MOTH_BEGIN_INSTR(LoadElementLookup) @@ -496,7 +496,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code MOTH_END_INSTR(LoadElementLookup) MOTH_BEGIN_INSTR(StoreElement) - engine->runtime.setElement(engine, VALUE(instr.base), VALUE(instr.index), VALUE(instr.source)); + Runtime::method_setElement(engine, VALUE(instr.base), VALUE(instr.index), VALUE(instr.source)); CHECK_EXCEPTION; MOTH_END_INSTR(StoreElement) @@ -507,7 +507,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code MOTH_END_INSTR(StoreElementLookup) MOTH_BEGIN_INSTR(LoadProperty) - STOREVALUE(instr.result, engine->runtime.getProperty(engine, VALUE(instr.base), instr.name)); + STOREVALUE(instr.result, Runtime::method_getProperty(engine, VALUE(instr.base), instr.name)); MOTH_END_INSTR(LoadProperty) MOTH_BEGIN_INSTR(GetLookup) @@ -516,7 +516,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code MOTH_END_INSTR(GetLookup) MOTH_BEGIN_INSTR(StoreProperty) - engine->runtime.setProperty(engine, VALUE(instr.base), instr.name, VALUE(instr.source)); + Runtime::method_setProperty(engine, VALUE(instr.base), instr.name, VALUE(instr.source)); CHECK_EXCEPTION; MOTH_END_INSTR(StoreProperty) @@ -527,42 +527,42 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code MOTH_END_INSTR(SetLookup) MOTH_BEGIN_INSTR(StoreQObjectProperty) - engine->runtime.setQmlQObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, VALUE(instr.source)); + Runtime::method_setQmlQObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, VALUE(instr.source)); CHECK_EXCEPTION; MOTH_END_INSTR(StoreQObjectProperty) MOTH_BEGIN_INSTR(LoadQObjectProperty) - STOREVALUE(instr.result, engine->runtime.getQmlQObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, instr.captureRequired)); + STOREVALUE(instr.result, Runtime::method_getQmlQObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, instr.captureRequired)); MOTH_END_INSTR(LoadQObjectProperty) MOTH_BEGIN_INSTR(StoreScopeObjectProperty) - engine->runtime.setQmlScopeObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, VALUE(instr.source)); + Runtime::method_setQmlScopeObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, VALUE(instr.source)); CHECK_EXCEPTION; MOTH_END_INSTR(StoreScopeObjectProperty) MOTH_BEGIN_INSTR(LoadScopeObjectProperty) - STOREVALUE(instr.result, engine->runtime.getQmlScopeObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, instr.captureRequired)); + STOREVALUE(instr.result, Runtime::method_getQmlScopeObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, instr.captureRequired)); MOTH_END_INSTR(LoadScopeObjectProperty) MOTH_BEGIN_INSTR(StoreContextObjectProperty) - engine->runtime.setQmlContextObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, VALUE(instr.source)); + Runtime::method_setQmlContextObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, VALUE(instr.source)); CHECK_EXCEPTION; MOTH_END_INSTR(StoreContextObjectProperty) MOTH_BEGIN_INSTR(LoadContextObjectProperty) - STOREVALUE(instr.result, engine->runtime.getQmlContextObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, instr.captureRequired)); + STOREVALUE(instr.result, Runtime::method_getQmlContextObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, instr.captureRequired)); MOTH_END_INSTR(LoadContextObjectProperty) MOTH_BEGIN_INSTR(LoadIdObject) - STOREVALUE(instr.result, engine->runtime.getQmlIdObject(engine, VALUE(instr.base), instr.index)); + STOREVALUE(instr.result, Runtime::method_getQmlIdObject(engine, VALUE(instr.base), instr.index)); MOTH_END_INSTR(LoadIdObject) MOTH_BEGIN_INSTR(LoadAttachedQObjectProperty) - STOREVALUE(instr.result, engine->runtime.getQmlAttachedProperty(engine, instr.attachedPropertiesId, instr.propertyIndex)); + STOREVALUE(instr.result, Runtime::method_getQmlAttachedProperty(engine, instr.attachedPropertiesId, instr.propertyIndex)); MOTH_END_INSTR(LoadAttachedQObjectProperty) MOTH_BEGIN_INSTR(LoadSingletonQObjectProperty) - STOREVALUE(instr.result, engine->runtime.getQmlSingletonQObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, instr.captureRequired)); + STOREVALUE(instr.result, Runtime::method_getQmlSingletonQObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, instr.captureRequired)); MOTH_END_INSTR(LoadSingletonQObjectProperty) MOTH_BEGIN_INSTR(Push) @@ -583,73 +583,73 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code } } #endif // DO_TRACE_INSTR - Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize); + Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize); QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData); callData->tag = QV4::Value::Integer_Type_Internal; callData->argc = instr.argc; callData->thisObject = QV4::Primitive::undefinedValue(); - STOREVALUE(instr.result, engine->runtime.callValue(engine, VALUE(instr.dest), callData)); + STOREVALUE(instr.result, Runtime::method_callValue(engine, VALUE(instr.dest), callData)); MOTH_END_INSTR(CallValue) MOTH_BEGIN_INSTR(CallProperty) TRACE(property name, "%s, args=%u, argc=%u, this=%s", qPrintable(runtimeStrings[instr.name]->toQString()), instr.callData, instr.argc, (VALUE(instr.base)).toString(context)->toQString().toUtf8().constData()); - Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize); + Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize); QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData); callData->tag = QV4::Value::Integer_Type_Internal; callData->argc = instr.argc; callData->thisObject = VALUE(instr.base); - STOREVALUE(instr.result, engine->runtime.callProperty(engine, instr.name, callData)); + STOREVALUE(instr.result, Runtime::method_callProperty(engine, instr.name, callData)); MOTH_END_INSTR(CallProperty) MOTH_BEGIN_INSTR(CallPropertyLookup) - Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize); + Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize); QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData); callData->tag = QV4::Value::Integer_Type_Internal; callData->argc = instr.argc; callData->thisObject = VALUE(instr.base); - STOREVALUE(instr.result, engine->runtime.callPropertyLookup(engine, instr.lookupIndex, callData)); + STOREVALUE(instr.result, Runtime::method_callPropertyLookup(engine, instr.lookupIndex, callData)); MOTH_END_INSTR(CallPropertyLookup) MOTH_BEGIN_INSTR(CallScopeObjectProperty) TRACE(property name, "%s, args=%u, argc=%u, this=%s", qPrintable(runtimeStrings[instr.name]->toQString()), instr.callData, instr.argc, (VALUE(instr.base)).toString(context)->toQString().toUtf8().constData()); - Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize); + Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize); QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData); callData->tag = QV4::Value::Integer_Type_Internal; callData->argc = instr.argc; callData->thisObject = VALUE(instr.base); - STOREVALUE(instr.result, engine->runtime.callQmlScopeObjectProperty(engine, instr.index, callData)); + STOREVALUE(instr.result, Runtime::method_callQmlScopeObjectProperty(engine, instr.index, callData)); MOTH_END_INSTR(CallScopeObjectProperty) MOTH_BEGIN_INSTR(CallContextObjectProperty) TRACE(property name, "%s, args=%u, argc=%u, this=%s", qPrintable(runtimeStrings[instr.name]->toQString()), instr.callData, instr.argc, (VALUE(instr.base)).toString(context)->toQString().toUtf8().constData()); - Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize); + Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize); QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData); callData->tag = QV4::Value::Integer_Type_Internal; callData->argc = instr.argc; callData->thisObject = VALUE(instr.base); - STOREVALUE(instr.result, engine->runtime.callQmlContextObjectProperty(engine, instr.index, callData)); + STOREVALUE(instr.result, Runtime::method_callQmlContextObjectProperty(engine, instr.index, callData)); MOTH_END_INSTR(CallContextObjectProperty) MOTH_BEGIN_INSTR(CallElement) - Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize); + Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize); QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData); callData->tag = QV4::Value::Integer_Type_Internal; callData->argc = instr.argc; callData->thisObject = VALUE(instr.base); - STOREVALUE(instr.result, engine->runtime.callElement(engine, VALUE(instr.index), callData)); + STOREVALUE(instr.result, Runtime::method_callElement(engine, VALUE(instr.index), callData)); MOTH_END_INSTR(CallElement) MOTH_BEGIN_INSTR(CallActivationProperty) - Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize); + Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize); QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData); callData->tag = QV4::Value::Integer_Type_Internal; callData->argc = instr.argc; callData->thisObject = QV4::Primitive::undefinedValue(); - STOREVALUE(instr.result, engine->runtime.callActivationProperty(engine, instr.name, callData)); + STOREVALUE(instr.result, Runtime::method_callActivationProperty(engine, instr.name, callData)); MOTH_END_INSTR(CallActivationProperty) MOTH_BEGIN_INSTR(CallGlobalLookup) - Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize); + Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize); QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData); callData->tag = QV4::Value::Integer_Type_Internal; callData->argc = instr.argc; @@ -662,141 +662,141 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code MOTH_END_INSTR(SetExceptionHandler) MOTH_BEGIN_INSTR(CallBuiltinThrow) - engine->runtime.throwException(engine, VALUE(instr.arg)); + Runtime::method_throwException(engine, VALUE(instr.arg)); CHECK_EXCEPTION; MOTH_END_INSTR(CallBuiltinThrow) MOTH_BEGIN_INSTR(CallBuiltinUnwindException) - STOREVALUE(instr.result, engine->runtime.unwindException(engine)); + STOREVALUE(instr.result, Runtime::method_unwindException(engine)); MOTH_END_INSTR(CallBuiltinUnwindException) MOTH_BEGIN_INSTR(CallBuiltinPushCatchScope) - engine->runtime.pushCatchScope(static_cast<QV4::NoThrowEngine*>(engine), instr.name); + Runtime::method_pushCatchScope(static_cast<QV4::NoThrowEngine*>(engine), instr.name); context = engine->currentContext; MOTH_END_INSTR(CallBuiltinPushCatchScope) MOTH_BEGIN_INSTR(CallBuiltinPushScope) - engine->runtime.pushWithScope(VALUE(instr.arg), static_cast<QV4::NoThrowEngine*>(engine)); + Runtime::method_pushWithScope(VALUE(instr.arg), static_cast<QV4::NoThrowEngine*>(engine)); context = engine->currentContext; CHECK_EXCEPTION; MOTH_END_INSTR(CallBuiltinPushScope) MOTH_BEGIN_INSTR(CallBuiltinPopScope) - engine->runtime.popScope(static_cast<QV4::NoThrowEngine*>(engine)); + Runtime::method_popScope(static_cast<QV4::NoThrowEngine*>(engine)); context = engine->currentContext; MOTH_END_INSTR(CallBuiltinPopScope) MOTH_BEGIN_INSTR(CallBuiltinForeachIteratorObject) - STOREVALUE(instr.result, engine->runtime.foreachIterator(engine, VALUE(instr.arg))); + STOREVALUE(instr.result, Runtime::method_foreachIterator(engine, VALUE(instr.arg))); MOTH_END_INSTR(CallBuiltinForeachIteratorObject) MOTH_BEGIN_INSTR(CallBuiltinForeachNextPropertyName) - STOREVALUE(instr.result, engine->runtime.foreachNextPropertyName(VALUE(instr.arg))); + STOREVALUE(instr.result, Runtime::method_foreachNextPropertyName(VALUE(instr.arg))); MOTH_END_INSTR(CallBuiltinForeachNextPropertyName) MOTH_BEGIN_INSTR(CallBuiltinDeleteMember) - STOREVALUE(instr.result, engine->runtime.deleteMember(engine, VALUE(instr.base), instr.member)); + STOREVALUE(instr.result, Runtime::method_deleteMember(engine, VALUE(instr.base), instr.member)); MOTH_END_INSTR(CallBuiltinDeleteMember) MOTH_BEGIN_INSTR(CallBuiltinDeleteSubscript) - STOREVALUE(instr.result, engine->runtime.deleteElement(engine, VALUE(instr.base), VALUE(instr.index))); + STOREVALUE(instr.result, Runtime::method_deleteElement(engine, VALUE(instr.base), VALUE(instr.index))); MOTH_END_INSTR(CallBuiltinDeleteSubscript) MOTH_BEGIN_INSTR(CallBuiltinDeleteName) - STOREVALUE(instr.result, engine->runtime.deleteName(engine, instr.name)); + STOREVALUE(instr.result, Runtime::method_deleteName(engine, instr.name)); MOTH_END_INSTR(CallBuiltinDeleteName) MOTH_BEGIN_INSTR(CallBuiltinTypeofScopeObjectProperty) - STOREVALUE(instr.result, engine->runtime.typeofScopeObjectProperty(engine, VALUE(instr.base), instr.index)); + STOREVALUE(instr.result, Runtime::method_typeofScopeObjectProperty(engine, VALUE(instr.base), instr.index)); MOTH_END_INSTR(CallBuiltinTypeofMember) MOTH_BEGIN_INSTR(CallBuiltinTypeofContextObjectProperty) - STOREVALUE(instr.result, engine->runtime.typeofContextObjectProperty(engine, VALUE(instr.base), instr.index)); + STOREVALUE(instr.result, Runtime::method_typeofContextObjectProperty(engine, VALUE(instr.base), instr.index)); MOTH_END_INSTR(CallBuiltinTypeofMember) MOTH_BEGIN_INSTR(CallBuiltinTypeofMember) - STOREVALUE(instr.result, engine->runtime.typeofMember(engine, VALUE(instr.base), instr.member)); + STOREVALUE(instr.result, Runtime::method_typeofMember(engine, VALUE(instr.base), instr.member)); MOTH_END_INSTR(CallBuiltinTypeofMember) MOTH_BEGIN_INSTR(CallBuiltinTypeofSubscript) - STOREVALUE(instr.result, engine->runtime.typeofElement(engine, VALUE(instr.base), VALUE(instr.index))); + STOREVALUE(instr.result, Runtime::method_typeofElement(engine, VALUE(instr.base), VALUE(instr.index))); MOTH_END_INSTR(CallBuiltinTypeofSubscript) MOTH_BEGIN_INSTR(CallBuiltinTypeofName) - STOREVALUE(instr.result, engine->runtime.typeofName(engine, instr.name)); + STOREVALUE(instr.result, Runtime::method_typeofName(engine, instr.name)); MOTH_END_INSTR(CallBuiltinTypeofName) MOTH_BEGIN_INSTR(CallBuiltinTypeofValue) - STOREVALUE(instr.result, engine->runtime.typeofValue(engine, VALUE(instr.value))); + STOREVALUE(instr.result, Runtime::method_typeofValue(engine, VALUE(instr.value))); MOTH_END_INSTR(CallBuiltinTypeofValue) MOTH_BEGIN_INSTR(CallBuiltinDeclareVar) - engine->runtime.declareVar(engine, instr.isDeletable, instr.varName); + Runtime::method_declareVar(engine, instr.isDeletable, instr.varName); MOTH_END_INSTR(CallBuiltinDeclareVar) MOTH_BEGIN_INSTR(CallBuiltinDefineArray) Q_ASSERT(instr.args + instr.argc <= stackSize); QV4::Value *args = stack + instr.args; - STOREVALUE(instr.result, engine->runtime.arrayLiteral(engine, args, instr.argc)); + STOREVALUE(instr.result, Runtime::method_arrayLiteral(engine, args, instr.argc)); MOTH_END_INSTR(CallBuiltinDefineArray) MOTH_BEGIN_INSTR(CallBuiltinDefineObjectLiteral) QV4::Value *args = stack + instr.args; - STOREVALUE(instr.result, engine->runtime.objectLiteral(engine, args, instr.internalClassId, instr.arrayValueCount, instr.arrayGetterSetterCountAndFlags)); + STOREVALUE(instr.result, Runtime::method_objectLiteral(engine, args, instr.internalClassId, instr.arrayValueCount, instr.arrayGetterSetterCountAndFlags)); MOTH_END_INSTR(CallBuiltinDefineObjectLiteral) MOTH_BEGIN_INSTR(CallBuiltinSetupArgumentsObject) - STOREVALUE(instr.result, engine->runtime.setupArgumentsObject(engine)); + STOREVALUE(instr.result, Runtime::method_setupArgumentsObject(engine)); MOTH_END_INSTR(CallBuiltinSetupArgumentsObject) MOTH_BEGIN_INSTR(CallBuiltinConvertThisToObject) - engine->runtime.convertThisToObject(engine); + Runtime::method_convertThisToObject(engine); CHECK_EXCEPTION; MOTH_END_INSTR(CallBuiltinConvertThisToObject) MOTH_BEGIN_INSTR(CreateValue) - Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize); + Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize); QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData); callData->tag = QV4::Value::Integer_Type_Internal; callData->argc = instr.argc; callData->thisObject = QV4::Primitive::undefinedValue(); - STOREVALUE(instr.result, engine->runtime.constructValue(engine, VALUE(instr.func), callData)); + STOREVALUE(instr.result, Runtime::method_constructValue(engine, VALUE(instr.func), callData)); MOTH_END_INSTR(CreateValue) MOTH_BEGIN_INSTR(CreateProperty) - Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize); + Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize); QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData); callData->tag = QV4::Value::Integer_Type_Internal; callData->argc = instr.argc; callData->thisObject = VALUE(instr.base); - STOREVALUE(instr.result, engine->runtime.constructProperty(engine, instr.name, callData)); + STOREVALUE(instr.result, Runtime::method_constructProperty(engine, instr.name, callData)); MOTH_END_INSTR(CreateProperty) MOTH_BEGIN_INSTR(ConstructPropertyLookup) - Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize); + Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize); QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData); callData->tag = QV4::Value::Integer_Type_Internal; callData->argc = instr.argc; callData->thisObject = VALUE(instr.base); - STOREVALUE(instr.result, engine->runtime.constructPropertyLookup(engine, instr.index, callData)); + STOREVALUE(instr.result, Runtime::method_constructPropertyLookup(engine, instr.index, callData)); MOTH_END_INSTR(ConstructPropertyLookup) MOTH_BEGIN_INSTR(CreateActivationProperty) - Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize); + Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize); QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData); callData->tag = QV4::Value::Integer_Type_Internal; callData->argc = instr.argc; callData->thisObject = QV4::Primitive::undefinedValue(); - STOREVALUE(instr.result, engine->runtime.constructActivationProperty(engine, instr.name, callData)); + STOREVALUE(instr.result, Runtime::method_constructActivationProperty(engine, instr.name, callData)); MOTH_END_INSTR(CreateActivationProperty) MOTH_BEGIN_INSTR(ConstructGlobalLookup) - Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize); + Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize); QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData); callData->tag = QV4::Value::Integer_Type_Internal; callData->argc = instr.argc; callData->thisObject = QV4::Primitive::undefinedValue(); - STOREVALUE(instr.result, engine->runtime.constructGlobalLookup(engine, instr.index, callData)); + STOREVALUE(instr.result, Runtime::method_constructGlobalLookup(engine, instr.index, callData)); MOTH_END_INSTR(ConstructGlobalLookup) MOTH_BEGIN_INSTR(Jump) @@ -818,7 +818,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code MOTH_END_INSTR(JumpNe) MOTH_BEGIN_INSTR(UNot) - STOREVALUE(instr.result, engine->runtime.uNot(VALUE(instr.source))); + STOREVALUE(instr.result, Runtime::method_uNot(VALUE(instr.source))); MOTH_END_INSTR(UNot) MOTH_BEGIN_INSTR(UNotBool) @@ -827,15 +827,15 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code MOTH_END_INSTR(UNotBool) MOTH_BEGIN_INSTR(UPlus) - STOREVALUE(instr.result, engine->runtime.uPlus(VALUE(instr.source))); + STOREVALUE(instr.result, Runtime::method_uPlus(VALUE(instr.source))); MOTH_END_INSTR(UPlus) MOTH_BEGIN_INSTR(UMinus) - STOREVALUE(instr.result, engine->runtime.uMinus(VALUE(instr.source))); + STOREVALUE(instr.result, Runtime::method_uMinus(VALUE(instr.source))); MOTH_END_INSTR(UMinus) MOTH_BEGIN_INSTR(UCompl) - STOREVALUE(instr.result, engine->runtime.complement(VALUE(instr.source))); + STOREVALUE(instr.result, Runtime::method_complement(VALUE(instr.source))); MOTH_END_INSTR(UCompl) MOTH_BEGIN_INSTR(UComplInt) @@ -843,32 +843,32 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code MOTH_END_INSTR(UComplInt) MOTH_BEGIN_INSTR(Increment) - STOREVALUE(instr.result, engine->runtime.increment(VALUE(instr.source))); + STOREVALUE(instr.result, Runtime::method_increment(VALUE(instr.source))); MOTH_END_INSTR(Increment) MOTH_BEGIN_INSTR(Decrement) - STOREVALUE(instr.result, engine->runtime.decrement(VALUE(instr.source))); + STOREVALUE(instr.result, Runtime::method_decrement(VALUE(instr.source))); MOTH_END_INSTR(Decrement) MOTH_BEGIN_INSTR(Binop) - QV4::Runtime::BinaryOperation op = *reinterpret_cast<QV4::Runtime::BinaryOperation *>(reinterpret_cast<char *>(&engine->runtime) + instr.alu); + QV4::Runtime::BinaryOperation op = *reinterpret_cast<QV4::Runtime::BinaryOperation *>(reinterpret_cast<char *>(&engine->runtime.runtimeMethods[instr.alu])); STOREVALUE(instr.result, op(VALUE(instr.lhs), VALUE(instr.rhs))); MOTH_END_INSTR(Binop) MOTH_BEGIN_INSTR(Add) - STOREVALUE(instr.result, engine->runtime.add(engine, VALUE(instr.lhs), VALUE(instr.rhs))); + STOREVALUE(instr.result, Runtime::method_add(engine, VALUE(instr.lhs), VALUE(instr.rhs))); MOTH_END_INSTR(Add) MOTH_BEGIN_INSTR(BitAnd) - STOREVALUE(instr.result, engine->runtime.bitAnd(VALUE(instr.lhs), VALUE(instr.rhs))); + STOREVALUE(instr.result, Runtime::method_bitAnd(VALUE(instr.lhs), VALUE(instr.rhs))); MOTH_END_INSTR(BitAnd) MOTH_BEGIN_INSTR(BitOr) - STOREVALUE(instr.result, engine->runtime.bitOr(VALUE(instr.lhs), VALUE(instr.rhs))); + STOREVALUE(instr.result, Runtime::method_bitOr(VALUE(instr.lhs), VALUE(instr.rhs))); MOTH_END_INSTR(BitOr) MOTH_BEGIN_INSTR(BitXor) - STOREVALUE(instr.result, engine->runtime.bitXor(VALUE(instr.lhs), VALUE(instr.rhs))); + STOREVALUE(instr.result, Runtime::method_bitXor(VALUE(instr.lhs), VALUE(instr.rhs))); MOTH_END_INSTR(BitXor) MOTH_BEGIN_INSTR(Shr) @@ -903,15 +903,15 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code MOTH_END_INSTR(ShlConst) MOTH_BEGIN_INSTR(Mul) - STOREVALUE(instr.result, engine->runtime.mul(VALUE(instr.lhs), VALUE(instr.rhs))); + STOREVALUE(instr.result, Runtime::method_mul(VALUE(instr.lhs), VALUE(instr.rhs))); MOTH_END_INSTR(Mul) MOTH_BEGIN_INSTR(Sub) - STOREVALUE(instr.result, engine->runtime.sub(VALUE(instr.lhs), VALUE(instr.rhs))); + STOREVALUE(instr.result, Runtime::method_sub(VALUE(instr.lhs), VALUE(instr.rhs))); MOTH_END_INSTR(Sub) MOTH_BEGIN_INSTR(BinopContext) - QV4::Runtime::BinaryOperationContext op = *reinterpret_cast<QV4::Runtime::BinaryOperationContext *>(reinterpret_cast<char *>(&engine->runtime) + instr.alu); + QV4::Runtime::BinaryOperationContext op = *reinterpret_cast<QV4::Runtime::BinaryOperationContext *>(reinterpret_cast<char *>(&engine->runtime.runtimeMethods[instr.alu])); STOREVALUE(instr.result, op(engine, VALUE(instr.lhs), VALUE(instr.rhs))); MOTH_END_INSTR(BinopContext) @@ -942,15 +942,15 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code MOTH_END_INSTR(LoadThis) MOTH_BEGIN_INSTR(LoadQmlContext) - VALUE(instr.result) = engine->runtime.getQmlContext(static_cast<QV4::NoThrowEngine*>(engine)); + VALUE(instr.result) = Runtime::method_getQmlContext(static_cast<QV4::NoThrowEngine*>(engine)); MOTH_END_INSTR(LoadQmlContext) MOTH_BEGIN_INSTR(LoadQmlImportedScripts) - VALUE(instr.result) = engine->runtime.getQmlImportedScripts(static_cast<QV4::NoThrowEngine*>(engine)); + VALUE(instr.result) = Runtime::method_getQmlImportedScripts(static_cast<QV4::NoThrowEngine*>(engine)); MOTH_END_INSTR(LoadQmlImportedScripts) MOTH_BEGIN_INSTR(LoadQmlSingleton) - VALUE(instr.result) = engine->runtime.getQmlSingleton(static_cast<QV4::NoThrowEngine*>(engine), instr.name); + VALUE(instr.result) = Runtime::method_getQmlSingleton(static_cast<QV4::NoThrowEngine*>(engine), instr.name); MOTH_END_INSTR(LoadQmlSingleton) #ifdef MOTH_THREADED_INTERPRETER diff --git a/src/qml/memory/qv4heap_p.h b/src/qml/memory/qv4heap_p.h index 7bedd705f9..89e69fd9d6 100644 --- a/src/qml/memory/qv4heap_p.h +++ b/src/qml/memory/qv4heap_p.h @@ -169,6 +169,12 @@ struct Q_QML_EXPORT Base { #endif }; V4_ASSERT_IS_TRIVIAL(Base) +// This class needs to consist only of pointer sized members to allow +// for a size/offset translation when cross-compiling between 32- and +// 64-bit. +Q_STATIC_ASSERT(std::is_standard_layout<Base>::value); +Q_STATIC_ASSERT(offsetof(Base, vt) == 0); +Q_STATIC_ASSERT(sizeof(Base) == QT_POINTER_SIZE); } diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp index 1a1d92aa0e..180371c088 100644 --- a/src/qml/memory/qv4mm.cpp +++ b/src/qml/memory/qv4mm.cpp @@ -117,14 +117,16 @@ struct MemorySegment { pageReservation = PageReservation::reserve(size, OSAllocator::JSGCHeapPages); base = reinterpret_cast<Chunk *>((reinterpret_cast<quintptr>(pageReservation.base()) + Chunk::ChunkSize - 1) & ~(Chunk::ChunkSize - 1)); nChunks = NumChunks; - if (base != pageReservation.base()) + availableBytes = size - (reinterpret_cast<quintptr>(base) - reinterpret_cast<quintptr>(pageReservation.base())); + if (availableBytes < SegmentSize) --nChunks; } MemorySegment(MemorySegment &&other) { qSwap(pageReservation, other.pageReservation); qSwap(base, other.base); - qSwap(nChunks, other.nChunks); qSwap(allocatedMap, other.allocatedMap); + qSwap(availableBytes, other.availableBytes); + qSwap(nChunks, other.nChunks); } ~MemorySegment() { @@ -154,7 +156,7 @@ struct MemorySegment { void free(Chunk *chunk, size_t size) { DEBUG << "freeing chunk" << chunk; size_t index = static_cast<size_t>(chunk - base); - size_t end = index + (size - 1)/Chunk::ChunkSize + 1; + size_t end = qMin(static_cast<size_t>(NumChunks), index + (size - 1)/Chunk::ChunkSize + 1); while (index < end) { Q_ASSERT(testBit(index)); clearBit(index); @@ -173,11 +175,19 @@ struct MemorySegment { PageReservation pageReservation; Chunk *base = 0; quint64 allocatedMap = 0; + size_t availableBytes = 0; uint nChunks = 0; }; Chunk *MemorySegment::allocate(size_t size) { + if (!allocatedMap && size >= SegmentSize) { + // chunk allocated for one huge allocation + Q_ASSERT(availableBytes >= size); + pageReservation.commit(base, size); + allocatedMap = ~static_cast<quintptr>(0); + return base; + } size_t requiredChunks = (size + sizeof(Chunk) - 1)/sizeof(Chunk); uint sequence = 0; Chunk *candidate = 0; diff --git a/src/qml/memory/qv4mmdefs_p.h b/src/qml/memory/qv4mmdefs_p.h index f66630061d..1fc7b6a527 100644 --- a/src/qml/memory/qv4mmdefs_p.h +++ b/src/qml/memory/qv4mmdefs_p.h @@ -51,6 +51,7 @@ // #include <private/qv4global_p.h> +#include <private/qv4runtimeapi_p.h> #include <QtCore/qalgorithms.h> #include <qdebug.h> @@ -266,6 +267,9 @@ Q_STATIC_ASSERT((1 << Chunk::BitShift) == Chunk::Bits); // Base class for the execution engine +#if defined(Q_CC_MSVC) || defined(Q_CC_GNU) +#pragma pack(push, 1) +#endif struct EngineBase { Heap::ExecutionContext *current = 0; @@ -273,7 +277,22 @@ struct EngineBase { quint8 hasException = false; quint8 writeBarrierActive = false; quint16 unused = 0; +#if QT_POINTER_SIZE == 8 + quint8 padding[4]; +#endif + MemoryManager *memoryManager = 0; + Runtime runtime; }; +#if defined(Q_CC_MSVC) || defined(Q_CC_GNU) +#pragma pack(pop) +#endif + +Q_STATIC_ASSERT(std::is_standard_layout<EngineBase>::value); +Q_STATIC_ASSERT(offsetof(EngineBase, current) == 0); +Q_STATIC_ASSERT(offsetof(EngineBase, jsStackTop) == offsetof(EngineBase, current) + QT_POINTER_SIZE); +Q_STATIC_ASSERT(offsetof(EngineBase, hasException) == offsetof(EngineBase, jsStackTop) + QT_POINTER_SIZE); +Q_STATIC_ASSERT(offsetof(EngineBase, memoryManager) == offsetof(EngineBase, hasException) + QT_POINTER_SIZE); +Q_STATIC_ASSERT(offsetof(EngineBase, runtime) == offsetof(EngineBase, memoryManager) + QT_POINTER_SIZE); // Some helper classes and macros to automate the generation of our // tables used for marking objects diff --git a/src/qml/memory/qv4writebarrier_p.h b/src/qml/memory/qv4writebarrier_p.h index de9c63c2ea..455de4bf3d 100644 --- a/src/qml/memory/qv4writebarrier_p.h +++ b/src/qml/memory/qv4writebarrier_p.h @@ -227,6 +227,11 @@ struct ValueArray { } }; +// It's really important that the offset of values in this structure is +// constant across all architecture, otherwise JIT cross-compiled code will +// have wrong offsets between host and target. +Q_STATIC_ASSERT(offsetof(ValueArray<0>, values) == 8); + } QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index af94ece496..d4d21583ba 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -791,7 +791,7 @@ void QQmlData::signalEmitted(QAbstractDeclarativeData *, QObject *object, int in // marshalled back onto the QObject's thread and handled by QML from there. This is tested // by the qqmlecmascript::threadSignal() autotest. if (ddata->notifyList && - QThread::currentThreadId() != QObjectPrivate::get(object)->threadData->threadId) { + QThread::currentThreadId() != QObjectPrivate::get(object)->threadData->threadId.load()) { if (!QObjectPrivate::get(object)->threadData->thread) return; diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index bd6b9a1599..bb9b69c479 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -1971,7 +1971,9 @@ QString QQmlMetaType::prettyTypeName(const QObject *object) const int lastSlash = typeName.lastIndexOf(QLatin1Char('/')); if (lastSlash != -1) typeName = typeName.mid(lastSlash + 1); - } else { + } + + if (typeName.isEmpty()) { typeName = QString::fromUtf8(object->metaObject()->className()); int marker = typeName.indexOf(QLatin1String("_QMLTYPE_")); if (marker != -1) @@ -1982,10 +1984,12 @@ QString QQmlMetaType::prettyTypeName(const QObject *object) typeName = typeName.leftRef(marker) + QLatin1Char('*'); type = QQmlMetaType::qmlType(QMetaType::type(typeName.toLatin1())); if (type) { - typeName = type->qmlTypeName(); - const int lastSlash = typeName.lastIndexOf(QLatin1Char('/')); + QString qmlTypeName = type->qmlTypeName(); + const int lastSlash = qmlTypeName.lastIndexOf(QLatin1Char('/')); if (lastSlash != -1) - typeName = typeName.mid(lastSlash + 1); + qmlTypeName = qmlTypeName.mid(lastSlash + 1); + if (!qmlTypeName.isEmpty()) + typeName = qmlTypeName; } } } diff --git a/src/qml/qml/qqmlnotifier.cpp b/src/qml/qml/qqmlnotifier.cpp index 185f9687fb..538ca822ee 100644 --- a/src/qml/qml/qqmlnotifier.cpp +++ b/src/qml/qml/qqmlnotifier.cpp @@ -122,8 +122,8 @@ void QQmlNotifierEndpoint::connect(QObject *source, int sourceSignal, QQmlEngine disconnect(); Q_ASSERT(engine); - if (QObjectPrivate::get(source)->threadData->threadId != - QObjectPrivate::get(engine)->threadData->threadId) { + if (QObjectPrivate::get(source)->threadData->threadId.load() != + QObjectPrivate::get(engine)->threadData->threadId.load()) { QString sourceName; QDebug(&sourceName) << source; diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index 68eb989c70..eedb649ef6 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -80,10 +80,6 @@ # define NAME_MAX _POSIX_SYMLINK_MAX #endif -// LSB has a broken version of qOffsetOf that can't be used at compile time -// https://lsbbugs.linuxfoundation.org/show_bug.cgi?id=3462 -#undef qOffsetOf -#define qOffsetOf(TYPE, MEMBER) __builtin_qOffsetOf (TYPE, MEMBER) #endif // #define DATABLOB_DEBUG @@ -1249,20 +1245,20 @@ void QQmlTypeLoader::initializeEngine(QQmlExtensionInterface *iface, void QQmlTypeLoader::setData(QQmlDataBlob *blob, const QByteArray &data) { QML_MEMORY_SCOPE_URL(blob->url()); - QQmlDataBlob::Data d; - d.d = &data; + QQmlDataBlob::SourceCodeData d; + d.inlineSourceCode = QString::fromUtf8(data); setData(blob, d); } void QQmlTypeLoader::setData(QQmlDataBlob *blob, const QString &fileName) { QML_MEMORY_SCOPE_URL(blob->url()); - QQmlDataBlob::Data d; - d.d = &fileName; + QQmlDataBlob::SourceCodeData d; + d.fileInfo = QFileInfo(fileName); setData(blob, d); } -void QQmlTypeLoader::setData(QQmlDataBlob *blob, const QQmlDataBlob::Data &d) +void QQmlTypeLoader::setData(QQmlDataBlob *blob, const QQmlDataBlob::SourceCodeData &d) { QML_MEMORY_SCOPE_URL(blob->url()); QQmlCompilingProfiler prof(QQmlEnginePrivate::get(engine())->profiler, blob); @@ -2069,7 +2065,7 @@ bool QQmlTypeData::tryLoadFromDiskCache() QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit = v4->iselFactory->createUnitForLoading(); { QString error; - if (!unit->loadFromDisk(url(), v4->iselFactory.data(), &error)) { + if (!unit->loadFromDisk(url(), m_backupSourceCode.sourceTimeStamp(), v4->iselFactory.data(), &error)) { qCDebug(DBG_DISK_CACHE) << "Error loading" << url().toString() << "from disk cache:" << error; return false; } @@ -2239,7 +2235,7 @@ void QQmlTypeData::done() qCDebug(DBG_DISK_CACHE) << "Checksum mismatch for cached version of" << m_compiledData->url().toString(); if (!loadFromSource()) return; - m_backupSourceCode.clear(); + m_backupSourceCode = SourceCodeData(); m_compiledData = nullptr; } @@ -2346,13 +2342,9 @@ bool QQmlTypeData::loadImplicitImport() return true; } -void QQmlTypeData::dataReceived(const Data &data) +void QQmlTypeData::dataReceived(const SourceCodeData &data) { - QString error; - m_backupSourceCode = data.readAll(&error, &m_sourceTimeStamp); - // if we failed to read the source code, process it _after_ we've tried - // to use the disk cache, in order to support scenarios where the source - // was removed deliberately. + m_backupSourceCode = data; if (tryLoadFromDiskCache()) return; @@ -2360,8 +2352,8 @@ void QQmlTypeData::dataReceived(const Data &data) if (isError()) return; - if (!error.isEmpty()) { - setError(error); + if (!m_backupSourceCode.exists()) { + setError(QQmlTypeLoader::tr("No such file or directory")); return; } @@ -2380,12 +2372,19 @@ void QQmlTypeData::initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *un bool QQmlTypeData::loadFromSource() { - QString code = QString::fromUtf8(m_backupSourceCode); m_document.reset(new QmlIR::Document(isDebugging())); - m_document->jsModule.sourceTimeStamp = m_sourceTimeStamp; + m_document->jsModule.sourceTimeStamp = m_backupSourceCode.sourceTimeStamp(); QQmlEngine *qmlEngine = typeLoader()->engine(); QmlIR::IRBuilder compiler(QV8Engine::get(qmlEngine)->illegalNames()); - if (!compiler.generateFromQml(code, finalUrlString(), m_document.data())) { + + QString sourceError; + const QString source = m_backupSourceCode.readAll(&sourceError); + if (!sourceError.isEmpty()) { + setError(sourceError); + return false; + } + + if (!compiler.generateFromQml(source, finalUrlString(), m_document.data())) { QList<QQmlError> errors; errors.reserve(compiler.errors.count()); for (const QQmlJS::DiagnosticMessage &msg : qAsConst(compiler.errors)) { @@ -2523,7 +2522,7 @@ void QQmlTypeData::compile(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCach QString errorString; if (m_compiledData->saveToDisk(url(), &errorString)) { QString error; - if (!m_compiledData->loadFromDisk(url(), enginePrivate->v4engine()->iselFactory.data(), &error)) { + if (!m_compiledData->loadFromDisk(url(), m_backupSourceCode.sourceTimeStamp(), enginePrivate->v4engine()->iselFactory.data(), &error)) { // ignore error, keep using the in-memory compilation unit. } } else { @@ -2876,14 +2875,14 @@ struct EmptyCompilationUnit : public QV4::CompiledData::CompilationUnit void linkBackendToEngine(QV4::ExecutionEngine *) override {} }; -void QQmlScriptBlob::dataReceived(const Data &data) +void QQmlScriptBlob::dataReceived(const SourceCodeData &data) { QV4::ExecutionEngine *v4 = QV8Engine::getV4(m_typeLoader->engine()); if (!disableDiskCache() || forceDiskCache()) { QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit = v4->iselFactory->createUnitForLoading(); QString error; - if (unit->loadFromDisk(url(), v4->iselFactory.data(), &error)) { + if (unit->loadFromDisk(url(), data.sourceTimeStamp(), v4->iselFactory.data(), &error)) { initializeFromCompilationUnit(unit); return; } else { @@ -2894,8 +2893,9 @@ void QQmlScriptBlob::dataReceived(const Data &data) QmlIR::Document irUnit(isDebugging()); + irUnit.jsModule.sourceTimeStamp = data.sourceTimeStamp(); QString error; - QString source = QString::fromUtf8(data.readAll(&error, &irUnit.jsModule.sourceTimeStamp)); + QString source = data.readAll(&error); if (!error.isEmpty()) { setError(error); return; @@ -3059,10 +3059,10 @@ void QQmlQmldirData::setPriority(int priority) m_priority = priority; } -void QQmlQmldirData::dataReceived(const Data &data) +void QQmlQmldirData::dataReceived(const SourceCodeData &data) { QString error; - m_content = QString::fromUtf8(data.readAll(&error)); + m_content = data.readAll(&error); if (!error.isEmpty()) { setError(error); return; @@ -3074,34 +3074,54 @@ void QQmlQmldirData::initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit * Q_UNIMPLEMENTED(); } -QByteArray QQmlDataBlob::Data::readAll(QString *error, qint64 *sourceTimeStamp) const +QString QQmlDataBlob::SourceCodeData::readAll(QString *error) const { - Q_ASSERT(!d.isNull()); error->clear(); - if (d.isT1()) { - if (sourceTimeStamp) - *sourceTimeStamp = 0; - return *d.asT1(); - } - QFile f(*d.asT2()); + if (!inlineSourceCode.isEmpty()) + return inlineSourceCode; + + QFile f(fileInfo.absoluteFilePath()); if (!f.open(QIODevice::ReadOnly)) { *error = f.errorString(); - return QByteArray(); + return QString(); } - if (sourceTimeStamp) { - QDateTime timeStamp = QFileInfo(f).lastModified(); - // Files from the resource system do not have any time stamps, so fall back to the application - // executable. - if (!timeStamp.isValid()) - timeStamp = QFileInfo(QCoreApplication::applicationFilePath()).lastModified(); - *sourceTimeStamp = timeStamp.toMSecsSinceEpoch(); + + const qint64 fileSize = fileInfo.size(); + + if (uchar *mappedData = f.map(0, fileSize)) { + QString source = QString::fromUtf8(reinterpret_cast<const char *>(mappedData), fileSize); + f.unmap(mappedData); + return source; } - QByteArray data(f.size(), Qt::Uninitialized); + + QByteArray data(fileSize, Qt::Uninitialized); if (f.read(data.data(), data.length()) != data.length()) { *error = f.errorString(); - return QByteArray(); + return QString(); } - return data; + return QString::fromUtf8(data); +} + +QDateTime QQmlDataBlob::SourceCodeData::sourceTimeStamp() const +{ + if (!inlineSourceCode.isEmpty()) + return QDateTime(); + + QDateTime timeStamp = fileInfo.lastModified(); + if (timeStamp.isValid()) + return timeStamp; + + static QDateTime appTimeStamp; + if (!appTimeStamp.isValid()) + appTimeStamp = QFileInfo(QCoreApplication::applicationFilePath()).lastModified(); + return appTimeStamp; +} + +bool QQmlDataBlob::SourceCodeData::exists() const +{ + if (!inlineSourceCode.isEmpty()) + return true; + return fileInfo.exists(); } QT_END_NAMESPACE diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h index 915b1bcc4c..1bd2c7f1e1 100644 --- a/src/qml/qml/qqmltypeloader_p.h +++ b/src/qml/qml/qqmltypeloader_p.h @@ -54,6 +54,7 @@ #include <QtQml/qtqmlglobal.h> #include <QtCore/qobject.h> #include <QtCore/qatomic.h> +#include <QtCore/qfileinfo.h> #if QT_CONFIG(qml_network) #include <QtNetwork/qnetworkreply.h> #endif @@ -130,16 +131,16 @@ public: QList<QQmlError> errors() const; - class Data { + class SourceCodeData { public: - QByteArray readAll(QString *error, qint64 *sourceTimeStamp = 0) const; + QString readAll(QString *error) const; + QDateTime sourceTimeStamp() const; + bool exists() const; private: friend class QQmlDataBlob; friend class QQmlTypeLoader; - inline Data(); - Data(const Data &); - Data &operator=(const Data &); - QBiPointer<const QByteArray, const QString> d; + QString inlineSourceCode; + QFileInfo fileInfo; }; protected: @@ -152,7 +153,7 @@ protected: void addDependency(QQmlDataBlob *); // Callbacks made in load thread - virtual void dataReceived(const Data &) = 0; + virtual void dataReceived(const SourceCodeData &) = 0; virtual void initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit*) = 0; virtual void done(); #if QT_CONFIG(qml_network) @@ -339,7 +340,7 @@ private: void setData(QQmlDataBlob *, const QByteArray &); void setData(QQmlDataBlob *, const QString &fileName); - void setData(QQmlDataBlob *, const QQmlDataBlob::Data &); + void setData(QQmlDataBlob *, const QQmlDataBlob::SourceCodeData &); void setCachedUnit(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit); template<typename T> @@ -436,7 +437,7 @@ public: protected: void done() override; void completed() override; - void dataReceived(const Data &) override; + void dataReceived(const SourceCodeData &) override; void initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *unit) override; void allDependenciesDone() override; void downloadProgressChanged(qreal) override; @@ -462,8 +463,7 @@ private: void scriptImported(QQmlScriptBlob *blob, const QV4::CompiledData::Location &location, const QString &qualifier, const QString &nameSpace) override; - qint64 m_sourceTimeStamp = 0; - QByteArray m_backupSourceCode; // used when cache verification fails. + SourceCodeData m_backupSourceCode; // used when cache verification fails. QScopedPointer<QmlIR::Document> m_document; QV4::CompiledData::TypeReferenceMap m_typeReferences; @@ -547,7 +547,7 @@ public: QQmlScriptData *scriptData() const; protected: - void dataReceived(const Data &) override; + void dataReceived(const SourceCodeData &) override; void initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *unit) override; void done() override; @@ -578,7 +578,7 @@ public: void setPriority(int); protected: - void dataReceived(const Data &) override; + void dataReceived(const SourceCodeData &) override; void initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit*) override; private: @@ -587,11 +587,6 @@ private: int m_priority; }; -QQmlDataBlob::Data::Data() -{ -} - - QT_END_NAMESPACE diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp index ec40c7846d..68a64a28f0 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp @@ -1885,7 +1885,7 @@ void GlobalExtensions::method_qsTr(const BuiltinFunction *, Scope &scope, CallDa ExecutionContext *parentCtx = scope.engine->currentContext; // The first non-empty source URL in the call stack determines the translation context. while (!!parentCtx && context.isEmpty()) { - if (QV4::CompiledData::CompilationUnit *unit = parentCtx->d()->compilationUnit) { + if (CompiledData::CompilationUnit *unit = static_cast<CompiledData::CompilationUnit*>(parentCtx->d()->compilationUnit)) { QString fileName = unit->fileName(); QUrl url(unit->fileName()); if (url.isValid() && url.isRelative()) { diff --git a/src/quick/configure.json b/src/quick/configure.json index 4ed11e8318..047fa8c948 100644 --- a/src/quick/configure.json +++ b/src/quick/configure.json @@ -51,6 +51,7 @@ "quick-canvas": { "label": "Canvas item", "purpose": "Provides the Qt Quick Canvas Item", + "condition": "features.quick-path", "output": [ "privateFeature" ] @@ -97,6 +98,14 @@ "privateFeature" ] }, + "quick-particles": { + "label": "Particle support", + "purpose": "Provides a particle system for Qt Quick", + "condition": "features.quick-shadereffect && features.quick-sprite && features.opengl", + "output": [ + "privateFeature" + ] + }, "quick-path": { "label": "Path support", "purpose": "Provides Path elements in Qt Quick", diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp index a81ab619ac..da9379e7af 100644 --- a/src/quick/items/context2d/qquickcanvasitem.cpp +++ b/src/quick/items/context2d/qquickcanvasitem.cpp @@ -47,6 +47,7 @@ #include <qsgtextureprovider.h> #include <QtQuick/private/qquickpixmapcache_p.h> #include <QtGui/QGuiApplication> +#include <qsgtextureprovider.h> #include <qqmlinfo.h> #include <private/qqmlengine_p.h> diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp index 66afd3828b..db9b1acbdf 100644 --- a/src/quick/items/context2d/qquickcontext2d.cpp +++ b/src/quick/items/context2d/qquickcontext2d.cpp @@ -49,8 +49,9 @@ #include <QtQuick/private/qsgcontext_p.h> #include <private/qquicksvgparser_p.h> +#if QT_CONFIG(quick_path) #include <private/qquickpath_p.h> - +#endif #include <private/qquickimage_p_p.h> #include <qqmlinfo.h> @@ -567,9 +568,10 @@ struct QQuickJSContext2D : public QV4::Object static void method_set_shadowOffsetY(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); // should these two be on the proto? +#if QT_CONFIG(quick_path) static void method_get_path(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); static void method_set_path(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - +#endif static void method_get_font(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); static void method_set_font(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); static void method_get_textAlign(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); @@ -2032,6 +2034,7 @@ void QQuickJSContext2D::method_set_shadowOffsetY(const QV4::BuiltinFunction *, Q RETURN_UNDEFINED(); } +#if QT_CONFIG(quick_path) void QQuickJSContext2D::method_get_path(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); @@ -2058,6 +2061,7 @@ void QQuickJSContext2D::method_set_path(const QV4::BuiltinFunction *, QV4::Scope r->d()->context->m_v4path.set(scope.engine, value); RETURN_UNDEFINED(); } +#endif // QT_CONFIG(quick_path) //rects /*! @@ -4208,7 +4212,9 @@ QQuickContext2DEngineData::QQuickContext2DEngineData(QV4::ExecutionEngine *v4) proto->defineAccessorProperty(QStringLiteral("fillStyle"), QQuickJSContext2D::method_get_fillStyle, QQuickJSContext2D::method_set_fillStyle); proto->defineAccessorProperty(QStringLiteral("shadowColor"), QQuickJSContext2D::method_get_shadowColor, QQuickJSContext2D::method_set_shadowColor); proto->defineAccessorProperty(QStringLiteral("textBaseline"), QQuickJSContext2D::method_get_textBaseline, QQuickJSContext2D::method_set_textBaseline); +#if QT_CONFIG(quick_path) proto->defineAccessorProperty(QStringLiteral("path"), QQuickJSContext2D::method_get_path, QQuickJSContext2D::method_set_path); +#endif proto->defineAccessorProperty(QStringLiteral("lineJoin"), QQuickJSContext2D::method_get_lineJoin, QQuickJSContext2D::method_set_lineJoin); proto->defineAccessorProperty(QStringLiteral("lineWidth"), QQuickJSContext2D::method_get_lineWidth, QQuickJSContext2D::method_set_lineWidth); proto->defineAccessorProperty(QStringLiteral("textAlign"), QQuickJSContext2D::method_get_textAlign, QQuickJSContext2D::method_set_textAlign); diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp index b6c45c40a8..f1f82f9e0e 100644 --- a/src/quick/items/qquickevents.cpp +++ b/src/quick/items/qquickevents.cpp @@ -193,8 +193,8 @@ Item { */ /*! - \qmlproperty int QtQuick::MouseEvent::x - \qmlproperty int QtQuick::MouseEvent::y + \qmlproperty real QtQuick::MouseEvent::x + \qmlproperty real QtQuick::MouseEvent::y These properties hold the coordinates of the position supplied by the mouse event. */ @@ -340,8 +340,8 @@ Item { */ /*! - \qmlproperty int QtQuick::WheelEvent::x - \qmlproperty int QtQuick::WheelEvent::y + \qmlproperty real QtQuick::WheelEvent::x + \qmlproperty real QtQuick::WheelEvent::y These properties hold the coordinates of the position supplied by the wheel event. */ diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index d97c731157..6a2946bdcc 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -642,8 +642,10 @@ is finished. \section1 Limitations - \note Due to an implementation detail, items placed inside a Flickable cannot anchor to it by - \c id. Use \c parent instead. + \note Due to an implementation detail, items placed inside a Flickable + cannot anchor to the Flickable. Instead, use \l {Item::}{parent}, which + refers to the Flickable's \l contentItem. The size of the content item is + determined by \l contentWidth and \l contentHeight. */ /*! diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp index eeffe1ee48..4d6ae0c3e2 100644 --- a/src/quick/items/qquickitemsmodule.cpp +++ b/src/quick/items/qquickitemsmodule.cpp @@ -273,7 +273,7 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor) qmlRegisterType<QQuickAnchorSet>(); qmlRegisterType<QQuickAnchorAnimation>(uri, major, minor,"AnchorAnimation"); qmlRegisterType<QQuickParentAnimation>(uri, major, minor,"ParentAnimation"); -#if QT_CONFIG(quick_canvas) +#if QT_CONFIG(quick_path) qmlRegisterType<QQuickPathAnimation>("QtQuick",2,0,"PathAnimation"); qmlRegisterType<QQuickPathInterpolator>("QtQuick",2,0,"PathInterpolator"); #endif diff --git a/src/quick/items/qquickpainteditem_p.h b/src/quick/items/qquickpainteditem_p.h index 229fbf1007..3e160ed55a 100644 --- a/src/quick/items/qquickpainteditem_p.h +++ b/src/quick/items/qquickpainteditem_p.h @@ -51,6 +51,7 @@ // We mean it. // +#include "qquickpainteditem.h" #include "qquickitem_p.h" #include "qquickpainteditem.h" #include <QtGui/qcolor.h> diff --git a/src/quick/items/qquickshadereffect.cpp b/src/quick/items/qquickshadereffect.cpp index 436d7b33ce..d317c1d19b 100644 --- a/src/quick/items/qquickshadereffect.cpp +++ b/src/quick/items/qquickshadereffect.cpp @@ -873,9 +873,11 @@ void QQuickShaderEffectPrivate::updatePolish() q->m_impl->maybeUpdateShaders(); } +#if QT_CONFIG(opengl) bool QQuickShaderEffect::isOpenGLShaderEffect() const { return m_glImpl != Q_NULLPTR; } +#endif QT_END_NAMESPACE diff --git a/src/quick/items/qquickshadereffect_p.h b/src/quick/items/qquickshadereffect_p.h index d269dc5e50..30bd018098 100644 --- a/src/quick/items/qquickshadereffect_p.h +++ b/src/quick/items/qquickshadereffect_p.h @@ -117,7 +117,9 @@ public: bool isComponentComplete() const; QString parseLog(); +#if QT_CONFIG(opengl) bool isOpenGLShaderEffect() const; +#endif Q_SIGNALS: void fragmentShaderChanged(); diff --git a/src/src.pro b/src/src.pro index 24e139415b..3bb399acd4 100644 --- a/src/src.pro +++ b/src/src.pro @@ -10,7 +10,7 @@ qtHaveModule(gui):qtConfig(animation) { quick \ qmltest - qtConfig(quick-shadereffect):qtConfig(quick-sprite):qtConfig(opengl(es1|es2)?): \ + qtConfig(quick-particles): \ SUBDIRS += particles qtHaveModule(widgets): SUBDIRS += quickwidgets } diff --git a/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp b/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp index 8be82c30f9..f193d3928a 100644 --- a/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp +++ b/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp @@ -135,7 +135,7 @@ void QQmlDebugMsgClient::messageReceived(const QByteArray &data) QVERIFY(ds.atEnd()); QVERIFY(type >= QtDebugMsg); - QVERIFY(type <= QtFatalMsg); + QVERIFY(type <= QtInfoMsg); QVERIFY(timestamp > 0); LogEntry entry((QtMsgType)type, QString::fromUtf8(message)); diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp index 31b8d63ec2..d248cf9708 100644 --- a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp +++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp @@ -257,7 +257,7 @@ public: stringify = jsEngine.evaluate(QLatin1String("JSON.stringify")); } - void connect(); + void connect(bool redundantRefs = false, bool namesAsObjects = false); void interrupt(); void continueDebugging(StepAction stepAction); @@ -304,9 +304,13 @@ public: }; -void QJSDebugClient::connect() +void QJSDebugClient::connect(bool redundantRefs, bool namesAsObjects) { - sendMessage(packMessage(CONNECT)); + QJSValue jsonVal = parser.call(QJSValueList() << QLatin1String("{}")); + jsonVal.setProperty("redundantRefs", QJSValue(redundantRefs)); + jsonVal.setProperty("namesAsObjects", QJSValue(namesAsObjects)); + sendMessage(packMessage(CONNECT, + stringify.call(QJSValueList() << jsonVal).toString().toUtf8())); } void QJSDebugClient::interrupt() @@ -870,8 +874,10 @@ void tst_QQmlDebugJS::interrupt() //void connect() QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); init(qmlscene); - client->connect(); + client->connect(redundantRefs, namesAsObjects); client->interrupt(); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(interruptRequested()))); @@ -882,8 +888,10 @@ void tst_QQmlDebugJS::getVersion() //void version() QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); init(qmlscene); - client->connect(); + client->connect(redundantRefs, namesAsObjects); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(connected()))); client->version(); @@ -894,9 +902,11 @@ void tst_QQmlDebugJS::getVersionWhenAttaching() { //void version() QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); init(qmlscene, QLatin1String(TIMER_QMLFILE), false); - client->connect(); + client->connect(redundantRefs, namesAsObjects); client->version(); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result()))); @@ -907,8 +917,10 @@ void tst_QQmlDebugJS::disconnect() //void disconnect() QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); init(qmlscene); - client->connect(); + client->connect(redundantRefs, namesAsObjects); client->disconnect(); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result()))); @@ -918,12 +930,14 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnCompleted() { //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1) QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); int sourceLine = 34; init(qmlscene, ONCOMPLETED_QMLFILE); client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true); - client->connect(); + client->connect(redundantRefs, namesAsObjects); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); QString jsonString(client->response); @@ -939,12 +953,14 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnComponentCreated() { //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1) QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); int sourceLine = 34; init(qmlscene, CREATECOMPONENT_QMLFILE); client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true); - client->connect(); + client->connect(redundantRefs, namesAsObjects); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); QString jsonString(client->response); @@ -959,10 +975,12 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnComponentCreated() void tst_QQmlDebugJS::setBreakpointInScriptOnTimerCallback() { QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); int sourceLine = 35; init(qmlscene, TIMER_QMLFILE); - client->connect(); + client->connect(redundantRefs, namesAsObjects); //We can set the breakpoint after connect() here because the timer is repeating and if we miss //its first iteration we can still catch the second one. client->setBreakpoint(QLatin1String(TIMER_QMLFILE), sourceLine, -1, true); @@ -981,12 +999,14 @@ void tst_QQmlDebugJS::setBreakpointInScriptInDifferentFile() { //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1) QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); int sourceLine = 31; init(qmlscene, LOADJSFILE_QMLFILE); client->setBreakpoint(QLatin1String(TEST_JSFILE), sourceLine, -1, true); - client->connect(); + client->connect(redundantRefs, namesAsObjects); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); QString jsonString(client->response); @@ -1002,13 +1022,15 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnComment() { //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1) QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); int sourceLine = 34; int actualLine = 36; init(qmlscene, BREAKPOINTRELOCATION_QMLFILE); client->setBreakpoint(QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true); - client->connect(); + client->connect(redundantRefs, namesAsObjects); QEXPECT_FAIL("", "Relocation of breakpoints is disabled right now", Abort); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()), 1)); @@ -1025,13 +1047,15 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnEmptyLine() { //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1) QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); int sourceLine = 35; int actualLine = 36; init(qmlscene, BREAKPOINTRELOCATION_QMLFILE); client->setBreakpoint(QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true); - client->connect(); + client->connect(redundantRefs, namesAsObjects); QEXPECT_FAIL("", "Relocation of breakpoints is disabled right now", Abort); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()), 1)); @@ -1048,12 +1072,14 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnOptimizedBinding() { //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1) QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); int sourceLine = 39; init(qmlscene, BREAKPOINTRELOCATION_QMLFILE); client->setBreakpoint(QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true); - client->connect(); + client->connect(redundantRefs, namesAsObjects); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); QString jsonString(client->response); @@ -1068,11 +1094,13 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnOptimizedBinding() void tst_QQmlDebugJS::setBreakpointInScriptWithCondition() { QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); int out = 10; int sourceLine = 37; init(qmlscene, CONDITION_QMLFILE); - client->connect(); + client->connect(redundantRefs, namesAsObjects); //The breakpoint is in a timer loop so we can set it after connect(). client->setBreakpoint(QLatin1String(CONDITION_QMLFILE), sourceLine, 1, true, QLatin1String("a > 10")); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); @@ -1105,12 +1133,14 @@ void tst_QQmlDebugJS::setBreakpointInScriptWithCondition() void tst_QQmlDebugJS::setBreakpointInScriptThatQuits() { QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); init(qmlscene, QUIT_QMLFILE); int sourceLine = 36; client->setBreakpoint(QLatin1String(QUIT_QMLFILE), sourceLine, -1, true); - client->connect(); + client->connect(redundantRefs, namesAsObjects); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); QString jsonString(client->response); @@ -1147,12 +1177,14 @@ void tst_QQmlDebugJS::clearBreakpoint() { //void clearBreakpoint(int breakpoint); QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); int sourceLine1 = 37; int sourceLine2 = 38; init(qmlscene, CHANGEBREAKPOINT_QMLFILE); - client->connect(); + client->connect(redundantRefs, namesAsObjects); //The breakpoints are in a timer loop so we can set them after connect(). //Furthermore the breakpoints should be hit in the right order because setting of breakpoints //can only occur in the QML event loop. (see QCOMPARE for sourceLine2 below) @@ -1195,10 +1227,12 @@ void tst_QQmlDebugJS::setExceptionBreak() { //void setExceptionBreak(QString type, bool enabled = false); QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); init(qmlscene, EXCEPTION_QMLFILE); client->setExceptionBreak(QJSDebugClient::All,true); - client->connect(); + client->connect(redundantRefs, namesAsObjects); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); } @@ -1206,12 +1240,14 @@ void tst_QQmlDebugJS::stepNext() { //void continueDebugging(StepAction stepAction, int stepCount = 1); QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); int sourceLine = 37; init(qmlscene, STEPACTION_QMLFILE); client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true); - client->connect(); + client->connect(redundantRefs, namesAsObjects); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); client->continueDebugging(QJSDebugClient::Next); @@ -1230,13 +1266,15 @@ void tst_QQmlDebugJS::stepIn() { //void continueDebugging(StepAction stepAction, int stepCount = 1); QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); int sourceLine = 41; int actualLine = 37; init(qmlscene, STEPACTION_QMLFILE); client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine, 1, true); - client->connect(); + client->connect(redundantRefs, namesAsObjects); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); client->continueDebugging(QJSDebugClient::In); @@ -1255,13 +1293,15 @@ void tst_QQmlDebugJS::stepOut() { //void continueDebugging(StepAction stepAction, int stepCount = 1); QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); int sourceLine = 37; int actualLine = 41; init(qmlscene, STEPACTION_QMLFILE); client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true); - client->connect(); + client->connect(redundantRefs, namesAsObjects); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); client->continueDebugging(QJSDebugClient::Out); @@ -1280,6 +1320,8 @@ void tst_QQmlDebugJS::continueDebugging() { //void continueDebugging(StepAction stepAction, int stepCount = 1); QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); int sourceLine1 = 41; int sourceLine2 = 38; @@ -1287,7 +1329,7 @@ void tst_QQmlDebugJS::continueDebugging() client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine1, -1, true); client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine2, -1, true); - client->connect(); + client->connect(redundantRefs, namesAsObjects); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); client->continueDebugging(QJSDebugClient::Continue); @@ -1306,12 +1348,14 @@ void tst_QQmlDebugJS::backtrace() { //void backtrace(int fromFrame = -1, int toFrame = -1, bool bottom = false); QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); int sourceLine = 34; init(qmlscene, ONCOMPLETED_QMLFILE); client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true); - client->connect(); + client->connect(redundantRefs, namesAsObjects); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); client->backtrace(); @@ -1322,12 +1366,14 @@ void tst_QQmlDebugJS::getFrameDetails() { //void frame(int number = -1); QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); int sourceLine = 34; init(qmlscene, ONCOMPLETED_QMLFILE); client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true); - client->connect(); + client->connect(redundantRefs, namesAsObjects); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); client->frame(); @@ -1338,12 +1384,14 @@ void tst_QQmlDebugJS::getScopeDetails() { //void scope(int number = -1, int frameNumber = -1); QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); int sourceLine = 34; init(qmlscene, ONCOMPLETED_QMLFILE); client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true); - client->connect(); + client->connect(redundantRefs, namesAsObjects); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); client->scope(); @@ -1374,11 +1422,13 @@ void tst_QQmlDebugJS::evaluateInLocalScope() //void evaluate(QString expr, bool global = false, bool disableBreak = false, int frame = -1, const QVariantMap &addContext = QVariantMap()); QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); int sourceLine = 34; init(qmlscene, ONCOMPLETED_QMLFILE); client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true); - client->connect(); + client->connect(redundantRefs, namesAsObjects); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); client->frame(); @@ -1461,10 +1511,12 @@ void tst_QQmlDebugJS::getScripts() //void scripts(int types = -1, QList<int> ids = QList<int>(), bool includeSource = false, QVariant filter = QVariant()); QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); init(qmlscene); client->setBreakpoint(QString(TEST_QMLFILE), 35, -1, true); - client->connect(); + client->connect(redundantRefs, namesAsObjects); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); client->scripts(); @@ -1482,8 +1534,16 @@ void tst_QQmlDebugJS::getScripts() void tst_QQmlDebugJS::targetData() { QTest::addColumn<bool>("qmlscene"); - QTest::newRow("custom") << false; - QTest::newRow("qmlscene") << true; + QTest::addColumn<bool>("redundantRefs"); + QTest::addColumn<bool>("namesAsObjects"); + QTest::newRow("custom / redundant / objects") << false << true << true; + QTest::newRow("qmlscene / redundant / objects") << true << true << true; + QTest::newRow("custom / redundant / strings") << false << true << false; + QTest::newRow("qmlscene / redundant / strings") << true << true << false; + QTest::newRow("custom / sparse / objects") << false << false << true; + QTest::newRow("qmlscene / sparse / objects") << true << false << true; + QTest::newRow("custom / sparse / strings") << false << false << false; + QTest::newRow("qmlscene / sparse / strings") << true << false << false; } QTEST_MAIN(tst_QQmlDebugJS) diff --git a/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp index 56320b8365..6d0d884ed7 100644 --- a/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp +++ b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp @@ -120,7 +120,6 @@ public: typedef QV4DataCollector::Refs Refs; typedef QV4DataCollector::Ref Ref; struct NamedRefs { - QJsonArray refs; QJsonObject scope; int size() const { @@ -131,15 +130,6 @@ public: return scope.contains(name); } - QJsonObject resolveRef(int ref) const { - foreach (const QJsonValue &val, refs) { - QJsonObject obj = val.toObject(); - if (obj.value(QLatin1String("handle")).toInt() == ref) - return obj; - } - return QJsonObject(); - } - #define DUMP_JSON(x) {\ QJsonDocument doc(x);\ qDebug() << #x << "=" << doc.toJson(QJsonDocument::Indented);\ @@ -209,7 +199,6 @@ public slots: request.expression, &collector); debugger->runInEngine(&job); m_expressionResults << job.returnValue(); - m_expressionRefs << job.refs(); } if (m_captureContextInfo) @@ -235,24 +224,17 @@ public: ScopeJob job(&collector, i, 0); debugger->runInEngine(&job); NamedRefs &refs = m_capturedScope.last(); - refs.refs = job.refs(); QJsonObject object = job.returnValue(); object = object.value(QLatin1String("object")).toObject(); - int ref = object.value(QLatin1String("ref")).toInt(); - object = refs.resolveRef(ref); + if (object.contains("ref") && !object.contains("properties")) { + QVERIFY(collector.redundantRefs()); + object = collector.lookupRef(object.value("ref").toInt(), true); + QVERIFY(object.contains("properties")); + } foreach (const QJsonValue &value, object.value(QLatin1String("properties")).toArray()) { QJsonObject property = value.toObject(); QString name = property.value(QLatin1String("name")).toString(); property.remove(QLatin1String("name")); - if (property.contains(QLatin1String("ref"))) { - int childRef = property.value(QLatin1String("ref")).toInt(); - if (childRef >= 0 && refs.refs.size() > childRef) { - property.remove(QLatin1String("ref")); - property.insert(QLatin1String("properties"), - refs.resolveRef(childRef).value( - QLatin1String("properties")).toArray()); - } - } refs.scope.insert(name, property); } } @@ -283,7 +265,6 @@ public: QVector<ExpressionRequest> m_expressionRequests; QV4Debugger::Speed m_resumeSpeed; QList<QJsonObject> m_expressionResults; - QList<QJsonArray> m_expressionRefs; QV4Debugger *m_debugger; // Utility methods: @@ -315,9 +296,13 @@ private slots: void conditionalBreakPointInQml(); // context access: + void readArguments_data() { redundancy_data(); } void readArguments(); + void readLocals_data() { redundancy_data(); } void readLocals(); + void readObject_data() { redundancy_data(); } void readObject(); + void readContextInAllFrames_data() { redundancy_data(); } void readContextInAllFrames(); // exceptions: @@ -325,7 +310,9 @@ private slots: void breakInCatch(); void breakInWith(); + void evaluateExpression_data() { redundancy_data(); } void evaluateExpression(); + void stepToEndOfScript_data() { redundancy_data(); } void stepToEndOfScript(); void lastLineOfLoop_data(); @@ -343,6 +330,8 @@ private: waitForSignal(m_engine, SIGNAL(evaluateFinished()), /*timeout*/0); } + void redundancy_data(); + TestEngine *m_engine; QV4::ExecutionEngine *m_v4; TestAgent *m_debuggerAgent; @@ -537,6 +526,9 @@ void tst_qv4debugger::conditionalBreakPointInQml() void tst_qv4debugger::readArguments() { + QFETCH(bool, redundantRefs); + m_debuggerAgent->collector.setRedundantRefs(redundantRefs); + m_debuggerAgent->m_captureContextInfo = true; QString script = "function f(a, b, c, d) {\n" @@ -560,6 +552,9 @@ void tst_qv4debugger::readArguments() void tst_qv4debugger::readLocals() { + QFETCH(bool, redundantRefs); + m_debuggerAgent->collector.setRedundantRefs(redundantRefs); + m_debuggerAgent->m_captureContextInfo = true; QString script = "function f(a, b) {\n" @@ -583,6 +578,9 @@ void tst_qv4debugger::readLocals() void tst_qv4debugger::readObject() { + QFETCH(bool, redundantRefs); + m_debuggerAgent->collector.setRedundantRefs(redundantRefs); + m_debuggerAgent->m_captureContextInfo = true; QString script = "function f(a) {\n" @@ -599,6 +597,12 @@ void tst_qv4debugger::readObject() QVERIFY(frame0.contains("b")); QCOMPARE(frame0.type("b"), QStringLiteral("object")); QJsonObject b = frame0.rawValue("b"); + QVERIFY(b.contains(QStringLiteral("ref"))); + QVERIFY(b.contains(QStringLiteral("value"))); + QVERIFY(!b.contains(QStringLiteral("properties"))); + QVERIFY(b.value("value").isDouble()); + QCOMPARE(b.value("value").toInt(), 2); + b = m_debuggerAgent->collector.lookupRef(b.value("ref").toInt(), true); QVERIFY(b.contains(QStringLiteral("properties"))); QVERIFY(b.value("properties").isArray()); QJsonArray b_props = b.value("properties").toArray(); @@ -614,7 +618,8 @@ void tst_qv4debugger::readObject() QCOMPARE(b_tail.value("name").toString(), QStringLiteral("tail")); QVERIFY(b_tail.contains("ref")); - QJsonObject b_tail_value = m_debuggerAgent->collector.lookupRef(b_tail.value("ref").toInt()); + QJsonObject b_tail_value = m_debuggerAgent->collector.lookupRef(b_tail.value("ref").toInt(), + true); QCOMPARE(b_tail_value.value("type").toString(), QStringLiteral("object")); QVERIFY(b_tail_value.contains("properties")); QJsonArray b_tail_props = b_tail_value.value("properties").toArray(); @@ -631,6 +636,9 @@ void tst_qv4debugger::readObject() void tst_qv4debugger::readContextInAllFrames() { + QFETCH(bool, redundantRefs); + m_debuggerAgent->collector.setRedundantRefs(redundantRefs); + m_debuggerAgent->m_captureContextInfo = true; QString script = "function fact(n) {\n" @@ -678,7 +686,8 @@ void tst_qv4debugger::pauseOnThrow() QCOMPARE(m_debuggerAgent->m_pauseReason, QV4Debugger::Throwing); QCOMPARE(m_debuggerAgent->m_stackTrace.size(), 2); QVERIFY(m_debuggerAgent->m_thrownValue >= qint64(0)); - QJsonObject exception = m_debuggerAgent->collector.lookupRef(m_debuggerAgent->m_thrownValue); + QJsonObject exception = m_debuggerAgent->collector.lookupRef(m_debuggerAgent->m_thrownValue, + true); // DUMP_JSON(exception); QCOMPARE(exception.value("type").toString(), QStringLiteral("string")); QCOMPARE(exception.value("value").toString(), QStringLiteral("hard")); @@ -722,6 +731,9 @@ void tst_qv4debugger::breakInWith() void tst_qv4debugger::evaluateExpression() { + QFETCH(bool, redundantRefs); + m_debuggerAgent->collector.setRedundantRefs(redundantRefs); + QString script = "function testFunction() {\n" " var x = 10\n" @@ -750,14 +762,12 @@ void tst_qv4debugger::evaluateExpression() evaluateJavaScript(script, "evaluateExpression"); - QCOMPARE(m_debuggerAgent->m_expressionRefs.count(), 4); - QCOMPARE(m_debuggerAgent->m_expressionRefs[0].size(), 1); - QJsonObject result0 = m_debuggerAgent->m_expressionRefs[0].first().toObject(); + QCOMPARE(m_debuggerAgent->m_expressionResults.count(), 4); + QJsonObject result0 = m_debuggerAgent->m_expressionResults[0]; QCOMPARE(result0.value("type").toString(), QStringLiteral("number")); QCOMPARE(result0.value("value").toInt(), 10); for (int i = 1; i < 4; ++i) { - QCOMPARE(m_debuggerAgent->m_expressionRefs[i].size(), 1); - QJsonObject result1 = m_debuggerAgent->m_expressionRefs[1].first().toObject(); + QJsonObject result1 = m_debuggerAgent->m_expressionResults[i]; QCOMPARE(result1.value("type").toString(), QStringLiteral("number")); QCOMPARE(result1.value("value").toInt(), 20); } @@ -765,6 +775,9 @@ void tst_qv4debugger::evaluateExpression() void tst_qv4debugger::stepToEndOfScript() { + QFETCH(bool, redundantRefs); + m_debuggerAgent->collector.setRedundantRefs(redundantRefs); + QString script = "var ret = 0;\n" "ret += 4;\n" @@ -827,6 +840,13 @@ void tst_qv4debugger::lastLineOfLoop() QCOMPARE(secondState.lineNumber, 7); } +void tst_qv4debugger::redundancy_data() +{ + QTest::addColumn<bool>("redundantRefs"); + QTest::addRow("redundant") << true; + QTest::addRow("sparse") << false; +} + QTEST_MAIN(tst_qv4debugger) #include "tst_qv4debugger.moc" diff --git a/tests/auto/qml/qml.pro b/tests/auto/qml/qml.pro index 7d182b7255..b347b603bb 100644 --- a/tests/auto/qml/qml.pro +++ b/tests/auto/qml/qml.pro @@ -70,14 +70,17 @@ qtHaveModule(widgets) { qjsvalue } -SUBDIRS += $$PUBLICTESTS \ - qqmlextensionplugin +SUBDIRS += $$PUBLICTESTS SUBDIRS += $$METATYPETESTS qtConfig(process) { !contains(QT_CONFIG, no-qml-debug): SUBDIRS += debugger SUBDIRS += qmllint qmlplugindump } +qtConfig(library) { + SUBDIRS += qqmlextensionplugin +} + qtConfig(private_tests): \ SUBDIRS += $$PRIVATETESTS diff --git a/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp b/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp index b265607fd1..17aa6087d2 100644 --- a/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp +++ b/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp @@ -174,7 +174,7 @@ struct TestCompiler { QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine); QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit = v4->iselFactory->createUnitForLoading(); - return unit->loadFromDisk(QUrl::fromLocalFile(testFilePath), v4->iselFactory.data(), &lastErrorString); + return unit->loadFromDisk(QUrl::fromLocalFile(testFilePath), QFileInfo(testFilePath).lastModified(), v4->iselFactory.data(), &lastErrorString); } void closeMapping() diff --git a/tests/auto/qml/qmlmin/tst_qmlmin.cpp b/tests/auto/qml/qmlmin/tst_qmlmin.cpp index 3ed0aa7446..90868d2ead 100644 --- a/tests/auto/qml/qmlmin/tst_qmlmin.cpp +++ b/tests/auto/qml/qmlmin/tst_qmlmin.cpp @@ -29,7 +29,9 @@ #include <qtest.h> #include <QLibraryInfo> #include <QDir> +#if QT_CONFIG(process) #include <QProcess> +#endif #include <QDebug> #include <QQmlError> #include <cstdlib> @@ -42,7 +44,7 @@ public: private slots: void initTestCase(); -#if !defined(QTEST_CROSS_COMPILED) // sources not available when cross compiled +#if QT_CONFIG(process) && !defined(QTEST_CROSS_COMPILED) // sources not available when cross compiled void qmlMinify_data(); void qmlMinify(); #endif @@ -166,7 +168,7 @@ Examples are any .qml files under the examples/ directory that start with a lower case letter. */ -#if !defined(QTEST_CROSS_COMPILED) // sources not available when cross compiled +#if QT_CONFIG(process) && !defined(QTEST_CROSS_COMPILED) // sources not available when cross compiled void tst_qmlmin::qmlMinify_data() { QTest::addColumn<QString>("file"); @@ -183,7 +185,7 @@ void tst_qmlmin::qmlMinify_data() } #endif -#if !defined(QTEST_CROSS_COMPILED) // sources not available when cross compiled +#if QT_CONFIG(process) && !defined(QTEST_CROSS_COMPILED) // sources not available when cross compiled void tst_qmlmin::qmlMinify() { QFETCH(QString, file); diff --git a/tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp b/tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp index 74add85cb0..f7748b2da9 100644 --- a/tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp +++ b/tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp @@ -29,7 +29,9 @@ #include "../../shared/util.h" #include <QQmlApplicationEngine> #include <QSignalSpy> +#if QT_CONFIG(process) #include <QProcess> +#endif #include <QDebug> class tst_qqmlapplicationengine : public QQmlDataTest diff --git a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp index 9fbd719d7b..30e517c8f9 100644 --- a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp +++ b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp @@ -52,6 +52,7 @@ private slots: void qmlPropertyValueInterceptorCast(); void qmlType(); void invalidQmlTypeName(); + void prettyTypeName(); void registrationType(); void compositeType(); void externalEnums(); @@ -72,6 +73,16 @@ public: }; QML_DECLARE_TYPE(TestType); +class TestType2 : public QObject +{ + Q_OBJECT +}; + +class TestType3 : public QObject +{ + Q_OBJECT +}; + class ExternalEnums : public QObject { Q_OBJECT @@ -214,13 +225,28 @@ void tst_qqmlmetatype::invalidQmlTypeName() { QStringList currFailures = QQmlMetaType::typeRegistrationFailures(); QCOMPARE(qmlRegisterType<TestType>("TestNamespace", 1, 0, "Test$Type"), -1); // should fail due to invalid QML type name. + QCOMPARE(qmlRegisterType<TestType>("Test", 1, 0, "EndingInSlash/"), -1); QStringList nowFailures = QQmlMetaType::typeRegistrationFailures(); foreach (const QString &f, currFailures) nowFailures.removeOne(f); - QCOMPARE(nowFailures.size(), 1); + QCOMPARE(nowFailures.size(), 2); QCOMPARE(nowFailures.at(0), QStringLiteral("Invalid QML element name \"Test$Type\"")); + QCOMPARE(nowFailures.at(1), QStringLiteral("Invalid QML element name \"EndingInSlash/\"")); +} + +void tst_qqmlmetatype::prettyTypeName() +{ + TestType2 obj2; + QCOMPARE(QQmlMetaType::prettyTypeName(&obj2), QString("TestType2")); + QVERIFY(qmlRegisterType<TestType2>("Test", 1, 0, "") >= 0); + QCOMPARE(QQmlMetaType::prettyTypeName(&obj2), QString("TestType2")); + + TestType3 obj3; + QCOMPARE(QQmlMetaType::prettyTypeName(&obj3), QString("TestType3")); + QVERIFY(qmlRegisterType<TestType3>("Test", 1, 0, "OtherName") >= 0); + QCOMPARE(QQmlMetaType::prettyTypeName(&obj3), QString("OtherName")); } void tst_qqmlmetatype::isList() diff --git a/tests/auto/qml/v4misc/tst_v4misc.cpp b/tests/auto/qml/v4misc/tst_v4misc.cpp index 88b6ae92a8..55a1f65608 100644 --- a/tests/auto/qml/v4misc/tst_v4misc.cpp +++ b/tests/auto/qml/v4misc/tst_v4misc.cpp @@ -26,6 +26,7 @@ ** ****************************************************************************/ +#include <qhashfunctions.h> #include <qtest.h> #define V4_AUTOTEST @@ -46,17 +47,12 @@ private slots: void moveMapping_2(); }; -QT_BEGIN_NAMESPACE -// Avoid QHash randomization so that the temp numbering is stable. -extern Q_CORE_EXPORT QBasicAtomicInt qt_qhash_seed; // from qhash.cpp -QT_END_NAMESPACE - using namespace QT_PREPEND_NAMESPACE(QV4::IR); void tst_v4misc::initTestCase() { - qt_qhash_seed.store(0); - QCOMPARE(qt_qhash_seed.load(), 0); + qSetGlobalQHashSeed(0); + QCOMPARE(qGlobalQHashSeed(), 0); } // split between two ranges diff --git a/tests/auto/quick/examples/tst_examples.cpp b/tests/auto/quick/examples/tst_examples.cpp index d5c9aaeb90..b6742b9efe 100644 --- a/tests/auto/quick/examples/tst_examples.cpp +++ b/tests/auto/quick/examples/tst_examples.cpp @@ -29,7 +29,6 @@ #include <qtest.h> #include <QLibraryInfo> #include <QDir> -#include <QProcess> #include <QDebug> #include <QtQuick/QQuickItem> #include <QtQuick/QQuickView> diff --git a/tests/auto/toolsupport/tst_toolsupport.cpp b/tests/auto/toolsupport/tst_toolsupport.cpp index 526ba8f375..6ee1db805a 100644 --- a/tests/auto/toolsupport/tst_toolsupport.cpp +++ b/tests/auto/toolsupport/tst_toolsupport.cpp @@ -101,7 +101,7 @@ void tst_toolsupport::offsets_data() = QTest::newRow("CompiledData::CompilationUnit::data") << pmm_to_offsetof(&QV4::CompiledData::CompilationUnit::data); - data << 8 << 16; + data << 12 << 24; } { @@ -109,7 +109,7 @@ void tst_toolsupport::offsets_data() = QTest::newRow("CompiledData::CompilationUnit::runtimeStrings") << pmm_to_offsetof(&QV4::CompiledData::CompilationUnit::runtimeStrings); - data << 12 << 24; + data << 0 << 0; } { diff --git a/tests/benchmarks/qml/holistic/testtypes.h b/tests/benchmarks/qml/holistic/testtypes.h index 0736982373..a752a8585b 100644 --- a/tests/benchmarks/qml/holistic/testtypes.h +++ b/tests/benchmarks/qml/holistic/testtypes.h @@ -43,6 +43,7 @@ #include <QtQml/qjsvalue.h> #include <QtQml/qqmlscriptstring.h> #include <QtQml/qqmlcomponent.h> +#include <QtCore/qregexp.h> class MyQmlAttachedObject : public QObject { diff --git a/tests/manual/scenegraph_lancelot/scenegrabber/main.cpp b/tests/manual/scenegraph_lancelot/scenegrabber/main.cpp index 886cfc6599..6da0799bbc 100644 --- a/tests/manual/scenegraph_lancelot/scenegrabber/main.cpp +++ b/tests/manual/scenegraph_lancelot/scenegrabber/main.cpp @@ -29,6 +29,7 @@ #include <QtCore/QTimer> #include <QtCore/QDebug> #include <QtCore/QFileInfo> +#include <QtCore/QHashFunctions> #include <QtGui/QGuiApplication> #include <QtGui/QImage> @@ -134,11 +135,9 @@ private: }; -Q_CORE_EXPORT extern QBasicAtomicInt qt_qhash_seed; - int main(int argc, char *argv[]) { - qt_qhash_seed = 0; + qSetGlobalQHashSeed(0); QGuiApplication a(argc, argv); diff --git a/tools/qml/main.cpp b/tools/qml/main.cpp index 1699d3d81b..53dd35da07 100644 --- a/tools/qml/main.cpp +++ b/tools/qml/main.cpp @@ -567,7 +567,7 @@ int main(int argc, char *argv[]) loadDummyDataFiles(e, dummyDir); for (const QString &path : qAsConst(files)) { - QUrl url = QUrl::fromUserInput(path, QDir::currentPath()); + QUrl url = QUrl::fromUserInput(path, QDir::currentPath(), QUrl::AssumeLocalFile); if (verboseMode) printf("qml: loading %s\n", qPrintable(url.toString())); QByteArray strippedFile; diff --git a/tools/qmlcachegen/qmlcachegen.cpp b/tools/qmlcachegen/qmlcachegen.cpp index 9a68e2ac97..657b1e8501 100644 --- a/tools/qmlcachegen/qmlcachegen.cpp +++ b/tools/qmlcachegen/qmlcachegen.cpp @@ -32,13 +32,13 @@ #include <QFile> #include <QFileInfo> #include <QDateTime> +#include <QHashFunctions> #include <private/qqmlirbuilder_p.h> #include <private/qv4isel_moth_p.h> #include <private/qqmljsparser_p.h> QT_BEGIN_NAMESPACE -extern Q_CORE_EXPORT QBasicAtomicInt qt_qhash_seed; namespace QV4 { namespace JIT { Q_QML_EXPORT QV4::EvalISelFactory *createISelForArchitecture(const QString &architecture); @@ -291,7 +291,7 @@ static bool compileJSFile(const QString &inputFileName, const QString &outputFil int main(int argc, char **argv) { // Produce reliably the same output for the same input by disabling QHash's random seeding. - qt_qhash_seed.testAndSetRelaxed(-1, 0); + qSetGlobalQHashSeed(0); QCoreApplication app(argc, argv); QCoreApplication::setApplicationName(QStringLiteral("qmlcachegen")); diff --git a/tools/qmljs/qmljs.cpp b/tools/qmljs/qmljs.cpp index 081e0660d5..182547490d 100644 --- a/tools/qmljs/qmljs.cpp +++ b/tools/qmljs/qmljs.cpp @@ -157,7 +157,7 @@ int main(int argc, char *argv[]) if (cache && QFile::exists(fn + QLatin1Char('c'))) { QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit = iSelFactory->createUnitForLoading(); QString error; - if (unit->loadFromDisk(QUrl::fromLocalFile(fn), iSelFactory, &error)) { + if (unit->loadFromDisk(QUrl::fromLocalFile(fn), QFileInfo(fn).lastModified(), iSelFactory, &error)) { script.reset(new QV4::Script(&vm, nullptr, unit)); } else { std::cout << "Error loading" << qPrintable(fn) << "from disk cache:" << qPrintable(error) << std::endl; diff --git a/tools/qmlprofiler/qmlprofilerdata.cpp b/tools/qmlprofiler/qmlprofilerdata.cpp index 668cb3ce2d..596ad8d47f 100644 --- a/tools/qmlprofiler/qmlprofilerdata.cpp +++ b/tools/qmlprofiler/qmlprofilerdata.cpp @@ -33,6 +33,7 @@ #include <QHash> #include <QFile> #include <QXmlStreamReader> +#include <QRegExp> #include <limits> diff --git a/tools/qmlscene/main.cpp b/tools/qmlscene/main.cpp index 1e8d91a95b..7741c4c45b 100644 --- a/tools/qmlscene/main.cpp +++ b/tools/qmlscene/main.cpp @@ -33,6 +33,7 @@ #include <QtCore/qpointer.h> #include <QtCore/qscopedpointer.h> #include <QtCore/qtextstream.h> +#include <QtCore/qregexp.h> #include <QtGui/QGuiApplication> #include <QtGui/QOpenGLFunctions> diff --git a/tools/tools.pro b/tools/tools.pro index bf39a649df..5d9d3740ce 100644 --- a/tools/tools.pro +++ b/tools/tools.pro @@ -10,7 +10,7 @@ SUBDIRS += \ qml \ qmllint - qtConfig(qml-network):!contains(QT_CONFIG, no-qml-debug): SUBDIRS += qmlprofiler + qtConfig(qml-profiler): SUBDIRS += qmlprofiler qtHaveModule(quick) { !static: { @@ -18,7 +18,7 @@ SUBDIRS += \ qmlscene \ qmltime - qtConfig(regularexpression) { + qtConfig(regularexpression):qtConfig(process) { SUBDIRS += \ qmlplugindump } |