aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2017-03-23 14:37:05 +0100
committerSimon Hausmann <simon.hausmann@qt.io>2017-03-23 14:43:46 +0100
commit24d0266ee45cf6a3c5b9142453966199702fbf90 (patch)
tree3484070112f5d4cbd1da4683398d0b41d748be65
parent12569460e765ea01935ab60e06b5a5acf770ebe7 (diff)
parent8f5366aed675ce7928448be2f6d739d0548b350e (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
-rw-r--r--examples/quick/demos/stocqt/content/StockListModel.qml35
-rw-r--r--src/imports/builtins/builtins.qmltypes32
-rw-r--r--src/imports/imports.pro2
-rw-r--r--src/imports/particles/plugins.qmltypes6
-rw-r--r--src/imports/qtquick2/plugins.qmltypes114
-rw-r--r--src/imports/testlib/plugins.qmltypes42
-rw-r--r--src/imports/window/plugins.qmltypes56
-rw-r--r--src/particles/particles.pri10
-rw-r--r--src/particles/qquickparticlesmodule.cpp6
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp87
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h26
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp17
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.h21
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp45
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h6
-rw-r--r--src/plugins/scenegraph/openvg/openvg.pro7
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgcontext.cpp5
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgcontext_p.h2
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.cpp4
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.h2
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgspritenode.h2
-rw-r--r--src/qml/compiler/qv4codegen.cpp4
-rw-r--r--src/qml/compiler/qv4compilationunitmapper.cpp7
-rw-r--r--src/qml/compiler/qv4compilationunitmapper_p.h4
-rw-r--r--src/qml/compiler/qv4compilationunitmapper_unix.cpp5
-rw-r--r--src/qml/compiler/qv4compilationunitmapper_win.cpp4
-rw-r--r--src/qml/compiler/qv4compileddata.cpp7
-rw-r--r--src/qml/compiler/qv4compileddata_p.h18
-rw-r--r--src/qml/compiler/qv4compiler.cpp2
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h2
-rw-r--r--src/qml/compiler/qv4isel_moth.cpp75
-rw-r--r--src/qml/compiler/qv4isel_moth_p.h2
-rw-r--r--src/qml/compiler/qv4jsir_p.h4
-rw-r--r--src/qml/configure.json13
-rw-r--r--src/qml/jit/qv4assembler.cpp33
-rw-r--r--src/qml/jit/qv4assembler_p.h25
-rw-r--r--src/qml/jit/qv4binop.cpp10
-rw-r--r--src/qml/jit/qv4binop_p.h4
-rw-r--r--src/qml/jit/qv4isel_masm.cpp30
-rw-r--r--src/qml/jit/qv4unop.cpp2
-rw-r--r--src/qml/jsruntime/qv4arraydata.cpp2
-rw-r--r--src/qml/jsruntime/qv4context.cpp4
-rw-r--r--src/qml/jsruntime/qv4context_p.h64
-rw-r--r--src/qml/jsruntime/qv4engine.cpp3
-rw-r--r--src/qml/jsruntime/qv4engine_p.h4
-rw-r--r--src/qml/jsruntime/qv4global_p.h2
-rw-r--r--src/qml/jsruntime/qv4lookup_p.h6
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp14
-rw-r--r--src/qml/jsruntime/qv4runtimeapi_p.h388
-rw-r--r--src/qml/jsruntime/qv4scopedvalue_p.h2
-rw-r--r--src/qml/jsruntime/qv4script_p.h2
-rw-r--r--src/qml/jsruntime/qv4value_p.h2
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp162
-rw-r--r--src/qml/memory/qv4heap_p.h6
-rw-r--r--src/qml/memory/qv4mm.cpp16
-rw-r--r--src/qml/memory/qv4mmdefs_p.h19
-rw-r--r--src/qml/memory/qv4writebarrier_p.h5
-rw-r--r--src/qml/qml/qqmlengine.cpp2
-rw-r--r--src/qml/qml/qqmlmetatype.cpp12
-rw-r--r--src/qml/qml/qqmlnotifier.cpp4
-rw-r--r--src/qml/qml/qqmltypeloader.cpp114
-rw-r--r--src/qml/qml/qqmltypeloader_p.h31
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp2
-rw-r--r--src/quick/configure.json9
-rw-r--r--src/quick/items/context2d/qquickcanvasitem.cpp1
-rw-r--r--src/quick/items/context2d/qquickcontext2d.cpp10
-rw-r--r--src/quick/items/qquickevents.cpp8
-rw-r--r--src/quick/items/qquickflickable.cpp6
-rw-r--r--src/quick/items/qquickitemsmodule.cpp2
-rw-r--r--src/quick/items/qquickpainteditem_p.h1
-rw-r--r--src/quick/items/qquickshadereffect.cpp2
-rw-r--r--src/quick/items/qquickshadereffect_p.h2
-rw-r--r--src/src.pro2
-rw-r--r--tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp2
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp118
-rw-r--r--tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp82
-rw-r--r--tests/auto/qml/qml.pro7
-rw-r--r--tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp2
-rw-r--r--tests/auto/qml/qmlmin/tst_qmlmin.cpp8
-rw-r--r--tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp2
-rw-r--r--tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp28
-rw-r--r--tests/auto/qml/v4misc/tst_v4misc.cpp10
-rw-r--r--tests/auto/quick/examples/tst_examples.cpp1
-rw-r--r--tests/auto/toolsupport/tst_toolsupport.cpp4
-rw-r--r--tests/benchmarks/qml/holistic/testtypes.h1
-rw-r--r--tests/manual/scenegraph_lancelot/scenegrabber/main.cpp5
-rw-r--r--tools/qml/main.cpp2
-rw-r--r--tools/qmlcachegen/qmlcachegen.cpp4
-rw-r--r--tools/qmljs/qmljs.cpp2
-rw-r--r--tools/qmlprofiler/qmlprofilerdata.cpp1
-rw-r--r--tools/qmlscene/main.cpp1
-rw-r--r--tools/tools.pro4
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
}