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
This commit is contained in:
commit
24d0266ee4
|
@ -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) + "%");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -149,6 +149,25 @@ Module {
|
|||
"AlignCenter": 132
|
||||
}
|
||||
}
|
||||
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: {
|
||||
|
@ -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" }
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ qtHaveModule(quick) {
|
|||
sharedimage \
|
||||
testlib
|
||||
|
||||
qtConfig(quick-shadereffect):qtConfig(quick-sprite):qtConfig(opengl(es1|es2)?): \
|
||||
qtConfig(quick-particles): \
|
||||
SUBDIRS += particles
|
||||
}
|
||||
|
||||
|
|
|
@ -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" }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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: []
|
||||
|
@ -439,6 +439,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"
|
||||
|
@ -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: {
|
||||
|
@ -2209,18 +2233,6 @@ Module {
|
|||
type: "bool"
|
||||
Parameter { name: "point"; type: "QPointF" }
|
||||
}
|
||||
Method {
|
||||
name: "mapToGlobal"
|
||||
revision: 7
|
||||
type: "QPointF"
|
||||
Parameter { name: "point"; type: "QPointF" }
|
||||
}
|
||||
Method {
|
||||
name: "mapFromGlobal"
|
||||
revision: 7
|
||||
type: "QPointF"
|
||||
Parameter { name: "point"; type: "QPointF" }
|
||||
}
|
||||
Method {
|
||||
name: "mapFromItem"
|
||||
Parameter { type: "QQmlV4Function"; isPointer: true }
|
||||
|
@ -2229,6 +2241,16 @@ Module {
|
|||
name: "mapToItem"
|
||||
Parameter { type: "QQmlV4Function"; isPointer: true }
|
||||
}
|
||||
Method {
|
||||
name: "mapFromGlobal"
|
||||
revision: 7
|
||||
Parameter { type: "QQmlV4Function"; isPointer: true }
|
||||
}
|
||||
Method {
|
||||
name: "mapToGlobal"
|
||||
revision: 7
|
||||
Parameter { type: "QQmlV4Function"; isPointer: true }
|
||||
}
|
||||
Method { name: "forceActiveFocus" }
|
||||
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: {
|
||||
|
@ -2494,6 +2525,10 @@ Module {
|
|||
name: "released"
|
||||
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 {
|
||||
|
|
|
@ -4,10 +4,44 @@ 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"
|
||||
|
@ -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"
|
||||
|
|
|
@ -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" }
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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 *)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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" ]
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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))))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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] = {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) \
|
||||
Member(class, ValueArray, ValueArray, locals)
|
||||
#else
|
||||
#define CallContextMembers(class, Member) \
|
||||
Member(class, Pointer, FunctionObject *, function) \
|
||||
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)
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 };
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
{ }
|
||||
Runtime();
|
||||
|
||||
// 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));
|
||||
|
||||
// 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));
|
||||
#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
|
||||
|
||||
// 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));
|
||||
void *runtimeMethods[RuntimeMethodCount];
|
||||
|
||||
RUNTIME_METHOD(Bool, compareInstanceof, (ExecutionEngine *engine, const Value &left, const Value &right));
|
||||
RUNTIME_METHOD(Bool, compareIn, (ExecutionEngine *engine, const Value &left, const Value &right));
|
||||
static uint runtimeMethodOffset(RuntimeMethods method) { return method*QT_POINTER_SIZE; }
|
||||
|
||||
// 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));
|
||||
#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
|
||||
|
||||
// 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));
|
||||
|
||||
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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -68,8 +68,6 @@ namespace Heap {
|
|||
struct Base;
|
||||
}
|
||||
|
||||
typedef uint Bool;
|
||||
|
||||
struct Q_QML_PRIVATE_EXPORT Value
|
||||
{
|
||||
private:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
// We mean it.
|
||||
//
|
||||
|
||||
#include "qquickpainteditem.h"
|
||||
#include "qquickitem_p.h"
|
||||
#include "qquickpainteditem.h"
|
||||
#include <QtGui/qcolor.h>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -117,7 +117,9 @@ public:
|
|||
bool isComponentComplete() const;
|
||||
QString parseLog();
|
||||
|
||||
#if QT_CONFIG(opengl)
|
||||
bool isOpenGLShaderEffect() const;
|
||||
#endif
|
||||
|
||||
Q_SIGNALS:
|
||||
void fragmentShaderChanged();
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
#include <qtest.h>
|
||||
#include <QLibraryInfo>
|
||||
#include <QDir>
|
||||
#include <QProcess>
|
||||
#include <QDebug>
|
||||
#include <QtQuick/QQuickItem>
|
||||
#include <QtQuick/QQuickView>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include <QtQml/qjsvalue.h>
|
||||
#include <QtQml/qqmlscriptstring.h>
|
||||
#include <QtQml/qqmlcomponent.h>
|
||||
#include <QtCore/qregexp.h>
|
||||
|
||||
class MyQmlAttachedObject : public QObject
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <QHash>
|
||||
#include <QFile>
|
||||
#include <QXmlStreamReader>
|
||||
#include <QRegExp>
|
||||
|
||||
#include <limits>
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue