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:
Simon Hausmann 2017-03-23 14:37:05 +01:00
commit 24d0266ee4
92 changed files with 1208 additions and 767 deletions

View File

@ -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) + "%");
}
}
}
}

View File

@ -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" }
}

View File

@ -20,7 +20,7 @@ qtHaveModule(quick) {
sharedimage \
testlib
qtConfig(quick-shadereffect):qtConfig(quick-sprite):qtConfig(opengl(es1|es2)?): \
qtConfig(quick-particles): \
SUBDIRS += particles
}

View File

@ -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" }
}
}

View File

@ -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 {

View File

@ -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"

View File

@ -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" }

View File

@ -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 \

View File

@ -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");

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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) {

View File

@ -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;

View File

@ -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
}

View File

@ -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)
{

View File

@ -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;
};

View File

@ -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 *)
{

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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())

View File

@ -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;

View File

@ -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.

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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>

View File

@ -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

View File

@ -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" ]
}
},

View File

@ -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();

View File

@ -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))))
{
}

View File

@ -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] = {

View File

@ -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;

View File

@ -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

View File

@ -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)

View File

@ -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;
}

View File

@ -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;

View File

@ -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)

View File

@ -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);

View File

@ -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 };

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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;

View File

@ -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)

View File

@ -68,8 +68,6 @@ namespace Heap {
struct Base;
}
typedef uint Bool;
struct Q_QML_PRIVATE_EXPORT Value
{
private:

View File

@ -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

View File

@ -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);
}

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;
}
}
}

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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()) {

View File

@ -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",

View File

@ -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>

View File

@ -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);

View File

@ -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.
*/

View File

@ -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.
*/
/*!

View File

@ -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

View File

@ -51,6 +51,7 @@
// We mean it.
//
#include "qquickpainteditem.h"
#include "qquickitem_p.h"
#include "qquickpainteditem.h"
#include <QtGui/qcolor.h>

View File

@ -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

View File

@ -117,7 +117,9 @@ public:
bool isComponentComplete() const;
QString parseLog();
#if QT_CONFIG(opengl)
bool isOpenGLShaderEffect() const;
#endif
Q_SIGNALS:
void fragmentShaderChanged();

View File

@ -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
}

View File

@ -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));

View File

@ -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)

View File

@ -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"

View File

@ -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

View File

@ -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()

View File

@ -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);

View 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

View File

@ -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()

View File

@ -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

View File

@ -29,7 +29,6 @@
#include <qtest.h>
#include <QLibraryInfo>
#include <QDir>
#include <QProcess>
#include <QDebug>
#include <QtQuick/QQuickItem>
#include <QtQuick/QQuickView>

View File

@ -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;
}
{

View File

@ -43,6 +43,7 @@
#include <QtQml/qjsvalue.h>
#include <QtQml/qqmlscriptstring.h>
#include <QtQml/qqmlcomponent.h>
#include <QtCore/qregexp.h>
class MyQmlAttachedObject : public QObject
{

View File

@ -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);

View File

@ -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;

View File

@ -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"));

View File

@ -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;

View File

@ -33,6 +33,7 @@
#include <QHash>
#include <QFile>
#include <QXmlStreamReader>
#include <QRegExp>
#include <limits>

View File

@ -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>

View File

@ -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
}